1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
9 #include "mozilla/Assertions.h"
10 #include "mozilla/CheckedInt.h"
11 #include "mozilla/EndianUtils.h"
12 #include "mozilla/EnumSet.h"
13 #include "mozilla/Range.h"
14 #include "mozilla/Span.h"
25 uint8_t* write(size_t size
) {
26 auto buf
= data
.AppendElements(size
);
31 void codeUint8(const uint8_t& val
) { *write(sizeof val
) = val
; }
34 void codeUint8(const EnumSet
<T
>& val
) {
35 // EnumSets are always represented as uint32_t values, so we need to
36 // assert that the value actually fits in a uint8 before writing it.
37 uint32_t value
= val
.serialize();
38 codeUint8(CheckedUint8(value
).value());
41 void codeUint16(const uint16_t& val
) {
42 LittleEndian::writeUint16(write(sizeof val
), val
);
45 void codeUint32(const uint32_t& val
) {
46 LittleEndian::writeUint32(write(sizeof val
), val
);
49 void codeString(const nsCString
& str
) {
50 auto len
= CheckedUint16(str
.Length()).value();
53 memcpy(write(len
), str
.BeginReading(), len
);
56 size_t cursor() const { return cursor_
; }
58 uint8_t* Get() { return data
.Elements(); }
60 const uint8_t* Get() const { return data
.Elements(); }
63 nsTArray
<uint8_t> data
;
69 explicit InputBuffer(const Range
<uint8_t>& buffer
) : data(buffer
) {}
71 const uint8_t* read(size_t size
) {
72 MOZ_ASSERT(checkCapacity(size
));
74 auto buf
= &data
[cursor_
];
79 bool codeUint8(uint8_t& val
) {
80 if (checkCapacity(sizeof val
)) {
81 val
= *read(sizeof val
);
87 bool codeUint8(EnumSet
<T
>& val
) {
89 if (codeUint8(value
)) {
90 val
.deserialize(value
);
95 bool codeUint16(uint16_t& val
) {
96 if (checkCapacity(sizeof val
)) {
97 val
= LittleEndian::readUint16(read(sizeof val
));
102 bool codeUint32(uint32_t& val
) {
103 if (checkCapacity(sizeof val
)) {
104 val
= LittleEndian::readUint32(read(sizeof val
));
109 bool codeString(nsCString
& str
) {
111 if (codeUint16(len
)) {
112 if (checkCapacity(len
)) {
114 memcpy(str
.BeginWriting(), read(len
), len
);
120 bool error() { return error_
; }
122 bool finished() { return error_
|| !remainingCapacity(); }
124 size_t remainingCapacity() { return data
.length() - cursor_
; }
126 size_t cursor() const { return cursor_
; }
128 const uint8_t* Get() const { return data
.begin().get(); }
131 bool checkCapacity(size_t size
) {
132 if (size
> remainingCapacity()) {
141 const Range
<uint8_t>& data
;
145 } // namespace loader
146 } // namespace mozilla
148 #endif // IOBuffers_h