blob: c80f7200fc3b7ff8a3d7e2df0e84b3e3f0ef40b5 [file] [log] [blame]
// 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 <assert.h>
#include <algorithm>
#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 <typename T>
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<T*>(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<uint8*>(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<T*>(reinterpret_cast<uint8*>(buffer_) + offset);
}
// Allow TypedBuffer<T> 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_