/[pearpc]/src/tools/store.cc
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /src/tools/store.cc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 11 - (show annotations)
Thu Sep 6 16:48:55 2007 UTC (11 years, 10 months ago) by dpavlin
File size: 13005 byte(s)
more forgotten files
1 /*
2 * HT Editor
3 * store.cc
4 *
5 * Copyright (C) 1999-2003 Sebastian Biallas (sb@biallas.net)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include <cerrno>
22 #include <cstring>
23
24 #include "atom.h"
25 #include "debug.h"
26 #include "endianess.h"
27 #include "snprintf.h"
28 #include "store.h"
29 #include "strtools.h"
30
31 static char hexchars[]="0123456789abcdef";
32
33 char oidchar(ObjectID oID, int byte)
34 {
35 unsigned char c = (oID >> (byte*8)) & 0xff;
36 if ((c<32) || (c>0x7f)) c = '?';
37 return c;
38 }
39
40 ObjectNotRegisteredException::ObjectNotRegisteredException(ObjectID aID)
41 : MsgfException("Object %x/%c%c%c-%x not registered.", aID,
42 oidchar(aID, 3), oidchar(aID, 2), oidchar(aID, 1), aID & 0xff)
43 {
44 }
45
46 /*
47 * CLASS ObjectStreamInter
48 */
49
50 ObjectStreamInter::ObjectStreamInter(Stream *s, bool own_s)
51 : ObjectStream(s, own_s)
52 {
53 }
54
55 void ObjectStreamInter::getObject(Object *&object, const char *name, ObjectID id)
56 {
57 if (id == OBJID_INVALID) {
58 GET_INT32X(*this, id);
59 if (!id) {
60 object = NULL;
61 return;
62 }
63 }
64 object_builder build = (object_builder)getAtomValue(id);
65 if (!build) throw ObjectNotRegisteredException(id);
66 object = build();
67 object->load(*this);
68 }
69
70 void ObjectStreamInter::putObject(const Object *object, const char *name, ObjectID id)
71 {
72 if (!object) {
73 if (id == OBJID_INVALID) {
74 PUTX_INT32X(*this, 0, "id");
75 return;
76 } else {
77 throw IllegalArgumentException(HERE);
78 }
79 }
80 if (id == OBJID_INVALID) {
81 id = object->getObjectID();
82 char buf[64];
83 char id_str[4];
84 id_str[3] = id&0xff;
85 id_str[2] = (id>>8)&0xff;
86 id_str[1] = (id>>16)&0xff;
87 id_str[0] = (id>>24)&0xff;
88 escape_special(buf, sizeof buf, id_str, 4);
89 putComment(buf);
90 PUTX_INT32X(*this, id, "id");
91 }
92 object_builder build = (object_builder)getAtomValue(id);
93 if (!build) {
94 throw ObjectNotRegisteredException(id);
95 }
96 object->store(*this);
97 }
98
99 /*
100 * CLASS ObjectStreamBin
101 */
102
103 ObjectStreamBin::ObjectStreamBin(Stream *s, bool own_s)
104 : ObjectStreamInter(s, own_s)
105 {
106 }
107
108 void ObjectStreamBin::getBinary(void *buf, uint size, const char *desc)
109 {
110 mStream->readx(buf, size);
111 }
112
113 bool ObjectStreamBin::getBool(const char *desc)
114 {
115 bool b;
116 mStream->readx(&b, 1);
117 return b;
118 }
119
120 uint64 ObjectStreamBin::getInt(uint size, const char *desc)
121 {
122 ASSERT(size <= 8);
123 byte neta[8];
124 mStream->readx(&neta, size);
125 return createHostInt64(neta, size, big_endian);
126 }
127
128 char *ObjectStreamBin::getString(const char *desc)
129 {
130 return getstrz(mStream);
131 }
132
133 byte *ObjectStreamBin::getLenString(int &length, const char *desc)
134 {
135 byte b;
136 mStream->readx(&b, 1);
137 switch (b) {
138 case 0xfe: {
139 byte neta[2];
140 mStream->readx(&neta, 2);
141 length = createHostInt(neta, 2, big_endian);
142 break;
143 }
144 case 0xff: {
145 byte neta[4];
146 mStream->readx(&neta, 4);
147 length = createHostInt(neta, 4, big_endian);
148 break;
149 }
150 default:
151 length = b;
152 break;
153 }
154 if (length==0) return NULL;
155 byte *p = (byte*)malloc(length);
156 mStream->readx(p, length);
157 return p;
158 }
159
160 void ObjectStreamBin::putBinary(const void *mem, uint size, const char *desc)
161 {
162 mStream->writex(mem, size);
163 }
164
165 void ObjectStreamBin::putBool(bool b, const char *desc)
166 {
167 b = (b) ? 1 : 0;
168 mStream->writex(&b, 1);
169 }
170
171 void ObjectStreamBin::putCommentf(const char *comment_format, ...)
172 {
173 // NOP
174 }
175
176 void ObjectStreamBin::putComment(const char *comment)
177 {
178 // NOP
179 }
180
181 void ObjectStreamBin::putInt(uint64 i, uint size, const char *desc, uint int_fmt_hint)
182 {
183 ASSERT(size <= 8);
184 byte neta[8];
185 createForeignInt64(neta, i, size, big_endian);
186 mStream->writex(neta, size);
187 }
188
189 void ObjectStreamBin::putSeparator()
190 {
191 // NOP
192 }
193
194 void ObjectStreamBin::putString(const char *string, const char *desc)
195 {
196 putstrz(this, string);
197 }
198
199 void ObjectStreamBin::putLenString(const byte *string, int len, const char *desc)
200 {
201 byte bLen;
202 if (len < 0xfe) {
203 bLen = len;
204 mStream->writex(&bLen, 1);
205 } else if (len <= 0xffff) {
206 byte neta[2];
207 createForeignInt(neta, len, 2, big_endian);
208 bLen = 0xfe;
209 mStream->writex(&bLen, 1);
210 mStream->writex(neta, 2);
211 } else {
212 byte neta[4];
213 createForeignInt(neta, len, 4, big_endian);
214 bLen = 0xff;
215 mStream->writex(&bLen, 1);
216 mStream->writex(neta, 4);
217 }
218 mStream->writex(string, len);
219 }
220
221 /*
222 * CLASS ObjectStreamText
223 */
224
225 ObjectStreamText::ObjectStreamText(Stream *s, bool own_s)
226 : ObjectStreamInter(s, own_s)
227 {
228 indent = 0;
229 cur = ' '; // must be initialized to a whitespace char
230 line = 1;
231 errorline = 0;
232 }
233
234 void ObjectStreamText::getBinary(void *buf, uint size, const char *desc)
235 {
236 readDesc(desc);
237 expect('=');
238 expect('[');
239 byte *pp=(byte *)buf;
240 for (uint i=0; i<size; i++) {
241 skipWhite();
242
243 int bb;
244 if ((bb = hexdigit(cur))==-1) setSyntaxError();
245 int b = bb*16;
246
247 readChar();
248 if ((bb = hexdigit(cur))==-1) setSyntaxError();
249 b += bb;
250
251 *pp++=b;
252
253 readChar();
254 }
255 expect(']');
256 }
257
258 bool ObjectStreamText::getBool(const char *desc)
259 {
260 readDesc(desc);
261 expect('=');
262 skipWhite();
263 if (cur=='f') {
264 readDesc("false");
265 return false;
266 } else {
267 readDesc("true");
268 return true;
269 }
270 }
271
272 static char mapchar(char c)
273 {
274 return 0;
275 }
276
277 uint64 ObjectStreamText::getInt(uint size, const char *desc)
278 {
279 readDesc(desc);
280 expect('=');
281 skipWhite();
282 if (mapchar(cur)!='0') setSyntaxError();
283 char str[40];
284 char *s=str;
285 do {
286 *s++ = cur;
287 if (s-str >= 39) setSyntaxError();
288 readChar();
289 } while (mapchar(cur)=='0' || mapchar(cur)=='A');
290 *s=0; s=str;
291 uint64 a;
292 const char *s2 = s;
293 if (!parseIntStr(s2, a, 10)) setSyntaxError();
294 return a;
295 }
296
297 void ObjectStreamText::getObject(Object *&object, const char *name, ObjectID id)
298 {
299 readDesc(name);
300 expect('=');
301 expect('{');
302 ObjectStreamInter::getObject(object, name, id);
303 expect('}');
304 }
305
306 char *ObjectStreamText::getString(const char *desc)
307 {
308 readDesc(desc);
309 expect('=');
310 skipWhite();
311 if (cur=='"') {
312 String s;
313 do {
314 readChar();
315 s += cur;
316 if (cur=='\\') {
317 readChar();
318 s += cur;
319 cur = 0; // hackish
320 }
321 } while (cur != '"');
322 readChar();
323 int str2l = s.length();
324 char *str2 = (char *)malloc(str2l);
325 unescape_special_str(str2, str2l, s);
326 return str2;
327 } else {
328 readDesc("NULL");
329 return NULL;
330 }
331 }
332
333 byte *ObjectStreamText::getLenString(int &len, const char *desc)
334 {
335 readDesc(desc);
336 expect('=');
337 skipWhite();
338 if (cur=='"') {
339 String s;
340 do {
341 readChar();
342 s += cur;
343 if (cur=='\\') {
344 readChar();
345 s += cur;
346 cur = 0; // hackish
347 }
348 } while (cur != '"');
349 readChar();
350 len = s.length()-1;
351 if (!len) return NULL;
352 byte *str2 = (byte *)malloc(len);
353 unescape_special(str2, len, s);
354 return str2;
355 } else {
356 readDesc("NULL");
357 return NULL;
358 }
359 }
360
361 void ObjectStreamText::putBinary(const void *mem, uint size, const char *desc)
362 {
363 putDesc(desc);
364 putChar('[');
365 for (uint i=0; i<size; i++) {
366 byte a = *((byte *)mem+i);
367 putChar(hexchars[(a & 0xf0) >> 4]);
368 putChar(hexchars[(a & 0x0f)]);
369 if (i+1<size) putChar(' ');
370 }
371 putS("]\n");
372 }
373
374 void ObjectStreamText::putBool(bool b, const char *desc)
375 {
376 putDesc(desc);
377 if (b) putS("true"); else putS("false");
378 putChar('\n');
379 }
380
381 void ObjectStreamText::putComment(const char *comment)
382 {
383 putIndent();
384 putS("# ");
385 putS(comment);
386 putChar('\n');
387 }
388
389 void ObjectStreamText::putInt(uint64 i, uint size, const char *desc, uint int_fmt_hint)
390 {
391 putDesc(desc);
392 char number[40];
393 switch (int_fmt_hint) {
394 case OS_FMT_DEC:
395 ht_snprintf(number, sizeof number, "%qd\n", i);
396 break;
397 case OS_FMT_HEX:
398 default:
399 ht_snprintf(number, sizeof number, "0x%qx\n", i);
400 break;
401 }
402 putS(number);
403 }
404
405 void ObjectStreamText::putObject(const Object *object, const char *name, ObjectID id)
406 {
407 putDesc(name);
408 putS("{\n");
409 indent++;
410 ObjectStreamInter::putObject(object, name, id);
411 indent--;
412 putIndent();
413 putS("}\n");
414 }
415
416 void ObjectStreamText::putSeparator()
417 {
418 putIndent();
419 putS("# ------------------------ \n");
420 }
421
422 void ObjectStreamText::putString(const char *string, const char *desc)
423 {
424 putDesc(desc);
425 if (string) {
426 int strl=strlen(string)*4+1;
427 char *str = (char*)malloc(strl);
428 putChar('"');
429 escape_special_str(str, strl, string, "\"");
430 putS(str);
431 putChar('"');
432 free(str);
433 } else {
434 putS("NULL");
435 }
436 putChar('\n');
437 }
438
439 void ObjectStreamText::putLenString(const byte *string, int len, const char *desc)
440 {
441 putDesc(desc);
442 if (string) {
443 int strl=len*4+1;
444 char *str = (char*)malloc(strl);
445 putChar('"');
446 escape_special(str, strl, string, len, "\"");
447 putS(str);
448 putChar('"');
449 free(str);
450 } else {
451 putS("NULL");
452 }
453 putChar('\n');
454 }
455
456 class TextSyntaxError: public MsgfException {
457 public:
458 TextSyntaxError::TextSyntaxError(uint line)
459 : MsgfException("syntax error in line %d", line)
460 {
461 }
462 };
463
464 void ObjectStreamText::setSyntaxError()
465 {
466 // FIXME: errorline still usable ?
467 if (!errorline) {
468 errorline = line;
469 throw TextSyntaxError(line);
470 }
471 }
472
473 int ObjectStreamText::getErrorLine()
474 {
475 return errorline;
476 }
477
478 void ObjectStreamText::expect(char c)
479 {
480 skipWhite();
481 if (cur!=c) setSyntaxError();
482 readChar();
483 }
484
485 void ObjectStreamText::skipWhite()
486 {
487 while (1) {
488 switch (mapchar(cur)) {
489 case '\n':
490 line++; // fallthrough
491 case ' ':
492 readChar();
493 break;
494 case '#':
495 do {
496 readChar();
497 } while (cur!='\n');
498 break;
499 default: return;
500 }
501 }
502 }
503
504 char ObjectStreamText::readChar()
505 {
506 mStream->readx(&cur, 1);
507 return cur;
508 }
509
510 void ObjectStreamText::readDesc(const char *desc)
511 {
512 skipWhite();
513 if (!desc) desc="data";
514 while (*desc) {
515 if (*desc!=cur) setSyntaxError();
516 readChar();
517 desc++;
518 }
519 }
520
521 void ObjectStreamText::putDesc(const char *desc)
522 {
523 putIndent();
524 if (desc) putS(desc); else putS("data");
525 putChar('=');
526 }
527
528 void ObjectStreamText::putIndent()
529 {
530 for(int i=0; i<indent; i++) putChar(' ');
531 }
532
533 void ObjectStreamText::putChar(char c)
534 {
535 mStream->writex(&c, 1);
536 }
537
538 void ObjectStreamText::putS(const char *s)
539 {
540 uint len=strlen(s);
541 if (mStream->write(s, len) != len) setSyntaxError();
542 }
543
544 /*
545 * ObjectStreamNative View:set/getData() methods
546 * (endian-dependend)
547 */
548
549 ObjectStreamNative::ObjectStreamNative(Stream *s, bool own_s, bool d)
550 : ObjectStream(s, own_s), allocd(true)
551 {
552 duplicate = d;
553 }
554
555 void *ObjectStreamNative::duppa(const void *p, int size)
556 {
557 if (duplicate) {
558 MemArea *m = new MemArea(p, size, true);
559 allocd += m;
560 return m->ptr;
561 } else {
562 // FIXME: un-const'ing p
563 return (void*)p;
564 }
565 }
566
567 void ObjectStreamNative::getBinary(void *buf, uint size, const char *desc)
568 {
569 void *pp;
570 mStream->readx(&pp, sizeof pp);
571 memmove(buf, pp, size);
572 }
573
574 bool ObjectStreamNative::getBool(const char *desc)
575 {
576 bool b;
577 mStream->readx(&b, sizeof b);
578 return b;
579 }
580
581 uint64 ObjectStreamNative::getInt(uint size, const char *desc)
582 {
583 switch (size) {
584 case 1:case 2:case 4: {
585 uint i = 0;
586 mStream->readx(&i, size);
587 return i;
588 }
589 case 8: {
590 uint64 i;
591 mStream->readx(&i, size);
592 return i;
593 }
594 }
595 throw IllegalArgumentException(HERE);
596 }
597
598 void ObjectStreamNative::getObject(Object *&object, const char *name, ObjectID id)
599 {
600 Object *pp;
601 mStream->readx(&pp, sizeof pp);
602 object = pp;
603 }
604
605 char *ObjectStreamNative::getString(const char *desc)
606 {
607 char *pp;
608 mStream->readx(&pp, sizeof pp);
609 return pp;
610 }
611
612 byte *ObjectStreamNative::getLenString(int &len, const char *desc)
613 {
614 byte *pp;
615 mStream->readx(&pp, sizeof pp);
616 // FIXME?
617 if (pp) len = strlen((char*)pp); else len = 0;
618 return pp;
619 }
620
621 void ObjectStreamNative::putBinary(const void *mem, uint size, const char *desc)
622 {
623 void *pp = mem ? duppa(mem, size) : NULL;
624 mStream->writex(&pp, sizeof pp);
625 }
626
627 void ObjectStreamNative::putBool(bool b, const char *desc)
628 {
629 mStream->writex(&b, sizeof b);
630 }
631
632 void ObjectStreamNative::putComment(const char *comment)
633 {
634 // NOP
635 }
636
637 void ObjectStreamNative::putInt(uint64 i, uint size, const char *desc, uint int_fmt_hint)
638 {
639 switch (size) {
640 case 1:case 2:case 4: {
641 uint x = i;
642 mStream->writex(&x, size);
643 return;
644 }
645 case 8: {
646 mStream->writex(&i, size);
647 return;
648 }
649 }
650 throw IllegalArgumentException(HERE);
651 }
652
653 void ObjectStreamNative::putObject(const Object *object, const char *name, ObjectID id)
654 {
655 Object *d = duplicate ? d->clone() : d;
656 mStream->write(&d, sizeof d);
657 }
658
659 void ObjectStreamNative::putSeparator()
660 {
661 // NOP
662 }
663
664 void ObjectStreamNative::putString(const char *string, const char *desc)
665 {
666 const char *pp = string ? (const char*)duppa(string, strlen(string)+1) : NULL;
667 mStream->write(&pp, sizeof pp);
668 }
669
670 void ObjectStreamNative::putLenString(const byte *string, int len, const char *desc)
671 {
672 const char *pp = string ? (const char*)duppa(string, len+1) : NULL;
673 mStream->write(&pp, sizeof pp);
674 }
675

  ViewVC Help
Powered by ViewVC 1.1.26