blob: e0c1c9eab60655abae66a32747e730286d8e1e2a [file] [log] [blame]
apatrick@chromium.org8963ec22012-07-09 22:34:06 +00001//
2// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// BinaryStream.h: Provides binary serialization of simple types.
8
Geoff Lang0a73dd82014-11-19 16:18:08 -05009#ifndef LIBANGLE_BINARYSTREAM_H_
10#define LIBANGLE_BINARYSTREAM_H_
apatrick@chromium.org8963ec22012-07-09 22:34:06 +000011
apatrick@chromium.org8963ec22012-07-09 22:34:06 +000012#include "common/angleutils.h"
Jamie Madill1b2a8f92014-05-14 13:09:39 -040013#include "common/mathutil.h"
apatrick@chromium.org8963ec22012-07-09 22:34:06 +000014
Geoff Lang0b7eef72014-06-12 14:10:47 -040015#include <cstddef>
16#include <string>
17#include <vector>
Brandon Joneseb994362014-09-24 10:27:28 -070018#include <stdint.h>
Geoff Lang0b7eef72014-06-12 14:10:47 -040019
Jamie Madill5ffa95d2015-01-05 13:15:20 -050020template <typename T>
21void StaticAssertIsFundamental()
22{
Jamie Madillce4c0002015-01-12 14:46:11 -050023 // c++11 STL is not available on OSX or Android
24#if !defined(ANGLE_PLATFORM_APPLE) && !defined(ANGLE_PLATFORM_ANDROID)
Jamie Madill5ffa95d2015-01-05 13:15:20 -050025 META_ASSERT(std::is_fundamental<T>::value);
26#else
27 union { T dummy; } dummy;
28 static_cast<void>(dummy);
29#endif
30}
31
apatrick@chromium.org8963ec22012-07-09 22:34:06 +000032namespace gl
33{
34
35class BinaryInputStream
36{
37 public:
38 BinaryInputStream(const void *data, size_t length)
39 {
40 mError = false;
41 mOffset = 0;
Brandon Joneseb994362014-09-24 10:27:28 -070042 mData = static_cast<const uint8_t*>(data);
apatrick@chromium.org8963ec22012-07-09 22:34:06 +000043 mLength = length;
44 }
45
Jamie Madill1b2a8f92014-05-14 13:09:39 -040046 // readInt will generate an error for bool types
47 template <class IntT>
48 IntT readInt()
apatrick@chromium.org8963ec22012-07-09 22:34:06 +000049 {
Jamie Madill1b2a8f92014-05-14 13:09:39 -040050 int value;
51 read(&value);
52 return static_cast<IntT>(value);
apatrick@chromium.org8963ec22012-07-09 22:34:06 +000053 }
54
Jamie Madill1b2a8f92014-05-14 13:09:39 -040055 template <class IntT>
56 void readInt(IntT *outValue)
apatrick@chromium.org8963ec22012-07-09 22:34:06 +000057 {
Jamie Madill1b2a8f92014-05-14 13:09:39 -040058 *outValue = readInt<IntT>();
apatrick@chromium.org8963ec22012-07-09 22:34:06 +000059 }
60
Jamie Madill1b2a8f92014-05-14 13:09:39 -040061 bool readBool()
62 {
63 int value;
64 read(&value);
65 return (value > 0);
66 }
67
68 void readBool(bool *outValue)
69 {
70 *outValue = readBool();
71 }
72
73 void readBytes(unsigned char outArray[], size_t count)
74 {
75 read<unsigned char>(outArray, count);
76 }
77
78 std::string readString()
79 {
80 std::string outString;
81 readString(&outString);
82 return outString;
83 }
84
85 void readString(std::string *v)
apatrick@chromium.org8963ec22012-07-09 22:34:06 +000086 {
87 size_t length;
Jamie Madill1b2a8f92014-05-14 13:09:39 -040088 readInt(&length);
apatrick@chromium.org8963ec22012-07-09 22:34:06 +000089
90 if (mError)
91 {
92 return;
93 }
94
95 if (mOffset + length > mLength)
96 {
97 mError = true;
98 return;
99 }
100
Brandon Joneseb994362014-09-24 10:27:28 -0700101 v->assign(reinterpret_cast<const char *>(mData) + mOffset, length);
apatrick@chromium.org8963ec22012-07-09 22:34:06 +0000102 mOffset += length;
103 }
104
apatrick@chromium.org60dafe82012-09-05 22:26:10 +0000105 void skip(size_t length)
106 {
107 if (mOffset + length > mLength)
108 {
109 mError = true;
110 return;
111 }
112
113 mOffset += length;
114 }
115
apatrick@chromium.org6f1796f2012-07-12 01:40:11 +0000116 size_t offset() const
117 {
118 return mOffset;
119 }
120
apatrick@chromium.org8963ec22012-07-09 22:34:06 +0000121 bool error() const
122 {
123 return mError;
124 }
125
126 bool endOfStream() const
127 {
128 return mOffset == mLength;
129 }
130
Brandon Joneseb994362014-09-24 10:27:28 -0700131 const uint8_t *data()
132 {
133 return mData;
134 }
135
apatrick@chromium.org8963ec22012-07-09 22:34:06 +0000136 private:
137 DISALLOW_COPY_AND_ASSIGN(BinaryInputStream);
138 bool mError;
139 size_t mOffset;
Brandon Joneseb994362014-09-24 10:27:28 -0700140 const uint8_t *mData;
apatrick@chromium.org8963ec22012-07-09 22:34:06 +0000141 size_t mLength;
Jamie Madill1b2a8f92014-05-14 13:09:39 -0400142
143 template <typename T>
144 void read(T *v, size_t num)
145 {
Jamie Madill5ffa95d2015-01-05 13:15:20 -0500146 StaticAssertIsFundamental<T>();
Jamie Madill1b2a8f92014-05-14 13:09:39 -0400147
148 size_t length = num * sizeof(T);
149
150 if (mOffset + length > mLength)
151 {
152 mError = true;
153 return;
154 }
155
156 memcpy(v, mData + mOffset, length);
157 mOffset += length;
158 }
159
160 template <typename T>
161 void read(T *v)
162 {
163 read(v, 1);
164 }
165
apatrick@chromium.org8963ec22012-07-09 22:34:06 +0000166};
167
168class BinaryOutputStream
169{
170 public:
171 BinaryOutputStream()
172 {
173 }
174
Jamie Madill1b2a8f92014-05-14 13:09:39 -0400175 // writeInt also handles bool types
176 template <class IntT>
177 void writeInt(IntT param)
apatrick@chromium.org8963ec22012-07-09 22:34:06 +0000178 {
Jamie Madill1b2a8f92014-05-14 13:09:39 -0400179 ASSERT(rx::IsIntegerCastSafe<int>(param));
180 int intValue = static_cast<int>(param);
181 write(&intValue, 1);
Geoff Lang11c3b302014-05-13 22:33:31 +0000182 }
183
Jamie Madill1b2a8f92014-05-14 13:09:39 -0400184 void writeString(const std::string &v)
Geoff Lang11c3b302014-05-13 22:33:31 +0000185 {
Jamie Madill1b2a8f92014-05-14 13:09:39 -0400186 writeInt(v.length());
187 write(v.c_str(), v.length());
apatrick@chromium.org8963ec22012-07-09 22:34:06 +0000188 }
189
Ehsan Akhgariaa7e1662014-07-05 21:13:11 -0400190 void writeBytes(const unsigned char *bytes, size_t count)
apatrick@chromium.org8963ec22012-07-09 22:34:06 +0000191 {
Jamie Madill1b2a8f92014-05-14 13:09:39 -0400192 write(bytes, count);
apatrick@chromium.org8963ec22012-07-09 22:34:06 +0000193 }
194
apatrick@chromium.org6f1796f2012-07-12 01:40:11 +0000195 size_t length() const
apatrick@chromium.org8963ec22012-07-09 22:34:06 +0000196 {
apatrick@chromium.org6f1796f2012-07-12 01:40:11 +0000197 return mData.size();
198 }
apatrick@chromium.org8963ec22012-07-09 22:34:06 +0000199
apatrick@chromium.org6f1796f2012-07-12 01:40:11 +0000200 const void* data() const
201 {
202 return mData.size() ? &mData[0] : NULL;
apatrick@chromium.org8963ec22012-07-09 22:34:06 +0000203 }
204
205 private:
206 DISALLOW_COPY_AND_ASSIGN(BinaryOutputStream);
207 std::vector<char> mData;
Jamie Madill1b2a8f92014-05-14 13:09:39 -0400208
209 template <typename T>
210 void write(const T *v, size_t num)
211 {
Jamie Madill5ffa95d2015-01-05 13:15:20 -0500212 StaticAssertIsFundamental<T>();
Jamie Madill1b2a8f92014-05-14 13:09:39 -0400213 const char *asBytes = reinterpret_cast<const char*>(v);
214 mData.insert(mData.end(), asBytes, asBytes + num * sizeof(T));
215 }
216
apatrick@chromium.org8963ec22012-07-09 22:34:06 +0000217};
218}
219
Geoff Lang0a73dd82014-11-19 16:18:08 -0500220#endif // LIBANGLE_BINARYSTREAM_H_