00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include <memory.h>
00037
00038 #include <stdnet/config.h>
00039 #include <stdnet/io/BufferedInputStream>
00040
00041 namespace stdbase {
00042 namespace io {
00043
00044 int BufferedInputStream::
00045 available() throw (IOException)
00046 {
00047 int len;
00048
00049 if (end_pos >= start_pos)
00050 {
00051 len = end_pos - start_pos;
00052 }
00053 else if ( start_pos > end_pos )
00054 {
00055 len = (BUFFER_MAX - start_pos) + end_pos - 1;
00056 }
00057 return len;
00058 }
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 void BufferedInputStream::
00081 mark( int readlimit)
00082 {
00083 mark_pos = start_pos;
00084 mark_read_limit = readlimit;
00085 mark_read_count = 0;
00086 }
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096 void BufferedInputStream::
00097 reset() throw (IOException)
00098 {
00099 if ( mark_read_limit == MARK_READ_LIMIT_EXCEEDED ||
00100 mark_read_limit == MARK_READ_LIMIT_NULL ||
00101 mark_pos == MARK_POS_UNSET ||
00102 mark_pos == MARK_POS_OVERWRITTEN )
00103 {
00104
00105
00106 throw IOException();
00107 }
00108
00109 start_pos = mark_pos;
00110 mark_read_limit = MARK_READ_LIMIT_NULL;
00111 mark_pos = 0;
00112 mark_read_count = 0;
00113 }
00114
00115
00116
00117
00118
00119 bool BufferedInputStream::
00120 markSupported()
00121 {
00122 return true;
00123 }
00124
00125
00126
00127
00128 int BufferedInputStream::
00129 read( byte buffer[], int len) throw (IOException)
00130 {
00131 prepare_buffer();
00132
00133 int ready = available();
00134 int copy1_size = len < ready ? len : ready;
00135 int remainder = len;
00136 int inlen = 0;
00137
00138 if ( start_pos < end_pos && end_pos <= BUFFER_MAX )
00139 {
00140
00141
00142 memcpy( buffer,
00143 & this->buffer[ start_pos ],
00144 copy1_size
00145 );
00146 advance_start_pos( copy1_size );
00147 remainder -= copy1_size;
00148 }
00149 else
00150 {
00151
00152
00153 int block1 = BUFFER_MAX - start_pos;
00154 int block2 = end_pos - 1;
00155 int L1, L2;
00156
00157 if ( block1 > copy1_size )
00158 {
00159 L1 = copy1_size;
00160 L2 = 0;
00161 }
00162 else
00163 {
00164 L1 = block1;
00165 L2 = block2 > (copy1_size - block1) ?
00166 copy1_size - block1: block2;
00167 }
00168
00169 memcpy(
00170 buffer,
00171 & this->buffer[ start_pos ],
00172 L1
00173 );
00174
00175 memcpy(
00176 buffer,
00177 this->buffer,
00178 L2
00179 );
00180 remainder -= L1 + L2;
00181 advance_start_pos( L1 + L2);
00182 }
00183
00184 if ( remainder > 0 )
00185 {
00186 inlen = FilterInputStream:: read(
00187 & buffer[ copy1_size ],
00188 remainder
00189 );
00190 }
00191 return inlen + copy1_size;
00192 }
00193
00194
00195
00196
00197
00198
00199
00200 int BufferedInputStream::
00201 read() throw (IOException)
00202 {
00203 prepare_buffer();
00204
00205 char ch = buffer[ start_pos ];
00206
00207 advance_start_pos( 1 );
00208
00209 return ch;
00210 }
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00225
00226 void BufferedInputStream::
00227 prepare_buffer() throw (IOException)
00228 {
00229
00230
00231
00232
00233 if ( end_pos == start_pos )
00234 {
00235 if ( end_pos == BUFFER_MAX )
00236 {
00237
00238 end_pos = start_pos = 0;
00239 }
00240
00241
00242 int len;
00243 int remainder = BUFFER_MAX - end_pos;
00244 int size = remainder < BUFF_CHUNK ? remainder : BUFF_CHUNK;
00245
00246 len = FilterInputStream:: read(
00247 (byte *)& buffer[ end_pos ],
00248 size
00249 );
00250 if ( len < 0 )
00251 throw IOException();
00252
00253 end_pos += len;
00254 }
00255
00256
00257
00258
00259 if ( mark_pos != MARK_POS_UNSET &&
00260 start_pos > end_pos &&
00261 end_pos > mark_pos )
00262 {
00263 mark_pos = MARK_POS_OVERWRITTEN;
00264 mark_read_limit = MARK_READ_LIMIT_EXCEEDED;
00265 }
00266 if ( mark_read_limit > 0 &&
00267 mark_read_count > mark_read_limit )
00268 {
00269 mark_pos = MARK_POS_UNSET;
00270 mark_read_limit = MARK_READ_LIMIT_EXCEEDED;
00271 }
00272 }
00273
00274
00275
00276 void BufferedInputStream::
00277 advance_start_pos( int count )
00278 throw (IOException)
00279 {
00280 if ( count > BUFFER_MAX )
00281 throw IOException();
00282
00283 start_pos += count;
00284 if ( start_pos > BUFFER_MAX )
00285 start_pos -= BUFFER_MAX;
00286
00287 if ( mark_pos != MARK_POS_UNSET )
00288 mark_read_count += count;
00289 }
00290
00291
00295
00296 system::reference< BufferedInputStream > BufferedInputStream::
00297 create( InputStreamRef r)
00298 {
00299 return BufferedInputStreamRef( new BufferedInputStream( r ));
00300 }
00301
00302
00306
00307 BufferedInputStream::
00308 BufferedInputStream( InputStreamRef input)
00309 : FilterInputStream( input ),
00310 start_pos( 0 ),
00311 end_pos( 0 ),
00312 mark_pos( MARK_POS_UNSET ),
00313 mark_read_limit( MARK_READ_LIMIT_NULL ),
00314 mark_read_count( 0 )
00315 {};
00316
00317 }
00318 }
00319
00320