1 : /* -*- c++ -*- */
2 : /*
3 : * Copyright (c) 2013 The Native Client Authors. All rights reserved.
4 : * Use of this source code is governed by a BSD-style license that can be
5 : * found in the LICENSE file.
6 : */
7 :
8 : #include "native_client/src/shared/serialization/serialization.h"
9 :
10 : #include <math.h>
11 : #include <stdio.h>
12 : #include <string.h>
13 :
14 : #include "native_client/src/shared/platform/nacl_check.h"
15 :
16 1 : int main(void) {
17 1 : nacl::SerializationBuffer buf;
18 :
19 1 : int8_t i8 = -128;
20 1 : uint8_t u8 = 127;
21 1 : int16_t i16 = -32768;
22 1 : uint16_t u16 = 65535;
23 1 : int32_t i32 = -2147483647 - 1;
24 1 : uint32_t u32 = 4294967295U;
25 1 : int64_t i64 = -2147483649LL;
26 1 : uint64_t u64 = 18446744073709551615ULL;
27 :
28 : // Check basic serialization/deserialization -- we get back what we
29 : // put in -- with various basic types and vectors. Test with some
30 : // extreme numerical values.
31 1 : CHECK(buf.Serialize<int16_t>(10));
32 1 : CHECK(buf.Serialize(i8));
33 1 : CHECK(buf.Serialize(u8));
34 1 : CHECK(buf.Serialize(i16));
35 1 : CHECK(buf.Serialize(u16));
36 1 : CHECK(buf.Serialize(i32));
37 1 : CHECK(buf.Serialize(u32));
38 1 : CHECK(buf.Serialize(i64));
39 1 : CHECK(buf.Serialize(u64));
40 :
41 1 : int8_t ci8 = 0;
42 1 : uint8_t cu8 = 0;
43 1 : int16_t ci16 = 0;
44 1 : uint16_t cu16 = 0;
45 1 : int32_t ci32 = 0;
46 1 : uint32_t cu32 = 0;
47 1 : int64_t ci64 = 0;
48 1 : uint64_t cu64 = 0;
49 :
50 1 : CHECK(buf.Deserialize(&ci16));
51 1 : CHECK(ci16 == 10);
52 : #define D(v) do { \
53 : CHECK(buf.Deserialize(&c ## v)); \
54 : CHECK(c ## v == v); \
55 : } while (0)
56 1 : D(i8);
57 1 : D(u8);
58 1 : D(i16);
59 1 : D(u16);
60 1 : D(i32);
61 1 : D(u32);
62 1 : D(i64);
63 1 : D(u64);
64 :
65 1 : CHECK(!buf.Deserialize(&ci8));
66 1 : buf.rewind();
67 :
68 1 : std::vector<int32_t> v;
69 1 : v.push_back(i32);
70 1 : v.push_back(3);
71 1 : v.push_back(1);
72 1 : v.push_back(4);
73 1 : v.push_back(1);
74 1 : v.push_back(5);
75 1 : v.push_back(9);
76 :
77 1 : CHECK(buf.Serialize(v));
78 :
79 : #if defined(NACL_HAS_IEEE_754)
80 : float e = M_E;
81 : double pi = M_PI;
82 : CHECK(buf.Serialize(e));
83 : CHECK(buf.Serialize(pi));
84 :
85 : long double e_exp_pi;
86 : e_exp_pi = powl(static_cast<long double>(e), static_cast<long double>(pi));
87 : CHECK(buf.Serialize(e_exp_pi));
88 : #endif
89 :
90 1 : CHECK(buf.Serialize("Hello world"));
91 : CHECK(buf.Serialize(
92 : "When in the Course of human events, it becomes necessary for"
93 : " one people to dissolve the political bands which have"
94 : " connected them with another, and to assume among the powers"
95 : " of the earth, the separate and equal station to which the"
96 : " Laws of Nature and of Nature's God entitle them, a decent"
97 : " respect to the opinions of mankind requires that they should"
98 1 : " declare the causes which impel them to the separation."));
99 :
100 1 : std::string msg("Goodbye cruel world");
101 :
102 1 : CHECK(buf.Serialize(msg));
103 :
104 1 : std::vector<std::string> vs;
105 :
106 1 : vs.push_back("When in the Course of human events, it becomes necessary for");
107 1 : vs.push_back(" one people to dissolve the political bands which have");
108 1 : vs.push_back(" connected them with another, and to assume among the powers");
109 1 : vs.push_back(" of the earth, the separate and equal station to which the");
110 1 : vs.push_back(" Laws of Nature and of Nature's God entitle them, a decent");
111 1 : vs.push_back(" respect to the opinions of mankind requires that they should");
112 1 : vs.push_back(" declare the causes which impel them to the separation.");
113 :
114 1 : CHECK(buf.Serialize(vs));
115 :
116 1 : buf.rewind();
117 :
118 1 : CHECK(buf.Deserialize(&ci16));
119 1 : CHECK(ci16 == 10);
120 1 : D(i8);
121 1 : D(u8);
122 1 : D(i16);
123 1 : D(u16);
124 1 : D(i32);
125 1 : D(u32);
126 1 : D(i64);
127 1 : D(u64);
128 :
129 1 : std::vector<int32_t> v2;
130 1 : CHECK(buf.Deserialize(&v2));
131 1 : CHECK(v.size() == v2.size());
132 1 : for (size_t ix = 0; ix < v.size(); ++ix) {
133 1 : CHECK(v[ix] == v2[ix]);
134 1 : }
135 : #if defined(NACL_HAS_IEEE_754)
136 : float f;
137 : CHECK(buf.Deserialize(&f));
138 : CHECK(f == e);
139 : double d;
140 : CHECK(buf.Deserialize(&d));
141 : CHECK(d == pi);
142 : long double ld;
143 : CHECK(buf.Deserialize(&ld));
144 : CHECK(ld == e_exp_pi);
145 : #endif
146 : char buffer[64];
147 1 : size_t nbytes = sizeof buffer;
148 1 : CHECK(buf.Deserialize(buffer, &nbytes));
149 1 : CHECK(nbytes == strlen("Hello world") + 1);
150 1 : CHECK(!strcmp(buffer, "Hello world"));
151 : char *obuf;
152 1 : CHECK(buf.Deserialize(&obuf));
153 : CHECK(!strcmp(obuf,
154 : "When in the Course of human events, it becomes necessary for"
155 : " one people to dissolve the political bands which have"
156 : " connected them with another, and to assume among the powers"
157 : " of the earth, the separate and equal station to which the"
158 : " Laws of Nature and of Nature's God entitle them, a decent"
159 : " respect to the opinions of mankind requires that they should"
160 1 : " declare the causes which impel them to the separation."));
161 :
162 1 : delete[] obuf;
163 :
164 1 : std::string msg2;
165 1 : CHECK(buf.Deserialize(&msg2));
166 1 : CHECK(msg2 == "Goodbye cruel world");
167 :
168 1 : std::vector<std::string> vs2;
169 :
170 1 : CHECK(buf.Deserialize(&vs2));
171 :
172 1 : CHECK(vs.size() == vs2.size());
173 1 : for (size_t ix = 0; ix < vs.size(); ++ix) {
174 1 : CHECK(vs[ix] == vs2[ix]);
175 1 : }
176 :
177 : // Check the ability to construct a SerializationBuffer from
178 : // "received data".
179 :
180 1 : buf.reset();
181 1 : CHECK(buf.Serialize(i8));
182 1 : CHECK(buf.Serialize(u8));
183 1 : CHECK(buf.Serialize(i16));
184 1 : CHECK(buf.Serialize(u16));
185 1 : CHECK(buf.Serialize(i32));
186 1 : CHECK(buf.Serialize(u32));
187 1 : CHECK(buf.Serialize(i64));
188 1 : CHECK(buf.Serialize(u64));
189 1 : CHECK(buf.Serialize(vs));
190 :
191 1 : nacl::SerializationBuffer buf2(buf.data(), buf.num_bytes());
192 : #define D2(v) do { \
193 : CHECK(buf2.Deserialize(&c ## v)); \
194 : CHECK(c ## v == v); \
195 : } while (0)
196 1 : D2(i8);
197 1 : D2(u8);
198 1 : D2(i16);
199 1 : D2(u16);
200 1 : D2(i32);
201 1 : D2(u32);
202 1 : D2(i64);
203 1 : D2(u64);
204 :
205 1 : vs2.clear();
206 1 : CHECK(buf2.Deserialize(&vs2));
207 :
208 1 : CHECK(vs.size() == vs2.size());
209 1 : for (size_t ix = 0; ix < vs.size(); ++ix) {
210 1 : CHECK(vs[ix] == vs2[ix]);
211 1 : }
212 :
213 : // Tests that use exposed implementation details.
214 :
215 : // Verify that the space needed to serialize vectors of a basic type
216 : // grows at the size of the basic type.
217 :
218 1 : buf.reset();
219 1 : CHECK(buf.Serialize(v));
220 1 : size_t v_size = buf.num_bytes();
221 1 : buf.reset();
222 1 : v.push_back(100);
223 1 : CHECK(buf.Serialize(v));
224 1 : v.pop_back();
225 1 : size_t v_prime_size = buf.num_bytes();
226 1 : CHECK(v_size + sizeof(int32_t) == v_prime_size);
227 :
228 : // Check typetag is offset based
229 1 : CHECK(buf.data()[0] >= nacl::kVectorOffset);
230 :
231 1 : CHECK(nacl::kRecursiveVector < nacl::kVectorOffset);
232 :
233 : // Check typetag is fixed, using recursive serialization
234 1 : buf.reset();
235 1 : std::vector<std::vector<int32_t> > vv;
236 1 : vv.push_back(v);
237 1 : vv.push_back(v);
238 1 : CHECK(buf.Serialize(vv));
239 1 : CHECK(buf.data()[0] == nacl::kRecursiveVector);
240 :
241 : // Check that the encoding space usage grows as expected, with the
242 : // nested vector also tagged etc. TODO(bsy): omit this test? this
243 : // may be too much implementation detail.
244 1 : size_t vv_size = buf.num_bytes();
245 1 : std::vector<int32_t> v_singleton;
246 1 : v_singleton.push_back(42);
247 1 : vv.push_back(v_singleton);
248 1 : buf.reset();
249 1 : CHECK(buf.Serialize(vv));
250 1 : size_t vv_plus_1_size = buf.num_bytes();
251 : CHECK(vv_size + nacl::SerializationBuffer::kTagBytes + 2 * sizeof(int32_t)
252 1 : == vv_plus_1_size);
253 :
254 1 : return 0;
255 1 : }
|