Back to home page

Project CMSSW displayed by LXR

 
 

    


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(); }