34 class test_unpacker :
public application_shell
37 test_unpacker() : application_shell(class_name()) {}
39 virtual int execute();
40 void test_unpacking();
61 const char *addr_list[] = {
"address" };
66 class address_ton :
public infoton,
public network_address
69 address_ton() : infoton(addr_classifier() +
"leaf") {}
71 virtual void pack(byte_array &packed_form)
const {
75 virtual bool unpack(byte_array &packed_form) {
80 return 5 *
sizeof(int) + 128 ;
83 virtual clonable *clone()
const {
84 return new address_ton(*
this);
89 class float_ton :
public infoton
95 float_ton() : infoton(math_classifier() +
"float") {}
97 virtual void pack(byte_array &packed_form)
const {
103 return sizeof(double) +
sizeof(
float);
106 virtual bool unpack(byte_array &packed_form) {
114 virtual clonable *clone()
const {
115 return new float_ton(*
this);
120 class int_set_ton :
public infoton
125 int_set_ton() : infoton(math_classifier() +
"intset") {}
127 virtual void pack(byte_array &packed_form)
const {
129 for (
int i = 0; i < nums.elements(); i++)
134 return sizeof(int) + nums.elements() *
sizeof(int);
137 virtual bool unpack(byte_array &packed_form) {
141 for (
int i = 0; i < len; i++) {
149 virtual clonable *clone()
const {
150 return new int_set_ton(*
this);
157 class address_chomper :
public tentacle_helper<address_ton>
161 : tentacle_helper<address_ton>(addr_classifier().subarray(1, 1), true) {}
165 class numerical_chomper :
public tentacle
168 numerical_chomper() : tentacle(math_classifier().subarray(1, 1), true) {}
170 outcome reconstitute(
const string_array &classifier, byte_array &packed_form,
174 if (classifier.length() < 2)
return BAD_INPUT;
175 astring key = classifier[1];
176 if (key ==
"float") {
177 float_ton *to_return =
new float_ton;
178 if (!to_return->unpack(packed_form)) {
182 reformed = to_return;
184 }
else if (key ==
"intset") {
185 int_set_ton *to_return =
new int_set_ton;
186 if (!to_return->unpack(packed_form)) {
190 reformed = to_return;
196 outcome consume(infoton &
formal(to_chow),
const octopus_request_id &
formal(item_id),
197 byte_array &transformed)
198 { transformed.reset();
return tentacle::BAD_INPUT; }
200 virtual void expunge(
const octopus_entity &
formal(zapola)) {}
207 class outer_arm :
public tentacle
211 : tentacle(base_classifier(), true),
213 _numer(new numerical_chomper),
214 _addron(new address_chomper)
217 outcome ret = _unpackers.add_tentacle(_numer);
218 if (ret != tentacle::OKAY)
220 astring(
"failed to add: ") + tentacle::outcome_name(ret));
221 ret = _unpackers.add_tentacle(_addron);
222 if (ret != tentacle::OKAY)
224 astring(
"failed to add: ") + tentacle::outcome_name(ret));
234 outcome reconstitute(
const string_array &classifier, byte_array &packed_form,
239 real_class.zap(0, 0);
241 return _unpackers.restore(real_class, packed_form, reformed);
244 outcome consume(infoton &to_chow,
const octopus_request_id &item_id,
245 byte_array &transformed)
250 real_class.zap(0, 0);
251 to_chow.set_classifier(real_class);
253 return _unpackers.evaluate((infoton *)to_chow.clone(), item_id);
256 void expunge(
const octopus_entity &
formal(whackola)) {}
260 numerical_chomper *_numer;
261 address_chomper *_addron;
266 void test_unpacker::test_unpacking()
268 octopus unpacky(
"local", 10 *
MEGABYTE);
269 outer_arm *outer =
new outer_arm;
270 outcome ret = unpacky.add_tentacle(outer);
271 if (ret != tentacle::OKAY)
273 astring(
"failed to add: ") + tentacle::outcome_name(ret));
277 jubjub.nums.add(299);
278 jubjub.nums.add(39274);
279 jubjub.nums.add(25182);
280 byte_array packed(10388);
281 infoton::fast_pack(packed, jubjub);
282 if (jubjub.packed_size() + infoton::fast_pack_overhead(jubjub.classifier())
283 != packed.length() - 10388)
285 astring(
"erroneous size calculated for first fast_pack"));
287 byte_array shirley_data;
288 packed.zap(0, 10387);
292 jubjub.pack(junk_jub);
293 if (packed.length() != junk_jub.length()
294 + infoton::fast_pack_overhead(jubjub.classifier()))
296 "sizes differed from calculated");
298 if (!infoton::fast_unpack(packed, shirley_class, shirley_data))
300 "failed shirley unpack");
301 if (packed.length() != 0)
303 "shirley didn't consume all");
304 if (shirley_class != jubjub.classifier())
306 "inequal orig classifier");
308 if (!scroop.unpack(shirley_data))
310 "failed scroop unpack");
311 if (shirley_data.length())
313 "scroop didn't consume all");
314 if (scroop.nums.length() != 3)
316 "wrong length in scroop");
317 if ( (scroop.nums[0] != jubjub.nums[0]) || (scroop.nums[1] != jubjub.nums[1])
318 || (scroop.nums[2] != jubjub.nums[2]) )
320 "erroneous information");
323 infoton::fast_pack(fasting, jubjub);
324 if (jubjub.packed_size() + infoton::fast_pack_overhead(jubjub.classifier())
327 astring(
"erroneous size calculated for second fast_pack"));
330 byte_array junk_fast;
331 jubjub.pack(junk_fast);
332 if (fasting.length() != junk_fast.length()
333 + infoton::fast_pack_overhead(jubjub.classifier()))
335 "sizes differed from calculated");
338 byte_array nudge_data;
339 if (!infoton::fast_unpack(fasting, nudge_class, nudge_data))
340 deadly_error(class_name(),
"test infoton fast pack",
"fast pack failed to unpack");
341 if (fasting.length())
342 deadly_error(class_name(),
"test infoton fast pack",
"fast pack didn't consume all");
344 if (!croup.unpack(nudge_data))
345 deadly_error(class_name(),
"test infoton fast pack",
"croup wouldn't unpack");
346 if ( (croup.nums[0] != jubjub.nums[0]) || (croup.nums[1] != jubjub.nums[1])
347 || (croup.nums[2] != jubjub.nums[2]) )
348 deadly_error(class_name(),
"test infoton fast pack",
"croup has errors");
355 (network_address &)norf = network_address(internet_address
356 (chunkmo,
"urp", 23841));
358 infoton::fast_pack(chunkmo, norf);
361 if (!infoton::fast_unpack(chunkmo, clarfiator, pacula))
362 deadly_error(class_name(),
"test fast_unpack",
"chunkmo has errors");
366 outcome scrung_ret = unpacky.restore(clarfiator, pacula, scrung);
367 if (scrung_ret != tentacle::OKAY)
369 a_sprintf(
"can't restore scrung: %s",
370 tentacle::outcome_name(scrung_ret)));
371 address_ton *rescrung =
dynamic_cast<address_ton *
>(scrung);
373 deadly_error(class_name(),
"test fast_unpack",
"wrong dynamic type for scrung");
374 address_ton &prescrung = *rescrung;
375 if ((network_address &)prescrung != (network_address &)norf)
376 deadly_error(class_name(),
"test fast_unpack",
"wrong network address restored");
383 int test_unpacker::execute()
390 log(
"unpacking octopus:: works for all functions tested.");
#define deadly_error(c, f, i)
#define formal(parameter)
This macro just eats what it's passed; it marks unused formal parameters.
#define NULL_POINTER
The value representing a pointer to nothing.
#define DEFINE_CLASS_NAME(objname)
Defines the name of a class by providing a couple standard methods.
#define HOOPLE_MAIN(obj_name, obj_args)
options that should work for most unix and linux apps.
void WHACK(contents *&ptr)
deletion with clearing of the pointer.
const int MEGABYTE
Number of bytes in a megabyte.
bool unpack(basis::byte_array &packed_form, set< contents > &to_unpack)
provides a way to unpack any set that stores packable objects.
void attach(byte_array &packed_form, const byte_array &to_attach)
Packs a byte_array "to_attach" into "packed_form".
void pack(basis::byte_array &packed_form, const set< contents > &to_pack)
provides a way to pack any set that stores packable objects.
bool detach(byte_array &packed_form, byte_array &to_detach)
Unpacks a byte_array "to_detach" from "packed_form".
int packed_size(const byte_array &packed_form)
Reports the size required to pack a byte array into a byte array.
#define SAFE_STATIC_CONST(type, func_name, parms)
this version returns a constant object instead.
string_array(1, math_list))) const char *addr_list[]
Automates some common tasks for tentacle implementations. This template provides some default impleme...