Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

store.cc

Go to the documentation of this file.
00001 /*
00002  *      HT Editor
00003  *      store.cc
00004  *
00005  *      Copyright (C) 1999-2002 Sebastian Biallas (sb@web-productions.de)
00006  *
00007  *      This program is free software; you can redistribute it and/or modify
00008  *      it under the terms of the GNU General Public License version 2 as
00009  *      published by the Free Software Foundation.
00010  *
00011  *      This program is distributed in the hope that it will be useful,
00012  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *      GNU General Public License for more details.
00015  *
00016  *      You should have received a copy of the GNU General Public License
00017  *      along with this program; if not, write to the Free Software
00018  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
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  *      CLASS ht_object_stream_inter
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 //                     o->done();
00055                                 delete o;
00056                                 o = NULL;
00057                         }
00058                 } else {
00059                         /* object not registered! */
00060 //                      assert(0);
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                         /* object not registered! */
00078                         assert(0);
00079                         putIntHex(0, 4, "id");
00080                 }
00081         } else {
00082                 putIntHex(0, 4, "id");
00083         }
00084 }
00085 
00086 /*
00087  *      CLASS ht_object_stream_bin
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         // empty
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         // empty
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         // empty
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  *      CLASS ht_object_stream_txt
00205  */
00206  
00207 void ht_object_stream_txt::init(ht_stream *s)
00208 {
00209         ht_object_stream::init(s);
00210         indent = 0;
00211         cur = ' '; // important to initialize it to a whitespace char
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         // do nothing
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]; // FIXME: the good old buffer overflow
00321                 char *s=str;
00322                 do {
00323                         readChar();
00324                         *s++=cur;
00325                         if (cur=='\\') {
00326                                 readChar();
00327                                 *s++=cur;
00328                                 cur = 0; // hackish
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++;  // fallthrough
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  *      CLASS ht_object_stream_memmap
00543  *   ht_object_stream_memmap dups strings + mem for set/getdata (pointers)
00544  *      and uses host endianess (integers)
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 }

Generated on Fri May 7 21:15:43 2004 by doxygen 1.3.5