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