datagen.c File Reference

Data generator support functions. More...

#include <stdio.h>
#include "ctl/dg/datagen.h"
#include "ctl/algorithm.temp.h"

Include dependency graph for datagen.c:

Go to the source code of this file.

Functions

void spew (void)
int bool_compare (const bool *p1, const bool *p2)
 Compare two scalar types for qsort, least-to-greatest.
int bool_rcompare (const bool *p1, const bool *p2)
 Compare two scalar types for qsort, greatest-to-least.
int int8_compare (const int8 *p1, const int8 *p2)
 Compare two scalar types for qsort, least-to-greatest.
int int8_rcompare (const int8 *p1, const int8 *p2)
 Compare two scalar types for qsort, greatest-to-least.
int uint8_compare (const uint8 *p1, const uint8 *p2)
 Compare two scalar types for qsort, least-to-greatest.
int uint8_rcompare (const uint8 *p1, const uint8 *p2)
 Compare two scalar types for qsort, greatest-to-least.
int int16_compare (const int16 *p1, const int16 *p2)
 Compare two scalar types for qsort, least-to-greatest.
int int16_rcompare (const int16 *p1, const int16 *p2)
 Compare two scalar types for qsort, greatest-to-least.
int uint16_compare (const uint16 *p1, const uint16 *p2)
 Compare two scalar types for qsort, least-to-greatest.
int uint16_rcompare (const uint16 *p1, const uint16 *p2)
 Compare two scalar types for qsort, greatest-to-least.
int int32_compare (const int32 *p1, const int32 *p2)
 Compare two scalar types for qsort, least-to-greatest.
int int32_rcompare (const int32 *p1, const int32 *p2)
 Compare two scalar types for qsort, greatest-to-least.
int uint32_compare (const uint32 *p1, const uint32 *p2)
 Compare two scalar types for qsort, least-to-greatest.
int uint32_rcompare (const uint32 *p1, const uint32 *p2)
 Compare two scalar types for qsort, greatest-to-least.
int int64_compare (const int64 *p1, const int64 *p2)
 Compare two scalar types for qsort, least-to-greatest.
int int64_rcompare (const int64 *p1, const int64 *p2)
 Compare two scalar types for qsort, greatest-to-least.
int uint64_compare (const uint64 *p1, const uint64 *p2)
 Compare two scalar types for qsort, least-to-greatest.
int uint64_rcompare (const uint64 *p1, const uint64 *p2)
 Compare two scalar types for qsort, greatest-to-least.
int float32_compare (const float32 *p1, const float32 *p2)
 Compare two scalar types for qsort, least-to-greatest Note: values nearly the same are treated as 'same'.
int float32_rcompare (const float32 *p1, const float32 *p2)
 Compare two scalar types for qsort, greatest-to-least Note: values nearly the same are treated as 'same'.
int float64_compare (const float64 *p1, const float64 *p2)
 Compare two scalar types for qsort, least-to-greatest Note: values nearly the same are treated as 'same'.
int float64_rcompare (const float64 *p1, const float64 *p2)
 Compare two scalar types for qsort, greatest-to-least Note: values nearly the same are treated as 'same'.
void char_string_swap (char *s1, char *s2, size_t count)
 Exchange the contents of two character arrays.
void wchar_t_string_swap (wchar_t *s1, wchar_t *s2, size_t count)
 Exchange the contents of two character arrays.


Detailed Description

Data generator support functions.

Author:
David Mace
The main assumption here is that it's bad to crash. Most sane people agree with this assessment. Especially in servers with untrustworthy clients (i.e. anything connected to the internet). Rather than put up a server and have one or two jokers discover they can crash it at will by trivially sending malformed packets, and then having them do so, I'd rather have code that checks the incomming data against expected ranges and expected sizes, and then recover, but that's just me.

Data that is going to be loaded should be pre-initialized to a state where it can be safely destroyed, such that when an error is found, the data can be discarded without leaking. Containers and pointers need to as a minimum be initialized to a known state.

Finally, as with any protocol/convention, it needs to be adhered to, in order to mean anything. This code provides templates to trivially generate the file formats and protocols for an application, and be shared between a client and server code bases, such that once defined, the protocol and files can be trivially extended or modified without any significant collateral damage.

The code that datagen.c, datagen.h, dg_patterns.h, dg_patterns.temp.h and algorithm.temp.h establish a pattern of record interactions to allow data to be moved around relatively efficiently, and above all SAFELY. At the same time, they provide a framework to define data that saves literally tens of thousands of lines of repetitive, and tedious code with repetition errors that are hard to spot, and many hours of fruitless snipe-hunts only to discover that a 'minor' oversight in adding a line of code to support a structure you extended in one place, but not another caused a new and frightful crash or symptom.

I have been involved on a lot of projects where serial protocols were written in C/C++, and well, not designed at all. From this sample, it's easy to deduce that a LOT of people jump into a server project without a clue how badly their ad-hoc serial code will sabotage their later development and release schedule, and even worse, what will happen when someone starts 'tinkering' with their server from a remote location. People literally write a block of code with the serialization intermixed with additional code and program flow, and some of them even insist on maintaining SEPARATE code bases on the client and server to pass the same messages around. This is madness, and it leads to errors that are totally irrecoverable, which means the server will die horribly, and VERY often.

One library. One protocol. One method. Use the same body of code to define how serialization of data is managed on both halves of a client/server application, and stick to the patterns you establish.

This system can be extended to integrate into other things, such as database records and Python (or other) scripting. It's only a matter of conforming to the pattern, typically by copying/pasting an existing block of code and rewriting it for the new purpose. An editor with a robust regular expression search/replace helps a lot.

Yes, this library is repetitive to work on, and when bugs exist, they are somewhat tedious and 'interesting' to fix. Multiply that tedium and adventure by every kind of record you would otherwise need to maintain, and you may begin to understand what this approach can save you from in the long-run... or may not, as I have had the misfortune to work for people who never caught a clue.

Beyond the serial communication, this library also provides two kinds of record writing. XML, and a binary format much the same as XML, except faster and simpler, with better fidelity for the floating point data (as long as the floating point formats on client and server are the same).

Definition in file datagen.c.


Generated on Fri Jan 2 15:28:35 2009 for Squat by  doxygen 1.5.6