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"
13 #if defined(WIN32) || defined(WIN64)
16 #include <arpa/inet.h>
21 void DataBuffer::Assign(const uint8_t* d
, size_t l
) {
24 memcpy(static_cast<void*>(data_
), static_cast<const void*>(d
), l
);
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
) {
36 if (index
+ count
> len_
) {
37 size_t newlen
= index
+ count
;
38 uint8_t* tmp
= new uint8_t[newlen
]; // Always > 0.
40 memcpy(static_cast<void*>(tmp
), static_cast<const void*>(data_
), len_
);
43 memset(static_cast<void*>(tmp
+ len_
), 0, index
- len_
);
50 memcpy(static_cast<void*>(data_
+ index
), static_cast<const void*>(val
),
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
,
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.
79 Write(0, old_value
, (std::min
)(old_len
, index
));
82 if (old_value
&& index
> old_len
) {
83 memset(old_value
+ index
, 0, index
- old_len
);
86 Write(index
, ins
, ins_len
);
87 // The tail of the old.
89 Write(index
+ ins_len
, old_value
+ index
+ remove
, tail_len
);
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));
100 if ((index
> len()) || (count
> (len() - index
))) {
104 for (size_t i
= 0; i
< count
; ++i
) {
105 *val
= (*val
<< 8) | data()[index
+ i
];
110 bool DataBuffer::Read(size_t index
, size_t count
, uint32_t* val
) const {
111 assert(count
<= sizeof(uint32_t));
114 if (!Read(index
, count
, &tmp
)) {
117 *val
= tmp
& 0xffffffff;
121 size_t DataBuffer::logging_limit
= 32;
123 /* static */ void DataBuffer::SetLogLimit(size_t limit
) {
124 DataBuffer::logging_limit
= limit
;
127 } // namespace nss_test