- }
- u[i] = (std::uint8_t)v;
-
- stream.write(reinterpret_cast<char*>(u), sizeof(IntType));
- }
- }
-
-
- // read_little_endian(s, out, N) : read integers in bulk from a little indian stream.
- // This reads N integers from stream s and put them in array out.
- template <typename IntType>
- inline void read_little_endian(std::istream& stream, IntType* out, std::size_t count) {
- if (IsLittleEndian)
- stream.read(reinterpret_cast<char*>(out), sizeof(IntType) * count);
- else
- for (std::size_t i = 0; i < count; ++i)
- out[i] = read_little_endian<IntType>(stream);
- }
-
-
- // write_little_endian(s, values, N) : write integers in bulk to a little indian stream.
- // This takes N integers from array values and writes them on stream s.
- template <typename IntType>
- inline void write_little_endian(std::ostream& stream, const IntType* values, std::size_t count) {
- if (IsLittleEndian)
- stream.write(reinterpret_cast<const char*>(values), sizeof(IntType) * count);
- else
- for (std::size_t i = 0; i < count; ++i)
- write_little_endian<IntType>(stream, values[i]);
- }
-
-
- // read_leb_128(s, out, N) : read N signed integers from the stream s, putting them in
- // the array out. The stream is assumed to be compressed using the signed LEB128 format.
- // See https://en.wikipedia.org/wiki/LEB128 for a description of the compression scheme.
- template <typename IntType>
- inline void read_leb_128(std::istream& stream, IntType* out, std::size_t count) {
-
- // Check the presence of our LEB128 magic string
- char leb128MagicString[Leb128MagicStringSize];
- stream.read(leb128MagicString, Leb128MagicStringSize);
- assert(strncmp(Leb128MagicString, leb128MagicString, Leb128MagicStringSize) == 0);
-
- static_assert(std::is_signed_v<IntType>, "Not implemented for unsigned types");
-
- const std::uint32_t BUF_SIZE = 4096;
- std::uint8_t buf[BUF_SIZE];
-
- auto bytes_left = read_little_endian<std::uint32_t>(stream);
-
- std::uint32_t buf_pos = BUF_SIZE;
- for (std::size_t i = 0; i < count; ++i)
- {
- IntType result = 0;
- size_t shift = 0;
- do
- {
- if (buf_pos == BUF_SIZE)
- {
- stream.read(reinterpret_cast<char*>(buf), std::min(bytes_left, BUF_SIZE));
- buf_pos = 0;
- }
-
- std::uint8_t byte = buf[buf_pos++];
- --bytes_left;
- result |= (byte & 0x7f) << shift;
- shift += 7;
-
- if ((byte & 0x80) == 0)
- {
- out[i] = (sizeof(IntType) * 8 <= shift || (byte & 0x40) == 0) ? result
- : result | ~((1 << shift) - 1);
- break;
- }
- }
- while (shift < sizeof(IntType) * 8);
- }
-
- assert(bytes_left == 0);
- }
-
-
- // write_leb_128(s, values, N) : write signed integers to a stream with LEB128 compression.
- // This takes N integers from array values, compress them with the LEB128 algorithm and
- // writes the result on the stream s.
- // See https://en.wikipedia.org/wiki/LEB128 for a description of the compression scheme.
- template <typename IntType>
- inline void write_leb_128(std::ostream& stream, const IntType* values, std::size_t count) {
-
- // Write our LEB128 magic string
- stream.write(Leb128MagicString, Leb128MagicStringSize);
-
- static_assert(std::is_signed_v<IntType>, "Not implemented for unsigned types");
-
- std::uint32_t byte_count = 0;
- for (std::size_t i = 0; i < count; ++i)
- {
- IntType value = values[i];
- std::uint8_t byte;
- do
- {
- byte = value & 0x7f;
- value >>= 7;
- ++byte_count;
- }
- while ((byte & 0x40) == 0 ? value != 0 : value != -1);
- }
-
- write_little_endian(stream, byte_count);
-
- const std::uint32_t BUF_SIZE = 4096;
- std::uint8_t buf[BUF_SIZE];
- std::uint32_t buf_pos = 0;
-
- auto flush = [&]() {
- if (buf_pos > 0)
- {
- stream.write(reinterpret_cast<char*>(buf), buf_pos);
- buf_pos = 0;
- }
- };
-
- auto write = [&](std::uint8_t byte) {
- buf[buf_pos++] = byte;
- if (buf_pos == BUF_SIZE)
- flush();
- };
-
- for (std::size_t i = 0; i < count; ++i)
- {
- IntType value = values[i];
- while (true)
- {
- std::uint8_t byte = value & 0x7f;
- value >>= 7;
- if ((byte & 0x40) == 0 ? value == 0 : value == -1)
- {
- write(byte);
- break;
- }
- write(byte | 0x80);
- }
- }
-
- flush();
- }
+ }
+ u[i] = (std::uint8_t) v;
+
+ stream.write(reinterpret_cast<char*>(u), sizeof(IntType));
+ }
+}
+
+
+// read_little_endian(s, out, N) : read integers in bulk from a little indian stream.
+// This reads N integers from stream s and put them in array out.
+template<typename IntType>
+inline void read_little_endian(std::istream& stream, IntType* out, std::size_t count) {
+ if (IsLittleEndian)
+ stream.read(reinterpret_cast<char*>(out), sizeof(IntType) * count);
+ else
+ for (std::size_t i = 0; i < count; ++i)
+ out[i] = read_little_endian<IntType>(stream);
+}
+
+
+// write_little_endian(s, values, N) : write integers in bulk to a little indian stream.
+// This takes N integers from array values and writes them on stream s.
+template<typename IntType>
+inline void write_little_endian(std::ostream& stream, const IntType* values, std::size_t count) {
+ if (IsLittleEndian)
+ stream.write(reinterpret_cast<const char*>(values), sizeof(IntType) * count);
+ else
+ for (std::size_t i = 0; i < count; ++i)
+ write_little_endian<IntType>(stream, values[i]);
+}
+
+
+// read_leb_128(s, out, N) : read N signed integers from the stream s, putting them in
+// the array out. The stream is assumed to be compressed using the signed LEB128 format.
+// See https://en.wikipedia.org/wiki/LEB128 for a description of the compression scheme.
+template<typename IntType>
+inline void read_leb_128(std::istream& stream, IntType* out, std::size_t count) {
+
+ // Check the presence of our LEB128 magic string
+ char leb128MagicString[Leb128MagicStringSize];
+ stream.read(leb128MagicString, Leb128MagicStringSize);
+ assert(strncmp(Leb128MagicString, leb128MagicString, Leb128MagicStringSize) == 0);
+
+ static_assert(std::is_signed_v<IntType>, "Not implemented for unsigned types");
+
+ const std::uint32_t BUF_SIZE = 4096;
+ std::uint8_t buf[BUF_SIZE];
+
+ auto bytes_left = read_little_endian<std::uint32_t>(stream);
+
+ std::uint32_t buf_pos = BUF_SIZE;
+ for (std::size_t i = 0; i < count; ++i)
+ {
+ IntType result = 0;
+ size_t shift = 0;
+ do
+ {
+ if (buf_pos == BUF_SIZE)
+ {
+ stream.read(reinterpret_cast<char*>(buf), std::min(bytes_left, BUF_SIZE));
+ buf_pos = 0;
+ }
+
+ std::uint8_t byte = buf[buf_pos++];
+ --bytes_left;
+ result |= (byte & 0x7f) << shift;
+ shift += 7;
+
+ if ((byte & 0x80) == 0)
+ {
+ out[i] = (sizeof(IntType) * 8 <= shift || (byte & 0x40) == 0)
+ ? result
+ : result | ~((1 << shift) - 1);
+ break;
+ }
+ } while (shift < sizeof(IntType) * 8);
+ }
+
+ assert(bytes_left == 0);
+}
+
+
+// write_leb_128(s, values, N) : write signed integers to a stream with LEB128 compression.
+// This takes N integers from array values, compress them with the LEB128 algorithm and
+// writes the result on the stream s.
+// See https://en.wikipedia.org/wiki/LEB128 for a description of the compression scheme.
+template<typename IntType>
+inline void write_leb_128(std::ostream& stream, const IntType* values, std::size_t count) {
+
+ // Write our LEB128 magic string
+ stream.write(Leb128MagicString, Leb128MagicStringSize);
+
+ static_assert(std::is_signed_v<IntType>, "Not implemented for unsigned types");
+
+ std::uint32_t byte_count = 0;
+ for (std::size_t i = 0; i < count; ++i)
+ {
+ IntType value = values[i];
+ std::uint8_t byte;
+ do
+ {
+ byte = value & 0x7f;
+ value >>= 7;
+ ++byte_count;
+ } while ((byte & 0x40) == 0 ? value != 0 : value != -1);
+ }
+
+ write_little_endian(stream, byte_count);
+
+ const std::uint32_t BUF_SIZE = 4096;
+ std::uint8_t buf[BUF_SIZE];
+ std::uint32_t buf_pos = 0;
+
+ auto flush = [&]() {
+ if (buf_pos > 0)
+ {
+ stream.write(reinterpret_cast<char*>(buf), buf_pos);
+ buf_pos = 0;
+ }
+ };
+
+ auto write = [&](std::uint8_t byte) {
+ buf[buf_pos++] = byte;
+ if (buf_pos == BUF_SIZE)
+ flush();
+ };
+
+ for (std::size_t i = 0; i < count; ++i)
+ {
+ IntType value = values[i];
+ while (true)
+ {
+ std::uint8_t byte = value & 0x7f;
+ value >>= 7;
+ if ((byte & 0x40) == 0 ? value == 0 : value == -1)
+ {
+ write(byte);
+ break;
+ }
+ write(byte | 0x80);
+ }
+ }
+
+ flush();
+}