1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
|
// Copyright 2012 The Chromium Authors
// 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 <stdint.h>
#include <algorithm>
#include "base/memory/raw_ptr.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 {
public:
TypedBuffer() = default;
// Creates an instance of the object allocating a buffer of the given size.
explicit TypedBuffer(uint32_t length) : length_(length) {
if (length_ > 0) {
buffer_ = reinterpret_cast<T*>(new uint8_t[length_]);
}
}
TypedBuffer(TypedBuffer&& rvalue) : TypedBuffer() { Swap(rvalue); }
TypedBuffer(const TypedBuffer&) = delete;
TypedBuffer& operator=(const TypedBuffer&) = delete;
~TypedBuffer() {
if (buffer_) {
delete[] reinterpret_cast<uint8_t*>(buffer_.ExtractAsDangling().get());
}
}
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_);
return *buffer_;
}
T* operator->() const {
assert(buffer_);
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<T*>(reinterpret_cast<uint8_t*>(buffer_.get()) +
offset);
}
// Allow TypedBuffer<T> to be used in boolean expressions.
explicit operator bool() const { return buffer_ != nullptr; }
// Swap two buffers.
void Swap(TypedBuffer& other) {
std::swap(buffer_, other.buffer_);
std::swap(length_, other.length_);
}
private:
// Points to the owned buffer.
raw_ptr<T> buffer_ = nullptr;
// Length of the owned buffer in bytes.
uint32_t length_ = 0;
};
} // namespace remoting
#endif // REMOTING_BASE_TYPED_BUFFER_H_
|