|
||||
File indexing completed on 2024-04-06 12:31:52
0001 #include "Utilities/StorageFactory/interface/Storage.h" 0002 #include "FWCore/Utilities/interface/Exception.h" 0003 #include <cassert> 0004 0005 using namespace edm::storage; 0006 0007 Storage::Storage() {} 0008 0009 Storage::~Storage() {} 0010 0011 ////////////////////////////////////////////////////////////////////// 0012 IOSize Storage::read(IOBuffer into, IOOffset pos) { return read(into.data(), into.size(), pos); } 0013 0014 IOSize Storage::read(void *into, IOSize n, IOOffset pos) { 0015 // FIXME: this is not thread safe! split into separate interface 0016 // that a particular storage can choose to support or not? make 0017 // sure that throw semantics are correct here! 0018 // FIXME: use saveposition object in case exceptions are thrown? 0019 IOOffset here = position(); 0020 position(pos); 0021 n = read(into, n); 0022 position(here); 0023 return n; 0024 } 0025 0026 IOSize Storage::readv(IOPosBuffer *into, IOSize n) { 0027 IOOffset here = position(); 0028 IOSize total = 0; 0029 for (IOSize i = 0; i < n; ++i) { 0030 try { 0031 position(into[i].offset()); 0032 total += read(into[i].data(), into[i].size()); 0033 } catch (cms::Exception &) { 0034 if (!total) 0035 throw; 0036 break; 0037 } 0038 } 0039 position(here); 0040 return total; 0041 } 0042 0043 ////////////////////////////////////////////////////////////////////// 0044 ////////////////////////////////////////////////////////////////////// 0045 ////////////////////////////////////////////////////////////////////// 0046 /** @fn IOSize Storage::read(void *into, IOSize n) 0047 0048 Read into @a into at most @a n number of bytes. 0049 0050 If this is a blocking stream, the call will block until some data 0051 can be read, end of input is reached, or an exception is thrown. 0052 For a non-blocking stream the available input is returned. If 0053 none is available, an exception is thrown. 0054 0055 @return The number of bytes actually read. This is less or equal 0056 to the size of the buffer. Zero indicates that the end of the 0057 input has been reached: end of file, or remote end closing for a 0058 connected channel like a pipe or a socket. Otherwise the value 0059 can be less than requested if limited amount of input is currently 0060 available for platform or implementation reasons. 0061 0062 @throws In case of error, a #IOError exception is thrown. This 0063 includes the situation where the input stream is in non-blocking 0064 mode and no input is currently available (FIXME: make this 0065 simpler; clarify which exception). */ 0066 0067 /** Read the next single byte from the input stream and return it as 0068 an @c unsigned @c char cast to an @c int, -1 to indicate end of 0069 intput data. 0070 0071 If this is a blocking stream, the call will block until the byte 0072 can be read, end of data is reached, or an exception is thrown. 0073 For a non-blocking input a character is returned if one is 0074 available, otherwise an exception is thrown. 0075 0076 The base class implementation simply forwards the call to 0077 #read(void *, IOSize) method. 0078 0079 @return The byte cast from a <tt>unsigned char</tt> to an @c int 0080 (in range 0...255, inclusive) if one could be read, or @c -1 to 0081 indicate end of input data. 0082 0083 @throws In case of error, a #IOError exception is thrown. This 0084 includes the situation where the input stream is in non-blocking 0085 mode and no input is currently available (FIXME: make this 0086 simpler; clarify which exception). */ 0087 int Storage::read() { 0088 unsigned char byte; 0089 IOSize n = read(&byte, 1); 0090 return n == 0 ? -1 : byte; 0091 } 0092 0093 /** Read from the input stream into the buffer starting at @a into 0094 and of size @a n. 0095 0096 If this is a blocking stream, the call will block until some data 0097 can be read, end of input is reached, or an exception is thrown. 0098 For a non-blocking stream the available input is returned. If 0099 none is available, an exception is thrown. 0100 0101 The base class implementation simply forwards the call to 0102 #read(void *, IOSize) method. 0103 0104 @return The number of bytes actually read. This is less or equal 0105 to the size of the buffer. Zero indicates that the end of the 0106 input has been reached: end of file, or remote end closing for a 0107 connected channel like a pipe or a socket. Otherwise the value 0108 can be less than requested if limited amount of input is currently 0109 available for platform or implementation reasons. 0110 0111 @throws In case of error, a #IOError exception is thrown. This 0112 includes the situation where the input stream is in non-blocking 0113 mode and no input is currently available (FIXME: make this 0114 simpler; clarify which exception). */ 0115 IOSize Storage::read(IOBuffer into) { return read(into.data(), into.size()); } 0116 0117 /** Read from the input stream into multiple scattered buffers. 0118 There are @a buffers to fill in an array starting at @a into; 0119 the memory those buffers occupy does not need to be contiguous. 0120 The buffers are filled in the order given, eac buffer is filled 0121 fully before the subsequent buffers. 0122 0123 If this is a blocking stream, the call will block until some data 0124 can be read, end of input is reached, or an exception is thrown. 0125 For a non-blocking stream the available input is returned. If 0126 none is available, an exception is thrown. 0127 0128 The base class implementation uses #read(void *, IOSize) method, 0129 but derived classes may implement a more efficient alternative. 0130 0131 @return The number of bytes actually read. This is less or equal 0132 to the size of the buffer. Zero indicates that the end of the 0133 input has been reached: end of file, or remote end closing for a 0134 connected channel like a pipe or a socket. Otherwise the value 0135 can be less than requested if limited amount of input is currently 0136 available for platform or implementation reasons. Note that the 0137 return value indicates the number of bytes read, not the number of 0138 buffers; it is the sum total of bytes filled into all the buffers. 0139 0140 @throws In case of error, a #IOError exception is thrown. However 0141 if some data has already been read, the error is swallowed and the 0142 method returns the data read so far. It is assumed that 0143 persistent errors will occur anyway on the next read and sporadic 0144 errors like stream becoming unvailable can be ignored. Use 0145 #xread() if a different policy is desirable. */ 0146 IOSize Storage::readv(IOBuffer *into, IOSize buffers) { 0147 assert(!buffers || into); 0148 0149 // Keep reading as long as possible; ignore errors if we have read 0150 // something, otherwise pass it on. 0151 IOSize status; 0152 IOSize done = 0; 0153 try { 0154 for (IOSize i = 0; i < buffers; done += status, ++i) 0155 if ((status = read(into[i])) == 0) 0156 break; 0157 } catch (cms::Exception &) { 0158 if (!done) 0159 throw; 0160 } 0161 0162 return done; 0163 } 0164 0165 ////////////////////////////////////////////////////////////////////// 0166 ////////////////////////////////////////////////////////////////////// 0167 ////////////////////////////////////////////////////////////////////// 0168 /** Like the corresponding #read() method but reads until the 0169 requested number of bytes are read or end of file is reached. 0170 Reads @a n bytes of data into the buffer @a into. This method is 0171 simply redirected to #xread(void *, IOSize). 0172 0173 Unlike #read() which may return less data than requested, this 0174 function attempts to read, possibly in multiple #read() calls, the 0175 exact requested amount of data. It stops reading only if it 0176 reaches the end of the input stream (i.e., #read() returns zero). 0177 0178 If the you know the stream blocks on #read() and it would be 0179 inconvenient to handle partial #read() results, use this method as 0180 a convenience for hiding platforms and circumstance differences. 0181 It makes no sense to use this method with non-blocking input. 0182 0183 @return The number of bytes actually read into the buffer, i.e. 0184 the size of the buffer. It will be less only if the end of the 0185 file has been reached. 0186 0187 @throws All exceptions from #read() are passed through unhandled. 0188 Therefore it is possible that an exception is thrown when this 0189 function has already read some data. */ 0190 IOSize Storage::xread(IOBuffer into) { return xread(into.data(), into.size()); } 0191 0192 /** Like the corresponding #read() method but reads until the 0193 requested number of bytes are read or end of file is reached. 0194 Reads data into the buffer @a into for its full size. 0195 0196 Unlike #read() which may return less data than requested, this 0197 function attempts to read, possibly in multiple #read() calls, the 0198 exact requested amount of data. It stops reading only if it 0199 reaches the end of the input stream (i.e., #read() returns zero). 0200 0201 If the you know the stream blocks on #read() and it would be 0202 inconvenient to handle partial #read() results, use this method as 0203 a convenience for hiding platforms and circumstance differences. 0204 It makes no sense to use this method with non-blocking input. 0205 0206 @return The number of bytes actually read into the buffer, i.e. 0207 the size of the buffer. It will be less only if the end of the 0208 file has been reached. 0209 0210 @throws All exceptions from #read() are passed through unhandled. 0211 Therefore it is possible that an exception is thrown when this 0212 function has already read some data. */ 0213 IOSize Storage::xread(void *into, IOSize n) { 0214 assert(into); 0215 0216 // Keep reading as long as possible. Let system errors fly over 0217 // us, they are a hard error. 0218 IOSize x; 0219 IOSize done = 0; 0220 while (done < n && (x = read((char *)into + done, n - done))) 0221 done += x; 0222 0223 return done; 0224 } 0225 0226 /** Like the corresponding #readv() method but reads until the 0227 requested number of bytes are read or end of file is reached. 0228 Reads data into @a buffers starting at @a into, each for its full 0229 size. The buffers are filled in the order given. This method 0230 uses #xread(void *, IOSize). 0231 0232 Unlike #readv() which may return less data than requested, this 0233 function attempts to read, possibly in multiple #read() calls, the 0234 exact requested amount of data. It stops reading only if it 0235 reaches the end of the input stream (i.e., #read() returns zero). 0236 0237 If the you know the stream blocks on #read() and it would be 0238 inconvenient to handle partial #read() results, use this method as 0239 a convenience for hiding platforms and circumstance differences. 0240 It makes no sense to use this method with non-blocking input. 0241 0242 @return The number of bytes actually read into the buffer, i.e. 0243 the size of the buffer. It will be less only if the end of the 0244 file has been reached. 0245 0246 @throws All exceptions from #read() are passed through unhandled. 0247 Therefore it is possible that an exception is thrown when this 0248 function has already read some data. */ 0249 IOSize Storage::xreadv(IOBuffer *into, IOSize buffers) { 0250 // FIXME: Use read(into, buffers) and then sort out in case of 0251 // failure, the readv probably succeed directly with much less 0252 // overhead. 0253 0254 assert(!buffers || into); 0255 0256 // Keep reading as long as possible. Let system errors fly 0257 // over us, they are a hard error. 0258 IOSize x; 0259 IOSize done = 0; 0260 for (IOSize i = 0; i < buffers; ++i) { 0261 done += (x = xread(into[i])); 0262 if (x < into[i].size()) 0263 break; 0264 } 0265 return done; 0266 } 0267 0268 ////////////////////////////////////////////////////////////////////// 0269 IOSize Storage::write(IOBuffer from, IOOffset pos) { return write(from.data(), from.size(), pos); } 0270 0271 IOSize Storage::write(const void *from, IOSize n, IOOffset pos) { 0272 // FIXME: this is not thread safe! split into separate interface 0273 // that a particular storage can choose to support or not? make 0274 // sure that throw semantics are correct here! 0275 0276 // FIXME: use saveposition object in case exceptions are thrown? 0277 IOOffset here = position(); 0278 position(pos); 0279 n = write(from, n); 0280 position(here); 0281 return n; 0282 } 0283 0284 IOSize Storage::writev(const IOPosBuffer *from, IOSize n) { 0285 IOSize total = 0; 0286 for (IOSize i = 0; i < n; ++i) { 0287 try { 0288 total += write(from[i].data(), from[i].size(), from[i].offset()); 0289 } catch (cms::Exception &) { 0290 if (!total) 0291 throw; 0292 break; 0293 } 0294 } 0295 return total; 0296 } 0297 0298 ////////////////////////////////////////////////////////////////////// 0299 ////////////////////////////////////////////////////////////////////// 0300 ////////////////////////////////////////////////////////////////////// 0301 /** @fn IOSize Storage::write (const void *from, IOSize n) 0302 Write @a n bytes of data starting at address @a from. 0303 0304 @return The number of bytes written. Normally this will be @a n, 0305 but can be less, even zero, for example if the stream is 0306 non-blocking mode and cannot accept input at this time. 0307 0308 @throws In case of error, an exception is thrown. However if the 0309 stream is in non-blocking mode and cannot accept output, it will 0310 @em not throw an exception -- the return value will be less than 0311 requested. */ 0312 0313 /** Write a single byte to the output stream. This method is simply 0314 redirected to #write(const void *, IOSize). 0315 0316 Note that derived classes should not normally call this method, 0317 as it simply routes the call back to derived class through the 0318 other virtual functions. Use this method only at the "outside 0319 edge" when transferring calls from one object to another, not 0320 in up/down calls in the inheritance tree. 0321 0322 @return The number of bytes written. Normally this will be one, 0323 but can be zero if the stream is in non-blocking mode and cannot 0324 accept output at this time. 0325 0326 @throws In case of error, an exception is thrown. However if the 0327 stream is in non-blocking mode and cannot accept output, it will 0328 @em not throw an exception -- zero will be returned. */ 0329 IOSize Storage::write(unsigned char byte) { return write(&byte, 1); } 0330 0331 /** Write to the output stream the buffer @a from. This method is 0332 simply redirected to #write(const void *, IOSize). 0333 0334 Note that derived classes should not normally call this method, 0335 as it simply routes the call back to derived class through the 0336 other virtual functions. Use this method only at the "outside 0337 edge" when transferring calls from one object to another, not 0338 in up/down calls in the inheritance tree. 0339 0340 @return The number of bytes actually written. This is less or 0341 equal to the size of the buffer. The value can be less than 0342 requested if the stream is unable to accept all the output for 0343 platform or implementation reasons. 0344 0345 @throws In case of error, an exception is thrown. However if the 0346 stream is in non-blocking mode and cannot accept output, it will 0347 @em not throw an exception -- the return value will be less than 0348 requested. */ 0349 IOSize Storage::write(IOBuffer from) { return write(from.data(), from.size()); } 0350 0351 /** Write to the output stream from multiple buffers. There are @a 0352 buffers to fill in an array starting at @a from. The buffers are 0353 filled in the order given, each buffer fully before the subsequent 0354 buffers. The method uses #write(const void *, IOSize), but may be 0355 implemented more efficiently in derived classes. 0356 0357 Note that derived classes should not normally call this method, 0358 as it simply routes the call back to derived class through the 0359 other virtual functions. Use this method only at the "outside 0360 edge" when transferring calls from one object to another, not 0361 in up/down calls in the inheritance tree. 0362 0363 @return The number of bytes actually written. This is less or 0364 equal to the size of the buffers. The value can be less than 0365 requested if the stream is unable to accept all the output for 0366 platform or implementation reasons. Note that the return value 0367 indicates the number of bytes written, not the number of buffers; 0368 it is the sum total of bytes written from all the buffers. 0369 0370 @throws In case of error, an exception is thrown. However if the 0371 stream is in non-blocking mode and cannot accept output, it will 0372 @em not throw an exception -- the return value will be less than 0373 requested. */ 0374 IOSize Storage::writev(const IOBuffer *from, IOSize buffers) { 0375 assert(!buffers || from); 0376 0377 // Keep writing as long as possible; ignore errors if we have 0378 // written something, otherwise pass it on. 0379 IOSize x; 0380 IOSize done = 0; 0381 try { 0382 for (IOSize i = 0; i < buffers; ++i) { 0383 done += (x = write(from[i].data(), from[i].size())); 0384 if (x < from[i].size()) 0385 break; 0386 } 0387 } catch (cms::Exception &) { 0388 if (!done) 0389 throw; 0390 } 0391 0392 return done; 0393 } 0394 0395 ////////////////////////////////////////////////////////////////////// 0396 ////////////////////////////////////////////////////////////////////// 0397 ////////////////////////////////////////////////////////////////////// 0398 /** Like the corresponding #write() method but writes until the 0399 requested number of bytes are written. Writes @a from contents. 0400 This method is redirected to #xwrite(const void *, IOSize). 0401 0402 Unlike #write() which may write less data than requested, this 0403 function attempts to write, possibly in multiple #write() calls, 0404 the exact requested amount of data. It stops writing only in 0405 case of error. 0406 0407 If you know the stream blocks on #write() and it would be 0408 inconvenient to handle partial #write(), use this method as a 0409 convenience for hiding platforms and circumstance differences. 0410 It makes no sense to use this method with non-blocking output. 0411 0412 Note that derived classes should not normally call this method, 0413 as it simply routes the call back to derived class through the 0414 other virtual functions. Use this method only at the "outside 0415 edge" when transferring calls from one object to another, not 0416 in up/down calls in the inheritance tree. 0417 0418 @return The number of bytes actually written from the buffer, i.e. 0419 the size of the buffer. 0420 0421 @throws All exceptions from #write() are passed through unhandled. 0422 Therefore it is possible that an exception is thrown when this 0423 function has already written some data. */ 0424 IOSize Storage::xwrite(IOBuffer from) { return xwrite(from.data(), from.size()); } 0425 0426 /** Like the corresponding #write() method but writes until the 0427 requested number of bytes are written. Writes data from the 0428 buffer @a from for its full size. 0429 0430 Unlike #write() which may write less data than requested, this 0431 function attempts to write, possibly in multiple #write() calls, 0432 the exact requested amount of data. It stops writing only in 0433 case of error. 0434 0435 If you know the stream blocks on #write() and it would be 0436 inconvenient to handle partial #write(), use this method as a 0437 convenience for hiding platforms and circumstance differences. 0438 It makes no sense to use this method with non-blocking output. 0439 0440 Note that derived classes should not normally call this method, 0441 as it simply routes the call back to derived class through the 0442 other virtual functions. Use this method only at the "outside 0443 edge" when transferring calls from one object to another, not 0444 in up/down calls in the inheritance tree. 0445 0446 @return The number of bytes actually written from the buffer, i.e. 0447 the size of the buffer. 0448 0449 @throws All exceptions from #write() are passed through unhandled. 0450 Therefore it is possible that an exception is thrown when this 0451 function has already written some data. */ 0452 IOSize Storage::xwrite(const void *from, IOSize n) { 0453 // Keep writing until we've written it all. Let errors fly over. 0454 IOSize done = 0; 0455 while (done < n) 0456 done += write((const char *)from + done, n - done); 0457 0458 return done; 0459 } 0460 0461 /** Like the corresponding #writev() method but writes until the 0462 requested number of bytes are written. Writes data from @a 0463 buffers starting at @a from, each for its full size. The 0464 buffers are filled in the order given. This method uses 0465 #xwrite(const void *, IOSize). 0466 0467 Unlike #write() which may write less data than requested, this 0468 function attempts to write, possibly in multiple #write() calls, 0469 the exact requested amount of data. It stops writing only in 0470 case of error. 0471 0472 If you know the stream blocks on #write() and it would be 0473 inconvenient to handle partial #write(), use this method as a 0474 convenience for hiding platforms and circumstance differences. 0475 It makes no sense to use this method with non-blocking output. 0476 0477 Note that derived classes should not normally call this method, 0478 as it simply routes the call back to derived class through the 0479 other virtual functions. Use this method only at the "outside 0480 edge" when transferring calls from one object to another, not 0481 in up/down calls in the inheritance tree. 0482 0483 @return The number of bytes actually written from the buffer, i.e. 0484 the size of the buffer. 0485 0486 @throws All exceptions from #write() are passed through unhandled. 0487 Therefore it is possible that an exception is thrown when this 0488 function has already written some data. */ 0489 IOSize Storage::xwritev(const IOBuffer *from, IOSize buffers) { 0490 // Keep writing until we've written it all. Let errors fly over. 0491 // FIXME: Use writev(from, buffers) and then sort out in case of 0492 // failure, the writev probably succeed directly with much less 0493 // overhead. 0494 assert(!buffers || from); 0495 0496 IOSize done = 0; 0497 for (IOSize i = 0; i < buffers; ++i) 0498 done += xwrite(from[i].data(), from[i].size()); 0499 0500 return done; 0501 } 0502 0503 ////////////////////////////////////////////////////////////////////// 0504 IOOffset Storage::position() const { 0505 Storage *self = const_cast<Storage *>(this); 0506 return self->position(0, CURRENT); 0507 } 0508 0509 IOOffset Storage::size() const { 0510 // FIXME: use saveposition object in case exceptions are thrown? 0511 Storage *self = const_cast<Storage *>(this); 0512 IOOffset here = position(); 0513 self->position(0, END); 0514 IOOffset size = position(); 0515 self->position(here); // FIXME: VERIFY()? 0516 return size; 0517 } 0518 0519 void Storage::rewind() { position(0); } 0520 0521 ////////////////////////////////////////////////////////////////////// 0522 bool Storage::prefetch(const IOPosBuffer * /* what */, IOSize /* n */) { return false; } 0523 0524 ////////////////////////////////////////////////////////////////////// 0525 void Storage::flush() {} 0526 0527 void Storage::close() {} 0528 0529 ////////////////////////////////////////////////////////////////////// 0530 bool Storage::eof() const { return position() == size(); }
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.2.1 LXR engine. The LXR team |