// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef REMOTING_BASE_TYPED_BUFFER_H_ #define REMOTING_BASE_TYPED_BUFFER_H_ #include #include #include "base/basictypes.h" #include "base/move.h" namespace remoting { // A scoper for a variable-length structure such as SID, SECURITY_DESCRIPTOR and // similar. These structures typically consist of a header followed by variable- // length data, so the size may not match sizeof(T). The class supports // move-only semantics and typed buffer getters. template class TypedBuffer { MOVE_ONLY_TYPE_FOR_CPP_03(TypedBuffer, RValue) public: TypedBuffer() : buffer_(NULL), length_(0) { } // Creates an instance of the object allocating a buffer of the given size. explicit TypedBuffer(uint32 length) : buffer_(NULL), length_(length) { if (length_ > 0) buffer_ = reinterpret_cast(new uint8[length_]); } // Move constructor for C++03 move emulation of this type. TypedBuffer(RValue rvalue) : buffer_(NULL), length_(0) { TypedBuffer temp; temp.Swap(*rvalue.object); Swap(temp); } ~TypedBuffer() { if (buffer_) { delete[] reinterpret_cast(buffer_); buffer_ = NULL; } } // Move operator= for C++03 move emulation of this type. TypedBuffer& operator=(RValue rvalue) { TypedBuffer temp; temp.Swap(*rvalue.object); Swap(temp); return *this; } // Accessors to get the owned buffer. // operator* and operator-> will assert() if there is no current buffer. T& operator*() const { assert(buffer_ != NULL); return *buffer_; } T* operator->() const { assert(buffer_ != NULL); return buffer_; } T* get() const { return buffer_; } uint32 length() const { return length_; } // Helper returning a pointer to the structure starting at a specified byte // offset. T* GetAtOffset(uint32 offset) { return reinterpret_cast(reinterpret_cast(buffer_) + offset); } // Allow TypedBuffer to be used in boolean expressions, but not // implicitly convertible to a real bool (which is dangerous). typedef T* TypedBuffer::*Testable; operator Testable() const { return buffer_ ? &TypedBuffer::buffer_ : NULL; } // Swap two buffers. void Swap(TypedBuffer& other) { std::swap(buffer_, other.buffer_); std::swap(length_, other.length_); } private: // Points to the owned buffer. T* buffer_; // Length of the owned buffer in bytes. uint32 length_; }; } // namespace remoting #endif // REMOTING_BASE_TYPED_BUFFER_H_