00001 /* 00002 // $Id: //open/dev/fennel/flatfile/FlatFileBuffer.cpp#1 $ 00003 // Fennel is a library of data storage and processing components. 00004 // Copyright (C) 2005-2009 The Eigenbase Project 00005 // Copyright (C) 2009-2009 SQLstream, Inc. 00006 // Copyright (C) 2005-2009 LucidEra, Inc. 00007 // 00008 // This program is free software; you can redistribute it and/or modify it 00009 // under the terms of the GNU General Public License as published by the Free 00010 // Software Foundation; either version 2 of the License, or (at your option) 00011 // any later version approved by The Eigenbase Project. 00012 // 00013 // This program is distributed in the hope that it will be useful, 00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 // GNU General Public License for more details. 00017 // 00018 // You should have received a copy of the GNU General Public License 00019 // along with this program; if not, write to the Free Software 00020 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00021 */ 00022 00023 #include "fennel/common/CommonPreamble.h" 00024 #include "fennel/common/FennelResource.h" 00025 #include "fennel/common/FennelExcn.h" 00026 #include "fennel/device/RandomAccessFileDevice.h" 00027 #include "fennel/flatfile/FlatFileBuffer.h" 00028 00029 FENNEL_BEGIN_CPPFILE("$Id: //open/dev/fennel/flatfile/FlatFileBuffer.cpp#1 $"); 00030 00031 FlatFileBuffer::FlatFileBuffer(const std::string &path) 00032 { 00033 this->path = path; 00034 pBuffer = NULL; 00035 bufferSize = 0; 00036 contentSize = 0; 00037 pCurrent = NULL; 00038 pFile = NULL; 00039 } 00040 00041 FlatFileBuffer::~FlatFileBuffer() 00042 { 00043 } 00044 00045 void FlatFileBuffer::closeImpl() 00046 { 00047 if (pFile) { 00048 fclose(pFile); 00049 pFile = NULL; 00050 } 00051 contentSize = 0; 00052 pCurrent = NULL; 00053 } 00054 00055 void FlatFileBuffer::setStorage(char *pBuffer, uint size) 00056 { 00057 this->pBuffer = pBuffer; 00058 bufferSize = size; 00059 contentSize = 0; 00060 pCurrent = NULL; 00061 } 00062 00063 void FlatFileBuffer::open() 00064 { 00065 // in case we are reopening 00066 close(); 00067 00068 // NOTE jvs 17-Oct-2008: we use fopen here instead of ifstream 00069 // in case we want to support popen("gunzip") in the future. 00070 00071 pFile = fopen(path.c_str(), "r"); 00072 if (!pFile) { 00073 throw FennelExcn( 00074 FennelResource::instance().readDataFailed(path)); 00075 } 00076 00077 needsClose = true; 00078 00079 filePosition = 0; 00080 contentSize = 0; 00081 pCurrent = NULL; 00082 } 00083 00084 uint FlatFileBuffer::read() 00085 { 00086 int residual = 0; 00087 if (pCurrent != NULL) { 00088 assert(pBuffer <= pCurrent && pCurrent <= getEndPtr()); 00089 residual = getEndPtr() - pCurrent; 00090 memmove(pBuffer, pCurrent, residual); 00091 contentSize = residual; 00092 } 00093 pCurrent = pBuffer; 00094 00095 uint free = bufferSize - residual; 00096 char *target = pBuffer + residual; 00097 uint targetSize = free; 00098 00099 size_t actualSize = fread(target, 1, targetSize, pFile); 00100 if (ferror(pFile)) { 00101 // FIXME jvs 19-Oct-2008: the error message here is confusingly 00102 // switched with the error message for opening the file. 00103 throw FennelExcn( 00104 FennelResource::instance().dataTransferFailed(path, targetSize)); 00105 } 00106 filePosition += actualSize; 00107 contentSize = residual + actualSize; 00108 return actualSize; 00109 } 00110 00111 char *FlatFileBuffer::getReadPtr() 00112 { 00113 assert(pCurrent != NULL && pBuffer <= pCurrent); 00114 return pCurrent; 00115 } 00116 00117 char *FlatFileBuffer::getEndPtr() 00118 { 00119 assert(pBuffer != NULL); 00120 return pBuffer + contentSize; 00121 } 00122 00123 int FlatFileBuffer::getSize() 00124 { 00125 return getEndPtr() - getReadPtr(); 00126 } 00127 00128 bool FlatFileBuffer::isFull() 00129 { 00130 assert(pBuffer != NULL); 00131 return (pCurrent == pBuffer && contentSize == bufferSize); 00132 } 00133 00134 bool FlatFileBuffer::isComplete() 00135 { 00136 assert(pFile); 00137 return feof(pFile); 00138 } 00139 00140 bool FlatFileBuffer::isDone() 00141 { 00142 return isComplete() && getReadPtr() >= getEndPtr(); 00143 } 00144 00145 void FlatFileBuffer::setReadPtr(char *ptr) 00146 { 00147 assert(pBuffer <= pCurrent && pCurrent <= ptr && ptr <= getEndPtr()); 00148 pCurrent = ptr; 00149 } 00150 00151 FENNEL_END_CPPFILE("$Id: //open/dev/fennel/flatfile/FlatFileBuffer.cpp#1 $"); 00152 00153 // End FlatFileBuffer.cpp