- Main Page
- Related Pages
- Modules
- Classes
- Files

# ObjectStreamReader.h

Go to the documentation of this file.

    00001 #ifndef FDO_IO_OBJECTSTREAMREADER_H
    00002 #define FDO_IO_OBJECTSTREAMREADER_H
    00003 //
    00004
    00005 //
    00006 // Copyright (C) 2004-2006  Autodesk, Inc.
    00007 //
    00008 // This library is free software; you can redistribute it and/or
    00009 // modify it under the terms of version 2.1 of the GNU Lesser
    00010 // General Public License as published by the Free Software Foundation.
    00011 //
    00012 // This library is distributed in the hope that it will be useful,
    00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
    00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00015 // Lesser General Public License for more details.
    00016 //
    00017 // You should have received a copy of the GNU Lesser General Public
    00018 // License along with this library; if not, write to the Free Software
    00019 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    00020 //
    00021
    00022 #include <FdoCommon.h>
    00023 #include <Common/IStreamReaderTmpl.h>
    00024
    00025 /// \brief
    00026 /// FdoIoObjectStreamReader is the template for all
    00027 /// readers on FdoIoStream. Readers for various sized objects
    00028 /// or primitive types can be based on this class.
    00029 template <typename T> class FdoIoObjectStreamReader : public FdoIStreamReaderTmpl<T>
    00030 {
    00031 public:
    00032     /// \brief
    00033     /// Gets the stream length
    00034     ///
    00035     /// \return
    00036     /// Returns the size of the data source in number of items
    00037     ///
    00038     FDO_API_COMMON virtual FdoInt64   GetLength()
    00039     {
    00040         FdoInt64 byteCount = mStream->GetLength();
    00041
    00042     /// Return the number of objects (floor if #bytes/object size)
    00043     /// Partial objects at end of stream are ignored.
    00044         return( byteCount / sizeof(T) );
    00045     }
    00046
    00047
    00048     /// \brief
    00049     /// Skips a number of items
    00050     ///
    00051     /// \param offset
    00052     /// Input number of items to skip
    00053     ///
    00054     FDO_API_COMMON virtual void       Skip(const FdoInt32 offset)
    00055     {
    00056         mStream->Skip( offset * sizeof(T) );
    00057     }
    00058
    00059     /// \brief
    00060     /// Gets the current stream position. Position is
    00061     /// measured by number of items from the stream start
    00062     ///
    00063     /// \return
    00064     /// Returns the current index in the stream
    00065     ///
    00066     FDO_API_COMMON virtual FdoInt64   GetIndex()
    00067     {
    00068         FdoInt64 byteIndex = mStream->GetIndex();
    00069
    00070         if ( (byteIndex % sizeof(T)) != 0 )
    00071             throw FdoException::Create(
    00072                 FdoException::NLSGetMessage(
    00073                     FDO_NLSID(FDO_36_STREAMINDEXALIGN),
    00074                     "%1$s: Current byte position %2$d does not align with size of item being read ($3$d)",
    00075                     "FdoIoObjectStreamReader::GetIndex",
    00076                     byteIndex,
    00077                     sizeof(T)
    00078                 )
    00079             );
    00080
    00081         return( byteIndex / sizeof(T) );
    00082     }
    00083
    00084
    00085     /// \brief
    00086     /// Reset the current index to the stream start. Allows re-reading.
    00087     ///
    00088     FDO_API_COMMON virtual void       Reset()
    00089     {
    00090         mStream->Reset();
    00091     }
    00092
    00093     /// \brief
    00094     /// Reads in the next block of items. Use ReadNext( buffer) to read in
    00095     /// the entire stream. The caller is responsible to allocate a buffer large
    00096     /// enough to store data.
    00097     ///
    00098     /// \param buffer
    00099     /// Output array holding data read in.
    00100     /// \param offset
    00101     /// Input index in the array indicating the beginning of the output buffer.
    00102     /// If zero, then the buffer is reused. If the end of the buffer, then read in
    00103     /// appending mode. Throws "out-of-bounds" exception if not in this range.
    00104     /// \param count
    00105     /// Input number of items to be read in. If -1 read the entire stream.
    00106     /// Throws "out-of-bounds"  exception if not a positive value or -1.
    00107     ///
    00108     /// \return
    00109     /// Returns the number of items actually read in. When 0 (zero) then the
    00110     /// end-of-stream was reached.
    00111     ///
    00112     FDO_API_COMMON virtual FdoInt32   ReadNext( T* buffer,
    00113                                       const FdoInt32 offset = 0,
    00114                                       const FdoInt32 count = -1)
    00115     {
    00116         FdoInt32 objectsRead = 0;
    00117         FdoInt32 totalObjectsRead = 0;
    00118         FdoInt32 bytesRead = 0;
    00119
    00120         if ( offset < 0 )
    00121             throw FdoException::Create(
    00122                 FdoException::NLSGetMessage(
    00123                     FDO_NLSID(FDO_5_INDEXOUTOFBOUNDS)
    00124                 )
    00125             );
    00126
    00127         if ( count < -1 )
    00128             throw FdoException::Create(
    00129                 FdoException::NLSGetMessage(
    00130                     FDO_NLSID(FDO_5_INDEXOUTOFBOUNDS)
    00131                 )
    00132             );
    00133
    00134         if ( count == -1 ) {
    00135             for ( ; ; ) {
    00136                 objectsRead = ReadNext( buffer, offset + totalObjectsRead, mBlockSize );
    00137                 if ( objectsRead == 0 )
    00138                     break;
    00139                 totalObjectsRead += objectsRead;
    00140             }
    00141
    00142             return(totalObjectsRead);
    00143         }
    00144         else {
    00145             FdoInt32 lCount = count;
    00146
    00147     /// If the stream provides context information then calculate
    00148     /// how many items are left to read.
    00149             if ( mStream->HasContext() ) {
    00150                 FdoInt64 length = GetLength();
    00151
    00152                 if ( length > -1 ) {
    00153                     FdoInt64 pos = GetIndex();
    00154                     FdoInt64 remaining = ( length - pos ) / sizeof(T);
    00155     /// Items that will be read is lessor of items to read
    00156     /// and items remaining. This ensures that we don't
    00157     /// read any partial item at the end of the stream.
    00158                     lCount = lCount < remaining ? lCount : (FdoInt32) remaining;
    00159                 }
    00160             }
    00161
    00162             bytesRead =  (FdoInt32) mStream->Read( &buffer[offset], lCount * sizeof(T));
    00163
    00164             return( bytesRead / sizeof(T) );
    00165         }
    00166     }
    00167     /// \param buffer
    00168     /// Output array holding data read in.
    00169     /// \param offset
    00170     /// Input index in the array indicating the beginning of the output buffer.
    00171     /// If zero, then the buffer is reused. If the end of the buffer, then read in
    00172     /// appending mode. Throws "out-of-bounds" exception if not in this range.
    00173     /// \param count
    00174     /// Input number of items to be read in. If -1 read the entire stream.
    00175     /// Throws "out-of-bounds"  exception if not a positive value or -1.
    00176     ///
    00177     /// \return
    00178     /// Returns the number of items actually read in. When 0 (zero) then the
    00179     /// end-of-stream was reached.
    00180     ///
    00181
    00182     /// \brief
    00183     /// Reads in the next block of items. Use ReadNext( buffer) to read in
    00184     /// the entire stream. The caller is responsible to create/dispose the FdoArray.
    00185     ///
    00186     /// \param buffer
    00187     /// Input array holding data read in.
    00188     /// \param offset
    00189     /// Input index in the array indicating the beginning of the output buffer.
    00190     /// If zero, then the buffer is reused. If the end of the buffer, then read in
    00191     /// appending mode. Throws "out-of-bounds" exception if not in this range.
    00192     /// \param count
    00193     /// Input number of items to be read in. If -1 read the entire stream.
    00194     /// Throws "out-of-bounds"  exception if not a positive value or -1.
    00195     ///
    00196     /// \return
    00197     /// Returns the number of items actually read in. When 0 (zero) then the
    00198     /// end-of-stream was reached.
    00199     ///
    00200     FDO_API_COMMON virtual FdoInt32       ReadNext(  FdoArray<T> * &buffer,
    00201                                         const FdoInt32 offset = 0,
    00202                                         const FdoInt32 count = -1 )
    00203     {
    00204         FdoInt32 lCount = count;
    00205
    00206         FdoInt32 lCount2 = 0;
    00207         FdoInt64 byteRemaining = 0;
    00208         FdoInt64 remaining = 0;
    00209
    00210         if ( offset < 0 )
    00211             throw FdoException::Create(
    00212                 FdoException::NLSGetMessage(
    00213                     FDO_NLSID(FDO_5_INDEXOUTOFBOUNDS)
    00214                 )
    00215             );
    00216
    00217         if ( count < -1 )
    00218             throw FdoException::Create(
    00219                 FdoException::NLSGetMessage(
    00220                     FDO_NLSID(FDO_5_INDEXOUTOFBOUNDS)
    00221                 )
    00222             );
    00223
    00224         if ( count == -1 ) {
    00225             byteRemaining = mStream->GetLength() - mStream->GetIndex();
    00226             remaining = byteRemaining / sizeof(T);
    00227
    00228             if ( remaining > LONG_MAX )
    00229                 throw FdoException::Create(
    00230                     FdoException::NLSGetMessage(
    00231                         FDO_NLSID(FDO_46_REMAININGSTREAMSIZE),
    00232                         "%1$s: Cannot read remainder of stream, there are more than %$2d items remaining.",
    00233                         "FdoIoObjectStreamReader::ReadNext(FdoArray<T>,FdoInt32,FdoInt32)",
    00234                         LONG_MAX
    00235                     )
    00236                 );
    00237
    00238             lCount = (FdoInt32) remaining;
    00239         }
    00240         T* tmpBuffer = buffer->GetData();
    00241
    00242         lCount2 = ReadNext( tmpBuffer, offset, lCount );
    00243
    00244         return(lCount2);
    00245     }
    00246
    00247 protected:
    00248 /// \cond DOXYGEN-IGNORE
    00249     FdoIoObjectStreamReader() {}
    00250
    00251     FdoIoObjectStreamReader( FdoIoStream* stream )
    00252     {
    00253         FDO_SAFE_ADDREF(stream);
    00254         mStream = stream;
    00255     }
    00256
    00257     ~FdoIoObjectStreamReader()
    00258     {
    00259     }
    00260 /// \endcond
    00261
    00262 private:
    00263     FdoIoStreamP mStream;
    00264     static const FdoInt32 mBlockSize = 4096;
    00265 };
    00266
    00267 #endif
    00268
    00269

Please send us your comment about this page