00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <basis/chaos.h>
00016 #include <basis/function.h>
00017 #include <basis/guards.h>
00018 #include <basis/istring.h>
00019 #include <basis/packable.h>
00020 #include <mathematics/float_plus.h>
00021 #include <opsystem/application_shell.h>
00022 #include <data_struct/static_memory_gremlin.h>
00023
00024 #include <math.h>
00025
00026 using namespace basis;
00027
00028 HOOPLE_STARTUP_CODE;
00029
00030 #define DIE(group, message) \
00031 deadly_error("test_packable", group " test group", message)
00032
00033 #define TRY_ON(type, value, group) { \
00034 byte_array temp_array; \
00035 attach(temp_array, type(value)); \
00036 type output; \
00037 \
00038 if (!detach(temp_array, output)) \
00039 DIE(group, "couldn't unpack " #type); \
00040 if (output != type(value)) \
00041 DIE(group, #type " value didn't match " #value); \
00042 if (temp_array.length()) \
00043 DIE(group, #type " detach of " #value " had data left"); \
00044 }
00045
00046 #define TRY_ON_OBSCURE(type, value, group) { \
00047 byte_array temp_array; \
00048 obscure_attach(temp_array, type(value)); \
00049 type output; \
00050 \
00051 if (!obscure_detach(temp_array, output)) \
00052 DIE(group, "couldn't obscure unpack " #type); \
00053 if (output != type(value)) \
00054 DIE(group, #type " value didn't obscure match " #value); \
00055 if (temp_array.length()) \
00056 DIE(group, #type " obscure detach of " #value " had data left"); \
00057 }
00058
00059 #define TRY_ON_F(type, value, group) { \
00060 byte_array temp_array; \
00061 attach(temp_array, type(value)); \
00062 type output; \
00063 \
00064 if (!detach(temp_array, output)) \
00065 DIE(group, "couldn't unpack " #type); \
00066
00067 \
00068 \
00069 int exponent_1, exponent_2; \
00070 double mantissa_1 = frexp(output, &exponent_1); \
00071 double mantissa_2 = frexp(output, &exponent_2); \
00072 if ( (mantissa_1 != mantissa_2) || (exponent_1 != exponent_2) ) { \
00073 isprintf error_msg(#type " value didn't match " #value ", %f vs. %f", value, output); \
00074 DIE(group, error_msg); \
00075 } \
00076 if (temp_array.length()) \
00077 DIE(group, #type " detach of " #value " had data left"); \
00078 }
00079
00080 class test_packable : public application_shell
00081 {
00082 public:
00083 test_packable() : application_shell("test_packable") {}
00084 ~test_packable() {}
00085
00086 IMPLEMENT_CLASS_NAME("test_packable");
00087
00088 int execute();
00089 };
00090
00092
00093 int test_packable::execute()
00094 {
00095 {
00096 #define TEST "first"
00097 TRY_ON(int, 2383, TEST);
00098 TRY_ON(int, -18281, TEST);
00099 TRY_ON(long, 337628, TEST);
00100 TRY_ON(long, -987887, TEST);
00101 TRY_ON(short, 12983, TEST);
00102 TRY_ON(short, -32700, TEST);
00103 TRY_ON(u_int, 2988384, TEST);
00104 TRY_ON(u_int, 92982984, TEST);
00105 TRY_ON(u_long, 388745, TEST);
00106 TRY_ON(u_long, 993787, TEST);
00107 TRY_ON(u_short, 12983, TEST);
00108 TRY_ON(u_short, 48377, TEST);
00109 TRY_ON_OBSCURE(int, -23948377, TEST);
00110 TRY_ON_OBSCURE(int, 28938, TEST);
00111 #undef TEST
00112 }
00113 {
00114 #define TEST "second"
00115 TRY_ON(int, 0, TEST);
00116 TRY_ON(int, MAXINT, TEST);
00117 TRY_ON(int, MININT, TEST);
00118 TRY_ON(byte, 0, TEST);
00119 TRY_ON(byte, MAXBYTE, TEST);
00120 TRY_ON(byte, MINBYTE, TEST);
00121 TRY_ON(char, 0, TEST);
00122 TRY_ON(char, MAXCHAR, TEST);
00123 TRY_ON(char, MINCHAR, TEST);
00124 TRY_ON(long, 0, TEST);
00125 TRY_ON(long, MAXLONG, TEST);
00126 TRY_ON(long, MINLONG, TEST);
00127 TRY_ON(short, 0, TEST);
00128 TRY_ON(short, MAXSHORT, TEST);
00129 TRY_ON(short, MINSHORT, TEST);
00130 u_long max_u_long = MAXLONG | MINLONG;
00131 TRY_ON(u_int, 0, TEST);
00132 TRY_ON(u_int, max_u_long, TEST);
00133 TRY_ON(u_int, max_u_long - 1, TEST);
00134 TRY_ON(u_int, max_u_long - 2, TEST);
00135 TRY_ON(u_int, max_u_long - 3, TEST);
00136 TRY_ON(u_long, 0, TEST);
00137 TRY_ON(u_long, max_u_long, TEST);
00138 TRY_ON(u_long, max_u_long - 1, TEST);
00139 TRY_ON(u_long, max_u_long - 2, TEST);
00140 TRY_ON(u_long, max_u_long - 3, TEST);
00141 u_short max_u_short = MAXSHORT | MINSHORT;
00142 TRY_ON(u_short, 0, TEST);
00143 TRY_ON(u_short, max_u_short, TEST);
00144 TRY_ON(u_short, max_u_short - 1, TEST);
00145 TRY_ON(u_short, max_u_short - 2, TEST);
00146 TRY_ON(u_short, max_u_short - 3, TEST);
00147 #undef TEST
00148 }
00149 {
00150 #define TEST "third"
00151
00152 TRY_ON_F(double, 0.0, TEST);
00153 TRY_ON_F(double, 1.0, TEST);
00154 TRY_ON_F(double, -1.0, TEST);
00155 TRY_ON_F(double, 1.1, TEST);
00156 TRY_ON_F(double, -1.1, TEST);
00157 TRY_ON_F(double, 1983.293, TEST);
00158 TRY_ON_F(double, -1983.293, TEST);
00159 TRY_ON_F(double, 984.293e20, TEST);
00160 TRY_ON_F(double, -984.293e31, TEST);
00161
00162 const int MAX_FLOAT_ITERS = 100000;
00163 int iters = 0;
00164 while (iters++ < MAX_FLOAT_ITERS) {
00165 double dividend = randomizer().inclusive(1, MAXINT / 2);
00166 double divisor = randomizer().inclusive(1, MAXINT / 2);
00167 double multiplier = randomizer().inclusive(1, MAXINT / 2);
00168 double rand_float = (dividend / divisor) * multiplier;
00169 if (randomizer().inclusive(0, 1) == 1)
00170 rand_float = -1.0 * rand_float;
00171 TRY_ON_F(double, rand_float, "third--loop");
00172
00173 }
00174 #undef TEST
00175 }
00176
00177 {
00178 #define TEST "fourth"
00179
00180 const char *tunnel_vision = "plants can make good friends.";
00181 const char *fresnel_lense = "chimney sweeps carry some soot.";
00182 const char *snoopy = "small white dog with black spots.";
00183 byte_array stored;
00184 int fregose = 38861;
00185 double perky_doodle = 3799.283e10;
00186 const char *emptyish = "";
00187 int jumboat = 998;
00188
00189 attach(stored, fregose);
00190 attach(stored, tunnel_vision);
00191 attach(stored, snoopy);
00192 attach(stored, perky_doodle);
00193 attach(stored, fresnel_lense);
00194 attach(stored, emptyish);
00195 attach(stored, jumboat);
00196
00197 istring tunnel_copy;
00198 istring fresnel_copy;
00199 istring snoopy_copy;
00200 int freg_copy;
00201 double perk_copy;
00202 istring emp_copy;
00203 int jum_copy;
00204 if (!detach(stored, freg_copy))
00205 DIE(TEST, "first int failed to unpack");
00206 if (!detach(stored, tunnel_copy))
00207 DIE(TEST, "first string failed to unpack");
00208 if (!detach(stored, snoopy_copy))
00209 DIE(TEST, "second string failed to unpack");
00210 if (!detach(stored, perk_copy))
00211 DIE(TEST, "first double failed to unpack");
00212 if (!detach(stored, fresnel_copy))
00213 DIE(TEST, "third string failed to unpack");
00214 if (!detach(stored, emp_copy))
00215 DIE(TEST, "fourth string failed to unpack");
00216 if (!detach(stored, jum_copy))
00217 DIE(TEST, "second int failed to unpack");
00218
00219 if (freg_copy != fregose)
00220 DIE(TEST, "first int had wrong contents");
00221 if (tunnel_copy != tunnel_vision)
00222 DIE(TEST, "first string had wrong contents");
00223 if (snoopy_copy != snoopy)
00224 DIE(TEST, "second string had wrong contents");
00225 if (perk_copy != perky_doodle)
00226 DIE(TEST, "first double had wrong contents");
00227 if (fresnel_copy != fresnel_lense)
00228 DIE(TEST, "third string had wrong contents");
00229 if (emp_copy != emptyish)
00230 DIE(TEST, "fourth string had wrong contents");
00231 if (jum_copy != jumboat)
00232 DIE(TEST, "second int had wrong contents");
00233 if (stored.length())
00234 DIE(TEST, "array still had contents after detaching");
00235
00236
00237 #undef TEST
00238 }
00239
00240 guards::alert_message("packable:: works for those functions tested.");
00241 return 0;
00242 }
00243
00245
00246 int main(int formal(argc), char *formal(argv)[])
00247 {
00248 test_packable root_program;
00249 return root_program.execute();
00250 }
00251