1
// ---------------------------------------------------------------------------
3
// - standard object library - block buffer class implementation -
4
// ---------------------------------------------------------------------------
5
// - This program is free software; you can redistribute it and/or modify -
6
// - it provided that this copyright notice is kept intact. -
8
// - This program is distributed in the hope that it will be useful, but -
9
// - without any warranty; without even the implied warranty of -
10
// - merchantability or fitness for a particular purpose. In no event shall -
11
// - the copyright holder be liable for any direct, indirect, incidental or -
12
// - special damages arising in any way out of the use of this software. -
13
// ---------------------------------------------------------------------------
14
// - copyright (c) 1999-2011 amaury darsch -
15
// ---------------------------------------------------------------------------
20
#include "Unicode.hpp"
21
#include "Integer.hpp"
22
#include "QuarkZone.hpp"
23
#include "Exception.hpp"
24
#include "BlockBuffer.hpp"
28
// -------------------------------------------------------------------------
30
// -------------------------------------------------------------------------
32
// create a default block buffer
34
BlockBuffer::BlockBuffer (void) : Buffer (Encoding::BYTE){
35
// set the block buffer
38
// force non resizable
42
// create a block buffer by size
44
BlockBuffer::BlockBuffer (const long size) : Buffer (size, Encoding::BYTE) {
45
// set the block buffer
48
// force non resizable
52
// return the class name
54
String BlockBuffer::repr (void) const {
58
// reset this block buffer
60
void BlockBuffer::reset (void) {
63
// reset the base object
65
// reset the local members
76
// get the buffer read count
78
t_long BlockBuffer::getrcnt (void) const {
81
t_long result = d_rcnt;
90
// get the buffer write count
92
t_long BlockBuffer::getwcnt (void) const {
95
t_long result = d_wcnt;
104
// add a character to this block buffer
106
long BlockBuffer::add (const char value) {
109
// add the character in the buffer
110
long result = Buffer::add (value);
111
// update the write counter
122
// get the next available character
124
char BlockBuffer::read (void) {
127
// read the next character
128
char result = Buffer::read ();
129
// update the read counter
139
// pushback a character to this block buffer
141
long BlockBuffer::pushback (const char value) {
144
// add the character in the buffer
145
long result = Buffer::pushback (value);
146
// update the write counter
157
// copy a character array into the block buffer
159
long BlockBuffer::copy (const char* data, const long size) {
162
// reset the buffer in bound mode
163
if (full () == true) Buffer::reset ();
164
// add the buffer data
165
long result = Buffer::add (data, size);
175
// add a string in this buffer
177
long BlockBuffer::copy (const String& s) {
182
cbuf = Unicode::encode (d_emod, s);
183
long size = Ascii::strlen (cbuf);
185
long result = copy (cbuf, size);
197
// copy a buffer into the block buffer
199
long BlockBuffer::copy (Buffer& buffer) {
202
// reset the buffer in bound mode
203
if (full () == true) Buffer::reset ();
206
while ((buffer.empty () == false) && (full () == false)) {
207
result += add (buffer.read ());
218
// copy an input stream into the block buffer
220
long BlockBuffer::copy (InputStream& is) {
225
// reset the buffer if full (i.e bound mode)
226
if (full () == true) Buffer::reset ();
227
// copy directly the block
228
if (empty () == true ) {
229
// copy directly by block
230
result = is.copy (p_data, d_size);
235
// add the buffer data
236
while ((is.valid () == true) && (full () == false)) {
237
result += add (is.read ());
248
// copy a block buffer to an output stream
250
long BlockBuffer::copy (OutputStream& os) {
255
while (empty () == false) {
257
long size = os.write (p_data, d_blen);
258
// adjust by shifting
272
// copy an input stream into an output stream
274
long BlockBuffer::copy (OutputStream& os, InputStream& is) {
278
while (is.valid () == true) {
279
// copy the input stream
280
long rdsz = copy (is);
281
// copy to the output stream
282
long wrsz = copy (os);
284
throw Exception ("buffer-error", "buffer copy size differences");
296
// -------------------------------------------------------------------------
297
// - object section -
298
// -------------------------------------------------------------------------
301
static const long QUARK_ZONE_LENGTH = 5;
302
static QuarkZone zone (QUARK_ZONE_LENGTH);
304
// the object supported quarks
305
static const long QUARK_COPY = zone.intern ("copy");
306
static const long QUARK_RCNT = zone.intern ("read-count");
307
static const long QUARK_WCNT = zone.intern ("write-count");
308
static const long QUARK_COPYIS = zone.intern ("copy-input-stream");
309
static const long QUARK_COPYOS = zone.intern ("copy-output-stream");
311
// create a new object in a generic way
313
Object* BlockBuffer::mknew (Vector* argv) {
314
long argc = (argv == nilp) ? 0 : argv->length ();
316
if (argc == 0) return new BlockBuffer;
319
long size = argv->getlong (0);
320
return new BlockBuffer (size);
322
throw Exception ("argument-error", "too many argument for block buffer");
325
// return true if the given quark is defined
327
bool BlockBuffer::isquark (const long quark, const bool hflg) const {
329
if (zone.exists (quark) == true) {
333
bool result = hflg ? Buffer::isquark (quark, hflg) : false;
338
// apply this object with a set of arguments and a quark
340
Object* BlockBuffer::apply (Runnable* robj, Nameset* nset, const long quark,
342
// get the number of arguments
343
long argc = (argv == nilp) ? 0 : argv->length ();
345
// dispatch 0 argument
347
if (quark == QUARK_RCNT) return new Integer (getrcnt ());
348
if (quark == QUARK_WCNT) return new Integer (getwcnt ());
351
// dispatch 1 argument
353
if (quark == QUARK_COPY) {
354
Object* obj = argv->get (0);
355
// check for a string
356
String* sobj = dynamic_cast<String*> (obj);
358
long result = copy (*sobj);
359
return new Integer (result);
361
// check for a buffer
362
Buffer* bobj = dynamic_cast<Buffer*> (obj);
364
long result = copy (*bobj);
365
return new Integer (result);
367
// check for an input stream
368
InputStream* is = dynamic_cast<InputStream*> (obj);
370
long result = copy (*is);
371
return new Integer (result);
373
// check for an output stream
374
OutputStream* os = dynamic_cast<OutputStream*> (obj);
376
long result = copy (*os);
377
return new Integer (result);
379
throw Exception ("type-error",
380
"invalid object to copy in block buffer",
383
if (quark == QUARK_COPYIS) {
384
Object* obj = argv->get (0);
385
// check for an input stream
386
InputStream* is = dynamic_cast<InputStream*> (obj);
388
long result = copy (*is);
389
return new Integer (result);
391
throw Exception ("type-error",
392
"invalid object to copy in block buffer",
395
if (quark == QUARK_COPYOS) {
396
Object* obj = argv->get (0);
397
// check for an output stream
398
OutputStream* os = dynamic_cast<OutputStream*> (obj);
400
long result = copy (*os);
401
return new Integer (result);
403
throw Exception ("type-error",
404
"invalid object to copy in block buffer",
409
// dispatch 2 arguments
411
if (quark == QUARK_COPY) {
412
Object* oobj = argv->get (0);
413
// check for an output stream
414
OutputStream* os = dynamic_cast<OutputStream*> (oobj);
416
throw Exception ("type-error",
417
"invalid object to copy in block buffer",
418
Object::repr (oobj));
420
// check for an input stream
421
Object* iobj = argv->get (1);
422
InputStream* is = dynamic_cast<InputStream*> (iobj);
424
throw Exception ("type-error",
425
"invalid object to copy in block buffer",
426
Object::repr (iobj));
428
long result = copy (*os, *is);
429
return new Integer (result);
432
// call the buffer method
433
return Buffer::apply (robj, nset, quark, argv);