/*------------------------------------------------------------------------------ * Copyright (C) 2003-2006 Jos van den Oever * * Distributable under the terms of either the Apache License (Version 2.0) or * the GNU Lesser General Public License, as specified in the COPYING file. ------------------------------------------------------------------------------*/ #ifndef STRINGREADER_H #define STRINGREADER_H #include "streambase.h" namespace jstreams { template class StringReader : public StreamBase { private: int64_t markpt; T* data; bool dataowner; StringReader(const StringReader&); void operator=(const StringReader&); public: StringReader(const T* value, int32_t length = -1, bool copy = true); ~StringReader(); int32_t read(const T*& start, int32_t min, int32_t max); int64_t skip(int64_t ntoskip); int64_t mark(int32_t readlimit); int64_t reset(int64_t pos); }; template StringReader::StringReader(const T* value, int32_t length, bool copy) : markpt(0), dataowner(copy) { if (length < 0) { length = 0; while ( value[length] != '\0' ) length++; } StreamBase::size = length; if (copy) { data = new T[length+1]; size_t s = (size_t)(length*sizeof(T)); memcpy(data, value, s); data[length] = 0; } else { // casting away const is ok, because we don't write anyway data = (T*)value; } } template StringReader::~StringReader() { if (dataowner) { delete [] data; } } template int32_t StringReader::read(const T*& start, int32_t min, int32_t max) { int64_t left = StreamBase::size - StreamBase::position; if (left == 0) { StreamBase::status = Eof; return -1; } if (min < 0) min = 0; int32_t nread = (int32_t)(max > left || max < 1) ?left :max; start = data + StreamBase::position; StreamBase::position += nread; if (StreamBase::position == StreamBase::size) { StreamBase::status = Eof; } return nread; } template int64_t StringReader::skip(int64_t ntoskip) { const T* start; return read(start, ntoskip, ntoskip); } template int64_t StringReader::mark(int32_t /*readlimit*/) { markpt = StreamBase::position; return markpt; } template int64_t StringReader::reset(int64_t newpos) { if (newpos < 0) { StreamBase::status = Ok; StreamBase::position = 0; } else if (newpos < StreamBase::size) { StreamBase::status = Ok; StreamBase::position = newpos; } else { StreamBase::position = StreamBase::size; StreamBase::status = Eof; } return StreamBase::position; } } // end namespace jstreams #endif