/[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

Annotation of /src/tools/store.cc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 11 - (hide annotations)
Thu Sep 6 16:48:55 2007 UTC (16 years, 7 months ago) by dpavlin
File size: 13005 byte(s)
more forgotten files
1 dpavlin 11 /*
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