Bug 1882457 - Update the release process docs for the monorepo migration. r=ahal...
[gecko.git] / security / nss / cpputil / databuffer.cc
blob1420d76b453bae3b0252411a5446d34dc9874cb5
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 #include "databuffer.h"
8 #include <algorithm>
9 #include <cassert>
10 #include <cstring>
11 #include <iomanip>
12 #include <iostream>
13 #if defined(WIN32) || defined(WIN64)
14 #include <winsock2.h>
15 #else
16 #include <arpa/inet.h>
17 #endif
19 namespace nss_test {
21 void DataBuffer::Assign(const uint8_t* d, size_t l) {
22 if (d) {
23 Allocate(l);
24 memcpy(static_cast<void*>(data_), static_cast<const void*>(d), l);
25 } else {
26 assert(l == 0);
27 data_ = nullptr;
28 len_ = 0;
32 // Write will do a new allocation and expand the size of the buffer if needed.
33 // Returns the offset of the end of the write.
34 size_t DataBuffer::Write(size_t index, const uint8_t* val, size_t count) {
35 assert(val);
36 if (index + count > len_) {
37 size_t newlen = index + count;
38 uint8_t* tmp = new uint8_t[newlen]; // Always > 0.
39 if (data_) {
40 memcpy(static_cast<void*>(tmp), static_cast<const void*>(data_), len_);
42 if (index > len_) {
43 memset(static_cast<void*>(tmp + len_), 0, index - len_);
45 delete[] data_;
46 data_ = tmp;
47 len_ = newlen;
49 if (data_) {
50 memcpy(static_cast<void*>(data_ + index), static_cast<const void*>(val),
51 count);
53 return index + count;
56 // Write an integer, also performing host-to-network order conversion.
57 // Returns the offset of the end of the write.
58 size_t DataBuffer::Write(size_t index, uint32_t val, size_t count) {
59 assert(count <= sizeof(uint32_t));
60 uint32_t nvalue = htonl(val);
61 auto* addr = reinterpret_cast<const uint8_t*>(&nvalue);
62 return Write(index, addr + sizeof(uint32_t) - count, count);
65 void DataBuffer::Splice(const uint8_t* ins, size_t ins_len, size_t index,
66 size_t remove) {
67 assert(ins);
68 uint8_t* old_value = data_;
69 size_t old_len = len_;
71 // The amount of stuff remaining from the tail of the old.
72 size_t tail_len = old_len - (std::min)(old_len, index + remove);
73 // The new length: the head of the old, the new, and the tail of the old.
74 len_ = index + ins_len + tail_len;
75 data_ = new uint8_t[len_ ? len_ : 1];
77 // The head of the old.
78 if (old_value) {
79 Write(0, old_value, (std::min)(old_len, index));
81 // Maybe a gap.
82 if (old_value && index > old_len) {
83 memset(old_value + index, 0, index - old_len);
85 // The new.
86 Write(index, ins, ins_len);
87 // The tail of the old.
88 if (tail_len > 0) {
89 Write(index + ins_len, old_value + index + remove, tail_len);
92 delete[] old_value;
95 // This can't use the same trick as Write(), since we might be reading from a
96 // smaller data source.
97 bool DataBuffer::Read(size_t index, size_t count, uint64_t* val) const {
98 assert(count <= sizeof(uint64_t));
99 assert(val);
100 if ((index > len()) || (count > (len() - index))) {
101 return false;
103 *val = 0;
104 for (size_t i = 0; i < count; ++i) {
105 *val = (*val << 8) | data()[index + i];
107 return true;
110 bool DataBuffer::Read(size_t index, size_t count, uint32_t* val) const {
111 assert(count <= sizeof(uint32_t));
112 uint64_t tmp;
114 if (!Read(index, count, &tmp)) {
115 return false;
117 *val = tmp & 0xffffffff;
118 return true;
121 size_t DataBuffer::logging_limit = 32;
123 /* static */ void DataBuffer::SetLogLimit(size_t limit) {
124 DataBuffer::logging_limit = limit;
127 } // namespace nss_test