// 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 #include "base/logging.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) public: TypedBuffer() : TypedBuffer(0) {} // Creates an instance of the object allocating a buffer of the given size. explicit TypedBuffer(uint32_t length) : buffer_(NULL), length_(length) { if (length_ > 0) buffer_ = reinterpret_cast(new uint8_t[length_]); } TypedBuffer(TypedBuffer&& rvalue) : TypedBuffer() { Swap(rvalue); } ~TypedBuffer() { if (buffer_) { delete[] reinterpret_cast(buffer_); buffer_ = NULL; } } TypedBuffer& operator=(TypedBuffer&& rvalue) { Swap(rvalue); 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_t length() const { return length_; } // Helper returning a pointer to the structure starting at a specified byte // offset. T* GetAtOffset(uint32_t 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_t length_; }; } // namespace remoting #endif // REMOTING_BASE_TYPED_BUFFER_H_