35 using namespace basis;
45 #define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger::get(), astring(s))
55 virtual int execute();
56 void test_unpacking();
77 const char *addr_list[] = {
"address" };
85 address_ton() :
infoton(addr_classifier() +
"leaf") {}
87 const char *class_name()
const {
return "address_ton"; }
102 return 5 *
sizeof(int) + 128 ;
106 return new address_ton(*
this);
111 class float_ton :
public infoton
117 float_ton() :
infoton(math_classifier() +
"float") {}
119 const char *class_name()
const {
return "float_ton"; }
131 return sizeof(double) +
sizeof(
float);
143 return new float_ton(*
this);
148 class int_set_ton :
public infoton
153 int_set_ton() :
infoton(math_classifier() +
"intset") {}
155 const char *class_name()
const {
return "int_set_ton"; }
159 for (
int indy = 0; indy < nums.
length(); indy++) {
161 if (indy < nums.
length() - 1) {
170 for (
int i = 0; i < nums.
elements(); i++)
175 return sizeof(int) + nums.
elements() *
sizeof(int);
182 for (
int i = 0; i < len; i++) {
191 return new int_set_ton(*
this);
202 :
tentacle_helper<address_ton>(addr_classifier().subarray(1, 1), true) {}
206 class numerical_chomper :
public tentacle
209 numerical_chomper() :
tentacle(math_classifier().subarray(1, 1), true) {}
215 if (classifier.
length() < 2)
return BAD_INPUT;
218 float_ton *to_return =
new float_ton;
219 if (!to_return->unpack(packed_form)) {
223 reformed = to_return;
225 }
else if (key ==
astring(
"intset")) {
226 int_set_ton *to_return =
new int_set_ton;
227 if (!to_return->unpack(packed_form)) {
231 reformed = to_return;
239 { transformed.
reset();
return tentacle::BAD_INPUT; }
252 :
tentacle(base_classifier(), true),
254 _numer(new numerical_chomper),
255 _addron(new address_chomper)
258 outcome ret = _unpackers.add_tentacle(_numer);
259 if (ret != tentacle::OKAY)
261 astring(
"failed to add: ") + tentacle::outcome_name(ret));
262 ret = _unpackers.add_tentacle(_addron);
263 if (ret != tentacle::OKAY)
265 astring(
"failed to add: ") + tentacle::outcome_name(ret));
280 real_class.
zap(0, 0);
282 return _unpackers.restore(real_class, packed_form, reformed);
291 real_class.
zap(0, 0);
294 return _unpackers.evaluate(
dynamic_cast<infoton *
>(to_chow.
clone()), item_id);
301 numerical_chomper *_numer;
302 address_chomper *_addron;
307 void test_unpacker::test_unpacking()
310 outer_arm *outer =
new outer_arm;
311 outcome ret = unpacky.add_tentacle(outer);
312 if (ret != tentacle::OKAY)
314 astring(
"failed to add: ") + tentacle::outcome_name(ret));
318 jubjub.nums.add(299);
319 jubjub.nums.add(39274);
320 jubjub.nums.add(25182);
322 infoton::fast_pack(packed, jubjub);
323 if (jubjub.packed_size() + infoton::fast_pack_overhead(jubjub.classifier())
324 != packed.length() - 10388)
326 astring(
"erroneous size calculated for first fast_pack"));
329 packed.
zap(0, 10387);
333 jubjub.pack(junk_jub);
334 if (packed.length() != junk_jub.
length()
335 + infoton::fast_pack_overhead(jubjub.classifier()))
337 "sizes differed from calculated");
339 if (!infoton::fast_unpack(packed, shirley_class, shirley_data))
341 "failed shirley unpack");
342 if (packed.length() != 0)
344 "shirley didn't consume all");
345 if (shirley_class != jubjub.classifier())
347 "inequal orig classifier");
349 if (!scroop.unpack(shirley_data))
351 "failed scroop unpack");
352 if (shirley_data.
length())
354 "scroop didn't consume all");
355 if (scroop.nums.length() != 3)
357 "wrong length in scroop");
358 if ( (scroop.nums[0] != jubjub.nums[0]) || (scroop.nums[1] != jubjub.nums[1])
359 || (scroop.nums[2] != jubjub.nums[2]) )
361 "erroneous information");
364 infoton::fast_pack(fasting, jubjub);
365 if (jubjub.packed_size() + infoton::fast_pack_overhead(jubjub.classifier())
368 astring(
"erroneous size calculated for second fast_pack"));
372 jubjub.pack(junk_fast);
374 + infoton::fast_pack_overhead(jubjub.classifier()))
376 "sizes differed from calculated");
380 if (!infoton::fast_unpack(fasting, nudge_class, nudge_data))
381 deadly_error(class_name(),
"test infoton fast pack",
"fast pack failed to unpack");
383 deadly_error(class_name(),
"test infoton fast pack",
"fast pack didn't consume all");
385 if (!croup.unpack(nudge_data))
386 deadly_error(class_name(),
"test infoton fast pack",
"croup wouldn't unpack");
387 if ( (croup.nums[0] != jubjub.nums[0]) || (croup.nums[1] != jubjub.nums[1])
388 || (croup.nums[2] != jubjub.nums[2]) )
389 deadly_error(class_name(),
"test infoton fast pack",
"croup has errors");
397 (chunkmo,
"urp", 23841));
399 infoton::fast_pack(chunkmo, norf);
402 if (!infoton::fast_unpack(chunkmo, clarfiator, pacula))
403 deadly_error(class_name(),
"test fast_unpack",
"chunkmo has errors");
407 outcome scrung_ret = unpacky.restore(clarfiator, pacula, scrung);
408 if (scrung_ret != tentacle::OKAY)
411 tentacle::outcome_name(scrung_ret)));
412 address_ton *rescrung =
dynamic_cast<address_ton *
>(scrung);
414 deadly_error(class_name(),
"test fast_unpack",
"wrong dynamic type for scrung");
415 address_ton &prescrung = *rescrung;
417 deadly_error(class_name(),
"test fast_unpack",
"wrong network address restored");
424 int test_unpacker::execute()
432 LOG(
astring(class_name()) +
":: works for all functions tested.");
The application_shell is a base object for console programs.
a_sprintf is a specialization of astring that provides printf style support.
void reset(int number=0, const contents *initial_contents=NULL_POINTER)
Resizes this array and sets the contents from an array of contents.
int length() const
Returns the current reported length of the allocated C array.
outcome zap(int start, int end)
Deletes from "this" the objects inclusively between "start" and "end".
Provides a dynamically resizable ASCII character string.
Defines the base class for all string processing objects in hoople.
virtual base_string & concatenate_string(const base_string &s)=0
Modifies "this" by concatenating "s" onto it.
A very common template for a dynamic array of bytes.
A clonable object knows how to make copy of itself.
Outcomes describe the state of completion for an operation.
An infoton is an individual request parcel with accompanying information.
void set_classifier(const structures::string_array &new_classifier)
sets the infoton's classifier to the "new_classifier".
const structures::string_array & classifier() const
this array of strings is the "name" for this infoton.
virtual clonable * clone() const =0
must be provided to allow creation of a copy of this object.
Provides a way of identifying users of an octopus object.
Identifies requests made on an octopus by users.
Octopus is a design pattern for generalized request processing systems.
provides prefab implementations for parts of the tentacle object.
Manages a service within an octopus by processing certain infotons.
this type of address describes a destination out on the internet.
A simple object that wraps a templated set of ints.
int elements() const
Returns the number of elements in this set.
An array of strings with some additional helpful methods.
#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 FUNCDEF(func_in)
FUNCDEF sets the name of a function (and plugs it into the callstack).
Provides macros that implement the 'main' program of an application.
#define HOOPLE_MAIN(obj_name, obj_args)
options that should work for most unix and linux apps.
Implements an application lock to ensure only one is running at once.
The guards collection helps in testing preconditions and reporting errors.
void WHACK(contents *&ptr)
deletion with clearing of the pointer.
const int MEGABYTE
Number of bytes in a megabyte.
A logger that sends to the console screen using the standard output device.
An extension to floating point primitives providing approximate equality.
Provides access to the operating system's socket methods.
A dynamic container class that holds any kind of object via pointers.
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.
Useful support functions for unit testing, especially within hoople.
#define SAFE_STATIC_CONST(type, func_name, parms)
this version returns a constant object instead.
Automates some common tasks for tentacle implementations. This template provides some default impleme...
string_array(1, math_list))) const char *addr_list[]