• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef REMOTING_BASE_TYPED_BUFFER_H_
6 #define REMOTING_BASE_TYPED_BUFFER_H_
7 
8 #include <assert.h>
9 
10 #include <algorithm>
11 
12 #include "base/basictypes.h"
13 #include "base/move.h"
14 
15 namespace remoting {
16 
17 // A scoper for a variable-length structure such as SID, SECURITY_DESCRIPTOR and
18 // similar. These structures typically consist of a header followed by variable-
19 // length data, so the size may not match sizeof(T). The class supports
20 // move-only semantics and typed buffer getters.
21 template <typename T>
22 class TypedBuffer {
MOVE_ONLY_TYPE_FOR_CPP_03(TypedBuffer,RValue)23   MOVE_ONLY_TYPE_FOR_CPP_03(TypedBuffer, RValue)
24 
25  public:
26   TypedBuffer() : buffer_(NULL), length_(0) {
27   }
28 
29   // Creates an instance of the object allocating a buffer of the given size.
TypedBuffer(uint32 length)30   explicit TypedBuffer(uint32 length) : buffer_(NULL), length_(length) {
31     if (length_ > 0)
32       buffer_ = reinterpret_cast<T*>(new uint8[length_]);
33   }
34 
35   // Move constructor for C++03 move emulation of this type.
TypedBuffer(RValue rvalue)36   TypedBuffer(RValue rvalue) : buffer_(NULL), length_(0) {
37     TypedBuffer temp;
38     temp.Swap(*rvalue.object);
39     Swap(temp);
40   }
41 
~TypedBuffer()42   ~TypedBuffer() {
43     if (buffer_) {
44       delete[] reinterpret_cast<uint8*>(buffer_);
45       buffer_ = NULL;
46     }
47   }
48 
49   // Move operator= for C++03 move emulation of this type.
50   TypedBuffer& operator=(RValue rvalue) {
51     TypedBuffer temp;
52     temp.Swap(*rvalue.object);
53     Swap(temp);
54     return *this;
55   }
56 
57   // Accessors to get the owned buffer.
58   // operator* and operator-> will assert() if there is no current buffer.
59   T& operator*() const {
60     assert(buffer_ != NULL);
61     return *buffer_;
62   }
63   T* operator->() const  {
64     assert(buffer_ != NULL);
65     return buffer_;
66   }
get()67   T* get() const { return buffer_; }
68 
length()69   uint32 length() const { return length_; }
70 
71   // Helper returning a pointer to the structure starting at a specified byte
72   // offset.
GetAtOffset(uint32 offset)73   T* GetAtOffset(uint32 offset) {
74     return reinterpret_cast<T*>(reinterpret_cast<uint8*>(buffer_) + offset);
75   }
76 
77   // Allow TypedBuffer<T> to be used in boolean expressions, but not
78   // implicitly convertible to a real bool (which is dangerous).
79   typedef T* TypedBuffer::*Testable;
Testable()80   operator Testable() const { return buffer_ ? &TypedBuffer::buffer_ : NULL; }
81 
82   // Swap two buffers.
Swap(TypedBuffer & other)83   void Swap(TypedBuffer& other) {
84     std::swap(buffer_, other.buffer_);
85     std::swap(length_, other.length_);
86   }
87 
88  private:
89   // Points to the owned buffer.
90   T* buffer_;
91 
92   // Length of the owned buffer in bytes.
93   uint32 length_;
94 };
95 
96 }  // namespace remoting
97 
98 #endif  // REMOTING_BASE_TYPED_BUFFER_H_
99