1 /*------------------------------------------------------------------------------
2 * Copyright (C) 2003-2006 Jos van den Oever
3 *
4 * Distributable under the terms of either the Apache License (Version 2.0) or
5 * the GNU Lesser General Public License, as specified in the COPYING file.
6 ------------------------------------------------------------------------------*/
7 /* This file is part of Strigi Desktop Search
8  *
9  * Copyright (C) 2006 Jos van den Oever <jos@vandenoever.info>
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Library General Public
13  * License as published by the Free Software Foundation; either
14  * version 2 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Library General Public License for more details.
20  *
21  * You should have received a copy of the GNU Library General Public License
22  * along with this library; see the file COPYING.LIB.  If not, write to
23  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24  * Boston, MA 02110-1301, USA.
25  */
26 #ifndef STRINGREADER_H
27 #define STRINGREADER_H
28 
29 /**
30  * Author: Jos van den Oever
31  *         Ben van Klinken
32  **/
33 
34 
35 #include "streambase.h"
36 
37 namespace jstreams {
38 
39 template <class T>
40 class StringReader : public StreamBase<T> {
41 private:
42     int64_t markpt;
43     T* data;
44     bool dataowner;
45     StringReader(const StringReader<T>&);
46     void operator=(const StringReader<T>&);
47 public:
48     StringReader(const T* value, int32_t length = -1, bool copy = true);
49     ~StringReader();
50     int32_t read(const T*& start, int32_t min, int32_t max);
51     int64_t skip(int64_t ntoskip);
52     int64_t reset(int64_t pos);
53 };
54 
55 typedef StringReader<char> StringInputStream;
56 
57 template <class T>
StringReader(const T * value,int32_t length,bool copy)58 StringReader<T>::StringReader(const T* value, int32_t length, bool copy)
59         : markpt(0), dataowner(copy) {
60     if (length < 0) {
61         length = 0;
62         while (value[length] != '\0') {
63             length++;
64         }
65     }
66     StreamBase<T>::size = length;
67     if (copy) {
68         data = new T[length+1];
69         size_t s = (size_t)(length*sizeof(T));
70         memcpy(data, value, s);
71         data[length] = 0;
72     } else {
73         // casting away const is ok, because we don't write anyway
74         data = (T*)value;
75     }
76 }
77 template <class T>
~StringReader()78 StringReader<T>::~StringReader() {
79     if (dataowner) {
80         delete [] data;
81     }
82 }
83 template <class T>
84 int32_t
read(const T * & start,int32_t min,int32_t max)85 StringReader<T>::read(const T*& start, int32_t min, int32_t max) {
86     int64_t left = StreamBase<T>::size - StreamBase<T>::position;
87     if (left == 0) {
88         StreamBase<T>::status = Eof;
89         return -1;
90     }
91     if (min < 0) min = 0;
92     int32_t nread = (int32_t)((max > left || max < 1) ?left :max);
93     start = data + StreamBase<T>::position;
94     StreamBase<T>::position += nread;
95     if (StreamBase<T>::position == StreamBase<T>::size) {
96         StreamBase<T>::status = Eof;
97     }
98     return nread;
99 }
100 template <class T>
101 int64_t
skip(int64_t ntoskip)102 StringReader<T>::skip(int64_t ntoskip) {
103     const T* start;
104     return read(start, ntoskip, ntoskip);
105 }
106 template <class T>
107 int64_t
reset(int64_t newpos)108 StringReader<T>::reset(int64_t newpos) {
109     if (newpos < 0) {
110         StreamBase<T>::status = Ok;
111         StreamBase<T>::position = 0;
112     } else if (newpos < StreamBase<T>::size) {
113         StreamBase<T>::status = Ok;
114         StreamBase<T>::position = newpos;
115     } else {
116         StreamBase<T>::position = StreamBase<T>::size;
117         StreamBase<T>::status = Eof;
118     }
119     return StreamBase<T>::position;
120 }
121 
122 } // end namespace jstreams
123 
124 #endif
125