blob: cf7bd16b7af2f1f8b3794f5ac97a6075f8f39c28 [file] [log] [blame]
/*------------------------------------------------------------------------------
* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
*
* 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.
------------------------------------------------------------------------------*/
#include "CLucene/StdHeader.h"
#include "IndexInput.h"
CL_NS_USE(util)
CL_NS_DEF(store)
IndexInput::IndexInput()
{
}
IndexInput::IndexInput(const IndexInput& other)
{
}
int32_t IndexInput::readInt() {
int32_t b = (readByte() << 24);
b |= (readByte() << 16);
b |= (readByte() << 8);
return (b | readByte());
}
int32_t IndexInput::readVInt() {
uint8_t b = readByte();
int32_t i = b & 0x7F;
for (int32_t shift = 7; (b & 0x80) != 0; shift += 7) {
b = readByte();
i |= (b & 0x7F) << shift;
}
return i;
}
int64_t IndexInput::readLong() {
int64_t i = ((int64_t)readInt() << 32);
return (i | ((int64_t)readInt() & 0xFFFFFFFFL));
}
int64_t IndexInput::readVLong() {
uint8_t b = readByte();
int64_t i = b & 0x7F;
for (int32_t shift = 7; (b & 0x80) != 0; shift += 7) {
b = readByte();
i |= (((int64_t)b) & 0x7FL) << shift;
}
return i;
}
void IndexInput::skipChars( const int32_t count) {
for (int32_t i = 0; i < count; i++) {
TCHAR b = readByte();
if ((b & 0x80) == 0) {
// Do Nothing.
} else if ((b & 0xE0) != 0xE0) {
readByte();
} else {
readByte();
readByte();
}
}
}
int32_t IndexInput::readString(TCHAR* buffer, const int32_t maxLength){
int32_t len = readVInt();
int32_t ml=maxLength-1;
if ( len >= ml ){
readChars(buffer, 0, ml);
buffer[ml] = 0;
//we have to finish reading all the data for this string!
if ( len-ml > 0 ){
//seek(getFilePointer()+(len-ml)); <- that was the wrong way to "finish reading"
skipChars(len-ml);
}
return ml;
}else{
readChars(buffer, 0, len);
buffer[len] = 0;
return len;
}
}
TCHAR* IndexInput::readString(const bool _unique){
int32_t len = readVInt();
if ( len == 0){
if ( _unique ) //todo: does non unique ever occur?
return stringDuplicate(LUCENE_BLANK_STRING);
else
return LUCENE_BLANK_STRING;
}
TCHAR* ret = _CL_NEWARRAY(TCHAR,len+1);
readChars(ret, 0, len);
ret[len] = 0;
return ret;
}
void IndexInput::readChars( TCHAR* buffer, const int32_t start, const int32_t len) {
const int32_t end = start + len;
TCHAR b;
for (int32_t i = start; i < end; ++i) {
b = readByte();
if ((b & 0x80) == 0) {
b = (b & 0x7F);
} else if ((b & 0xE0) != 0xE0) {
b = (((b & 0x1F) << 6)
| (readByte() & 0x3F));
} else {
b = ((b & 0x0F) << 12) | ((readByte() & 0x3F) << 6);
b |= (readByte() & 0x3F);
}
buffer[i] = b;
}
}
BufferedIndexInput::BufferedIndexInput(int32_t _bufferSize):
buffer(NULL),
bufferSize(_bufferSize),
bufferStart(0),
bufferLength(0),
bufferPosition(0)
{
}
BufferedIndexInput::BufferedIndexInput(const BufferedIndexInput& other):
IndexInput(other),
buffer(NULL),
bufferSize(other.bufferSize),
bufferStart(other.bufferStart),
bufferLength(other.bufferLength),
bufferPosition(other.bufferPosition)
{
/* DSR: Does the fact that sometime clone.buffer is not NULL even when
** clone.bufferLength is zero indicate memory corruption/leakage?
** if ( clone.buffer != NULL) { */
if (other.bufferLength != 0 && other.buffer != NULL) {
buffer = _CL_NEWARRAY(uint8_t,bufferLength);
memcpy(buffer,other.buffer,bufferLength * sizeof(uint8_t));
}
}
void BufferedIndexInput::readBytes(uint8_t* b, const int32_t len){
if (len < bufferSize) {
for (int32_t i = 0; i < len; ++i) // read byte-by-byte
b[i] = readByte();
} else { // read all-at-once
int64_t start = getFilePointer();
seekInternal(start);
readInternal(b, len);
bufferStart = start + len; // adjust stream variables
bufferPosition = 0;
bufferLength = 0; // trigger refill() on read
}
}
int64_t BufferedIndexInput::getFilePointer() const{
return bufferStart + bufferPosition;
}
void BufferedIndexInput::seek(const int64_t pos) {
if ( pos < 0 )
_CLTHROWA(CL_ERR_IO, "IO Argument Error. Value must be a positive value.");
if (pos >= bufferStart && pos < (bufferStart + bufferLength))
bufferPosition = (int32_t)(pos - bufferStart); // seek within buffer
else {
bufferStart = pos;
bufferPosition = 0;
bufferLength = 0; // trigger refill() on read()
seekInternal(pos);
}
}
void BufferedIndexInput::close(){
_CLDELETE_ARRAY(buffer);
bufferLength = 0;
bufferPosition = 0;
bufferStart = 0;
}
BufferedIndexInput::~BufferedIndexInput(){
BufferedIndexInput::close();
}
void BufferedIndexInput::refill() {
int64_t start = bufferStart + bufferPosition;
int64_t end = start + bufferSize;
if (end > length()) // don't read past EOF
end = length();
bufferLength = (int32_t)(end - start);
if (bufferLength == 0)
_CLTHROWA(CL_ERR_IO, "IndexInput read past EOF");
if (buffer == NULL){
buffer = _CL_NEWARRAY(uint8_t,bufferSize); // allocate buffer lazily
}
readInternal(buffer, bufferLength);
bufferStart = start;
bufferPosition = 0;
}
IndexInputStream::IndexInputStream(IndexInput* input){
this->input = input;
this->size = input->length();
this->position = input->getFilePointer();
}
IndexInputStream::~IndexInputStream(){
}
int32_t IndexInputStream::fillBuffer(char* start, int32_t space){
int64_t avail = input->length()-input->getFilePointer();
if ( avail == 0 )
return -1;
else if ( avail<space )
space = (int32_t)avail;
input->readBytes((uint8_t*)start,space);
return space;
}
CL_NS_END