blob: a8cffb58179fc789168309971eef8d47cb4c66b7 [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{
23#ifndef ANGLE_PLATFORM_APPLE
24 META_ASSERT(std::is_fundamental<T>::value);
25#else
26 union { T dummy; } dummy;
27 static_cast<void>(dummy);
28#endif
29}
30
apatrick@chromium.org8963ec22012-07-09 22:34:06 +000031namespace gl
32{
33
34class BinaryInputStream
35{
36 public:
37 BinaryInputStream(const void *data, size_t length)
38 {
39 mError = false;
40 mOffset = 0;
Brandon Joneseb994362014-09-24 10:27:28 -070041 mData = static_cast<const uint8_t*>(data);
apatrick@chromium.org8963ec22012-07-09 22:34:06 +000042 mLength = length;
43 }
44
Jamie Madill1b2a8f92014-05-14 13:09:39 -040045 // readInt will generate an error for bool types
46 template <class IntT>
47 IntT readInt()
apatrick@chromium.org8963ec22012-07-09 22:34:06 +000048 {
Jamie Madill1b2a8f92014-05-14 13:09:39 -040049 int value;
50 read(&value);
51 return static_cast<IntT>(value);
apatrick@chromium.org8963ec22012-07-09 22:34:06 +000052 }
53
Jamie Madill1b2a8f92014-05-14 13:09:39 -040054 template <class IntT>
55 void readInt(IntT *outValue)
apatrick@chromium.org8963ec22012-07-09 22:34:06 +000056 {
Jamie Madill1b2a8f92014-05-14 13:09:39 -040057 *outValue = readInt<IntT>();
apatrick@chromium.org8963ec22012-07-09 22:34:06 +000058 }
59
Jamie Madill1b2a8f92014-05-14 13:09:39 -040060 bool readBool()
61 {
62 int value;
63 read(&value);
64 return (value > 0);
65 }
66
67 void readBool(bool *outValue)
68 {
69 *outValue = readBool();
70 }
71
72 void readBytes(unsigned char outArray[], size_t count)
73 {
74 read<unsigned char>(outArray, count);
75 }
76
77 std::string readString()
78 {
79 std::string outString;
80 readString(&outString);
81 return outString;
82 }
83
84 void readString(std::string *v)
apatrick@chromium.org8963ec22012-07-09 22:34:06 +000085 {
86 size_t length;
Jamie Madill1b2a8f92014-05-14 13:09:39 -040087 readInt(&length);
apatrick@chromium.org8963ec22012-07-09 22:34:06 +000088
89 if (mError)
90 {
91 return;
92 }
93
94 if (mOffset + length > mLength)
95 {
96 mError = true;
97 return;
98 }
99
Brandon Joneseb994362014-09-24 10:27:28 -0700100 v->assign(reinterpret_cast<const char *>(mData) + mOffset, length);
apatrick@chromium.org8963ec22012-07-09 22:34:06 +0000101 mOffset += length;
102 }
103
apatrick@chromium.org60dafe82012-09-05 22:26:10 +0000104 void skip(size_t length)
105 {
106 if (mOffset + length > mLength)
107 {
108 mError = true;
109 return;
110 }
111
112 mOffset += length;
113 }
114
apatrick@chromium.org6f1796f2012-07-12 01:40:11 +0000115 size_t offset() const
116 {
117 return mOffset;
118 }
119
apatrick@chromium.org8963ec22012-07-09 22:34:06 +0000120 bool error() const
121 {
122 return mError;
123 }
124
125 bool endOfStream() const
126 {
127 return mOffset == mLength;
128 }
129
Brandon Joneseb994362014-09-24 10:27:28 -0700130 const uint8_t *data()
131 {
132 return mData;
133 }
134
apatrick@chromium.org8963ec22012-07-09 22:34:06 +0000135 private:
136 DISALLOW_COPY_AND_ASSIGN(BinaryInputStream);
137 bool mError;
138 size_t mOffset;
Brandon Joneseb994362014-09-24 10:27:28 -0700139 const uint8_t *mData;
apatrick@chromium.org8963ec22012-07-09 22:34:06 +0000140 size_t mLength;
Jamie Madill1b2a8f92014-05-14 13:09:39 -0400141
142 template <typename T>
143 void read(T *v, size_t num)
144 {
Jamie Madill5ffa95d2015-01-05 13:15:20 -0500145 StaticAssertIsFundamental<T>();
Jamie Madill1b2a8f92014-05-14 13:09:39 -0400146
147 size_t length = num * sizeof(T);
148
149 if (mOffset + length > mLength)
150 {
151 mError = true;
152 return;
153 }
154
155 memcpy(v, mData + mOffset, length);
156 mOffset += length;
157 }
158
159 template <typename T>
160 void read(T *v)
161 {
162 read(v, 1);
163 }
164
apatrick@chromium.org8963ec22012-07-09 22:34:06 +0000165};
166
167class BinaryOutputStream
168{
169 public:
170 BinaryOutputStream()
171 {
172 }
173
Jamie Madill1b2a8f92014-05-14 13:09:39 -0400174 // writeInt also handles bool types
175 template <class IntT>
176 void writeInt(IntT param)
apatrick@chromium.org8963ec22012-07-09 22:34:06 +0000177 {
Jamie Madill1b2a8f92014-05-14 13:09:39 -0400178 ASSERT(rx::IsIntegerCastSafe<int>(param));
179 int intValue = static_cast<int>(param);
180 write(&intValue, 1);
Geoff Lang11c3b302014-05-13 22:33:31 +0000181 }
182
Jamie Madill1b2a8f92014-05-14 13:09:39 -0400183 void writeString(const std::string &v)
Geoff Lang11c3b302014-05-13 22:33:31 +0000184 {
Jamie Madill1b2a8f92014-05-14 13:09:39 -0400185 writeInt(v.length());
186 write(v.c_str(), v.length());
apatrick@chromium.org8963ec22012-07-09 22:34:06 +0000187 }
188
Ehsan Akhgariaa7e1662014-07-05 21:13:11 -0400189 void writeBytes(const unsigned char *bytes, size_t count)
apatrick@chromium.org8963ec22012-07-09 22:34:06 +0000190 {
Jamie Madill1b2a8f92014-05-14 13:09:39 -0400191 write(bytes, count);
apatrick@chromium.org8963ec22012-07-09 22:34:06 +0000192 }
193
apatrick@chromium.org6f1796f2012-07-12 01:40:11 +0000194 size_t length() const
apatrick@chromium.org8963ec22012-07-09 22:34:06 +0000195 {
apatrick@chromium.org6f1796f2012-07-12 01:40:11 +0000196 return mData.size();
197 }
apatrick@chromium.org8963ec22012-07-09 22:34:06 +0000198
apatrick@chromium.org6f1796f2012-07-12 01:40:11 +0000199 const void* data() const
200 {
201 return mData.size() ? &mData[0] : NULL;
apatrick@chromium.org8963ec22012-07-09 22:34:06 +0000202 }
203
204 private:
205 DISALLOW_COPY_AND_ASSIGN(BinaryOutputStream);
206 std::vector<char> mData;
Jamie Madill1b2a8f92014-05-14 13:09:39 -0400207
208 template <typename T>
209 void write(const T *v, size_t num)
210 {
Jamie Madill5ffa95d2015-01-05 13:15:20 -0500211 StaticAssertIsFundamental<T>();
Jamie Madill1b2a8f92014-05-14 13:09:39 -0400212 const char *asBytes = reinterpret_cast<const char*>(v);
213 mData.insert(mData.end(), asBytes, asBytes + num * sizeof(T));
214 }
215
apatrick@chromium.org8963ec22012-07-09 22:34:06 +0000216};
217}
218
Geoff Lang0a73dd82014-11-19 16:18:08 -0500219#endif // LIBANGLE_BINARYSTREAM_H_