00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <assert.h>
00028 #include <string.h>
00029 #include <stdlib.h>
00030 #include <stdio.h>
00031 #include <time.h>
00032
00033 #include "BufStream.H"
00034 #include "Basics.H"
00035
00036 #include <iostream>
00037 #include <iomanip>
00038 #include <sstream>
00039
00040 using std::cout;
00041 using std::cerr;
00042 using std::endl;
00043 using std::ios;
00044 using std::hex;
00045 using std::dec;
00046 using std::setw;
00047 using std::setfill;
00048 using std::ostringstream;
00049 using std::string;
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 struct LongId
00061 {
00062 struct { unsigned char byte[32]; } value;
00063
00064 int length() const throw()
00065 {
00066 unsigned int len = 1;
00067 while((len < sizeof(value.byte)) && (value.byte[len] != 0))
00068 {
00069 len++;
00070 }
00071 return len;
00072 }
00073
00074 void append(unsigned int index) throw ()
00075 {
00076 unsigned char* start = &value.byte[0];
00077 unsigned char* end =
00078 (unsigned char*) memchr((const void*) (start + 1), 0, sizeof(value)-1);
00079 while (index > 0) {
00080 if (end >= &value.byte[sizeof(value)]) {
00081
00082 return;
00083 }
00084 int newbyte = index & 0x7f;
00085 index >>= 7;
00086 if (index > 0) newbyte |= 0x80;
00087 *end++ = newbyte;
00088 }
00089 }
00090
00091 LongId()
00092 {
00093 memset(&(this->value), 0, sizeof(this->value));
00094
00095
00096 int target_bytes = (random() % 16) + 8;
00097 while(length() < target_bytes)
00098 append(random() % 8192);
00099 }
00100
00101 };
00102
00103 using std::ostream;
00104
00105
00106
00107 ostream&
00108 operator<<(ostream& s, const LongId& longid)
00109 {
00110 int i;
00111 int len = longid.length();
00112 for (i=0; i<len; i++) {
00113 s << setw(2) << setfill('0') << hex
00114 << (int) (longid.value.byte[i] & 0xff);
00115 }
00116 s << setfill(' ') << dec;
00117 return s;
00118 }
00119
00120 ostream&
00121 PutQuotedString(ostream& s, const char* string)
00122 {
00123 s << '\"';
00124 while (*string) {
00125 if (*string == '\"' || *string == '\\') {
00126 s << '\\';
00127 }
00128 s << *string++;
00129 }
00130 s << '\"';
00131 return s;
00132 }
00133
00134
00135 string random_arc()
00136 {
00137 string result;
00138 int length = 4 + (random() % 20);
00139 static const char *letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
00140 static const char *digits = "0123456789";
00141 static const char *specials = "_.";
00142 while(result.size() < length)
00143 {
00144 switch(random() % 8)
00145 {
00146 case 0:
00147 result += specials[random() % 2];
00148 break;
00149 case 1:
00150 case 2:
00151 result += digits[random() % 10];
00152 break;
00153 default:
00154 result += letters[random() % 52];
00155 break;
00156 }
00157 }
00158
00159 return result;
00160 }
00161
00162
00163
00164 void print_stream_state(unsigned int state)
00165 {
00166 bool first = true;
00167 if(state & ios::eofbit)
00168 {
00169 cerr << "eof";
00170 state &= ~((unsigned int) ios::eofbit);
00171 first = false;
00172 }
00173 if(state & ios::failbit)
00174 {
00175 if(!first)
00176 cerr << "|";
00177 cerr << "fail";
00178 state &= ~((unsigned int) ios::failbit);
00179 first = false;
00180 }
00181 if(state & ios::badbit)
00182 {
00183 if(!first)
00184 cerr << "|";
00185 cerr << "bad";
00186 state &= ~((unsigned int) ios::badbit);
00187 first = false;
00188 }
00189 if(state != 0)
00190 {
00191 if(!first)
00192 cerr << "|";
00193 cerr << "0x" << hex << state << dec;
00194 }
00195 }
00196
00197 void print_state_if_not_good(const ios &stream,
00198 const char *name, const char *marker)
00199 {
00200 if(!stream.good())
00201 {
00202 cerr << name << " state (" << marker << "): ";
00203 print_stream_state(stream.rdstate());
00204 cerr << endl;
00205 abort();
00206 }
00207 }
00208
00209
00210 void format_time(LongId longid, time_t timestamp, std::ostream &out)
00211 {
00212 out << "(time " << longid << " " << timestamp << ")\n";
00213 }
00214
00215
00216 void format_del(LongId longid, time_t timestamp, string &arc, std::ostream &out)
00217 {
00218 out << "(del " << longid << " ";
00219 PutQuotedString(out, arc.c_str());
00220 out << " " << timestamp << ")\n";
00221 }
00222
00223
00224 void format_insf(LongId longid, time_t timestamp, string &arc,
00225 unsigned int sid, bool mast,
00226
00227 std::ostream &out)
00228 {
00229 out << "(insf " << longid << " ";
00230 PutQuotedString(out, arc.c_str());
00231 out << " 0x" << hex << sid << dec << " "
00232 << (int) mast << " " << timestamp;
00233
00234
00235
00236
00237
00238
00239 out << ")\n";
00240 }
00241
00242
00243 void format_insu(LongId longid, time_t timestamp, string &arc,
00244 unsigned int sid, bool mast,
00245 std::ostream &out)
00246 {
00247 out << "(insu " << longid << " ";
00248 PutQuotedString(out, arc.c_str());
00249 out << " 0x" << hex << sid << dec << " "
00250 << (int) mast << " " << timestamp << ")\n";
00251 }
00252
00253
00254
00255 void output_tests()
00256 {
00257 {
00258 Basics::OBufStream foo;
00259
00260 print_state_if_not_good(foo, "foo", "start");
00261 foo << "Here's a simple test.";
00262 print_state_if_not_good(foo, "foo", "1");
00263
00264 const char *foo_str = foo.str();
00265
00266 if(strcmp(foo_str, "Here's a simple test.") != 0)
00267 {
00268 cerr << "foo.str() = \"" << foo.str() << "\"" << endl
00269 << "strlen(foo.str()) = " << strlen(foo.str()) << endl;
00270 abort();
00271 }
00272 }
00273
00274 {
00275 char foo2_buf[256];
00276 Basics::OBufStream foo2(foo2_buf, sizeof(foo2_buf));
00277
00278 print_state_if_not_good(foo2, "foo2", "start");
00279 foo2 << "Here's another test, with some text that's a bit longer.";
00280 print_state_if_not_good(foo2, "foo2", "1");
00281 foo2 << endl;
00282 print_state_if_not_good(foo2, "foo2", "2");
00283 foo2 << "And a second sentence on another line.";
00284 print_state_if_not_good(foo2, "foo2", "3");
00285 foo2 << endl;
00286 print_state_if_not_good(foo2, "foo2", "4");
00287
00288 const char *foo2_str = foo2.str();
00289
00290 if(strcmp(foo2_str, ("Here's another test, with some text that's a bit longer.\n"
00291 "And a second sentence on another line.\n")) != 0)
00292 {
00293 cerr << "foo2.str() = \"" << foo2.str() << "\"" << endl
00294 << "strlen(foo2.str()) = " << strlen(foo2.str()) << endl;
00295 abort();
00296 }
00297
00298 assert(foo2.str() == foo2_buf);
00299 }
00300
00301 {
00302 char logrec[512], logrec2[10];
00303
00304 Basics::OBufStream time_tos(logrec, sizeof(logrec));
00305
00306 Basics::OBufStream time_tos2;
00307
00308 Basics::OBufStream time_tos3(logrec2, sizeof(logrec2), 0, true);
00309 ostringstream time_oss;
00310
00311
00312 LongId longid;
00313 time_t timestamp = time(0);
00314
00315 format_time(longid, timestamp, time_tos);
00316 format_time(longid, timestamp, time_tos2);
00317 format_time(longid, timestamp, time_tos3);
00318 format_time(longid, timestamp, time_oss);
00319
00320 assert(strcmp(time_oss.str().c_str(), time_tos.str()) == 0);
00321 assert(strcmp(time_oss.str().c_str(), time_tos2.str()) == 0);
00322 assert(strcmp(time_oss.str().c_str(), time_tos3.str()) == 0);
00323 assert(time_tos.str() == logrec);
00324 assert(time_tos3.str() != logrec2);
00325 }
00326
00327 {
00328 char logrec[512], logrec2[10];
00329
00330 Basics::OBufStream del_tos(logrec, sizeof(logrec));
00331
00332 Basics::OBufStream del_tos2;
00333
00334 Basics::OBufStream del_tos3(logrec2, sizeof(logrec2), 0, true);
00335 ostringstream del_oss;
00336
00337
00338 LongId longid;
00339 time_t timestamp = time(0);
00340 string arc = random_arc();
00341
00342
00343 format_del(longid, timestamp, arc, del_tos);
00344 format_del(longid, timestamp, arc, del_tos2);
00345 format_del(longid, timestamp, arc, del_tos3);
00346 format_del(longid, timestamp, arc, del_oss);
00347
00348
00349 assert(strcmp(del_oss.str().c_str(), del_tos.str()) == 0);
00350 assert(strcmp(del_oss.str().c_str(), del_tos2.str()) == 0);
00351 assert(strcmp(del_oss.str().c_str(), del_tos3.str()) == 0);
00352
00353
00354
00355 assert(del_tos.str() == logrec);
00356 assert(del_tos3.str() != logrec2);
00357 }
00358
00359 {
00360 char logrec[512], logrec2[10];
00361
00362 Basics::OBufStream insf_tos(logrec, sizeof(logrec));
00363
00364 Basics::OBufStream insf_tos2;
00365
00366 Basics::OBufStream insf_tos3(logrec2, sizeof(logrec2), 0, true);
00367 ostringstream insf_oss;
00368
00369
00370 LongId longid;
00371 time_t timestamp = time(0);
00372 string arc = random_arc();
00373 unsigned int sid = random();
00374 bool mast = ((random() % 2) == 0) ? true : false;
00375
00376 format_insf(longid, timestamp, arc, sid, mast, insf_tos);
00377 format_insf(longid, timestamp, arc, sid, mast, insf_tos2);
00378 format_insf(longid, timestamp, arc, sid, mast, insf_tos3);
00379 format_insf(longid, timestamp, arc, sid, mast, insf_oss);
00380
00381 assert(strcmp(insf_oss.str().c_str(), insf_tos.str()) == 0);
00382 assert(strcmp(insf_oss.str().c_str(), insf_tos2.str()) == 0);
00383 assert(strcmp(insf_oss.str().c_str(), insf_tos3.str()) == 0);
00384 assert(insf_tos.str() == logrec);
00385 assert(insf_tos3.str() != logrec2);
00386 }
00387
00388
00389 {
00390 char logrec[512], logrec2[10];
00391
00392 Basics::OBufStream insu_tos(logrec, sizeof(logrec));
00393
00394 Basics::OBufStream insu_tos2;
00395
00396 Basics::OBufStream insu_tos3(logrec2, sizeof(logrec2), 0, true);
00397 ostringstream insu_oss;
00398
00399 LongId longid;
00400 time_t timestamp = time(0);
00401 string arc = random_arc();
00402 unsigned int sid = random();
00403 bool mast = ((random() % 2) == 0) ? true : false;
00404
00405 format_insu(longid, timestamp, arc, sid, mast, insu_tos);
00406 format_insu(longid, timestamp, arc, sid, mast, insu_tos2);
00407 format_insu(longid, timestamp, arc, sid, mast, insu_tos3);
00408 format_insu(longid, timestamp, arc, sid, mast, insu_oss);
00409
00410 assert(strcmp(insu_oss.str().c_str(), insu_tos.str()) == 0);
00411 assert(strcmp(insu_oss.str().c_str(), insu_tos2.str()) == 0);
00412 assert(strcmp(insu_oss.str().c_str(), insu_tos3.str()) == 0);
00413 assert(insu_tos.str() == logrec);
00414 assert(insu_tos3.str() != logrec2);
00415 }
00416 }
00417
00418 void input_tests()
00419 {
00420
00421
00422
00423
00424 {
00425 char buf[20];
00426 int r = random();
00427 sprintf(buf, "%d", r);
00428
00429 Basics::IBufStream in_test(buf, sizeof(buf), strlen(buf));
00430
00431 int r2;
00432 in_test >> r2;
00433
00434 assert(r == r2);
00435 assert((unsigned int) in_test.tellg() == strlen(buf));
00436 }
00437
00438
00439
00440 {
00441 char data[] = { 0x0, 0x0, 0x0, 0x2, 0x1, 0x4e, 0x0, 0x0,
00442 0x0, 0x3, 0x4e, 0x0, 0x5, 0x45, 0x0, 0x1,
00443 0x4c, 0x0, 0x6 };
00444 Basics::IBufStream in(data, sizeof(data), sizeof(data));
00445
00446
00447 Basics::uint32 pVers;
00448 in.read((char *) &pVers, sizeof(pVers));
00449 assert(in.gcount() == sizeof(pVers));
00450 assert(Basics::ntoh32(pVers) == 2);
00451
00452
00453 bool8 hasPath;
00454 in.read((char *) &hasPath, sizeof(hasPath));
00455 assert(in.gcount() == sizeof(hasPath));
00456 assert(hasPath == 1);
00457
00458
00459 char pk;
00460 in.read(&pk, sizeof(pk));
00461 assert(in.gcount() == sizeof(pk));
00462 assert(pk == 'N');
00463
00464
00465 Basics::uint16 index;
00466 in.read((char *) &index, sizeof(index));
00467 assert(in.gcount() == sizeof(index));
00468 assert(index == 0);
00469
00470
00471 Basics::uint16 dpsLen;
00472 in.read((char *) &dpsLen, sizeof(dpsLen));
00473 assert(in.gcount() == sizeof(dpsLen));
00474 assert(Basics::ntoh16(dpsLen) == 3);
00475
00476
00477 in.read(&pk, sizeof(pk));
00478 assert(in.gcount() == sizeof(pk));
00479 assert(pk == 'N');
00480
00481 in.read((char *) &index, sizeof(index));
00482 assert(in.gcount() == sizeof(index));
00483 assert(Basics::ntoh16(index) == 5);
00484
00485
00486 in.read(&pk, sizeof(pk));
00487 assert(in.gcount() == sizeof(pk));
00488 assert(pk == 'E');
00489
00490 in.read((char *) &index, sizeof(index));
00491 assert(in.gcount() == sizeof(index));
00492 assert(Basics::ntoh16(index) == 1);
00493
00494
00495 in.read(&pk, sizeof(pk));
00496 assert(in.gcount() == sizeof(pk));
00497 assert(pk == 'L');
00498
00499 in.read((char *) &index, sizeof(index));
00500 assert(in.gcount() == sizeof(index));
00501 assert(Basics::ntoh16(index) == 6);
00502
00503
00504 assert((unsigned int) in.tellg() == sizeof(data));
00505 }
00506 }
00507
00508 void io_tests()
00509 {
00510
00511
00512 for(unsigned int i = 0; i < 100; i++)
00513 {
00514 int r = random();
00515 Basics::BufStream test;
00516 test << r;
00517 int r2;
00518 test >> r2;
00519 assert(r == r2);
00520 assert(test.tellp() == test.tellg());
00521 }
00522
00523
00524 {
00525 Basics::BufStream test(10);
00526 for(unsigned int i = 0; i < 100; i++)
00527 {
00528 int r = random();
00529 test << r << endl;
00530 int r2;
00531 test >> r2;
00532 char c;
00533 test.get(c);
00534 assert(r == r2);
00535 assert(c == '\n');
00536 assert(test.tellp() == test.tellg());
00537 }
00538 }
00539 }
00540
00541 int main(int argc, char* argv[])
00542 {
00543 srandom(time(0));
00544
00545 output_tests();
00546
00547 input_tests();
00548
00549 io_tests();
00550
00551 cout << "All tests passed!" << endl;
00552
00553 return 0;
00554 }