Path: blob/main_old/src/libANGLE/BinaryStream.h
1693 views
//1// Copyright 2012 The ANGLE Project Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file.4//56// BinaryStream.h: Provides binary serialization of simple types.78#ifndef LIBANGLE_BINARYSTREAM_H_9#define LIBANGLE_BINARYSTREAM_H_1011#include <stdint.h>12#include <cstddef>13#include <string>14#include <vector>1516#include "common/angleutils.h"17#include "common/mathutil.h"1819namespace gl20{21template <typename IntT>22struct PromotedIntegerType23{24using type = typename std::conditional<25std::is_signed<IntT>::value,26typename std::conditional<sizeof(IntT) <= 4, int32_t, int64_t>::type,27typename std::conditional<sizeof(IntT) <= 4, uint32_t, uint64_t>::type>::type;28};2930class BinaryInputStream : angle::NonCopyable31{32public:33BinaryInputStream(const void *data, size_t length)34{35mError = false;36mOffset = 0;37mData = static_cast<const uint8_t *>(data);38mLength = length;39}4041// readInt will generate an error for bool types42template <class IntT>43IntT readInt()44{45static_assert(!std::is_same<bool, std::remove_cv<IntT>()>(), "Use readBool");46using PromotedIntT = typename PromotedIntegerType<IntT>::type;47PromotedIntT value = 0;48read(&value);49ASSERT(angle::IsValueInRangeForNumericType<IntT>(value));50return static_cast<IntT>(value);51}5253template <class IntT>54void readInt(IntT *outValue)55{56*outValue = readInt<IntT>();57}5859template <class IntT, class VectorElementT>60void readIntVector(std::vector<VectorElementT> *param)61{62size_t size = readInt<size_t>();63for (size_t index = 0; index < size; ++index)64{65param->push_back(readInt<IntT>());66}67}6869template <class EnumT>70EnumT readEnum()71{72using UnderlyingType = typename std::underlying_type<EnumT>::type;73return static_cast<EnumT>(readInt<UnderlyingType>());74}7576template <class EnumT>77void readEnum(EnumT *outValue)78{79*outValue = readEnum<EnumT>();80}8182bool readBool()83{84int value = 0;85read(&value);86return (value > 0);87}8889void readBool(bool *outValue) { *outValue = readBool(); }9091void readBytes(unsigned char outArray[], size_t count) { read<unsigned char>(outArray, count); }9293std::string readString()94{95std::string outString;96readString(&outString);97return outString;98}99100void readString(std::string *v)101{102size_t length;103readInt(&length);104105if (mError)106{107return;108}109110angle::CheckedNumeric<size_t> checkedOffset(mOffset);111checkedOffset += length;112113if (!checkedOffset.IsValid() || mOffset + length > mLength)114{115mError = true;116return;117}118119v->assign(reinterpret_cast<const char *>(mData) + mOffset, length);120mOffset = checkedOffset.ValueOrDie();121}122123float readFloat()124{125float f;126read(&f, 1);127return f;128}129130void skip(size_t length)131{132angle::CheckedNumeric<size_t> checkedOffset(mOffset);133checkedOffset += length;134135if (!checkedOffset.IsValid() || mOffset + length > mLength)136{137mError = true;138return;139}140141mOffset = checkedOffset.ValueOrDie();142}143144size_t offset() const { return mOffset; }145size_t remainingSize() const146{147ASSERT(mLength >= mOffset);148return mLength - mOffset;149}150151bool error() const { return mError; }152153bool endOfStream() const { return mOffset == mLength; }154155const uint8_t *data() { return mData; }156157private:158bool mError;159size_t mOffset;160const uint8_t *mData;161size_t mLength;162163template <typename T>164void read(T *v, size_t num)165{166static_assert(std::is_fundamental<T>::value, "T must be a fundamental type.");167168angle::CheckedNumeric<size_t> checkedLength(num);169checkedLength *= sizeof(T);170if (!checkedLength.IsValid())171{172mError = true;173return;174}175176angle::CheckedNumeric<size_t> checkedOffset(mOffset);177checkedOffset += checkedLength;178179if (!checkedOffset.IsValid() || checkedOffset.ValueOrDie() > mLength)180{181mError = true;182return;183}184185memcpy(v, mData + mOffset, checkedLength.ValueOrDie());186mOffset = checkedOffset.ValueOrDie();187}188189template <typename T>190void read(T *v)191{192read(v, 1);193}194};195196class BinaryOutputStream : angle::NonCopyable197{198public:199BinaryOutputStream();200~BinaryOutputStream();201202// writeInt also handles bool types203template <class IntT>204void writeInt(IntT param)205{206static_assert(std::is_integral<IntT>::value, "Not an integral type");207static_assert(!std::is_same<bool, std::remove_cv<IntT>()>(), "Use writeBool");208using PromotedIntT = typename PromotedIntegerType<IntT>::type;209ASSERT(angle::IsValueInRangeForNumericType<PromotedIntT>(param));210PromotedIntT intValue = static_cast<PromotedIntT>(param);211write(&intValue, 1);212}213214// Specialized writeInt for values that can also be exactly -1.215template <class UintT>216void writeIntOrNegOne(UintT param)217{218if (param == static_cast<UintT>(-1))219{220writeInt(-1);221}222else223{224writeInt(param);225}226}227228template <class IntT>229void writeIntVector(const std::vector<IntT> ¶m)230{231writeInt(param.size());232for (IntT element : param)233{234writeIntOrNegOne(element);235}236}237238template <class EnumT>239void writeEnum(EnumT param)240{241using UnderlyingType = typename std::underlying_type<EnumT>::type;242writeInt<UnderlyingType>(static_cast<UnderlyingType>(param));243}244245void writeString(const std::string &v)246{247writeInt(v.length());248write(v.c_str(), v.length());249}250251void writeBytes(const unsigned char *bytes, size_t count) { write(bytes, count); }252253void writeBool(bool value)254{255int intValue = value ? 1 : 0;256write(&intValue, 1);257}258259void writeFloat(float value) { write(&value, 1); }260261size_t length() const { return mData.size(); }262263const void *data() const { return mData.size() ? &mData[0] : nullptr; }264265const std::vector<uint8_t> &getData() const { return mData; }266267private:268template <typename T>269void write(const T *v, size_t num)270{271static_assert(std::is_fundamental<T>::value, "T must be a fundamental type.");272const char *asBytes = reinterpret_cast<const char *>(v);273mData.insert(mData.end(), asBytes, asBytes + num * sizeof(T));274}275276std::vector<uint8_t> mData;277};278279inline BinaryOutputStream::BinaryOutputStream() {}280281inline BinaryOutputStream::~BinaryOutputStream() = default;282283} // namespace gl284285#endif // LIBANGLE_BINARYSTREAM_H_286287288