00001 /*
00002 This product contains certain software code or other information
00003 ("AT&T Software") proprietary to AT&T Corp. ("AT&T"). The AT&T
00004 Software is provided to you "AS IS". YOU ASSUME TOTAL RESPONSIBILITY
00005 AND RISK FOR USE OF THE AT&T SOFTWARE. AT&T DOES NOT MAKE, AND
00006 EXPRESSLY DISCLAIMS, ANY EXPRESS OR IMPLIED WARRANTIES OF ANY KIND
00007 WHATSOEVER, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
00008 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, WARRANTIES OF
00009 TITLE OR NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS, ANY
00010 WARRANTIES ARISING BY USAGE OF TRADE, COURSE OF DEALING OR COURSE OF
00011 PERFORMANCE, OR ANY WARRANTY THAT THE AT&T SOFTWARE IS "ERROR FREE" OR
00012 WILL MEET YOUR REQUIREMENTS.
00013
00014 Unless you accept a license to use the AT&T Software, you shall not
00015 reverse compile, disassemble or otherwise reverse engineer this
00016 product to ascertain the source code for any AT&T Software.
00017
00018 (c) AT&T Corp. All rights reserved. AT&T is a registered trademark of AT&T Corp.
00019
00020 ***********************************************************************
00021
00022 History:
00023
00024 24/11/99 - initial release by Hartmut Liefke, liefke@seas.upenn.edu
00025 Dan Suciu, suciu@research.att.com
00026 */
00027
00028 //**************************************************************************
00029 //**************************************************************************
00030
00031 // This module contains the input file class
00032 // Based on class 'CFile', the new class 'Input' implements the
00033 // buffer management
00034
00035
00036 #ifndef INPUT_HPP
00037 #define INPUT_HPP
00038
00039 #include <stdio.h>
00040 #include <string.h>
00041
00042 #include "File.hpp"
00043
00044 #ifndef min
00045 #define min(x,y) ( (x)>(y) ? (y) : (x))
00046 #endif
00047
00048 // The standard size of the file buffer
00049 #define FILEBUF_SIZE 65536L
00050
00051 // A macro for refilling the buffer to *at least* 'mylen' characters
00052 // If there are not enough characters in the file, then the program exits
00053 #define FillBufLen(mylen) if(endptr-curptr<(mylen)) { FillBuf(); if(endptr-curptr<(mylen)) {Error("Unexpected end of file!");Exit();}}
00054
00055 class Input : public CFile
00056 {
00057 char databuf[FILEBUF_SIZE]; // The data buffer
00058 char *curptr; // The current buffer position
00059 char *endptr; // Points to the end of the valid data
00060 // (curptr-endptr) determines the number
00061 // of remaining bytes
00062 unsigned long curlineno; // The current line number
00063 public:
00064 Input()
00065 {
00066 curptr=endptr=NULL;
00067 curlineno=1;
00068 }
00069
00070 void FillBuf() // The function fills the buffer as much as possible
00071 {
00072 int bytesread;
00073
00074 if(endptr-curptr>0)
00075 // Is there some unread data ?
00076 {
00077 memmove(databuf,curptr,endptr-curptr);
00078 endptr=databuf+(endptr-curptr);
00079 curptr=databuf;
00080 }
00081 else
00082 curptr=endptr=databuf;
00083
00084 // We try to fill the rest of the buffer
00085 bytesread=ReadBlock(endptr,databuf+FILEBUF_SIZE-endptr);
00086
00087 endptr+=bytesread;
00088 }
00089
00090 char OpenFile(char *filename)
00091 // Opens the file and fills the buffer
00092 {
00093 if(CFile::OpenFile(filename)==0)
00094 return 0;
00095
00096 curptr=endptr=databuf;
00097
00098 FillBuf();
00099
00100 curlineno=1;
00101
00102 return 1;
00103 }
00104
00105 char ReadData(char *dest,int len)
00106 // Reads 'len' characters into the buffer 'dest'
00107 // If the data is already in memory, we simply copy
00108 // Otherwise, we iteratively read more from the file
00109 // The functions returns 0 if 'len' bytes are read
00110 // It returns 1, if the end of the file has been reached
00111 {
00112 int savelen=len;
00113
00114 while(endptr-curptr<len)
00115 {
00116 if(IsEndOfFile())
00117 return 1;
00118
00119 len-=endptr-curptr;
00120
00121 while(curptr<endptr)
00122 {
00123 *dest=*curptr;
00124 if(*curptr=='\n')
00125 curlineno++;
00126 dest++;
00127 curptr++;
00128 }
00129 FillBuf();
00130 }
00131
00132 while(len>0)
00133 {
00134 *dest=*curptr;
00135 if(*curptr=='\n')
00136 curlineno++;
00137 dest++;
00138 curptr++;
00139 len--;
00140 }
00141 return 0;
00142 }
00143
00144 void GetChar(char *ptr)
00145 // Reads one single character and stores it in *ptr
00146 {
00147 FillBufLen(1);
00148 *ptr=*curptr;
00149 if(*curptr=='\n')
00150 curlineno++;
00151 curptr++;
00152 }
00153
00154 //********************************************************************
00155
00156 void ReadFullUInt32(unsigned long *data)
00157 // Reads a full integer (32 bit)
00158 {
00159 FillBufLen(sizeof(unsigned long));
00160
00161 *data=*(unsigned long *)curptr;
00162 curptr+=4;
00163 }
00164
00165 void ReadUInt32(unsigned long *data)
00166 // Reads a compressed integer
00167 // If the MSB (most significant bit) of the first byte is 0, then
00168 // we have a vlaue <128
00169 // If the MSB is zero, then we look at the second MSB - if it is 0, then
00170 // we have a value <16384, otherwise, a value <2^30
00171 {
00172 FillBufLen(1);
00173
00174 if(*(unsigned char *)curptr<128)
00175 *data=(unsigned)(unsigned char)*(curptr++);
00176 else
00177 {
00178 if(*(unsigned char *)curptr<192)
00179 {
00180 FillBufLen(1);
00181 *data=(((unsigned)(unsigned char)*(curptr++)-128)<<8)+(unsigned)(unsigned char)*(curptr++);
00182 }
00183 else
00184 {
00185 FillBufLen(3);
00186
00187 *data= (((unsigned)(unsigned char)*(curptr++)-192)<<24)+
00188 (((unsigned)(unsigned char)*(curptr++))<<16)+
00189 (((unsigned)(unsigned char)*(curptr++))<<8)+
00190 (unsigned)(unsigned char)*(curptr++);
00191 }
00192 }
00193 }
00194
00195 //**********************************************************************
00196
00197 void PeekData(char *ptr,int len)
00198 // The functions looks ahead 'len' bytes and stores them in 'ptr'
00199 {
00200 FillBufLen(len);
00201 mymemcpy(ptr,curptr,len);
00202 }
00203
00204 void PeekChar(char *ptr)
00205 // Peeks one character ahead and stores it in *ptr
00206 // Returns -1 if there was an error
00207 // Returns -2 if there is no character left
00208 // Returns 0 if everything is okay
00209 {
00210 FillBufLen(1);
00211 *ptr=*curptr;
00212 }
00213
00214 void SkipData(int len)
00215 // Skips 'len' characters
00216 // If the data is already in memory, we simply skip
00217 // Otherwise, we iteratively read more from the file
00218 // The functions returns 0 if 'len' bytes are skipped
00219 // Otherwise, it returns -1, if the was some I/O error
00220 // If we reached EOF, we return -2
00221 {
00222 while(endptr-curptr<len)
00223 {
00224 len-=endptr-curptr;
00225 curptr=endptr=databuf;
00226
00227 FillBuf();
00228 }
00229 curptr+=len;
00230 }
00231
00232 void FastSkipData(int len)
00233 // Does a fast skip - the data is already expected to be in the buffer
00234 {
00235 curptr+=len;
00236 }
00237
00238 void SkipChar()
00239 // Skips one single character
00240 {
00241 FillBufLen(1);
00242 if(*curptr=='\n')
00243 curlineno++;
00244 curptr++;
00245 }
00246
00247 char IsEndOfFile(unsigned len=0)
00248 // Checks whether we reached the end of the file
00249 {
00250 return (curptr+len==endptr)&&(iseof);
00251 }
00252
00253 int GetCurBlockPtr(char **ptr)
00254 // Returns the length of rest of data in the buffer and
00255 // stores the data pointer in *ptr
00256 {
00257 *ptr=curptr;
00258 return endptr-curptr;
00259 }
00260
00261 void RefillAndGetCurBlockPtr(char **ptr,int *len)
00262 // Refills and
00263 // returns the length of rest of data in the buffer and
00264 // stores the data pointer in *ptr
00265 {
00266 FillBuf();
00267 *ptr=curptr;
00268 *len=endptr-curptr;
00269 }
00270
00271 void UndoReadChar()
00272 // Unreads the last character that was read
00273 {
00274 curptr--;
00275 }
00276 };
00277
00278 #endif
1.2.11.1 written by Dimitri van Heesch,
© 1997-2001