1
/*------------------------------------------------------------------------------
2
* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
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
#include "CLucene/_ApiHeader.h"
8
#include "IndexInput.h"
9
#include "IndexOutput.h"
10
#include "CLucene/util/Misc.h"
15
IndexInput::IndexInput():
19
IndexInput::~IndexInput()
22
IndexInput::IndexInput(const IndexInput& /*other*/)
26
int32_t IndexInput::readInt() {
27
int32_t b = (readByte() << 24);
28
b |= (readByte() << 16);
29
b |= (readByte() << 8);
30
return (b | readByte());
33
int32_t IndexInput::readVInt() {
34
uint8_t b = readByte();
36
for (int32_t shift = 7; (b & 0x80) != 0; shift += 7) {
38
i |= (b & 0x7F) << shift;
43
int64_t IndexInput::readLong() {
44
int64_t i = ((int64_t)readInt() << 32);
45
return (i | ((int64_t)readInt() & 0xFFFFFFFFL));
48
int64_t IndexInput::readVLong() {
49
uint8_t b = readByte();
51
for (int32_t shift = 7; (b & 0x80) != 0; shift += 7) {
53
i |= (((int64_t)b) & 0x7FL) << shift;
58
void IndexInput::skipChars( const int32_t count) {
59
for (int32_t i = 0; i < count; i++) {
61
if ((b & 0x80) == 0) {
63
} else if ((b & 0xE0) != 0xE0) {
73
int32_t IndexInput::readString(char* buffer, const int32_t maxLength){
74
TCHAR* buf = _CL_NEWARRAY(TCHAR,maxLength);
77
ret = readString(buf,maxLength);
78
STRCPY_TtoA(buffer,buf,ret+1);
79
}_CLFINALLY ( _CLDELETE_CARRAY(buf); )
84
int32_t IndexInput::readString(TCHAR* buffer, const int32_t maxLength){
85
int32_t len = readVInt();
86
int32_t ml=maxLength-1;
88
readChars(buffer, 0, ml);
90
//we have to finish reading all the data for this string!
92
//seek(getFilePointer()+(len-ml)); <- that was the wrong way to "finish reading"
97
readChars(buffer, 0, len);
103
TCHAR* IndexInput::readString(){
104
int32_t len = readVInt();
107
return stringDuplicate(LUCENE_BLANK_STRING);
110
TCHAR* ret = _CL_NEWARRAY(TCHAR,len+1);
111
readChars(ret, 0, len);
117
void IndexInput::readBytes( uint8_t* b, const int32_t len, bool /*useBuffer*/) {
118
// Default to ignoring useBuffer entirely
122
void IndexInput::readChars( TCHAR* buffer, const int32_t start, const int32_t len) {
123
const int32_t end = start + len;
125
for (int32_t i = start; i < end; ++i) {
127
if ((b & 0x80) == 0) {
129
} else if ((b & 0xE0) != 0xE0) {
130
b = (((b & 0x1F) << 6)
131
| (readByte() & 0x3F));
133
b = ((b & 0x0F) << 12) | ((readByte() & 0x3F) << 6);
134
b |= (readByte() & 0x3F);
145
BufferedIndexInput::BufferedIndexInput(int32_t _bufferSize):
147
bufferSize(_bufferSize>=0?_bufferSize:CL_NS(store)::BufferedIndexOutput::BUFFER_SIZE),
154
BufferedIndexInput::BufferedIndexInput(const BufferedIndexInput& other):
157
bufferSize(other.bufferSize),
158
bufferStart(other.bufferStart),
159
bufferLength(other.bufferLength),
160
bufferPosition(other.bufferPosition)
162
/* DSR: Does the fact that sometime clone.buffer is not NULL even when
163
** clone.bufferLength is zero indicate memory corruption/leakage?
164
** if ( clone.buffer != NULL) { */
165
if (other.bufferLength != 0 && other.buffer != NULL) {
166
buffer = _CL_NEWARRAY(uint8_t,bufferLength);
167
memcpy(buffer,other.buffer,bufferLength * sizeof(uint8_t));
171
const char* BufferedIndexInput::getObjectName(){ return getClassName(); }
172
const char* BufferedIndexInput::getClassName(){ return "BufferedIndexInput"; }
174
void BufferedIndexInput::readBytes(uint8_t* b, const int32_t len){
175
readBytes(b, len, true);
177
void BufferedIndexInput::readBytes(uint8_t* _b, const int32_t _len, bool useBuffer){
181
if(len <= (bufferLength-bufferPosition)){
182
// the buffer contains enough data to satisfy this request
183
if(len>0) // to allow b to be null if len is 0...
184
memcpy(b, buffer + bufferPosition, len);
187
// the buffer does not have enough data. First serve all we've got.
188
int32_t available = bufferLength - bufferPosition;
190
memcpy(b, buffer + bufferPosition, available);
193
bufferPosition += available;
195
// and now, read the remaining 'len' bytes:
196
if (useBuffer && len<bufferSize){
197
// If the amount left to read is small enough, and
198
// we are allowed to use our buffer, do it in the usual
199
// buffered way: fill the buffer and copy from it:
201
if(bufferLength<len){
202
// Throw an exception when refill() could not read len bytes:
203
memcpy(b, buffer, bufferLength);
204
_CLTHROWA(CL_ERR_IO, "read past EOF");
206
memcpy(b, buffer, len);
210
// The amount left to read is larger than the buffer
211
// or we've been asked to not use our buffer -
212
// there's no performance reason not to read it all
213
// at once. Note that unlike the previous code of
214
// this function, there is no need to do a seek
215
// here, because there's no need to reread what we
216
// had in the buffer.
217
int64_t after = bufferStart+bufferPosition+len;
219
_CLTHROWA(CL_ERR_IO, "read past EOF");
220
readInternal(b, len);
223
bufferLength = 0; // trigger refill() on read
228
int64_t BufferedIndexInput::getFilePointer() const{
229
return bufferStart + bufferPosition;
232
void BufferedIndexInput::seek(const int64_t pos) {
234
_CLTHROWA(CL_ERR_IO, "IO Argument Error. Value must be a positive value.");
235
if (pos >= bufferStart && pos < (bufferStart + bufferLength))
236
bufferPosition = (int32_t)(pos - bufferStart); // seek within buffer
240
bufferLength = 0; // trigger refill() on read()
244
void BufferedIndexInput::close(){
245
_CLDELETE_ARRAY(buffer);
252
BufferedIndexInput::~BufferedIndexInput(){
253
BufferedIndexInput::close();
256
void BufferedIndexInput::refill() {
257
int64_t start = bufferStart + bufferPosition;
258
int64_t end = start + bufferSize;
259
if (end > length()) // don't read past EOF
261
bufferLength = (int32_t)(end - start);
262
if (bufferLength <= 0)
263
_CLTHROWA(CL_ERR_IO, "IndexInput read past EOF");
266
buffer = _CL_NEWARRAY(uint8_t,bufferSize); // allocate buffer lazily
268
readInternal(buffer, bufferLength);
275
void BufferedIndexInput::setBufferSize( int32_t newSize ) {
277
if ( newSize != bufferSize ) {
278
bufferSize = newSize;
279
if ( buffer != NULL ) {
281
uint8_t* newBuffer = _CL_NEWARRAY( uint8_t, newSize );
282
int32_t leftInBuffer = bufferLength - bufferPosition;
285
if ( leftInBuffer > newSize ) {
288
numToCopy = leftInBuffer;
291
memcpy( (void*)newBuffer, (void*)(buffer + bufferPosition), numToCopy );
293
bufferStart += bufferPosition;
295
bufferLength = numToCopy;
297
_CLDELETE_ARRAY( buffer );