mootBufferIO.h
Go to the documentation of this file.
1 /* -*- Mode: C++ -*- */
2 
3 /*
4  libmoot : moocow's part-of-speech tagging library
5  Copyright (C) 2004-2010 by Bryan Jurish <moocow@cpan.org>
6 
7  This library is free software; you can redistribute it and/or
8  modify it under the terms of the GNU Lesser General Public
9  License as published by the Free Software Foundation; either
10  version 3 of the License, or (at your option) any later version.
11 
12  This library is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  Lesser General Public License for more details.
16 
17  You should have received a copy of the GNU Lesser General Public
18  License along with this library; if not, write to the Free Software
19  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21 
22 /*--------------------------------------------------------------------------
23  * File: mootBufferIO.h
24  * Author: Bryan Jurish <moocow@cpan.org>
25  * Description:
26  * + moot PoS tagger : low-level I/O routines: C buffer I/O
27  *--------------------------------------------------------------------------*/
28 
33 #ifndef _MOOT_BUFFERIO_H
34 #define _MOOT_BUFFERIO_H
35 
36 //#include <stdio.h> // for EOF (via mooIO.h)
37 //#include <string.h> // for memcpy() and friends (via mootIO.h)
38 //#include <assert.h> // for sanity checks
39 #include <stdlib.h> // for memory allocation etc.
40 
41 #include <mootUtils.h> // for trimming
42 #include <mootArgs.h> // for moot_va_copy()
43 //#include <mootIO.h> // for everything else (via mootUtils.h)
44 
45 
46 
47 namespace mootio {
48  //using namespace std;
49 
50  /*====================================================================
51  * mootio: classes
52  *====================================================================*/
53 
62  class micbuffer : virtual public mistream
63  {
64  public:
65  const char *cb_rdata;
66  size_t cb_offset;
67  size_t cb_used;
68 
69  public:
70  /*----------------------------------------------------------
71  * micbuffer: constructors
72  */
74 
75 
81  micbuffer(const void *data, size_t len)
82  : mistream(),
83  cb_rdata(reinterpret_cast<const char*>(data)),
84  cb_offset(0),
85  cb_used(len)
86  {};
87 
89  micbuffer(const micbuffer &cb)
90  : mistream(),
91  cb_rdata(cb.cb_rdata),
92  cb_offset(cb.cb_offset),
93  cb_used(cb.cb_used)
94  {};
95 
97  virtual ~micbuffer(void) {};
98 
100  inline void clear(void)
101  {
102  cb_offset = 0;
103  cb_used = 0;
104  };
107  inline void release(void)
108  {
109  clear();
110  cb_rdata = NULL;
111  };
112 
114  inline void assign(const void *data, size_t len) {
115  cb_rdata = reinterpret_cast<const char *>(data);
116  cb_used = len;
117  cb_offset = 0;
118  };
120 
121  /*----------------------------------------------------------
122  * micbuffer: Integrity
123  */
125 
126 
127  virtual bool valid(void) { return true; };
128 
130  virtual bool eof(void) { return cb_offset >= cb_used; };
132 
133  /*----------------------------------------------------------
134  * micbuffer: Input
135  */
137 
138 
141  virtual ByteCount read(char *buf, size_t n) {
142  if (n==0 || cb_offset >= cb_used) return 0;
143  else if (n < cb_used - cb_offset) {
144  //-- normal case: copy local data to buf
145  memcpy(buf, cb_rdata+cb_offset, n);
146  cb_offset += n;
147  return static_cast<ByteCount>(n);
148  }
149  else {
150  //-- partial read: copy some data to buf
151  memcpy(buf, cb_rdata+cb_offset, cb_used-cb_offset);
152  ByteCount nread = static_cast<ByteCount>(cb_used-cb_offset);
153  cb_offset = cb_used;
154  return nread;
155  }
156  };
157 
159  virtual int getbyte(void) {
160  if (cb_offset >= cb_used) return EOF;
161  return cb_rdata[cb_offset++];
162  };
164 
165  /*----------------------------------------------------------
166  * micbuffer: Utilties
167  */
169 
170 
172  inline const char* data(void) const { return cb_rdata; };
173 
175  inline size_t size(void) const { return cb_used; };
176 
178  inline size_t capacity(void) const { return cb_used; };
179 
181  inline size_t offset(void) const { return cb_offset; };
182 
190  inline std::string as_string(bool normalize_ws=false,
191  bool trim_left=false,
192  bool trim_right=false)
193  const
194  {
195  std::string str;
196  str.reserve(cb_used-cb_offset);
197  to_string(str, normalize_ws, trim_left, trim_right);
198  return str;
199  };
200 
209  inline void to_string(std::string &str,
210  bool normalize_ws =false,
211  bool trim_left =false,
212  bool trim_right =false)
213  const
214  {
215  if (!cb_rdata) return;
216  if (!normalize_ws)
217  str.append(cb_rdata+cb_offset, cb_used-cb_offset);
218  else
220  str,
221  trim_left, trim_right);
222  };
224  }; //-- /micbuffer
225 
226 
227  /*====================================================================
228  * mootio: input/output: mcbuffer
229  *====================================================================*/
230 
240  class mcbuffer
241  : virtual public micbuffer,
242  virtual public mostream
243  {
244  public:
246  static const size_t CB_DEFAULT_SIZE = 32;
247 
249  static const size_t CB_DEFAULT_GET = 32;
250 
251  public:
252  char *cb_wdata;
253  size_t cb_alloc;
254  size_t cb_get;
255  bool cb_created;
257  public:
258  /*----------------------------------------------------------
259  * mcbuffer: constructors
260  */
262 
263 
264  mcbuffer(size_t size=CB_DEFAULT_SIZE)
265  : micbuffer(NULL,0),
266  cb_wdata(NULL),
267  cb_alloc(0),
268  cb_get(CB_DEFAULT_GET),
269  cb_created(true)
270  {
271  if (size) reserve(size);
272  };
273 
282  mcbuffer(void *data,
283  size_t used,
284  size_t alloc=0,
285  size_t get=CB_DEFAULT_GET)
286  : micbuffer(reinterpret_cast<const char *>(data),used),
287  cb_wdata(reinterpret_cast<char*>(data)),
288  cb_alloc(alloc),
289  cb_get(get),
290  cb_created(false)
291  {
292  if (!alloc) cb_alloc = cb_used;
293  cb_rdata = cb_wdata;
294  };
295 
297  mcbuffer(const micbuffer &cb)
298  : micbuffer(NULL,0),
299  cb_wdata(NULL),
300  cb_created(true)
301  {
302  reserve(cb.cb_used);
303  memcpy(cb_wdata, cb.cb_rdata, cb.cb_used);
304  cb_offset = cb.cb_offset;
305  cb_used = cb.cb_used;
306  cb_rdata = cb_wdata;
307  };
308 
310  inline void assign(const void *data, size_t len) {
311  reserve(len);
312  memcpy(cb_wdata, data, len);
313  cb_rdata = cb_wdata;
314  cb_offset = 0;
315  cb_used = len;
316  cb_created = true;
317  };
318 
320  virtual ~mcbuffer(void) { release(); };
321 
323  inline void clear(void)
324  {
325  cb_offset = 0;
326  cb_used = 0;
327  };
328 
330  inline void release(void)
331  {
332  clear();
333  if (cb_created && cb_wdata) free(cb_wdata);
334  cb_wdata = NULL;
335  cb_rdata = NULL;
336  cb_alloc = 0;
337  };
339 
340  /*----------------------------------------------------------
341  * mcbuffer: Output
342  */
344 
345 
346  virtual bool flush(void) {
347  if (!cb_offset || !cb_wdata) return true;
348  memmove(cb_wdata, cb_wdata+cb_offset, cb_used-cb_offset);
349  cb_used -= cb_offset;
350  cb_offset = 0;
351  return true;
352  };
353 
355  virtual bool write(const char *buf, size_t n) {
356  if (!reserve(n+cb_used, cb_get)) return false;
357  memcpy(cb_wdata+cb_used, buf, n);
358  cb_used += n;
359  return true;
360  };
361 
363  virtual bool putbyte(unsigned char c) {
364  if (!reserve(1+cb_used, cb_get)) return false;
365  cb_wdata[cb_used++] = c;
366  return true;
367  };
368 
370  virtual bool puts(const char *s) {
371  return write(s,strlen(s));
372  };
374  virtual bool puts(const std::string &s) {
375  return write(s.data(),s.size());
376  };
379  virtual bool vprintf(const char *fmt, va_list &ap)
380  {
381  va_list ap_tmp;
382  moot_va_copy(ap_tmp,ap);
383  size_t nchars = vsnprintf(cb_wdata+cb_used, cb_alloc-cb_used, fmt, ap);
384  if (nchars >= cb_alloc-cb_used) {
385  if (!reserve(1+nchars+cb_used, cb_get)) return false;
386  moot_va_copy(ap,ap_tmp);
387  vsnprintf(cb_wdata+cb_used, cb_alloc-cb_used, fmt, ap);
388  }
389  cb_used += nchars;
390  return true;
391  };
394  /*----------------------------------------------------------
395  * mcbuffer: Utilties
396  */
398 
399 
400  inline bool reserve(size_t size, size_t pad=0) {
401  if (size > cb_alloc) {
402  size_t newalloc = size+pad;
403  if (cb_created) {
404  //-- local buffer: we can just realloc()
405  if (cb_wdata) cb_wdata = reinterpret_cast<char *>(realloc(cb_wdata, newalloc));
406  else cb_wdata = reinterpret_cast<char *>(malloc(newalloc));
407  } else {
408  //-- user buffer: we need to slurp it
409  char *newdata = reinterpret_cast<char *>(malloc(newalloc));
410  memcpy(newdata, cb_wdata, cb_used);
411  cb_wdata = newdata;
412  cb_created = true;
413  }
414  assert(cb_wdata != NULL);
415  cb_rdata = cb_wdata;
416  cb_alloc = newalloc;
417  }
418  return true;
419  };
421 
422  }; //-- /mcbuffer
423 
424  /*====================================================================
425  * mootio: c-buffers: aliases
426  *====================================================================*/
427  typedef micbuffer mibuffer;
428  typedef mcbuffer mobuffer;
429  typedef mcbuffer mocbuffer;
430  typedef mcbuffer miocbuffer;
431  typedef mcbuffer miobuffer;
432  typedef mcbuffer mbuffer;
433 
434 }; //-- /namespace mootio
435 
436 
437 #endif //_MOOT_BUFFERIO_H
size_t size(void) const
Definition: mootBufferIO.h:177
virtual bool eof(void)
Definition: mootBufferIO.h:130
useful utilities, especially for command-line programs
const char * data(void) const
Definition: mootBufferIO.h:174
virtual ByteCount read(char *buf, size_t n)
Definition: mootBufferIO.h:141
mcbuffer mbuffer
alias for i/o buffers
Definition: mootBufferIO.h:464
size_t cb_offset
current read offset position in buffer
Definition: mootBufferIO.h:64
void release(void)
Definition: mootBufferIO.h:105
void clear(void)
Definition: mootBufferIO.h:98
virtual bool valid(void)
Definition: mootBufferIO.h:127
std::string as_string(bool normalize_ws=false, bool trim_left=false, bool trim_right=false) const
Definition: mootBufferIO.h:192
Abstract base class for output stream wrappers.
Definition: mootIO.h:194
size_t capacity(void) const
Definition: mootBufferIO.h:180
mcbuffer miobuffer
alias for i/o buffers
Definition: mootBufferIO.h:463
size_t offset(void) const
Definition: mootBufferIO.h:183
size_t cb_used
used length of buffer (in bytes)
Definition: mootBufferIO.h:65
mcbuffer mobuffer
alias for (input+)output buffers
Definition: mootBufferIO.h:460
Namespace for I/O stream wrappers.
Definition: mootBufferIO.h:45
utilities for functions taking variable number of arguments
Streambuf-like class for I/O on C char* buffers.
Definition: mootBufferIO.h:242
mcbuffer mocbuffer
alias for (input+)output buffers
Definition: mootBufferIO.h:461
micbuffer mibuffer
alias for input-only buffers
Definition: mootBufferIO.h:459
virtual int getbyte(void)
Definition: mootBufferIO.h:159
virtual ~micbuffer(void)
Definition: mootBufferIO.h:95
micbuffer(const void *data, size_t len)
Definition: mootBufferIO.h:79
int ByteCount
typedef for byte counts (should be signed, for compatibility)
Definition: mootIO.h:52
const char * cb_rdata
underlying character data buffer
Definition: mootBufferIO.h:63
void to_string(std::string &str, bool normalize_ws=false, bool trim_left=false, bool trim_right=false) const
Definition: mootBufferIO.h:211
Streambuf-like class for input from C char* buffers.
Definition: mootBufferIO.h:60
mcbuffer miocbuffer
alias for i/o buffers
Definition: mootBufferIO.h:462
void moot_normalize_ws(const char *buf, size_t len, std::string &out, bool trim_left=true, bool trim_right=true)
Abstract base class for input stream wrappers.
Definition: mootIO.h:129
void assign(const void *data, size_t len)
Definition: mootBufferIO.h:114