00001 /* 00002 // $Id: //open/dev/fennel/common/ByteInputStream.cpp#11 $ 00003 // Fennel is a library of data storage and processing components. 00004 // Copyright (C) 2005-2009 The Eigenbase Project 00005 // Copyright (C) 2005-2009 SQLstream, Inc. 00006 // Copyright (C) 2005-2009 LucidEra, Inc. 00007 // Portions Copyright (C) 1999-2009 John V. Sichi 00008 // 00009 // This program is free software; you can redistribute it and/or modify it 00010 // under the terms of the GNU General Public License as published by the Free 00011 // Software Foundation; either version 2 of the License, or (at your option) 00012 // any later version approved by The Eigenbase Project. 00013 // 00014 // This program is distributed in the hope that it will be useful, 00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 // GNU General Public License for more details. 00018 // 00019 // You should have received a copy of the GNU General Public License 00020 // along with this program; if not, write to the Free Software 00021 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00022 */ 00023 00024 #include "fennel/common/CommonPreamble.h" 00025 #include "fennel/common/ByteInputStream.h" 00026 00027 FENNEL_BEGIN_CPPFILE("$Id: //open/dev/fennel/common/ByteInputStream.cpp#11 $"); 00028 00029 ByteInputStream::ByteInputStream() 00030 { 00031 nullifyBuffer(); 00032 } 00033 00034 uint ByteInputStream::readBytes( 00035 void *pData,uint cbRequested) 00036 { 00037 uint cbActual = 0; 00038 if (pNextByte == pEndByte) { 00039 readNextBuffer(); 00040 } 00041 for (;;) { 00042 uint cbAvailable = getBytesAvailable(); 00043 if (!cbAvailable) { 00044 break; 00045 } 00046 if (cbRequested <= cbAvailable) { 00047 if (pData) { 00048 memcpy(pData,pNextByte,cbRequested); 00049 } 00050 pNextByte += cbRequested; 00051 cbActual += cbRequested; 00052 break; 00053 } 00054 if (pData) { 00055 memcpy(pData,pNextByte,cbAvailable); 00056 pData = static_cast<char *>(pData) + cbAvailable; 00057 } 00058 cbRequested -= cbAvailable; 00059 cbActual += cbAvailable; 00060 readNextBuffer(); 00061 } 00062 cbOffset += cbActual; 00063 return cbActual; 00064 } 00065 00066 void ByteInputStream::readPrevBuffer() 00067 { 00068 permAssert(false); 00069 } 00070 00071 void ByteInputStream::seekBackward(uint cb) 00072 { 00073 assert(cb <= cbOffset); 00074 cbOffset -= cb; 00075 if (pNextByte == pFirstByte) { 00076 readPrevBuffer(); 00077 pNextByte = pEndByte; 00078 } 00079 for (;;) { 00080 uint cbAvailable = getBytesConsumed(); 00081 assert(cbAvailable); 00082 if (cb <= cbAvailable) { 00083 pNextByte -= cb; 00084 break; 00085 } 00086 cb -= cbAvailable; 00087 readPrevBuffer(); 00088 pNextByte = pEndByte; 00089 } 00090 } 00091 00092 SharedByteStreamMarker ByteInputStream::newMarker() 00093 { 00094 return SharedByteStreamMarker(new SequentialByteStreamMarker(*this)); 00095 } 00096 00097 void ByteInputStream::mark(ByteStreamMarker &marker) 00098 { 00099 assert(&(marker.getStream()) == this); 00100 00101 SequentialByteStreamMarker &seqMarker = 00102 dynamic_cast<SequentialByteStreamMarker &>(marker); 00103 seqMarker.cbOffset = getOffset(); 00104 } 00105 00106 void ByteInputStream::reset(ByteStreamMarker const &marker) 00107 { 00108 assert(&(marker.getStream()) == this); 00109 00110 SequentialByteStreamMarker const &seqMarker = 00111 dynamic_cast<SequentialByteStreamMarker const &>(marker); 00112 assert(!isMAXU(seqMarker.cbOffset)); 00113 if (cbOffset == seqMarker.cbOffset) { 00114 // expedite common case where stream has not moved since mark 00115 return; 00116 } else if (cbOffset > seqMarker.cbOffset) { 00117 seekBackward(cbOffset - seqMarker.cbOffset); 00118 } else { 00119 seekForward(seqMarker.cbOffset - cbOffset); 00120 } 00121 } 00122 00123 FENNEL_END_CPPFILE("$Id: //open/dev/fennel/common/ByteInputStream.cpp#11 $"); 00124 00125 // End ByteInputStream.cpp