2 * Core externaliztion utilities
4 * Copyright (C) 1998-2000 Jose' Orlando Pereira, jop@di.uminho.pt
6 /* XTL - eXternalization Template Library - http://gsd.di.uminho.pt/~jop/xtl
7 * Copyright (C) 1998-2000 Jose' Orlando Pereira, Universidade do Minho
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
19 * You should have received a copy of the GNU Library General Public
20 * License along with this library; if not, write to the Free
21 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
24 * Id: objio.h 1.20 Fri, 05 May 2000 18:57:58 +0100 jop
30 #include <xtl/config.h>
36 template <class Buffer>
37 class generic_format {
41 void* require(int n) {return buffer.require(n);}
42 void unrequire(int n) {buffer.unrequire(n);}
43 void* desire(int n) {return buffer.desire(n);}
44 void undesire(int n) {buffer.undesire(n);}
46 void read(char* data, int size) {buffer.read(data, size);}
47 void write(char const* data, int size) {buffer.write(data, size);}
49 generic_format(Buffer& buf):buffer(buf) {}
53 void input_start_composite() {}
54 void input_end_composite() {}
56 void input_start_vector() {}
57 void input_end_vector() {}
59 virtual void output_start() {}
61 void output_start_composite() {}
62 void output_end_composite() {}
64 void output_start_vector() {}
65 void output_end_vector() {}
74 void input_start_array(int& n) {simple(n);}
75 bool input_end_array(int& n) {return n--<=0;}
77 void output_start_array(int n) {simple(n);}
78 void output_end_array() {}
81 template <class Buffer>
82 class raw_format: public generic_format<Buffer> {
84 typedef Buffer buffer;
86 raw_format(Buffer& buf):generic_format<Buffer>(buf) {}
89 inline void input_simple(T& data)
90 {data=*((T*)require(sizeof(T)));}
92 void input_start_array(int& n) {input_simple(n);}
93 bool input_end_array(int& n) {return !(n-->0);}
95 void input_chars(char* data, int size) {input_raw(data, size);}
97 void input_raw(char* data, int size) {
99 for(i=0;i<(size>>8)-1;i++,data+=256)
100 memcpy(data, require(256), 256);
102 memcpy(data, require(res), res);
106 inline void output_simple(T const& data)
107 {*((T*)desire(sizeof(T)))=data;}
109 void output_start_array(int n) {output_simple(n);}
110 void output_end_array() {}
112 void output_chars(char const* data, int size) {output_raw(data, size);}
114 void output_raw(char const* data, int size) {
116 for(i=0;i<(size>>8)-1;i++,data+=256)
117 memcpy(desire(256), data, 256);
119 memcpy(desire(res), data, res);
123 #ifdef XTL_CONFIG_CHOICE_MACROS
124 #include <xtl/macros.h>
127 #ifdef XTL_CONFIG_COMPOSITE_BUG
128 #define content(d) composite(d)
130 #define content(d) simple(d)
131 #define array_s array
132 #define vector_s vector
137 #define def_simple_input(type) \
138 inline obj_input& simple(type& data) { \
139 format.input_simple(data); \
143 template <class Format, class References=no_refs>
150 obj_input(Format& buf):format(buf)
151 {format.input_start();}
153 def_simple_input(bool);
154 def_simple_input(char);
155 def_simple_input(unsigned char);
156 def_simple_input(short);
157 def_simple_input(unsigned short);
158 def_simple_input(int);
159 def_simple_input(unsigned int);
160 def_simple_input(long);
161 def_simple_input(unsigned long);
162 def_simple_input(longlong);
163 def_simple_input(unsignedlonglong);
164 def_simple_input(float);
165 def_simple_input(double);
167 inline obj_input& cstring(char*& data) {
169 format.input_start_array(size);
170 data=new char[size+1];
171 format.input_chars(data, size);
173 format.input_end_array(size);
177 inline obj_input& cstring(char* data, int max) {
179 format.input_start_array(size);
180 format.input_chars(data, size>max?max:size);
181 data[size>max?max:size]=0;
182 format.input_end_array(size);
186 inline obj_input& simple(std::string& data) {
188 format.input_start_array(size);
189 char* tmp=new char[size];
190 format.input_chars(tmp, size);
191 data=std::string(tmp, size);
192 // FIXME: This causes a crash. Investigate...
194 format.input_end_array(size);
199 inline obj_input& vector(T data[], int size) {
200 format.input_start_vector();
201 for(int i=0;i<size;i++)
203 format.input_end_vector();
208 inline obj_input& array(T*& data, int& size) {
209 format.input_start_array(size);
211 for(int j=size,i=0;!format.input_end_array(j);i++)
216 #ifdef XTL_CONFIG_COMPOSITE_BUG
218 inline obj_input& vector_s(T data[], int size) {
219 format.input_start_vector();
220 for(int i=0;i<size;i++)
222 format.input_end_vector();
227 inline obj_input& array_s(T*& data, int& size) {
228 format.input_start_array(size);
230 for(int j=size,i=0;!format.input_end_array(j);i++)
236 inline obj_input& opaque(char data[], int size) {
237 format.input_start_vector();
238 format.input_raw(data, size);
239 format.input_end_vector();
243 inline obj_input& bytes(char*& data, int& size) {
245 format.input_start_array(size);
247 format.input_raw(data, size);
248 format.input_end_array(s);
252 // This is for compilers which do not support specialization
253 // If possible, use simple(T&) below.
255 inline obj_input& composite(T& data) {
256 format.input_start_composite();
257 ::composite(*this, data);
258 format.input_end_composite();
262 #ifndef XTL_CONFIG_COMPOSITE_BUG
264 inline obj_input& simple(T& data) {
265 format.input_start_composite();
266 ::composite(*this, data);
267 format.input_end_composite();
273 inline obj_input& reference(T*& data) {
274 refs.reference(*this, data);
279 inline obj_input& pointer(T*& data) {
288 inline obj_input& container(T& data) {
290 format.input_start_array(j);
291 while(!format.input_end_array(j)) {
292 typename T::value_type v;
294 data.insert(data.end(), v);
299 #ifdef XTL_CONFIG_CHOICE_MACROS
312 #define def_simple_output(type) \
313 inline obj_output& simple(type const& data) { \
314 format.output_simple(data); \
318 template <class Format, class References=no_refs>
325 obj_output(Format& buf):format(buf)
326 {format.output_start();}
328 def_simple_output(bool);
329 def_simple_output(char);
330 def_simple_output(unsigned char);
331 def_simple_output(short);
332 def_simple_output(unsigned short);
333 def_simple_output(int);
334 def_simple_output(unsigned int);
335 def_simple_output(long);
336 def_simple_output(unsigned long);
337 def_simple_output(longlong);
338 def_simple_output(unsignedlonglong);
339 def_simple_output(float);
340 def_simple_output(double);
342 inline obj_output& cstring(char const* data) {
343 int size=strlen(data);
344 format.output_start_array(size);
345 format.output_chars(data, size);
346 format.output_end_array();
350 inline obj_output& cstring(char const* data, int max) {
351 int size=strlen(data);
352 format.output_start_array(size);
353 format.output_chars(data, size);
354 format.output_end_array();
358 inline obj_output& simple(const std::string& data) {
359 int size=data.size();
360 format.output_start_array(size);
361 format.output_chars(data.data(), size);
362 format.output_end_array();
367 inline obj_output& vector(const T data[], int size) {
368 format.output_start_vector();
369 for(int i=0;i<size;i++)
371 format.output_end_vector();
376 inline obj_output& array(T const* data, int size) {
377 format.output_start_array(size);
378 for(int i=0;i<size;i++)
380 format.output_end_array();
383 #ifdef XTL_CONFIG_COMPOSITE_BUG
385 inline obj_output& vector_s(const T data[], int size) {
386 format.output_start_vector();
387 for(int i=0;i<size;i++)
389 format.output_end_vector();
394 inline obj_output& array_s(T const* data, int size) {
395 format.output_start_array(size);
396 for(int i=0;i<size;i++)
398 format.output_end_array();
403 inline obj_output& opaque(const char data[], int size) {
404 format.output_start_vector();
405 format.output_raw(data, size);
406 format.output_end_vector();
410 inline obj_output& bytes(char const* data, int size) {
411 format.output_start_array(size);
412 format.output_raw(data, size);
413 format.output_end_array();
417 // This is for compilers which do not support specialization
418 // If possible, use simple(T&) below.
420 inline obj_output& composite(T const& data) {
421 format.output_start_composite();
422 ::composite(*this, const_cast<T&>(data));
423 format.output_end_composite();
427 #ifndef XTL_CONFIG_COMPOSITE_BUG
429 inline obj_output& simple(T const& data) {
430 format.output_start_composite();
431 ::composite(*this, const_cast<T&>(data));
432 format.output_end_composite();
438 inline obj_output& reference(T const* data) {
439 refs.reference(*this, data);
444 inline obj_output& pointer(T const* data) {
445 bool exists=data!=NULL;
453 inline obj_output& container(T const& data) {
455 format.output_start_array(j);
456 for(typename T::const_iterator i=data.begin();
460 format.output_end_array();
464 #ifdef XTL_CONFIG_CHOICE_MACROS
475 #define option(t) (t*)NULL
480 #undef def_simple_input
481 #undef def_simple_output
483 template <class Stream, class T>
484 inline void composite(Stream& stream, T& data) {
485 data.composite(stream);
490 template <class Format, class T>
491 void reference(obj_input<Format>& stream, T*& data) {
494 stream.content(*data);
497 template <class Format, class T>
498 void reference(obj_output<Format>& stream, T const* data) {
499 stream.content(*data);
507 char *buffer, *ptr, *lim;
510 class buffer_overflow_error: public std::overflow_error {
515 buffer_overflow_error(int left, int needed):
516 std::overflow_error("XTL mem_buffer overflow"),
517 bytes_left(left),bytes_needed(needed) {}
520 mem_buffer(void *buf, int size):
521 buffer((char*)buf),ptr((char*)buf),lim(((char*)buf)+size) {}
523 inline void read(char* ptr, int size)
524 {memcpy(ptr, require(size), size);}
525 inline void write(char const* ptr, int size)
526 {memcpy(desire(size), ptr, size);}
528 inline void* require(int size) {
531 throw buffer_overflow_error(lim-aux,size);
534 inline void* desire(int size)
535 {return require(size);}
539 inline void unrequire(int n)
541 inline void undesire(int n)
550 template <class Format>
551 inline void composite(obj_input<Format>& stream) {
553 stream.array(buffer, size).simple(idx);
558 template <class Format>
559 inline void composite(obj_output<Format>& stream) {
560 stream.array(buffer, lim-buffer).simple((int)ptr-buffer);
565 #ifdef XTL_CONFIG_SIMPLE_CONTAINERS
572 template <class Stream, class T1, class T2>
573 inline void composite(Stream& stream, std::pair<const T1,T2>& data) {
574 stream.simple(const_cast<T1&>(data.first));
575 stream.simple(data.second);
578 template <class Stream, class T1, class T2>
579 inline void composite(Stream& stream, std::pair<T1,T2>& data) {
580 stream.simple(data.first);
581 stream.simple(data.second);
584 template <class Stream, class T>
585 inline void composite(Stream& stream, std::list<T>& data) {
586 stream.container(data);
589 template <class Stream, class T>
590 inline void composite(Stream& stream, std::vector<T>& data) {
591 stream.container(data);
594 template <class Stream, class T1, class T2>
595 inline void composite(Stream& stream, std::map<T1, T2>& data) {
596 stream.container(data);