00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <basis/byte_array.h>
00016 #include <basis/chaos.h>
00017 #include <basis/function.h>
00018 #include <basis/guards.h>
00019 #include <basis/istring.h>
00020 #include <data_struct/deep_array.cpp>
00021 #include <data_struct/matrix.cpp>
00022 #include <mathematics/float_plus.h>
00023 #include <mechanisms/time_stamp.h>
00024 #include <opsystem/application_shell.h>
00025 #include <loggers/console_logger.h>
00026 #include <data_struct/static_memory_gremlin.h>
00027
00028 const int MAX_TEST_DURATION = 1 * MINUTE_ms;
00029
00030
00031 const int MAX_SIMULTANEOUS_OBJECTS = 42;
00032
00033 const int MIN_OBJECT = -30;
00034 const int MAX_OBJECT = 98;
00035
00036 const int MIN_BLOCK = 100;
00037 const int MAX_BLOCK = MAX_OBJECT * 2;
00038
00039
00040
00041
00042 #define LOG(s) EMERGENCY_LOG(program_wide_logger(), s)
00043
00044 typedef void *void_pointer;
00045
00047
00048 class test_deep_array : public application_shell
00049 {
00050 public:
00051 test_deep_array() : application_shell(class_name()) {}
00052 IMPLEMENT_CLASS_NAME("test_deep_array");
00053 virtual int execute();
00054 void dump_deep_array(deep_array<void_pointer> &ar, const char *name);
00055 void test_deep_arrays_of_void_pointer();
00056 void test_packing_deep_arrays();
00057 };
00058
00060
00061 void test_deep_array::dump_deep_array(deep_array<void_pointer> &ar, const char *name)
00062 {
00063 #ifdef DEBUG_TEST_ARRAY
00064 LOG(isprintf("deep_array named \"%s\" has:", name));
00065 for (int i = 0; i < ar.length(); i++) {
00066 LOG(isprintf("\t%4d: %d", i, (int)ar[i]));
00067 }
00068 #else
00069 if (ar.length() || name) {}
00070 #endif
00071 }
00072
00073 void test_deep_array::test_deep_arrays_of_void_pointer()
00074 {
00075 FUNCDEF("void pointer test");
00076 if (sizeof(void_pointer) != 4)
00077 deadly_error(class_name(), func, "the void pointer has an unexpected size!");
00078 const int MAX_VOID_ARRAY = 20;
00079 deep_array<void_pointer> argh(MAX_VOID_ARRAY);
00080 deep_array<void_pointer> argh2(argh);
00081 if (argh.length() != MAX_VOID_ARRAY)
00082 deadly_error(class_name(), func, "the first deep_array length is incorrect!");
00083 if (argh2.length() != MAX_VOID_ARRAY)
00084 deadly_error(class_name(), func, "the copied deep_array length is incorrect!");
00085
00086
00087
00088
00089
00090
00091
00092 int starter;
00093 for (int i = 0; i < MAX_VOID_ARRAY; i++)
00094 argh[i] = (void_pointer)(&starter + i);
00095 dump_deep_array(argh, "first version");
00096
00097
00098 for (int j = 0; j < MAX_VOID_ARRAY; j++)
00099 if (argh[j] != (void *)(&starter + j))
00100 deadly_error(class_name(), func, "setting values are incorrect!");
00101
00102
00103 for (int k = 0; k < MAX_VOID_ARRAY; k++)
00104 argh[k] = (void_pointer)((int *)argh[k] + 98);
00105 dump_deep_array(argh, "second version");
00106
00107
00108 argh2 = argh;
00109 for (int n = 0; n < MAX_VOID_ARRAY; n++)
00110 if (argh2[n] != (void_pointer)(&starter + n + 98))
00111 deadly_error(class_name(), func, "assign values are incorrect!");
00112
00113
00114 argh.zap(3, 4);
00115 dump_deep_array(argh, "third version");
00116 for (int l = 0; l < 3; l++)
00117 if (argh[l] != (void_pointer)(&starter + l + 98))
00118 deadly_error(class_name(), func, "zap low values are incorrect!");
00119 for (int m = 3; m < MAX_VOID_ARRAY - 2; m++)
00120 if (argh[m] != (void_pointer)(&starter + m + 2 + 98))
00121 deadly_error(class_name(), func, "zap high values are incorrect!");
00122
00123
00124 }
00125
00127
00128 static istring blank_string;
00129
00130
00131 class jethro
00132 {
00133 public:
00134 jethro(const istring &i = blank_string) : _truck(i) {}
00135
00136 istring _truck;
00137
00138 bool operator ==(const jethro &tc) const { return tc._truck == _truck; }
00139 bool operator !=(const jethro &tc) const { return !(*this == tc); }
00140 };
00141
00143
00144
00145
00146 class test_content
00147 {
00148 public:
00149 byte _q;
00150 istring _ted;
00151 istring _jed;
00152 int_array _ned;
00153 matrix<jethro> _med;
00154 int_matrix _red;
00155
00156 test_content(byte q = 3)
00157 : _q(q), _ted("bl"), _jed("orp"),
00158 _ned(12, NIL),
00159 _med(3, 2),
00160 _red(2, 4)
00161 {
00162 for (int i = 0; i < _ned.length(); i++)
00163 _ned[i] = -i;
00164 for (int r = 0; r < _med.rows(); r++)
00165 for (int c = 0; c < _med.columns(); c++)
00166 _med[r][c] = jethro(istring((r*c) % 256, 1));
00167 for (int j = 0; j < _red.rows(); j++)
00168 for (int k = 0; k < _red.columns(); k++)
00169 _red[j][k] = j * k;
00170 }
00171
00172 bool operator ==(const test_content &tc) const {
00173 if (tc._q != _q)
00174 return false;
00175 if (tc._ted != _ted)
00176 return false;
00177 if (tc._jed != _jed)
00178 return false;
00179 if (tc._ned.length() != _ned.length())
00180 return false;
00181 for (int i = 0; i < _ned.length(); i++)
00182 if (tc._ned[i] != _ned[i])
00183 return false;
00184
00185 if (tc._med.rows() != _med.rows())
00186 return false;
00187 if (tc._med.columns() != _med.columns())
00188 return false;
00189 for (int c = 0; c < _med.columns(); c++)
00190 for (int r = 0; r < _med.rows(); r++)
00191 if (tc._med.get(r, c) != _med.get(r, c))
00192 return false;
00193
00194 if (tc._red.rows() != _red.rows())
00195 return false;
00196 if (tc._red.columns() != _red.columns())
00197 return false;
00198 for (int j = 0; j < _red.rows(); j++)
00199 for (int k = 0; k < _red.columns(); k++)
00200 if (tc._red.get(j, k) != _red.get(j, k))
00201 return false;
00202
00203 return true;
00204 }
00205 bool operator !=(const test_content &tc) const { return !operator ==(tc); }
00206
00207 operator byte() const { return _q; }
00208 };
00209
00211
00212 template <class contents>
00213 bool compare_deep_arrays(const deep_array<contents> &a, const deep_array<contents> &b)
00214 {
00215 if (a.length() != b.length()) return false;
00216 for (int i = 0; i < a.length(); i++)
00217 if (a[i] != b[i]) return false;
00218 return true;
00219 }
00220
00221 template <class contents>
00222 void fill_in(deep_array<contents> &to_fill, const contents &filler)
00223 {
00224 for (int i = 0; i < to_fill.length(); i++)
00225 if (!to_fill.restore(i))
00226 to_fill.put(i, filler);
00227 }
00228
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239 template <class contents>
00240 void deep_array_tester(test_deep_array &ta, const contents &bogus)
00241 {
00242
00243 contents *junk_space = new contents[MAX_OBJECT + MAX_BLOCK];
00244 for (int i = 0; i < MAX_OBJECT - 1; i++)
00245 junk_space[i] = contents(ta.randomizer().inclusive('a', 'z'));
00246 junk_space[MAX_OBJECT + MAX_BLOCK - 1] = '\0';
00247
00248 deep_array<contents> *testers[MAX_SIMULTANEOUS_OBJECTS];
00249 for (int c = 0; c < MAX_SIMULTANEOUS_OBJECTS; c++) {
00250
00251 testers[c] = new deep_array<contents>(ta.randomizer().inclusive(MIN_OBJECT, MAX_OBJECT));
00252
00253 for (int i = 0; i < testers[c]->length(); i++)
00254 testers[c]->put(i, junk_space[i]);
00255 }
00256
00257
00258
00259
00260 enum actions { first, do_size = first, do_assign, do_access, do_zap,
00261 do_reset, do_resizer, do_indices, do_concatenating, do_subarray,
00262 do_insert, do_overwrite, do_memory_paring, do_snarf, last = do_snarf };
00263
00264 time_stamp exit_time(MAX_TEST_DURATION);
00265 while (time_stamp() < exit_time) {
00266 int index = ta.randomizer().inclusive(0, MAX_SIMULTANEOUS_OBJECTS - 1);
00267 int choice = ta.randomizer().inclusive(first, last);
00268 switch (choice) {
00269 case do_size: {
00270 #ifdef DEBUG_TEST_ARRAY
00271 LOG(isprintf("do_size"));
00272 #endif
00273 deep_array<contents> old_version = *testers[index];
00274 bool at_front = bool(ta.randomizer().inclusive(0, 1));
00275 int new_size = ta.randomizer().inclusive(MIN_OBJECT, MAX_OBJECT);
00276 bool smaller = new_size < old_version.length();
00277 int difference = absolute_value(new_size - old_version.length());
00278 testers[index]->resize(new_size, at_front? common::NEW_AT_BEGINNING
00279 : common::NEW_AT_END);
00280 if (!smaller && difference) {
00281
00282
00283 if (at_front) {
00284 for (int i = 0; i < difference; i++)
00285 testers[index]->put(i, 'Q');
00286 } else {
00287 for (int i = old_version.length();
00288 i < old_version.length() + difference; i++)
00289 testers[index]->put(i, 'Q');
00290 }
00291 }
00292
00293 deep_array<contents> equivalent(0);
00294 if (at_front) {
00295 if (smaller) {
00296 equivalent = old_version.subarray(difference,
00297 old_version.length() - 1);
00298 } else {
00299 deep_array<contents> blank(difference);
00300 for (int i = 0; i < blank.length(); i++)
00301 blank[i] = 'Q';
00302 equivalent = blank + old_version;
00303 }
00304 } else {
00305 if (smaller) {
00306 equivalent = old_version.subarray(0, old_version.length()
00307 - difference - 1);
00308 } else {
00309 deep_array<contents> blank(difference);
00310 for (int i = 0; i < blank.length(); i++)
00311 blank[i] = 'Q';
00312 equivalent = old_version + blank;
00313 }
00314 }
00315 if (equivalent.length() != testers[index]->length())
00316 deadly_error(ta.class_name(), __WHERE__, "the resized form had "
00317 "erroneous length");
00318 if (!compare_deep_arrays(*testers[index], equivalent))
00319 deadly_error(ta.class_name(), __WHERE__, "the resized form had "
00320 "erroneous contents");
00321 break;
00322 }
00323 case do_assign: {
00324 #ifdef DEBUG_TEST_ARRAY
00325 LOG(isprintf("do_assign"));
00326 #endif
00327 deep_array<contents> arrh = *testers[index];
00328 int to_assign = ta.randomizer().inclusive(0, MAX_SIMULTANEOUS_OBJECTS - 1);
00329 *testers[index] = *testers[to_assign];
00330 if (!compare_deep_arrays(*testers[index], *testers[to_assign]))
00331 deadly_error(ta.class_name(), __WHERE__, "assign failed to copy deep_array");
00332 *testers[to_assign] = arrh;
00333 if (!compare_deep_arrays(*testers[to_assign], arrh))
00334 deadly_error(ta.class_name(), __WHERE__, "second assign failed");
00335 break;
00336 }
00337 case do_access: {
00338 #ifdef DEBUG_TEST_ARRAY
00339 LOG(isprintf("do_access"));
00340 #endif
00341 int start = ta.randomizer().inclusive(0, testers[index]->length());
00342 int end = ta.randomizer().inclusive(0, testers[index]->length());
00343 flip_increasing(start, end);
00344 deep_array<contents> accumulator(0);
00345 for (int i = start; i < end; i++) {
00346 contents c = contents(ta.randomizer().inclusive(1, 255));
00347 testers[index]->put(i, c);
00348 accumulator += c;
00349 }
00350 for (int j = start; j < end; j++)
00351 if (accumulator[j - start] != (*testers[index])[j])
00352 deadly_error(ta.class_name(), __WHERE__, "accessing failed");
00353 break;
00354 }
00355 case do_indices: {
00356 #ifndef CATCH_ERRORS // only works if not catching errors.
00357 #ifdef DEBUG_TEST_ARRAY
00358 LOG(isprintf("do_indices"));
00359 #endif
00360
00361 contents c1 = testers[index]->operator[](-50);
00362 contents c2 = testers[index]->operator[](-MAX_OBJECT);
00363 bool test = (c1 == c2);
00364 if (!test)
00365 deadly_error(ta.class_name(), __WHERE__, "invalid values were not same");
00366 int tests = ta.randomizer().inclusive(100, 500);
00367 for (int i = 0; i < tests; i++) {
00368 int indy = ta.randomizer().inclusive(-1000, MAX_OBJECT * 3);
00369
00370 contents c3 = testers[index]->operator[](indy);
00371 contents c4 = c3;
00372 if (c3 != c4)
00373 deadly_error(ta.class_name(), __WHERE__, "values were not same");
00374 }
00375 #endif
00376 break;
00377 }
00378 case do_resizer: {
00379 #ifdef DEBUG_TEST_ARRAY
00380 LOG(isprintf("do_resizer"));
00381 #endif
00382
00383 deep_array<contents> &arrh = *testers[index];
00384
00385 int i;
00386 for (i = 0; i < arrh.length(); i++)
00387 arrh[i] = contents((i + 23) % 256);
00388 int zap_amount = ta.randomizer().inclusive(1, arrh.length() - 1);
00389
00390 arrh.zap(0, zap_amount - 1);
00391
00392 for (i = 0; i < arrh.length(); i++)
00393 if (arrh[i] != contents((i + 23 + zap_amount) % 256))
00394 deadly_error(ta.class_name(), __WHERE__, "the resized form "
00395 "had different contents");
00396
00397 arrh.resize(arrh.length() + zap_amount, common::NEW_AT_END);
00398
00399
00400
00401 for (i = 0; i < arrh.length() - zap_amount; i++)
00402 if (arrh[i] != contents((i + 23 + zap_amount) % 256))
00403 deadly_error(ta.class_name(), __WHERE__, "the resized form "
00404 "had different contents");
00405
00406 arrh.zap(0, zap_amount - 1);
00407 for (i = 0; i < zap_amount; i++) {
00408 arrh.resize(arrh.length() + 1, common::NEW_AT_END);
00409 }
00410
00411
00412
00413 for (i = 0; i < arrh.length() - 2 * zap_amount; i++)
00414 if (arrh[i] != contents((i + 23 + 2 * zap_amount) % 256))
00415 deadly_error(ta.class_name(), __WHERE__, "the slowly resized "
00416 "form had different contents");
00417
00418
00419
00420
00421
00422 for (i = 0; i < arrh.length(); i++)
00423 arrh[i] = contents((i + 23) % 256);
00424 zap_amount = ta.randomizer().inclusive(1, arrh.length() - 1);
00425
00426 arrh.zap(0, zap_amount - 1);
00427
00428 for (i = 0; i < arrh.length(); i++)
00429 if (arrh[i] != contents((i + 23 + zap_amount) % 256))
00430 deadly_error(ta.class_name(), __WHERE__, "the resized form "
00431 "had different contents");
00432
00433 arrh.resize(arrh.length() + zap_amount,
00434 common::NEW_AT_BEGINNING);
00435
00436
00437
00438 for (i = zap_amount; i < arrh.length(); i++)
00439 if (arrh[i] != contents((i + 23) % 256))
00440 deadly_error(ta.class_name(), __WHERE__, "the resized form "
00441 "had different contents");
00442
00443 arrh.zap(0, zap_amount - 1);
00444 for (i = 0; i < zap_amount; i++) {
00445 arrh.resize(arrh.length() + 1, common::NEW_AT_BEGINNING);
00446 }
00447
00448
00449
00450 for (i = zap_amount; i < arrh.length(); i++)
00451 if (arrh[i] != contents((i + 23) % 256))
00452 deadly_error(ta.class_name(), __WHERE__, "the slowly resized "
00453 "form had different contents");
00454 break;
00455 }
00456 case do_zap: {
00457 #ifdef DEBUG_TEST_ARRAY
00458 LOG(isprintf("do_zap"));
00459 #endif
00460 int start;
00461 int end;
00462 bool erroneous = false;
00463 int chose = ta.randomizer().inclusive(1, 100);
00464 if (chose <= 90) {
00465
00466 start = ta.randomizer().inclusive(0, testers[index]->length() - 1);
00467 end = ta.randomizer().inclusive(0, testers[index]->length() - 1);
00468 } else if (chose <= 95) {
00469
00470
00471 start = 0;
00472 end = ta.randomizer().inclusive(0, testers[index]->length() - 1);
00473 } else {
00474
00475
00476 erroneous = true;
00477 start = ta.randomizer().inclusive(-2, testers[index]->length() + 3);
00478 end = ta.randomizer().inclusive(-2, testers[index]->length() + 3);
00479 }
00480 flip_increasing(start, end);
00481 deep_array<contents> old_version = *testers[index];
00482 testers[index]->zap(start, end);
00483 if (!erroneous) {
00484 deep_array<contents> old_head = old_version.subarray(0, start - 1);
00485 deep_array<contents> old_tail = old_version.subarray(end + 1,
00486 old_version.length() - 1);
00487 deep_array<contents> equivalent = old_head + old_tail;
00488 if (equivalent.length() != testers[index]->length())
00489 deadly_error(ta.class_name(), __WHERE__, "the zapped form had "
00490 "erroneous length");
00491 if (!compare_deep_arrays(*testers[index], equivalent))
00492 deadly_error(ta.class_name(), __WHERE__, "the zapped form had "
00493 "erroneous contents");
00494 }
00495 break;
00496 }
00497 case do_reset: {
00498 #ifdef DEBUG_TEST_ARRAY
00499 LOG(isprintf("do_reset"));
00500 #endif
00501 int junk_start = ta.randomizer().inclusive(MIN_BLOCK, MAX_BLOCK);
00502 int junk_end = ta.randomizer().inclusive(MIN_BLOCK, MAX_BLOCK);
00503 flip_increasing(junk_start, junk_end);
00504 int len = junk_end - junk_start + 1;
00505 testers[index]->reset(len);
00506 if (testers[index]->length() != len)
00507 deadly_error(ta.class_name(), __WHERE__, "reset gave a bad length");
00508 for (int i = 0; i < len; i++) {
00509 testers[index]->put(i, junk_space[junk_start + i]);
00510 if (testers[index]->get(i) != junk_space[junk_start + i])
00511 deadly_error(ta.class_name(), __WHERE__, "reset failed to copy data");
00512 }
00513 break;
00514 }
00515 case do_concatenating: {
00516 #ifdef DEBUG_TEST_ARRAY
00517 LOG(isprintf("do_concatenating"));
00518 #endif
00519 for (int i = 0; i < ta.randomizer().inclusive(1, 20); i++) {
00520 contents new_c = contents(ta.randomizer().inclusive('a', 'z'));
00521 testers[index]->concatenate(new_c);
00522 if (new_c != testers[index]->get(testers[index]->last()))
00523 deadly_error(ta.class_name(), __WHERE__,
00524 "value wrong after concatenate");
00525 }
00526 int indy = ta.randomizer().inclusive(0, MAX_SIMULTANEOUS_OBJECTS - 1);
00527 deep_array<contents> flirpan = *testers[indy];
00528 int start = ta.randomizer().inclusive(0, flirpan.length() - 1);
00529 int end = ta.randomizer().inclusive(0, flirpan.length() - 1);
00530 flip_increasing(start, end);
00531 flirpan = flirpan.subarray(start, end);
00532 deep_array<contents> grumzor = *testers[index];
00533 testers[index]->concatenate(flirpan);
00534 deep_array<contents> bubula = grumzor + flirpan;
00535 if (!compare_deep_arrays(bubula, *testers[index]))
00536 deadly_error(ta.class_name(), __WHERE__,
00537 "contents wrong after concatenate or concatenation");
00538 contents first_value;
00539 contents second_value;
00540 if (testers[index]->length() >= 1)
00541 first_value = testers[index]->get(0);
00542 if (testers[index]->length() >= 2)
00543 second_value = testers[index]->get(1);
00544 const int max_iters = ta.randomizer().inclusive(1, 42);
00545 for (int j = 0; j < max_iters; j++) {
00546 contents new_c = contents(ta.randomizer().inclusive('a', 'z'));
00547 *testers[index] = *testers[index] + new_c;
00548
00549 if (testers[index]->length() == 1) {
00550 first_value = testers[index]->get(0);
00551 } else if (testers[index]->length() == 2) {
00552 second_value = testers[index]->get(1);
00553 }
00554
00555 if (new_c != testers[index]->get(testers[index]->last()))
00556 deadly_error(ta.class_name(), __WHERE__, "value wrong after "
00557 "concatenation");
00558
00559 if ( (testers[index]->length() >= 1)
00560 && (first_value != testers[index]->get(0)) )
00561 deadly_error(ta.class_name(), __WHERE__, "first value got "
00562 "corrupted");
00563 if ( (testers[index]->length() >= 2)
00564 && (second_value != testers[index]->get(1)) )
00565 deadly_error(ta.class_name(), __WHERE__, "second value got "
00566 "corrupted");
00567
00568 *testers[index] += new_c;
00569
00570
00571 if (testers[index]->length() == 2) {
00572 second_value = testers[index]->get(1);
00573 }
00574 if (new_c != testers[index]->get(testers[index]->last()))
00575 deadly_error(ta.class_name(), __WHERE__, "value wrong after "
00576 "second concatenation");
00577 if ( (testers[index]->length() >= 1)
00578 && (first_value != testers[index]->get(0)) )
00579 deadly_error(ta.class_name(), __WHERE__, "first value got "
00580 "corrupted after second concat");
00581 if ( (testers[index]->length() >= 2)
00582 && (second_value != testers[index]->get(1)) )
00583 deadly_error(ta.class_name(), __WHERE__, "second value got "
00584 "corrupted after second concat");
00585 }
00586 break;
00587 }
00588 case do_subarray: {
00589 #ifdef DEBUG_TEST_ARRAY
00590 LOG(isprintf("do_subarray"));
00591 #endif
00592 fill_in(*testers[index], bogus);
00593 deep_array<contents> flirpan = *testers[index];
00594 int start = ta.randomizer().inclusive(0, flirpan.length() - 1);
00595 int end = ta.randomizer().inclusive(0, flirpan.length() - 1);
00596 flip_increasing(start, end);
00597 flirpan = flirpan.subarray(start, end);
00598 for (int i = 0; i < end - start; i++)
00599 if (flirpan[i] != testers[index]->get(i + start))
00600 deadly_error(ta.class_name(), __WHERE__, "subarray produced wrong deep_array");
00601 break;
00602 }
00603 case do_memory_paring: {
00604 #ifdef DEBUG_TEST_ARRAY
00605 LOG(isprintf("do_memory_paring"));
00606 #endif
00607 for (int i = 0; i < MAX_SIMULTANEOUS_OBJECTS; i++) {
00608
00609 if (testers[i]->length() > MAX_OBJECT) {
00610 testers[i]->zap(MAX_OBJECT, testers[i]->length() - 1);
00611 }
00612 }
00613 break;
00614 }
00615 case do_snarf: {
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646 }
00647 case do_insert: {
00648 #ifdef DEBUG_TEST_ARRAY
00649 LOG(isprintf("do_insert"));
00650 #endif
00651 fill_in(*testers[index], bogus);
00652 deep_array<contents> hold = *testers[index];
00653 int put_where = ta.randomizer().inclusive(0, hold.last());
00654 int how_many = ta.randomizer().inclusive(0, 25);
00655 testers[index]->insert(put_where, how_many);
00656 for (int i = 0; i < put_where; i++)
00657 if (hold[i] != testers[index]->get(i))
00658 deadly_error(ta.class_name(), __WHERE__, "bad contents on left after insert");
00659 for (int j = put_where + how_many; j < testers[index]->length(); j++)
00660 if (hold[j - how_many] != testers[index]->get(j))
00661 deadly_error(ta.class_name(), __WHERE__, "bad contents on right after insert");
00662 break;
00663 }
00664 case do_overwrite: {
00665 #ifdef DEBUG_TEST_ARRAY
00666 LOG(isprintf("do_overwrite"));
00667 #endif
00668 fill_in(*testers[index], bogus);
00669 if (!testers[index]->length()) continue;
00670 fill_in(*testers[index], bogus);
00671 deep_array<contents> hold = *testers[index];
00672 int index2 = index;
00673 while (index2 == index)
00674 index2 = ta.randomizer().inclusive(0, MAX_SIMULTANEOUS_OBJECTS - 1);
00675 fill_in(*testers[index2], bogus);
00676 deep_array<contents> &hold2 = *testers[index2];
00677 if (!hold2.length()) continue;
00678 int write_indy = ta.randomizer().inclusive(0, hold.last());
00679 int write_len = minimum(hold2.length(), (hold.length() - write_indy));
00680
00681 outcome ret = testers[index]->overwrite(write_indy,
00682 *testers[index2], write_len);
00683 if (ret != common::OKAY)
00684 deadly_error(ta.class_name(), __WHERE__, istring("bad outcome=")
00685 + common::outcome_name(ret));
00686 for (int i = 0; i < write_indy; i++)
00687 if (hold[i] != testers[index]->get(i))
00688 deadly_error(ta.class_name(), __WHERE__,
00689 "bad contents on left after overwrite");
00690 for (int j = write_indy; j < write_indy + write_len; j++)
00691 if (hold2[j - write_indy] != testers[index]->get(j))
00692 deadly_error(ta.class_name(), __WHERE__,
00693 "bad contents in middle after overwrite");
00694 for (int k = write_indy + write_len; k < testers[index]->length(); k++)
00695 if (hold[k] != testers[index]->get(k))
00696 deadly_error(ta.class_name(), __WHERE__,
00697 "bad contents on right after overwrite");
00698 break;
00699 }
00700 default: {
00701 deadly_error(ta.class_name(), "action choice", "invalid choice!");
00702 break;
00703 }
00704 }
00705 }
00706
00707
00708 delete [] junk_space;
00709 for (int d = 0; d < MAX_SIMULTANEOUS_OBJECTS; d++) delete testers[d];
00710 }
00711
00713
00714 struct gerkin { int l; byte *p; char *r; void *pffttt; };
00715
00716 gerkin borgia;
00717
00718 class foop
00719 {
00720 public:
00721 virtual ~foop() {}
00722 virtual gerkin *boorba() = 0;
00723 };
00724
00725 class boop : public foop
00726 {
00727 public:
00728 virtual gerkin *boorba() { return &borgia; }
00729 };
00730
00732
00733 class deep_pack_object : public packable
00734 {
00735 public:
00736 istring _glunk;
00737 int _foof;
00738
00739 deep_pack_object() : packable(), _glunk("arf"), _foof(2398) {}
00740 virtual ~deep_pack_object() { _glunk = ""; _foof = 0; }
00741
00742 virtual void pack(byte_array &packed_form) const {
00743 _glunk.pack(packed_form);
00744 basis::attach(packed_form, _foof);
00745 }
00746
00747 virtual bool unpack(byte_array &packed_form) {
00748 if (!_glunk.unpack(packed_form)) return false;
00749 if (!basis::detach(packed_form, _foof)) return false;
00750 return true;
00751 }
00752
00753 virtual int packed_size() const {
00754 return _glunk.length() + 1
00755 + sizeof(int);
00756 }
00757 };
00758
00759 void test_deep_array::test_packing_deep_arrays()
00760 {
00761 FUNCDEF("test_packing_deep_arrays");
00762 deep_array<deep_pack_object> fred1;
00763 for (int i = 0; i < 3 + chaos().inclusive(0, 80); i++)
00764 fred1 += deep_pack_object();
00765 byte_array packed_form;
00766 data_structure::pack(packed_form, fred1);
00767 if (data_structure::packed_size(fred1) != packed_form.length())
00768 deadly_error(func, "packed_size", "calculated wrong packed size");
00769 deep_array<deep_pack_object> fred2;
00770 if (!data_structure::unpack(packed_form, fred2))
00771 deadly_error(func, "unpack", "unpacking failed on deep array");
00772 if (fred2.length() != fred1.length())
00773 deadly_error(func, "unpack", "unpacking got wrong length in result");
00774 for (int i = 0; i < fred2.length(); i++) {
00775 if (fred2[i]._foof != 2398)
00776 deadly_error(func, "unpack", "unpacking got wrong int content");
00777 if (fred2[i]._glunk != "arf")
00778 deadly_error(func, "unpack", "unpacking got wrong string content");
00779 }
00780 }
00781
00783
00784 int test_deep_array::execute()
00785 {
00786 test_packing_deep_arrays();
00787 LOG(isprintf("did deep_array packing test."));
00788
00789 int_array checking_start;
00790 if (checking_start.length())
00791 deadly_error(class_name(), "int_array length",
00792 "has contents from empty constructor!");
00793
00794 float_plus<double> bogus4 = float(12.32);
00795 deep_array_tester<float_plus<double> >(*this, bogus4);
00796 LOG(isprintf("did float deep_array test."));
00797
00798 int bogus2 = 39;
00799 deep_array_tester<int>(*this, bogus2);
00800 LOG(isprintf("did int deep_array test."));
00801
00802 test_content bogus3(12);
00803 deep_array_tester<test_content>(*this, bogus3);
00804 LOG(isprintf("did test_content deep_array test."));
00805
00806 test_deep_arrays_of_void_pointer();
00807 LOG(isprintf("did void * deep_array test."));
00808
00809 byte bogus1 = 'c';
00810 deep_array_tester<byte>(*this, bogus1);
00811 LOG(isprintf("did byte deep_array test."));
00812
00813 guards::alert_message("deep_array:: works for those functions tested.");
00814
00815 return 0;
00816 }
00817
00818 HOOPLE_MAIN(test_deep_array, )
00819