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 1 : CHECK(buf.Serialize("Hello world"));
80 : CHECK(buf.Serialize(
81 : "When in the Course of human events, it becomes necessary for"
82 : " one people to dissolve the political bands which have"
83 : " connected them with another, and to assume among the powers"
84 : " of the earth, the separate and equal station to which the"
85 : " Laws of Nature and of Nature's God entitle them, a decent"
86 : " respect to the opinions of mankind requires that they should"
87 1 : " declare the causes which impel them to the separation."));
88 :
89 1 : std::string msg("Goodbye cruel world");
90 :
91 1 : CHECK(buf.Serialize(msg));
92 :
93 1 : std::vector<std::string> vs;
94 :
95 1 : vs.push_back("When in the Course of human events, it becomes necessary for");
96 1 : vs.push_back(" one people to dissolve the political bands which have");
97 1 : vs.push_back(" connected them with another, and to assume among the powers");
98 1 : vs.push_back(" of the earth, the separate and equal station to which the");
99 1 : vs.push_back(" Laws of Nature and of Nature's God entitle them, a decent");
100 1 : vs.push_back(" respect to the opinions of mankind requires that they should");
101 1 : vs.push_back(" declare the causes which impel them to the separation.");
102 :
103 1 : CHECK(buf.Serialize(vs));
104 :
105 1 : buf.rewind();
106 :
107 1 : CHECK(buf.Deserialize(&ci16));
108 1 : CHECK(ci16 == 10);
109 1 : D(i8);
110 1 : D(u8);
111 1 : D(i16);
112 1 : D(u16);
113 1 : D(i32);
114 1 : D(u32);
115 1 : D(i64);
116 1 : D(u64);
117 :
118 1 : std::vector<int32_t> v2;
119 1 : CHECK(buf.Deserialize(&v2));
120 1 : CHECK(v.size() == v2.size());
121 1 : for (size_t ix = 0; ix < v.size(); ++ix) {
122 1 : CHECK(v[ix] == v2[ix]);
123 1 : }
124 : char buffer[64];
125 1 : size_t nbytes = sizeof buffer;
126 1 : CHECK(buf.Deserialize(buffer, &nbytes));
127 1 : CHECK(nbytes == strlen("Hello world") + 1);
128 1 : CHECK(!strcmp(buffer, "Hello world"));
129 : char *obuf;
130 1 : CHECK(buf.Deserialize(&obuf));
131 : CHECK(!strcmp(obuf,
132 : "When in the Course of human events, it becomes necessary for"
133 : " one people to dissolve the political bands which have"
134 : " connected them with another, and to assume among the powers"
135 : " of the earth, the separate and equal station to which the"
136 : " Laws of Nature and of Nature's God entitle them, a decent"
137 : " respect to the opinions of mankind requires that they should"
138 1 : " declare the causes which impel them to the separation."));
139 :
140 1 : delete[] obuf;
141 :
142 1 : std::string msg2;
143 1 : CHECK(buf.Deserialize(&msg2));
144 1 : CHECK(msg2 == "Goodbye cruel world");
145 :
146 1 : std::vector<std::string> vs2;
147 :
148 1 : CHECK(buf.Deserialize(&vs2));
149 :
150 1 : CHECK(vs.size() == vs2.size());
151 1 : for (size_t ix = 0; ix < vs.size(); ++ix) {
152 1 : CHECK(vs[ix] == vs2[ix]);
153 1 : }
154 :
155 : // Check the ability to construct a SerializationBuffer from
156 : // "received data".
157 :
158 1 : buf.reset();
159 1 : CHECK(buf.Serialize(i8));
160 1 : CHECK(buf.Serialize(u8));
161 1 : CHECK(buf.Serialize(i16));
162 1 : CHECK(buf.Serialize(u16));
163 1 : CHECK(buf.Serialize(i32));
164 1 : CHECK(buf.Serialize(u32));
165 1 : CHECK(buf.Serialize(i64));
166 1 : CHECK(buf.Serialize(u64));
167 1 : CHECK(buf.Serialize(vs));
168 :
169 1 : nacl::SerializationBuffer buf2(buf.data(), buf.num_bytes());
170 : #define D2(v) do { \
171 : CHECK(buf2.Deserialize(&c ## v)); \
172 : CHECK(c ## v == v); \
173 : } while (0)
174 1 : D2(i8);
175 1 : D2(u8);
176 1 : D2(i16);
177 1 : D2(u16);
178 1 : D2(i32);
179 1 : D2(u32);
180 1 : D2(i64);
181 1 : D2(u64);
182 :
183 1 : vs2.clear();
184 1 : CHECK(buf2.Deserialize(&vs2));
185 :
186 1 : CHECK(vs.size() == vs2.size());
187 1 : for (size_t ix = 0; ix < vs.size(); ++ix) {
188 1 : CHECK(vs[ix] == vs2[ix]);
189 1 : }
190 :
191 : // Tests that use exposed implementation details.
192 :
193 : // Verify that the space needed to serialize vectors of a basic type
194 : // grows at the size of the basic type.
195 :
196 1 : buf.reset();
197 1 : CHECK(buf.Serialize(v));
198 1 : size_t v_size = buf.num_bytes();
199 1 : buf.reset();
200 1 : v.push_back(100);
201 1 : CHECK(buf.Serialize(v));
202 1 : v.pop_back();
203 1 : size_t v_prime_size = buf.num_bytes();
204 1 : CHECK(v_size + sizeof(int32_t) == v_prime_size);
205 :
206 : // Check typetag is offset based
207 1 : CHECK(buf.data()[0] >= nacl::kVectorOffset);
208 :
209 1 : CHECK(nacl::kRecursiveVector < nacl::kVectorOffset);
210 :
211 : // Check typetag is fixed, using recursive serialization
212 1 : buf.reset();
213 1 : std::vector<std::vector<int32_t> > vv;
214 1 : vv.push_back(v);
215 1 : vv.push_back(v);
216 1 : CHECK(buf.Serialize(vv));
217 1 : CHECK(buf.data()[0] == nacl::kRecursiveVector);
218 :
219 : // Check that the encoding space usage grows as expected, with the
220 : // nested vector also tagged etc. TODO(bsy): omit this test? this
221 : // may be too much implementation detail.
222 1 : size_t vv_size = buf.num_bytes();
223 1 : std::vector<int32_t> v_singleton;
224 1 : v_singleton.push_back(42);
225 1 : vv.push_back(v_singleton);
226 1 : buf.reset();
227 1 : CHECK(buf.Serialize(vv));
228 1 : size_t vv_plus_1_size = buf.num_bytes();
229 : CHECK(vv_size + nacl::SerializationBuffer::kTagBytes + 2 * sizeof(int32_t)
230 1 : == vv_plus_1_size);
231 :
232 1 : return 0;
233 1 : }
|