summaryrefslogtreecommitdiffstats
path: root/gfx/angle/checkout/src/libANGLE/BinaryStream.h
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/checkout/src/libANGLE/BinaryStream.h')
-rw-r--r--gfx/angle/checkout/src/libANGLE/BinaryStream.h286
1 files changed, 286 insertions, 0 deletions
diff --git a/gfx/angle/checkout/src/libANGLE/BinaryStream.h b/gfx/angle/checkout/src/libANGLE/BinaryStream.h
new file mode 100644
index 0000000000..35672f62e8
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/BinaryStream.h
@@ -0,0 +1,286 @@
+//
+// Copyright 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// BinaryStream.h: Provides binary serialization of simple types.
+
+#ifndef LIBANGLE_BINARYSTREAM_H_
+#define LIBANGLE_BINARYSTREAM_H_
+
+#include <stdint.h>
+#include <cstddef>
+#include <string>
+#include <vector>
+
+#include "common/angleutils.h"
+#include "common/mathutil.h"
+
+namespace gl
+{
+template <typename IntT>
+struct PromotedIntegerType
+{
+ using type = typename std::conditional<
+ std::is_signed<IntT>::value,
+ typename std::conditional<sizeof(IntT) <= 4, int32_t, int64_t>::type,
+ typename std::conditional<sizeof(IntT) <= 4, uint32_t, uint64_t>::type>::type;
+};
+
+class BinaryInputStream : angle::NonCopyable
+{
+ public:
+ BinaryInputStream(const void *data, size_t length)
+ {
+ mError = false;
+ mOffset = 0;
+ mData = static_cast<const uint8_t *>(data);
+ mLength = length;
+ }
+
+ // readInt will generate an error for bool types
+ template <class IntT>
+ IntT readInt()
+ {
+ static_assert(!std::is_same<bool, std::remove_cv<IntT>()>(), "Use readBool");
+ using PromotedIntT = typename PromotedIntegerType<IntT>::type;
+ PromotedIntT value = 0;
+ read(&value);
+ ASSERT(angle::IsValueInRangeForNumericType<IntT>(value));
+ return static_cast<IntT>(value);
+ }
+
+ template <class IntT>
+ void readInt(IntT *outValue)
+ {
+ *outValue = readInt<IntT>();
+ }
+
+ template <class IntT, class VectorElementT>
+ void readIntVector(std::vector<VectorElementT> *param)
+ {
+ size_t size = readInt<size_t>();
+ for (size_t index = 0; index < size; ++index)
+ {
+ param->push_back(readInt<IntT>());
+ }
+ }
+
+ template <class EnumT>
+ EnumT readEnum()
+ {
+ using UnderlyingType = typename std::underlying_type<EnumT>::type;
+ return static_cast<EnumT>(readInt<UnderlyingType>());
+ }
+
+ template <class EnumT>
+ void readEnum(EnumT *outValue)
+ {
+ *outValue = readEnum<EnumT>();
+ }
+
+ bool readBool()
+ {
+ int value = 0;
+ read(&value);
+ return (value > 0);
+ }
+
+ void readBool(bool *outValue) { *outValue = readBool(); }
+
+ void readBytes(unsigned char outArray[], size_t count) { read<unsigned char>(outArray, count); }
+
+ std::string readString()
+ {
+ std::string outString;
+ readString(&outString);
+ return outString;
+ }
+
+ void readString(std::string *v)
+ {
+ size_t length;
+ readInt(&length);
+
+ if (mError)
+ {
+ return;
+ }
+
+ angle::CheckedNumeric<size_t> checkedOffset(mOffset);
+ checkedOffset += length;
+
+ if (!checkedOffset.IsValid() || mOffset + length > mLength)
+ {
+ mError = true;
+ return;
+ }
+
+ v->assign(reinterpret_cast<const char *>(mData) + mOffset, length);
+ mOffset = checkedOffset.ValueOrDie();
+ }
+
+ float readFloat()
+ {
+ float f;
+ read(&f, 1);
+ return f;
+ }
+
+ void skip(size_t length)
+ {
+ angle::CheckedNumeric<size_t> checkedOffset(mOffset);
+ checkedOffset += length;
+
+ if (!checkedOffset.IsValid() || mOffset + length > mLength)
+ {
+ mError = true;
+ return;
+ }
+
+ mOffset = checkedOffset.ValueOrDie();
+ }
+
+ size_t offset() const { return mOffset; }
+ size_t remainingSize() const
+ {
+ ASSERT(mLength >= mOffset);
+ return mLength - mOffset;
+ }
+
+ bool error() const { return mError; }
+
+ bool endOfStream() const { return mOffset == mLength; }
+
+ const uint8_t *data() { return mData; }
+
+ private:
+ bool mError;
+ size_t mOffset;
+ const uint8_t *mData;
+ size_t mLength;
+
+ template <typename T>
+ void read(T *v, size_t num)
+ {
+ static_assert(std::is_fundamental<T>::value, "T must be a fundamental type.");
+
+ angle::CheckedNumeric<size_t> checkedLength(num);
+ checkedLength *= sizeof(T);
+ if (!checkedLength.IsValid())
+ {
+ mError = true;
+ return;
+ }
+
+ angle::CheckedNumeric<size_t> checkedOffset(mOffset);
+ checkedOffset += checkedLength;
+
+ if (!checkedOffset.IsValid() || checkedOffset.ValueOrDie() > mLength)
+ {
+ mError = true;
+ return;
+ }
+
+ memcpy(v, mData + mOffset, checkedLength.ValueOrDie());
+ mOffset = checkedOffset.ValueOrDie();
+ }
+
+ template <typename T>
+ void read(T *v)
+ {
+ read(v, 1);
+ }
+};
+
+class BinaryOutputStream : angle::NonCopyable
+{
+ public:
+ BinaryOutputStream();
+ ~BinaryOutputStream();
+
+ // writeInt also handles bool types
+ template <class IntT>
+ void writeInt(IntT param)
+ {
+ static_assert(std::is_integral<IntT>::value, "Not an integral type");
+ static_assert(!std::is_same<bool, std::remove_cv<IntT>()>(), "Use writeBool");
+ using PromotedIntT = typename PromotedIntegerType<IntT>::type;
+ ASSERT(angle::IsValueInRangeForNumericType<PromotedIntT>(param));
+ PromotedIntT intValue = static_cast<PromotedIntT>(param);
+ write(&intValue, 1);
+ }
+
+ // Specialized writeInt for values that can also be exactly -1.
+ template <class UintT>
+ void writeIntOrNegOne(UintT param)
+ {
+ if (param == static_cast<UintT>(-1))
+ {
+ writeInt(-1);
+ }
+ else
+ {
+ writeInt(param);
+ }
+ }
+
+ template <class IntT>
+ void writeIntVector(const std::vector<IntT> &param)
+ {
+ writeInt(param.size());
+ for (IntT element : param)
+ {
+ writeIntOrNegOne(element);
+ }
+ }
+
+ template <class EnumT>
+ void writeEnum(EnumT param)
+ {
+ using UnderlyingType = typename std::underlying_type<EnumT>::type;
+ writeInt<UnderlyingType>(static_cast<UnderlyingType>(param));
+ }
+
+ void writeString(const std::string &v)
+ {
+ writeInt(v.length());
+ write(v.c_str(), v.length());
+ }
+
+ void writeBytes(const unsigned char *bytes, size_t count) { write(bytes, count); }
+
+ void writeBool(bool value)
+ {
+ int intValue = value ? 1 : 0;
+ write(&intValue, 1);
+ }
+
+ void writeFloat(float value) { write(&value, 1); }
+
+ size_t length() const { return mData.size(); }
+
+ const void *data() const { return mData.size() ? &mData[0] : nullptr; }
+
+ const std::vector<uint8_t> &getData() const { return mData; }
+
+ private:
+ template <typename T>
+ void write(const T *v, size_t num)
+ {
+ static_assert(std::is_fundamental<T>::value, "T must be a fundamental type.");
+ const char *asBytes = reinterpret_cast<const char *>(v);
+ mData.insert(mData.end(), asBytes, asBytes + num * sizeof(T));
+ }
+
+ std::vector<uint8_t> mData;
+};
+
+inline BinaryOutputStream::BinaryOutputStream() {}
+
+inline BinaryOutputStream::~BinaryOutputStream() = default;
+
+} // namespace gl
+
+#endif // LIBANGLE_BINARYSTREAM_H_