Home | History | Annotate | Download | only in base
      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 {
     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.
     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.
     36   TypedBuffer(RValue rvalue) : buffer_(NULL), length_(0) {
     37     TypedBuffer temp;
     38     temp.Swap(*rvalue.object);
     39     Swap(temp);
     40   }
     41 
     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   }
     67   T* get() const { return buffer_; }
     68 
     69   uint32 length() const { return length_; }
     70 
     71   // Helper returning a pointer to the structure starting at a specified byte
     72   // 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;
     80   operator Testable() const { return buffer_ ? &TypedBuffer::buffer_ : NULL; }
     81 
     82   // Swap two buffers.
     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