1
/* Copyright (c) 2008 PrimeBase Technologies GmbH, Germany
3
* PrimeBase Media Stream for MySQL
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
* Original author: Paul McCullagh (H&G2JCtL)
20
* Continued development: Barry Leslie
25
* Basic input and output streams.
27
* These objects wrap the system streams, and simplify things.
28
* I also want to standardize exceptions and implement
29
* socket based streams.
45
* ---------------------------------------------------------------
49
void CSStream::pipe(CSOutputStream *out, CSInputStream *in)
58
buffer = (char *) cs_malloc(DEFAULT_BUFFER_SIZE);
62
size = in->read(buffer, DEFAULT_BUFFER_SIZE);
66
out->write(buffer, size);
79
* ---------------------------------------------------------------
83
CSStringBuffer *CSInputStream::readLine()
86
CSStringBuffer *sb = NULL;
92
new_(sb, CSStringBuffer(20));
95
while (ch != '\n' && ch != '\r' && ch != -1) {
96
sb->append((char) ch);
111
* ---------------------------------------------------------------
115
void CSOutputStream::printLine(const char *cstr)
124
void CSOutputStream::print(const char *cstr)
127
write(cstr, strlen(cstr));
131
void CSOutputStream::print(CSString *s)
134
print(s->getCString());
138
void CSOutputStream::print(int value)
142
snprintf(buffer, 20, "%d", value);
146
void CSOutputStream::print(uint64_t value)
150
snprintf(buffer, 30, "%"PRIu64"", value);
155
* ---------------------------------------------------------------
159
CSFileInputStream::~CSFileInputStream()
165
size_t CSFileInputStream::read(char *b, size_t len)
170
size = iFile->read(b, iReadOffset, len, 0);
175
int CSFileInputStream::read()
181
size = iFile->read(&ch, iReadOffset, 1, 0);
183
return_(size == 0 ? -1 : (int) ch);
186
void CSFileInputStream::reset() {iReadOffset = 0;}
188
int CSFileInputStream::peek()
194
size = iFile->read(&ch, iReadOffset, 1, 0);
195
return_(size == 0 ? -1 : (int) ch);
198
void CSFileInputStream::close()
205
CSFileInputStream *CSFileInputStream::newStream(CSFile *f)
207
CSFileInputStream *s;
209
if (!(s = new CSFileInputStream())) {
211
CSException::throwOSError(CS_CONTEXT, ENOMEM);
217
CSFileInputStream *CSFileInputStream::newStream(CSFile *f, off64_t offset)
219
CSFileInputStream *s;
221
if (!(s = new CSFileInputStream())) {
223
CSException::throwOSError(CS_CONTEXT, ENOMEM);
226
s->iReadOffset = offset;
231
* ---------------------------------------------------------------
232
* FILE OUTPUT STREAMS
235
CSFileOutputStream::~CSFileOutputStream()
241
void CSFileOutputStream::write(const char *b, size_t len)
244
iFile->write(b, iWriteOffset, len);
249
const char *CSFileOutputStream::getEOL()
252
return_(iFile->getEOL());
255
void CSFileOutputStream::flush()
262
void CSFileOutputStream::write(char b)
265
iFile->write(&b, iWriteOffset, 1);
270
void CSFileOutputStream::reset() {iWriteOffset = 0;}
272
void CSFileOutputStream::close()
279
CSFileOutputStream *CSFileOutputStream::newStream(CSFile *f)
281
CSFileOutputStream *s;
283
if (!(s = new CSFileOutputStream())) {
285
CSException::throwOSError(CS_CONTEXT, ENOMEM);
291
CSFileOutputStream *CSFileOutputStream::newStream(CSFile *f, off64_t offset)
293
CSFileOutputStream *s;
295
if (!(s = new CSFileOutputStream())) {
297
CSException::throwOSError(CS_CONTEXT, ENOMEM);
300
s->iWriteOffset = offset;
305
* ---------------------------------------------------------------
306
* SOCKET INPUT STREAMS
309
CSSocketInputStream::~CSSocketInputStream()
315
void CSSocketInputStream::close()
322
size_t CSSocketInputStream::read(char *b, size_t len)
325
return_(iSocket->read(b, len));
328
int CSSocketInputStream::read()
331
return_(iSocket->read());
334
int CSSocketInputStream::peek()
337
return_(iSocket->peek());
340
void CSSocketInputStream::reset()
343
CSException::throwException(CS_CONTEXT, CS_ERR_OPERATION_NOT_SUPPORTED, "CSSocketInputStream::reset() not supported");
348
CSSocketInputStream *CSSocketInputStream::newStream(CSSocket *s)
350
CSSocketInputStream *str;
352
if (!(str = new CSSocketInputStream())) {
354
CSException::throwOSError(CS_CONTEXT, ENOMEM);
361
* ---------------------------------------------------------------
362
* SOCKET OUTPUT STREAMS
365
CSSocketOutputStream::~CSSocketOutputStream()
371
void CSSocketOutputStream::close()
378
void CSSocketOutputStream::write(const char *b, size_t len)
381
iSocket->write(b, len);
385
void CSSocketOutputStream::flush()
392
void CSSocketOutputStream::write(char b)
399
void CSSocketOutputStream::reset()
402
CSException::throwException(CS_CONTEXT, CS_ERR_OPERATION_NOT_SUPPORTED, "CSSocketOutputStream::reset() not supported");
406
CSSocketOutputStream *CSSocketOutputStream::newStream(CSSocket *s)
408
CSSocketOutputStream *str;
410
if (!(str = new CSSocketOutputStream())) {
412
CSException::throwOSError(CS_CONTEXT, ENOMEM);
419
* ---------------------------------------------------------------
420
* BUFFERED INPUT STREAMS
423
CSBufferedInputStream::~CSBufferedInputStream()
429
void CSBufferedInputStream::close()
436
size_t CSBufferedInputStream::read(char *b, size_t len)
441
if (iBuffPos < iBuffTotal) {
442
tfer = iBuffTotal - iBuffPos;
445
memcpy(b, iBuffer + iBuffPos, tfer);
449
tfer = iStream->read(b, len);
453
int CSBufferedInputStream::read()
458
if (iBuffPos == iBuffTotal) {
459
iBuffTotal = iStream->read((char *) iBuffer, CS_STREAM_BUFFER_SIZE);
462
if (iBuffPos < iBuffTotal) {
463
ch = iBuffer[iBuffPos];
471
int CSBufferedInputStream::peek()
476
if (iBuffPos == iBuffTotal) {
477
iBuffTotal = iStream->read((char *) iBuffer, CS_STREAM_BUFFER_SIZE);
480
if (iBuffPos < iBuffTotal)
481
ch = iBuffer[iBuffPos];
487
void CSBufferedInputStream::reset()
489
iBuffPos = iBuffTotal =0;
493
CSBufferedInputStream *CSBufferedInputStream::newStream(CSInputStream* i)
495
CSBufferedInputStream *s;
497
if (!(s = new CSBufferedInputStream())) {
499
CSException::throwOSError(CS_CONTEXT, ENOMEM);
506
* ---------------------------------------------------------------
507
* BUFFERED OUTPUT STREAMS
510
CSBufferedOutputStream::~CSBufferedOutputStream()
516
void CSBufferedOutputStream::close()
523
void CSBufferedOutputStream::write(const char *b, size_t len)
528
if (iBuffTotal < CS_STREAM_BUFFER_SIZE) {
529
tfer = CS_STREAM_BUFFER_SIZE - iBuffTotal;
533
memcpy(iBuffer + iBuffTotal, b, tfer);
540
if (len > CS_STREAM_BUFFER_SIZE)
541
iStream->write(b, len);
543
memcpy(iBuffer, b, len);
550
void CSBufferedOutputStream::flush()
553
if (iBuffTotal > 0) {
554
iStream->write((char *) iBuffer, iBuffTotal);
560
void CSBufferedOutputStream::write(char b)
563
if (iBuffTotal == CS_STREAM_BUFFER_SIZE)
565
iBuffer[iBuffTotal] = b;
570
void CSBufferedOutputStream::reset()
576
CSBufferedOutputStream *CSBufferedOutputStream::newStream(CSOutputStream* i)
578
CSBufferedOutputStream *s;
580
if (!(s = new CSBufferedOutputStream())) {
582
CSException::throwOSError(CS_CONTEXT, ENOMEM);
589
* ---------------------------------------------------------------
590
* MEMORY INPUT STREAMS
592
CSMemoryInputStream *CSMemoryInputStream::newStream(const u_char* buffer, uint32_t length)
594
CSMemoryInputStream *s;
596
if (!(s = new CSMemoryInputStream())) {
597
CSException::throwOSError(CS_CONTEXT, ENOMEM);
600
s->iMemTotal = length;
605
CSMemoryOutputStream *CSMemoryOutputStream::newStream(size_t init_length, size_t min_alloc)
607
CSMemoryOutputStream *s;
609
if (!(s = new CSMemoryOutputStream())) {
610
CSException::throwOSError(CS_CONTEXT, ENOMEM);
613
s->iMemory = (u_char *) cs_malloc(init_length);
614
s->iMemTotal = init_length;
615
s->iMemSpace = init_length;
616
s->iMemPos = s->iMemory;
617
s->iMemMin = min_alloc;
621
CSMemoryOutputStream::~CSMemoryOutputStream()
627
void CSMemoryOutputStream::write(const char *b, size_t len)
629
if (iMemSpace < len) {
630
size_t new_size = iMemTotal + ((len < iMemMin)? iMemMin:len);
632
cs_realloc((void**) &iMemory, new_size);
633
iMemPos = iMemory + (iMemTotal - iMemSpace);
634
iMemSpace += (new_size - iMemTotal);
635
iMemTotal = new_size;
637
memcpy(iMemPos, b, len);
642
void CSMemoryOutputStream::write(const char b)
645
cs_realloc((void**) &iMemory, iMemTotal + iMemMin);
646
iMemPos = iMemory + iMemTotal;
647
iMemSpace += iMemMin;
648
iMemTotal += iMemMin;
655
void CSMemoryOutputStream::reset()
658
iMemSpace = iMemTotal;
662
* ---------------------------------------------------------------
663
* STATIC (user) MEMORY OUTPUT STREAM
665
void CSStaticMemoryOutputStream::write(const char *b, size_t len)
667
if (iMemSpace < len) {
669
CSException::throwException(CS_CONTEXT, CS_ERR_GENERIC_ERROR, "CSStaticMemoryOutputStream: overflow");
672
memcpy(iMemPos, b, len);
677
void CSStaticMemoryOutputStream::write(const char b)
681
CSException::throwException(CS_CONTEXT, CS_ERR_GENERIC_ERROR, "CSStaticMemoryOutputStream: overflow");
690
* ---------------------------------------------------------------
691
* Callback InPUT STREAM
694
CSCallbackInputStream *CSCallbackInputStream::newStream(CSStreamReadCallbackFunc callback, void *user_data)
696
CSCallbackInputStream *s;
698
if (!(s = new CSCallbackInputStream())) {
699
CSException::throwOSError(CS_CONTEXT, ENOMEM);
702
s->callback = callback;
703
s->cb_data = user_data;