30 using namespace basis;
39 #define DEBUG_CROMP_TRANSACTION
47 #ifdef DEBUG_CROMP_TRANSACTION
51 #define LOG(s) CLASS_EMERGENCY_LOG(file_logger(environment::TMP() + "/cromp_transaction.log"), s)
61 const char *cromp_transaction::outcome_name(
const outcome &to_name)
63 switch (to_name.
value()) {
64 case WAY_TOO_SMALL:
return "WAY_TOO_SMALL";
65 case ILLEGAL_LENGTH:
return "ILLEGAL_LENGTH";
66 default:
return communication_commons::outcome_name(to_name);
73 static bool _initted =
false;
86 for (
int i = 0; i < 8; i++)
91 return _hidden_cromp_array;
100 int cromp_transaction::minimum_flat_size(
const string_array &classifier,
103 return minimum_flat_size(
id)
104 + infoton::fast_pack_overhead(classifier);
111 #ifdef DEBUG_CROMP_TRANSACTION
114 int posn = packed_form.
length();
121 id.pack(packed_form);
124 infoton::fast_pack(packed_form, request);
125 #ifdef DEBUG_CROMP_TRANSACTION
128 infoton::fast_pack(temp_holding, request);
135 #ifdef DEBUG_CROMP_TRANSACTION
138 for (
int j = 6; j < 14; j++)
139 packed_form[posn + j] =
abyte(len_string[j - 6]);
141 #ifdef DEBUG_CROMP_TRANSACTION
145 if (!cromp_transaction::unflatten(
copy, tempo, urfid))
147 "failed to unpack what we just packed.");
148 else if (urfid !=
id)
150 else if (tempo != temp_holding)
159 #ifdef DEBUG_CROMP_TRANSACTION
165 if (peek_header(packed_form, len) != OKAY) {
166 #ifdef DEBUG_CROMP_TRANSACTION
167 LOG(
"failed to peek the header!");
171 packed_form.
zap(0, 14 - 1);
172 if (!req_id.
unpack(packed_form))
return false;
175 #ifdef DEBUG_CROMP_TRANSACTION
176 if (array_len > packed_form.
length())
178 "data needed is insufficient! peek was wrong.");
181 still_flat = packed_form.
subarray(0, array_len - 1);
182 packed_form.
zap(0, array_len - 1);
186 #define WHACK_AND_GO { packed_form.zap(0, 0); continue; }
188 #define CHECK_LENGTH \
189 if (packed_form.length() < necessary_length) { \
195 bool cromp_transaction::resynchronize(
byte_array &packed_form)
197 #ifdef DEBUG_CROMP_TRANSACTION
201 if (!packed_form.
length()) {
203 LOG(
"roasted entire contents...");
208 int necessary_length = 2;
219 for (
int k = 6; k < 14; k++) {
221 if (!parser_bits::is_hexadecimal(packed_form[k]))
224 #ifdef DEBUG_CROMP_TRANSACTION
225 LOG(
"found header again...");
234 #ifdef DEBUG_CROMP_TRANSACTION
238 #ifdef DEBUG_CROMP_TRANSACTION
239 LOG(
"checking for header");
241 if (packed_form.
length() < 14)
return WAY_TOO_SMALL;
242 if ( (packed_form[0] !=
'c') || (packed_form[1] !=
'r')
243 || (packed_form[2] !=
'o') || (packed_form[3] !=
'm')
244 || (packed_form[4] !=
'p') || (packed_form[5] !=
'!') )
246 #ifdef DEBUG_CROMP_TRANSACTION
247 LOG(
"obvious header bits look fine");
251 for (
int k = 6; k < 14; k++) {
252 if (!parser_bits::is_hexadecimal(packed_form[k])) {
253 #ifdef DEBUG_CROMP_TRANSACTION
254 LOG(
"found corruption in hex bytes");
258 len_string += char(packed_form[k]);
260 #ifdef DEBUG_CROMP_TRANSACTION
261 LOG(
"length was unpacked okay");
264 int items = sscanf(len_string.
s(),
"%08x", &temp_len);
267 #ifdef DEBUG_CROMP_TRANSACTION
268 LOG(
astring(
"couldn't parse the len_string of: ") + len_string);
273 #ifdef DEBUG_CROMP_TRANSACTION
274 LOG(
a_sprintf(
"length string is %s, len calc is %d and bytes "
275 "given are %d", len_string.
s(), length, packed_form.
length()));
278 if (length > packed_form.
length())
return PARTIAL;
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.
array subarray(int start, int end) const
Returns the array segment between the indices "start" and "end".
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".
int last() const
Returns the last valid element in the array.
Provides a dynamically resizable ASCII character string.
const char * s() const
synonym for observe. the 's' stands for "string", if that helps.
auto_synchronizer simplifies concurrent code by automatically unlocking.
A very common template for a dynamic array of bytes.
Outcomes describe the state of completion for an operation.
An infoton is an individual request parcel with accompanying information.
Identifies requests made on an octopus by users.
int packed_size() const
reports how large the packed id will be.
virtual bool unpack(basis::byte_array &packed_form)
Restores the packable from the "packed_form".
An array of strings with some additional helpful methods.
#define continuable_error(c, f, i)
char * copy(register char *str)
#define FUNCDEF(func_in)
FUNCDEF sets the name of a function (and plugs it into the callstack).
The guards collection helps in testing preconditions and reporting errors.
const int MEGABYTE
Number of bytes in a megabyte.
unsigned char abyte
A fairly important unit which is seldom defined...
void attach(byte_array &packed_form, const char *to_attach)
Packs a character string "to_attach" into "packed_form".
unsigned int un_int
Abbreviated name for unsigned integers.
const int MAXIMUM_TRANSACTION
byte_array & cromp_name_array()
A logger that sends to the console screen using the standard output device.
Provides access to the operating system's socket methods.
A dynamic container class that holds any kind of object via pointers.
#define SAFE_STATIC(type, func_name, parms)
Statically defines a singleton object whose scope is the program's lifetime.
#define static_class_name()