00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <errno.h>
00022 #include <string.h>
00023
00024 #include "htendian.h"
00025 #include "htatom.h"
00026 #include "htdebug.h"
00027 #include "htstring.h"
00028 #include "language.h"
00029 #include "store.h"
00030 #include "snprintf.h"
00031 #include "tools.h"
00032
00033 static char hexchars2[]="0123456789abcdef";
00034
00035
00036
00037
00038
00039 Object *ht_object_stream_inter::getObject(char *name)
00040 {
00041 Object *o;
00042 getObject(o, name);
00043 return o;
00044 }
00045
00046 void ht_object_stream_inter::getObject(Object *&o, char *name)
00047 {
00048 OBJECT_ID id=getIntHex(4, "id");
00049 if (id) {
00050 object_builder b=(object_builder)find_atom(id);
00051 if (b) {
00052 o=b();
00053 if (o->load(this)!=0) {
00054
00055 delete o;
00056 o = NULL;
00057 }
00058 } else {
00059
00060
00061 o = NULL;
00062 }
00063 } else {
00064 o = NULL;
00065 }
00066 }
00067
00068 void ht_object_stream_inter::putObject(Object *obj, char *name)
00069 {
00070 if (obj) {
00071 OBJECT_ID o=obj->object_id();
00072 object_builder b=(object_builder)find_atom(o);;
00073 if (b) {
00074 putIntHex(o, 4, "id");
00075 obj->store(this);
00076 } else {
00077
00078 assert(0);
00079 putIntHex(0, 4, "id");
00080 }
00081 } else {
00082 putIntHex(0, 4, "id");
00083 }
00084 }
00085
00086
00087
00088
00089
00090 void ht_object_stream_bin::init(ht_stream *s)
00091 {
00092 ht_object_stream_inter::init(s);
00093 }
00094
00095 void *ht_object_stream_bin::getBinary(int size, char *desc)
00096 {
00097 void *p = smalloc(size);
00098 if (stream->read(p, size) != (UINT)size) set_error(EIO | STERR_SYSTEM);
00099 return p;
00100 }
00101
00102 void ht_object_stream_bin::getBinary(void *p, int size, char *desc)
00103 {
00104 if (stream->read(p, size) != (UINT)size) set_error(EIO | STERR_SYSTEM);
00105 }
00106
00107 bool ht_object_stream_bin::getBool(char *desc)
00108 {
00109 bool b;
00110 if (stream->read(&b, 1) != 1) set_error(EIO | STERR_SYSTEM);
00111 return b;
00112 }
00113
00114 int ht_object_stream_bin::getIntDec(int size, char *desc)
00115 {
00116 return getIntHex(size, desc);
00117 }
00118
00119 int ht_object_stream_bin::getIntHex(int size, char *desc)
00120 {
00121 assert(size <= 8);
00122 byte neta[8];
00123 if (stream->read(&neta, size)!=(UINT)size) set_error(EIO | STERR_SYSTEM);
00124 return create_host_int(neta, size, big_endian);
00125 }
00126
00127 qword ht_object_stream_bin::getQWordDec(int size, char *desc)
00128 {
00129 return getQWordHex(size, desc);
00130 }
00131
00132 qword ht_object_stream_bin::getQWordHex(int size, char *desc)
00133 {
00134 assert(size == 8);
00135 byte neta[8];
00136 if (stream->read(&neta, size)!=(UINT)size) set_error(EIO | STERR_SYSTEM);
00137 return create_host_int64(neta, big_endian);
00138 }
00139
00140 void ht_object_stream_bin::getSeparator()
00141 {
00142
00143 }
00144
00145 char *ht_object_stream_bin::getString(char *desc)
00146 {
00147 return getstrz(stream);
00148 }
00149
00150 void ht_object_stream_bin::putBinary(void *mem, int size, char *desc)
00151 {
00152 if (stream->write(mem, size) != (UINT)size) set_error(EIO | STERR_SYSTEM);
00153 }
00154
00155 void ht_object_stream_bin::putBool(bool b, char *desc)
00156 {
00157 b = (b)?1:0;
00158 if (stream->write(&b, 1) != 1) set_error(EIO | STERR_SYSTEM);
00159 }
00160
00161 void ht_object_stream_bin::putInfo(char *info)
00162 {
00163
00164 }
00165
00166 void ht_object_stream_bin::putIntDec(int a, int size, char *desc)
00167 {
00168 putIntHex(a, size, desc);
00169 }
00170
00171 void ht_object_stream_bin::putIntHex(int a, int size, char *desc)
00172 {
00173 assert(size <= 8);
00174 byte neta[8];
00175 create_foreign_int(neta, a, size, big_endian);
00176 if (stream->write(&neta, size) != (UINT)size) set_error(EIO | STERR_SYSTEM);
00177 }
00178
00179 void ht_object_stream_bin::putQWordDec(qword a, int size, char *desc)
00180 {
00181 putQWordHex(a, size, desc);
00182 }
00183
00184 void ht_object_stream_bin::putQWordHex(qword a, int size, char *desc)
00185 {
00186 assert(size == 8);
00187 byte neta[8];
00188 create_foreign_int64(neta, a, size, big_endian);
00189 if (stream->write(&neta, size) != (UINT)size) set_error(EIO | STERR_SYSTEM);
00190 }
00191
00192 void ht_object_stream_bin::putSeparator()
00193 {
00194
00195 }
00196
00197 void ht_object_stream_bin::putString(char *string, char *desc)
00198 {
00199 UINT len = strlen(string)+1;
00200 if (stream->write(string, len) != len) set_error(EIO | STERR_SYSTEM);
00201 }
00202
00203
00204
00205
00206
00207 void ht_object_stream_txt::init(ht_stream *s)
00208 {
00209 ht_object_stream::init(s);
00210 indent = 0;
00211 cur = ' ';
00212 line = 1;
00213 errorline = 0;
00214 }
00215
00216 void *ht_object_stream_txt::getBinary(int size, char *desc)
00217 {
00218 void *p=smalloc(size);
00219 getBinary(p, size, desc);
00220 return p;
00221 }
00222
00223 void ht_object_stream_txt::getBinary(void *p, int size, char *desc)
00224 {
00225 readDesc(desc);
00226 expect('=');
00227 expect('[');
00228 byte *pp=(byte *)p;
00229 for (int i=0; i<size; i++) {
00230 skipWhite();
00231
00232 int bb;
00233 if ((bb = hexdigit(cur))==-1) setSyntaxError();
00234 int b = bb*16;
00235
00236 readChar();
00237 if ((bb = hexdigit(cur))==-1) setSyntaxError();
00238 b += bb;
00239
00240 *pp++=b;
00241
00242 readChar();
00243 }
00244 expect(']');
00245 }
00246
00247 bool ht_object_stream_txt::getBool(char *desc)
00248 {
00249 readDesc(desc);
00250 expect('=');
00251 skipWhite();
00252 if (cur=='f') {
00253 readDesc("false");
00254 return false;
00255 } else {
00256 readDesc("true");
00257 return true;
00258 }
00259 }
00260
00261 int ht_object_stream_txt::getIntDec(int size, char *desc)
00262 {
00263 return getIntHex(size, desc);
00264 }
00265
00266 int ht_object_stream_txt::getIntHex(int size, char *desc)
00267 {
00268 return QWORD_GET_LO(getQWordHex(size, desc));
00269 }
00270
00271 qword ht_object_stream_txt::getQWordDec(int size, char *desc)
00272 {
00273 return getQWordHex(size, desc);
00274 }
00275
00276 qword ht_object_stream_txt::getQWordHex(int size, char *desc)
00277 {
00278 readDesc(desc);
00279 expect('=');
00280 skipWhite();
00281 if (mapchar[(unsigned char)cur]!='0') setSyntaxError();
00282 char str[40];
00283 char *s=str;
00284 do {
00285 *s++ = cur;
00286 if (s-str >= 39) setSyntaxError();
00287 readChar();
00288 if (get_error()) return to_qword(0);
00289 } while (mapchar[(unsigned char)cur]=='0' || mapchar[(unsigned char)cur]=='A');
00290 *s=0; s=str;
00291 qword a;
00292 if (!bnstr(&s, &a, 10)) setSyntaxError();
00293 return a;
00294 }
00295
00296 void ht_object_stream_txt::getObject(Object *&o, char *name)
00297 {
00298 readDesc(name);
00299 expect('=');
00300 expect('{');
00301 if (!get_error()) {
00302 ht_object_stream_inter::getObject(o, name);
00303 } else {
00304 o = NULL;
00305 }
00306 expect('}');
00307 }
00308
00309 void ht_object_stream_txt::getSeparator()
00310 {
00311
00312 }
00313
00314 char *ht_object_stream_txt::getString(char *desc)
00315 {
00316 readDesc(desc);
00317 expect('=');
00318 skipWhite();
00319 if (cur=='"') {
00320 char str[1024];
00321 char *s=str;
00322 do {
00323 readChar();
00324 *s++=cur;
00325 if (cur=='\\') {
00326 readChar();
00327 *s++=cur;
00328 cur = 0;
00329 }
00330 if (get_error()) return NULL;
00331 } while (cur!='"');
00332 s--;*s=0;
00333 readChar();
00334 int str2l = strlen(str)+1;
00335 char *str2 = (char *)smalloc(str2l);
00336 unescape_special_str(str2, str2l, str);
00337 return str2;
00338 } else {
00339 readDesc("NULL");
00340 return NULL;
00341 }
00342 }
00343
00344 void ht_object_stream_txt::putBinary(void *mem, int size, char *desc)
00345 {
00346 putDesc(desc);
00347 putChar('[');
00348 for(int i=0; i<size; i++) {
00349 byte a = *((byte *)mem+i);
00350 putChar(hexchars2[(a & 0xf0) >> 4]);
00351 putChar(hexchars2[(a & 0x0f)]);
00352 if (i+1<size) putChar(' ');
00353 }
00354 putS("]\n");
00355 }
00356
00357 void ht_object_stream_txt::putBool(bool b, char *desc)
00358 {
00359 putDesc(desc);
00360 if (b) putS("true"); else putS("false");
00361 putChar('\n');
00362 }
00363
00364 void ht_object_stream_txt::putInfo(char *info)
00365 {
00366 putIndent();
00367 putS("# ");
00368 putS(info);
00369 putChar('\n');
00370 }
00371
00372 void ht_object_stream_txt::putIntDec(int a, int size, char *desc)
00373 {
00374 putDesc(desc);
00375 int b;
00376 switch (size) {
00377 case 1:
00378 b = (char) a;
00379 case 2:
00380 b = (short) a;
00381 case 4:
00382 b = (int) a;
00383 default:
00384 b = a;
00385 }
00386 char number[12];
00387 sprintf(number, "%d\n", a);
00388 putS(number);
00389 }
00390
00391 void ht_object_stream_txt::putIntHex(int a, int size, char *desc)
00392 {
00393 putDesc(desc);
00394 int b;
00395 switch (size) {
00396 case 1:
00397 b = (char) a;
00398 case 2:
00399 b = (short) a;
00400 case 4:
00401 b = (int) a;
00402 default:
00403 b = a;
00404 }
00405 char number2[12];
00406 sprintf(number2, "0x%x\n", b);
00407 putS(number2);
00408 }
00409
00410 void ht_object_stream_txt::putQWordDec(qword a, int size, char *desc)
00411 {
00412 putDesc(desc);
00413 char number[40];
00414 ht_snprintf(number, sizeof number, "%qd\n", &a);
00415 putS(number);
00416 }
00417
00418 void ht_object_stream_txt::putQWordHex(qword a, int size, char *desc)
00419 {
00420 putDesc(desc);
00421 char number2[40];
00422 ht_snprintf(number2, sizeof number2, "0x%qx\n", a);
00423 putS(number2);
00424 }
00425
00426 void ht_object_stream_txt::putObject(Object *obj, char *name)
00427 {
00428 putDesc(name);
00429 putS("{\n");
00430 indent++;
00431 ht_object_stream_inter::putObject(obj, name);
00432 indent--;
00433 putIndent();
00434 putS("}\n");
00435 }
00436
00437 void ht_object_stream_txt::putSeparator()
00438 {
00439 putIndent();
00440 putS("# ------------------------ \n");
00441 }
00442
00443 void ht_object_stream_txt::putString(char *string, char *desc)
00444 {
00445 putDesc(desc);
00446 if (string) {
00447 int strl=strlen(string)*4+1;
00448 char *str = (char*)smalloc(strl);
00449 putChar('"');
00450 escape_special_str(str, strl, string, "\"");
00451 putS(str);
00452 putChar('"');
00453 free(str);
00454 } else {
00455 putS("NULL");
00456 }
00457 putChar('\n');
00458 }
00459
00460 void ht_object_stream_txt::setSyntaxError()
00461 {
00462 if (!errorline) {
00463 set_error(EIO | STERR_SYSTEM);
00464 errorline = line;
00465 }
00466 }
00467
00468 int ht_object_stream_txt::getErrorLine()
00469 {
00470 return errorline;
00471 }
00472
00473 void ht_object_stream_txt::expect(char c)
00474 {
00475 skipWhite();
00476 if (cur!=c) setSyntaxError();
00477 readChar();
00478 }
00479
00480 void ht_object_stream_txt::skipWhite()
00481 {
00482 while (1) {
00483 switch (mapchar[(unsigned char)cur]) {
00484 case '\n':
00485 line++;
00486 case ' ':
00487 readChar();
00488 if (get_error()) return;
00489 break;
00490 case '#':
00491 do {
00492 readChar();
00493 if (get_error()) return;
00494 } while (cur!='\n');
00495 break;
00496 default: return;
00497 }
00498 }
00499 }
00500
00501 char ht_object_stream_txt::readChar()
00502 {
00503 if (stream->read(&cur, 1) != 1) setSyntaxError();
00504 return cur;
00505 }
00506
00507 void ht_object_stream_txt::readDesc(char *desc)
00508 {
00509 skipWhite();
00510 if (!desc) desc="data";
00511 while (*desc) {
00512 if (*desc!=cur) setSyntaxError();
00513 readChar();
00514 desc++;
00515 }
00516 }
00517
00518 void ht_object_stream_txt::putDesc(char *desc)
00519 {
00520 putIndent();
00521 if (desc) putS(desc); else putS("data");
00522 putChar('=');
00523 }
00524
00525 void ht_object_stream_txt::putIndent()
00526 {
00527 for(int i=0; i<indent; i++) putChar(' ');
00528 }
00529
00530 void ht_object_stream_txt::putChar(char c)
00531 {
00532 if (stream->write(&c, 1) != 1) setSyntaxError();
00533 }
00534
00535 void ht_object_stream_txt::putS(char *s)
00536 {
00537 UINT len=strlen(s);
00538 if (stream->write(s, len) != len) setSyntaxError();
00539 }
00540
00541
00542
00543
00544
00545
00546
00547 void ht_object_stream_memmap::init(ht_stream *s, bool d)
00548 {
00549 ht_object_stream_bin::init(s);
00550 duplicate=d;
00551 allocd = new ht_clist();
00552 allocd->init();
00553 }
00554
00555 void ht_object_stream_memmap::done()
00556 {
00557 ht_object_stream_bin::done();
00558 allocd->destroy();
00559 delete allocd;
00560 }
00561
00562 void *ht_object_stream_memmap::duppa(void *p, int size)
00563 {
00564 if (duplicate) {
00565 ht_data_mem *pp = new ht_data_mem(p, size);
00566 allocd->insert(pp);
00567 return pp->value;
00568 } else {
00569 return p;
00570 }
00571 }
00572
00573 void *ht_object_stream_memmap::getBinary(int size, char *desc)
00574 {
00575 void *pp;
00576 stream->read(&pp, sizeof pp);
00577 return pp;
00578 }
00579
00580 void ht_object_stream_memmap::getBinary(void *p, int size, char *desc)
00581 {
00582 void *pp;
00583 stream->read(&pp, sizeof pp);
00584 memmove(p, pp, size);
00585 }
00586
00587 int ht_object_stream_memmap::getIntDec(int size, char *desc)
00588 {
00589 return getIntHex(size, desc);
00590 }
00591
00592 int ht_object_stream_memmap::getIntHex(int size, char *desc)
00593 {
00594 assert(size <= 8);
00595 int a;
00596 if (stream->read(&a, size)!=(UINT)size) set_error(EIO | STERR_SYSTEM);
00597 return a;
00598 }
00599
00600 qword ht_object_stream_memmap::getQWordDec(int size, char *desc)
00601 {
00602 return getQWordHex(size, desc);
00603 }
00604
00605 qword ht_object_stream_memmap::getQWordHex(int size, char *desc)
00606 {
00607 assert(size==8);
00608 qword a;
00609 if (stream->read(&a, size)!=(UINT)size) set_error(EIO | STERR_SYSTEM);
00610 return a;
00611 }
00612
00613 char *ht_object_stream_memmap::getString(char *desc)
00614 {
00615 char *pp;
00616 stream->read(&pp, sizeof pp);
00617 return pp;
00618 }
00619
00620 UINT ht_object_stream_memmap::recordStart(UINT size)
00621 {
00622 return ((ht_streamfile*)stream)->tell()+size;
00623 }
00624
00625 void ht_object_stream_memmap::recordEnd(UINT a)
00626 {
00627 FILEOFS o =((ht_streamfile*)stream)->tell();
00628 if (o>a) HT_ERROR("kput");
00629 ((ht_streamfile*)stream)->seek(a);
00630 }
00631
00632 void ht_object_stream_memmap::putBinary(void *mem, int size, char *desc)
00633 {
00634 void *pp = mem ? duppa(mem, size) : NULL;
00635 stream->write(&pp, sizeof pp);
00636 }
00637
00638 void ht_object_stream_memmap::putIntDec(int a, int size, char *desc)
00639 {
00640 putIntHex(a, size, desc);
00641 }
00642
00643 void ht_object_stream_memmap::putIntHex(int a, int size, char *desc)
00644 {
00645 assert(size <= 8);
00646 if (stream->write(&a, size) != (UINT)size) set_error(EIO | STERR_SYSTEM);
00647 }
00648
00649 void ht_object_stream_memmap::putQWordDec(qword a, int size, char *desc)
00650 {
00651 putQWordHex(a, size, desc);
00652 }
00653
00654 void ht_object_stream_memmap::putQWordHex(qword a, int size, char *desc)
00655 {
00656 assert(size <= 8);
00657 if (stream->write(&a, size) != (UINT)size) set_error(EIO | STERR_SYSTEM);
00658 }
00659
00660 void ht_object_stream_memmap::putString(char *string, char *desc)
00661 {
00662 char *pp = string ? (char*)duppa(string, strlen(string)+1) : NULL;
00663 stream->write(&pp, sizeof pp);
00664 }