Backed out changeset e7acb4e12051 (bug 1893666) for causing xpcshell failures on...
[gecko.git] / security / nss / cpputil / databuffer.h
blob31651f8298d1fde48a71a34dfe6106a8a5589802
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef databuffer_h__
8 #define databuffer_h__
10 #include <algorithm>
11 #include <cstdint>
12 #include <cstring>
13 #include <iomanip>
14 #include <iostream>
16 namespace nss_test {
18 class DataBuffer {
19 public:
20 DataBuffer() : data_(nullptr), len_(0) {}
21 DataBuffer(const uint8_t* d, size_t l) : data_(nullptr), len_(0) {
22 Assign(d, l);
24 DataBuffer(const DataBuffer& other) : data_(nullptr), len_(0) {
25 Assign(other);
27 explicit DataBuffer(size_t l) : data_(nullptr), len_(0) { Allocate(l); }
28 ~DataBuffer() { delete[] data_; }
30 DataBuffer& operator=(const DataBuffer& other) {
31 if (&other != this) {
32 Assign(other);
34 return *this;
36 DataBuffer& operator=(DataBuffer&& other) {
37 if (this != &other) {
38 delete[] data_;
39 data_ = other.data_;
40 len_ = other.len_;
41 other.data_ = nullptr;
42 other.len_ = 0;
44 return *this;
47 void Allocate(size_t l) {
48 delete[] data_;
49 data_ = new uint8_t[l ? l : 1](); // Don't depend on new [0].
50 len_ = l;
53 void Truncate(size_t l) { len_ = (std::min)(len_, l); }
55 void Assign(const DataBuffer& other) { Assign(other.data(), other.len()); }
57 void Assign(const uint8_t* d, size_t l);
59 // Write will do a new allocation and expand the size of the buffer if needed.
60 // Returns the offset of the end of the write.
61 size_t Write(size_t index, const uint8_t* val, size_t count);
62 size_t Write(size_t index, const DataBuffer& buf) {
63 return Write(index, buf.data(), buf.len());
66 // Write an integer, also performing host-to-network order conversion.
67 // Returns the offset of the end of the write.
68 size_t Write(size_t index, uint32_t val, size_t count);
70 // Starting at |index|, remove |remove| bytes and replace them with the
71 // contents of |buf|.
72 void Splice(const DataBuffer& buf, size_t index, size_t remove = 0) {
73 Splice(buf.data(), buf.len(), index, remove);
76 void Splice(const uint8_t* ins, size_t ins_len, size_t index,
77 size_t remove = 0);
78 void Append(const DataBuffer& buf) { Splice(buf, len_); }
80 bool Read(size_t index, size_t count, uint64_t* val) const;
81 bool Read(size_t index, size_t count, uint32_t* val) const;
83 const uint8_t* data() const { return data_; }
84 uint8_t* data() { return data_; }
85 size_t len() const { return len_; }
86 bool empty() const { return len_ == 0; }
88 static void SetLogLimit(size_t limit);
89 friend std::ostream& operator<<(std::ostream& stream, const DataBuffer& buf);
91 private:
92 static size_t logging_limit;
93 uint8_t* data_;
94 size_t len_;
97 inline std::ostream& operator<<(std::ostream& stream, const DataBuffer& buf) {
98 stream << "[" << buf.len() << "] ";
99 for (size_t i = 0; i < buf.len(); ++i) {
100 if (i >= DataBuffer::logging_limit) {
101 stream << "...";
102 break;
104 stream << std::hex << std::setfill('0') << std::setw(2)
105 << static_cast<unsigned>(buf.data()[i]);
107 stream << std::dec;
108 return stream;
111 inline bool operator==(const DataBuffer& a, const DataBuffer& b) {
112 return (a.empty() && b.empty()) ||
113 (a.len() == b.len() && 0 == memcmp(a.data(), b.data(), a.len()));
116 inline bool operator!=(const DataBuffer& a, const DataBuffer& b) {
117 return !(a == b);
120 } // namespace nss_test
122 #endif