1 /* Automatic buffer driver for XTL
3 * Copyright (C) 2000 Allan Rae, allan.rae@mailbox.uq.edu.au
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: autobuf.h 1.4 Fri, 05 May 2000 18:57:58 +0100 jop
30 #include <xtl/config.h>
31 #include <xtl/objio.h>
33 /** Based on mem_buffer. It automatically increases it's capacity when being
34 written too. It still throws an exception if there is insufficient data
35 when reading. As a result the input and output routines memory handling
36 had to be separated (mem_buffer uses the same code for both) into required
37 memory (input) and desired memory (output). ARRae 20000423
39 Possible improvements:
40 auto_mem_buffer(char *, size_t) same constructor as mem_buffer
41 reserve(size_t) make it bigger if need be.
43 Rewrite XTL to use an iterator interface; at least at the buffer level.
45 class auto_mem_buffer {
47 class buffer_overflow_error: public std::overflow_error {
52 buffer_overflow_error(int left, int needed):
53 std::overflow_error("XTL auto_mem_buffer overflow"),
54 bytes_left(left),bytes_needed(needed) {}
57 auto_mem_buffer() : buffer(0), pos(0), lim(32) {
58 buffer = new char[lim];
61 auto_mem_buffer(size_t size) : buffer(0), pos(0), lim(4) {
62 // the smallest useful size is probably 8 bytes (4*2)
66 buffer = new char[lim];
69 // I haven't figured out why yet but this code causes a segfault upon
70 // destruction of the copy after the destruction of the original.
71 // HOWEVER, this only occurs in LyX, it doesn't occur in my test program
72 // which is almost identical to the way LyX operates. The major differences
73 // between LyX and the test program are the presense of libsigc++ and xforms.
74 // The contents of the mem buffer are used to build up an xforms dialog.
77 // auto_mem_buffer(auto_mem_buffer const & o)
78 // : buffer(0), pos(o.pos), lim(o.lim) {
79 // buffer = new char[lim];
80 // memcpy(buffer, o.buffer, (pos > 0) ? pos : lim);
87 inline void read(char* ptr, int size) {
88 memcpy(ptr, require(size), size);
91 inline void write(char const* ptr, int size) {
92 memcpy(desire(size), ptr, size);
95 inline void* require(int size) {
97 if ((pos += size) > lim)
98 throw buffer_overflow_error(lim - aux, size);
102 inline void* desire(int size) {
103 size_t const aux = pos;
104 if ((pos += size) > lim) {
108 char * tmp = new char[lim];
109 memcpy(tmp, buffer, aux);
119 inline void unrequire(int n)
122 inline void undesire(int n)
134 template <class Format>
135 inline void composite(obj_input<Format>& stream) {
137 stream.array(buffer, size).simple(idx);
143 template <class Format>
144 inline void composite(obj_output<Format>& stream) {
145 stream.array(buffer, lim).simple(pos);
148 auto_mem_buffer(auto_mem_buffer const &);