CLucene - a full-featured, c++ search engine
API Documentation
00001 /*------------------------------------------------------------------------------ 00002 * Copyright (C) 2003-2006 Jos van den Oever 00003 * 00004 * Distributable under the terms of either the Apache License (Version 2.0) or 00005 * the GNU Lesser General Public License, as specified in the COPYING file. 00006 ------------------------------------------------------------------------------*/ 00007 /* This file is part of Strigi Desktop Search 00008 * 00009 * Copyright (C) 2006 Jos van den Oever <jos@vandenoever.info> 00010 * 00011 * This library is free software; you can redistribute it and/or 00012 * modify it under the terms of the GNU Library General Public 00013 * License as published by the Free Software Foundation; either 00014 * version 2 of the License, or (at your option) any later version. 00015 * 00016 * This library is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00019 * Library General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU Library General Public License 00022 * along with this library; see the file COPYING.LIB. If not, write to 00023 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00024 * Boston, MA 02110-1301, USA. 00025 */ 00026 #ifndef SUBINPUTSTREAM_H 00027 #define SUBINPUTSTREAM_H 00028 00029 #include "streambase.h" 00030 00031 namespace jstreams { 00032 00033 template<class T> 00034 class SubInputStream : public StreamBase<T> { 00035 private: 00036 const int64_t offset; 00037 StreamBase<T> *input; 00038 public: 00039 SubInputStream(StreamBase<T> *input, int64_t size=-1); 00040 int32_t read(const T*& start, int32_t min, int32_t max); 00041 int64_t reset(int64_t newpos); 00042 int64_t skip(int64_t ntoskip); 00043 }; 00044 template<class T> 00045 SubInputStream<T>::SubInputStream(StreamBase<T> *i, int64_t length) 00046 : offset(i->getPosition()), input(i) { 00047 assert(length >= -1); 00048 // printf("substream offset: %lli\n", offset); 00049 StreamBase<T>::size = length; 00050 } 00051 00052 template<class T> 00053 int32_t SubInputStream<T>::read(const T*& start, int32_t min, int32_t max) { 00054 if (StreamBase<T>::size != -1) { 00055 const int64_t left = StreamBase<T>::size - StreamBase<T>::position; 00056 if (left == 0) { 00057 return -1; 00058 } 00059 // restrict the amount of data that can be read 00060 if (max <= 0 || max > left) { 00061 max = (int32_t)left; 00062 } 00063 if (min > max) min = max; 00064 if (left < min) min = (int32_t)left; 00065 } 00066 int32_t nread = input->read(start, min, max); 00067 if (nread < -1) { 00068 fprintf(stderr, "substream too short.\n"); 00069 StreamBase<T>::status = Error; 00070 StreamBase<T>::error = input->getError(); 00071 } else if (nread < min) { 00072 if (StreamBase<T>::size == -1) { 00073 StreamBase<T>::status = Eof; 00074 if (nread > 0) { 00075 StreamBase<T>::position += nread; 00076 StreamBase<T>::size = StreamBase<T>::position; 00077 } 00078 } else { 00079 // fprintf(stderr, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! nread %i min %i max %i size %lli\n", nread, min, max, size); 00080 // fprintf(stderr, "pos %lli parentpos %lli\n", position, input->getPosition()); 00081 // fprintf(stderr, "status: %i error: %s\n", input->getStatus(), input->getError()); 00082 // we expected data but didn't get enough so that's an error 00083 StreamBase<T>::status = Error; 00084 StreamBase<T>::error = "Premature end of stream\n"; 00085 nread = -2; 00086 } 00087 } else { 00088 StreamBase<T>::position += nread; 00089 if (StreamBase<T>::position == StreamBase<T>::size) { 00090 StreamBase<T>::status = Eof; 00091 } 00092 } 00093 return nread; 00094 } 00095 00096 template<class T> 00097 int64_t SubInputStream<T>::reset(int64_t newpos) { 00098 // fprintf(stderr, "subreset pos: %lli newpos: %lli offset: %lli\n", position, 00099 // newpos, offset); 00100 StreamBase<T>::position = input->reset(newpos + offset); 00101 if (StreamBase<T>::position < offset) { 00102 printf("###########\n"); 00103 StreamBase<T>::status = Error; 00104 StreamBase<T>::error = input->getError(); 00105 } else { 00106 StreamBase<T>::position -= offset; 00107 StreamBase<T>::status = input->getStatus(); 00108 } 00109 return StreamBase<T>::position; 00110 } 00111 00112 template<class T> 00113 int64_t SubInputStream<T>::skip(int64_t ntoskip) { 00114 // printf("subskip pos: %lli ntoskip: %lli offset: %lli\n", position, ntoskip, offset); 00115 if (StreamBase<T>::size == StreamBase<T>::position) { 00116 StreamBase<T>::status = Eof; 00117 return -1; 00118 } 00119 if (StreamBase<T>::size != -1) { 00120 const int64_t left = StreamBase<T>::size - StreamBase<T>::position; 00121 // restrict the amount of data that can be skipped 00122 if (ntoskip > left) { 00123 ntoskip = left; 00124 } 00125 } 00126 int64_t skipped = input->skip(ntoskip); 00127 if (input->getStatus() == Error) { 00128 StreamBase<T>::status = Error; 00129 StreamBase<T>::error = input->getError(); 00130 } else { 00131 StreamBase<T>::position += skipped; 00132 if (StreamBase<T>::position == StreamBase<T>::size) { 00133 StreamBase<T>::status = Eof; 00134 } 00135 } 00136 return skipped; 00137 } 00138 00139 } //end namespace jstreams 00140 00141 #endif