| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499 |
- /*
- -----------------------------------------------------------------------------
- This source file is part of OGRE
- (Object-oriented Graphics Rendering Engine)
- For the latest info, see http://www.ogre3d.org/
- Copyright (c) 2000-2011 Torus Knot Software Ltd
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
- -----------------------------------------------------------------------------
- */
- #pragma once
- #include "CmPrerequisitesUtil.h"
- #include <istream>
- namespace CamelotFramework
- {
- /** \addtogroup Core
- * @{
- */
- /** \addtogroup Resources
- * @{
- */
- /** General purpose class used for encapsulating the reading and writing of data.
- @remarks
- This class performs basically the same tasks as std::basic_istream,
- except that it does not have any formatting capabilities, and is
- designed to be subclassed to receive data from multiple sources,
- including libraries which have no compatibility with the STL's
- stream interfaces. As such, this is an abstraction of a set of
- wrapper classes which pretend to be standard stream classes but
- can actually be implemented quite differently.
- @par
- Generally, if a plugin or application provides an ArchiveFactory,
- it should also provide a DataStream subclass which will be used
- to stream data out of that Archive implementation, unless it can
- use one of the common implementations included.
- @note
- Ogre makes no guarantees about thread safety, for performance reasons.
- If you wish to access stream data asynchronously then you should
- organise your own mutexes to avoid race conditions.
- */
- class CM_UTILITY_EXPORT DataStream
- {
- public:
- enum AccessMode
- {
- READ = 1,
- WRITE = 2
- };
- protected:
- /// The name (e.g. resource name) that can be used to identify the source fot his data (optional)
- String mName;
- /// Size of the data in the stream (may be 0 if size cannot be determined)
- size_t mSize;
- /// What type of access is allowed (AccessMode)
- UINT16 mAccess;
- #define OGRE_STREAM_TEMP_SIZE 128
- public:
- /// Constructor for creating unnamed streams
- DataStream(UINT16 accessMode = READ) : mSize(0), mAccess(accessMode) {}
- /// Constructor for creating named streams
- DataStream(const String& name, UINT16 accessMode = READ)
- : mName(name), mSize(0), mAccess(accessMode) {}
- /// Returns the name of the stream, if it has one.
- const String& getName(void) { return mName; }
- /// Gets the access mode of the stream
- UINT16 getAccessMode() const { return mAccess; }
- /** Reports whether this stream is readable. */
- virtual bool isReadable() const { return (mAccess & READ) != 0; }
- /** Reports whether this stream is writeable. */
- virtual bool isWriteable() const { return (mAccess & WRITE) != 0; }
- virtual ~DataStream() {}
- // Streaming operators
- template<typename T> DataStream& operator>>(T& val);
- /** Read the requisite number of bytes from the stream,
- stopping at the end of the file.
- @param buf Reference to a buffer pointer
- @param count Number of bytes to read
- @returns The number of bytes read
- */
- virtual size_t read(void* buf, size_t count) = 0;
- /** Write the requisite number of bytes from the stream (only applicable to
- streams that are not read-only)
- @param buf Pointer to a buffer containing the bytes to write
- @param count Number of bytes to write
- @returns The number of bytes written
- */
- virtual size_t write(const void* buf, size_t count)
- {
- (void)buf;
- (void)count;
- // default to not supported
- return 0;
- }
- /** Get a single line from the stream.
- @remarks
- The delimiter character is not included in the data
- returned, and it is skipped over so the next read will occur
- after it. The buffer contents will include a
- terminating character.
- @note
- If you used this function, you <b>must</b> open the stream in <b>binary mode</b>,
- otherwise, it'll produce unexpected results.
- @param buf Reference to a buffer pointer
- @param maxCount The maximum length of data to be read, excluding the terminating character
- @param delim The delimiter to stop at
- @returns The number of bytes read, excluding the terminating character
- */
- virtual size_t readLine(char* buf, size_t maxCount, const String& delim = "\n");
-
- /** Returns a String containing the next line of data, optionally
- trimmed for whitespace.
- @remarks
- This is a convenience method for text streams only, allowing you to
- retrieve a String object containing the next line of data. The data
- is read up to the next newline character and the result trimmed if
- required.
- @note
- If you used this function, you <b>must</b> open the stream in <b>binary mode</b>,
- otherwise, it'll produce unexpected results.
- @param
- trimAfter If true, the line is trimmed for whitespace (as in
- String.trim(true,true))
- */
- virtual String getLine( bool trimAfter = true );
- /** Returns a String containing the entire stream.
- @remarks
- This is a convenience method for text streams only, allowing you to
- retrieve a String object containing all the data in the stream.
- */
- virtual String getAsString(void);
- /** Skip a single line from the stream.
- @note
- If you used this function, you <b>must</b> open the stream in <b>binary mode</b>,
- otherwise, it'll produce unexpected results.
- @param delim The delimiter(s) to stop at
- @returns The number of bytes skipped
- */
- virtual size_t skipLine(const String& delim = "\n");
- /** Skip a defined number of bytes. This can also be a negative value, in which case
- the file pointer rewinds a defined number of bytes. */
- virtual void skip(long count) = 0;
-
- /** Repositions the read point to a specified byte.
- */
- virtual void seek( size_t pos ) = 0;
-
- /** Returns the current byte offset from beginning */
- virtual size_t tell(void) const = 0;
- /** Returns true if the stream has reached the end.
- */
- virtual bool eof(void) const = 0;
- /** Returns the total size of the data to be read from the stream,
- or 0 if this is indeterminate for this stream.
- */
- size_t size(void) const { return mSize; }
- /** Close the stream; this makes further operations invalid. */
- virtual void close(void) = 0;
-
- };
- /** Shared pointer to allow data streams to be passed around without
- worrying about deallocation
- */
- typedef std::shared_ptr<DataStream> DataStreamPtr;
- /// List of DataStream items
- typedef List<DataStreamPtr>::type DataStreamList;
- /// Shared pointer to list of DataStream items
- typedef std::shared_ptr<DataStreamList> DataStreamListPtr;
- /** Common subclass of DataStream for handling data from chunks of memory.
- */
- class CM_UTILITY_EXPORT MemoryDataStream : public DataStream
- {
- protected:
- /// Pointer to the start of the data area
- UINT8* mData;
- /// Pointer to the current position in the memory
- UINT8* mPos;
- /// Pointer to the end of the memory
- UINT8* mEnd;
- /// Do we delete the memory on close
- bool mFreeOnClose;
- public:
-
- /** Wrap an existing memory chunk in a stream.
- @param pMem Pointer to the existing memory
- @param size The size of the memory chunk in bytes
- @param freeOnClose If true, the memory associated will be destroyed
- when the stream is destroyed. Note: it's important that if you set
- this option to true, that you allocated the memory using OGRE_ALLOC_T
- with a category of MEMCATEGORY_GENERAL ensure the freeing of memory
- matches up.
- @param readOnly Whether to make the stream on this memory read-only once created
- */
- MemoryDataStream(void* pMem, size_t size, bool freeOnClose = false, bool readOnly = false);
-
- /** Wrap an existing memory chunk in a named stream.
- @param name The name to give the stream
- @param pMem Pointer to the existing memory
- @param size The size of the memory chunk in bytes
- @param freeOnClose If true, the memory associated will be destroyed
- when the stream is destroyed. Note: it's important that if you set
- this option to true, that you allocated the memory using OGRE_ALLOC_T
- with a category of MEMCATEGORY_GENERAL ensure the freeing of memory
- matches up.
- @param readOnly Whether to make the stream on this memory read-only once created
- */
- MemoryDataStream(const String& name, void* pMem, size_t size,
- bool freeOnClose = false, bool readOnly = false);
- /** Create a stream which pre-buffers the contents of another stream.
- @remarks
- This constructor can be used to intentionally read in the entire
- contents of another stream, copying them to the internal buffer
- and thus making them available in memory as a single unit.
- @param sourceStream Another DataStream which will provide the source
- of data
- @param freeOnClose If true, the memory associated will be destroyed
- when the stream is destroyed.
- @param readOnly Whether to make the stream on this memory read-only once created
- */
- MemoryDataStream(DataStream& sourceStream,
- bool freeOnClose = true, bool readOnly = false);
-
- /** Create a stream which pre-buffers the contents of another stream.
- @remarks
- This constructor can be used to intentionally read in the entire
- contents of another stream, copying them to the internal buffer
- and thus making them available in memory as a single unit.
- @param sourceStream Weak reference to another DataStream which will provide the source
- of data
- @param freeOnClose If true, the memory associated will be destroyed
- when the stream is destroyed.
- @param readOnly Whether to make the stream on this memory read-only once created
- */
- MemoryDataStream(DataStreamPtr& sourceStream,
- bool freeOnClose = true, bool readOnly = false);
- /** Create a named stream which pre-buffers the contents of
- another stream.
- @remarks
- This constructor can be used to intentionally read in the entire
- contents of another stream, copying them to the internal buffer
- and thus making them available in memory as a single unit.
- @param name The name to give the stream
- @param sourceStream Another DataStream which will provide the source
- of data
- @param freeOnClose If true, the memory associated will be destroyed
- when the stream is destroyed.
- @param readOnly Whether to make the stream on this memory read-only once created
- */
- MemoryDataStream(const String& name, DataStream& sourceStream,
- bool freeOnClose = true, bool readOnly = false);
- /** Create a named stream which pre-buffers the contents of
- another stream.
- @remarks
- This constructor can be used to intentionally read in the entire
- contents of another stream, copying them to the internal buffer
- and thus making them available in memory as a single unit.
- @param name The name to give the stream
- @param sourceStream Another DataStream which will provide the source
- of data
- @param freeOnClose If true, the memory associated will be destroyed
- when the stream is destroyed.
- @param readOnly Whether to make the stream on this memory read-only once created
- */
- MemoryDataStream(const String& name, const DataStreamPtr& sourceStream,
- bool freeOnClose = true, bool readOnly = false);
- /** Create a stream with a brand new empty memory chunk.
- @param size The size of the memory chunk to create in bytes
- @param freeOnClose If true, the memory associated will be destroyed
- when the stream is destroyed.
- @param readOnly Whether to make the stream on this memory read-only once created
- */
- MemoryDataStream(size_t size, bool freeOnClose = true, bool readOnly = false);
- /** Create a named stream with a brand new empty memory chunk.
- @param name The name to give the stream
- @param size The size of the memory chunk to create in bytes
- @param freeOnClose If true, the memory associated will be destroyed
- when the stream is destroyed.
- @param readOnly Whether to make the stream on this memory read-only once created
- */
- MemoryDataStream(const String& name, size_t size,
- bool freeOnClose = true, bool readOnly = false);
- ~MemoryDataStream();
- /** Get a pointer to the start of the memory block this stream holds. */
- UINT8* getPtr(void) { return mData; }
-
- /** Get a pointer to the current position in the memory block this stream holds. */
- UINT8* getCurrentPtr(void) { return mPos; }
-
- /** @copydoc DataStream::read
- */
- size_t read(void* buf, size_t count);
- /** @copydoc DataStream::write
- */
- size_t write(const void* buf, size_t count);
- /** @copydoc DataStream::readLine
- */
- size_t readLine(char* buf, size_t maxCount, const String& delim = "\n");
-
- /** @copydoc DataStream::skipLine
- */
- size_t skipLine(const String& delim = "\n");
- /** @copydoc DataStream::skip
- */
- void skip(long count);
-
- /** @copydoc DataStream::seek
- */
- void seek( size_t pos );
-
- /** @copydoc DataStream::tell
- */
- size_t tell(void) const;
- /** @copydoc DataStream::eof
- */
- bool eof(void) const;
- /** @copydoc DataStream::close
- */
- void close(void);
- /** Sets whether or not to free the encapsulated memory on close. */
- void setFreeOnClose(bool free) { mFreeOnClose = free; }
- };
- /** Shared pointer to allow memory data streams to be passed around without
- worrying about deallocation
- */
- typedef std::shared_ptr<MemoryDataStream> MemoryDataStreamPtr;
- /** Common subclass of DataStream for handling data from
- std::basic_istream.
- */
- class CM_UTILITY_EXPORT FileDataStream : public DataStream
- {
- protected:
- /// Reference to source stream (read)
- std::shared_ptr<std::istream> mpInStream;
- /// Reference to source file stream (read-only)
- std::shared_ptr<std::ifstream> mpFStreamRO;
- /// Reference to source file stream (read-write)
- std::shared_ptr<std::fstream> mpFStream;
- bool mFreeOnClose;
- void determineAccess();
- public:
- /** Construct a read-only stream from an STL stream
- @param s Pointer to source stream
- @param freeOnClose Whether to delete the underlying stream on
- destruction of this class
- */
- FileDataStream(std::shared_ptr<std::ifstream> s,
- bool freeOnClose = true);
- /** Construct a read-write stream from an STL stream
- @param s Pointer to source stream
- @param freeOnClose Whether to delete the underlying stream on
- destruction of this class
- */
- FileDataStream(std::shared_ptr<std::fstream> s,
- bool freeOnClose = true);
- /** Construct named read-only stream from an STL stream
- @param name The name to give this stream
- @param s Pointer to source stream
- @param freeOnClose Whether to delete the underlying stream on
- destruction of this class
- */
- FileDataStream(const String& name,
- std::shared_ptr<std::ifstream> s,
- bool freeOnClose = true);
- /** Construct named read-write stream from an STL stream
- @param name The name to give this stream
- @param s Pointer to source stream
- @param freeOnClose Whether to delete the underlying stream on
- destruction of this class
- */
- FileDataStream(const String& name,
- std::shared_ptr<std::fstream> s,
- bool freeOnClose = true);
- /** Construct named read-only stream from an STL stream, and tell it the size
- @remarks
- This variant tells the class the size of the stream too, which
- means this class does not need to seek to the end of the stream
- to determine the size up-front. This can be beneficial if you have
- metadata about the contents of the stream already.
- @param name The name to give this stream
- @param s Pointer to source stream
- @param size Size of the stream contents in bytes
- @param freeOnClose Whether to delete the underlying stream on
- destruction of this class. If you specify 'true' for this you
- must ensure that the stream was allocated using OGRE_NEW_T with
- MEMCATEGRORY_GENERAL.
- */
- FileDataStream(const String& name,
- std::shared_ptr<std::ifstream> s,
- size_t size,
- bool freeOnClose = true);
- /** Construct named read-write stream from an STL stream, and tell it the size
- @remarks
- This variant tells the class the size of the stream too, which
- means this class does not need to seek to the end of the stream
- to determine the size up-front. This can be beneficial if you have
- metadata about the contents of the stream already.
- @param name The name to give this stream
- @param s Pointer to source stream
- @param size Size of the stream contents in bytes
- @param freeOnClose Whether to delete the underlying stream on
- destruction of this class. If you specify 'true' for this you
- must ensure that the stream was allocated using OGRE_NEW_T with
- MEMCATEGRORY_GENERAL.
- */
- FileDataStream(const String& name,
- std::shared_ptr<std::fstream> s,
- size_t size,
- bool freeOnClose = true);
- ~FileDataStream();
- /** @copydoc DataStream::read
- */
- size_t read(void* buf, size_t count);
- /** @copydoc DataStream::write
- */
- size_t write(const void* buf, size_t count);
- /** @copydoc DataStream::readLine
- */
- size_t readLine(char* buf, size_t maxCount, const String& delim = "\n");
-
- /** @copydoc DataStream::skip
- */
- void skip(long count);
-
- /** @copydoc DataStream::seek
- */
- void seek( size_t pos );
- /** @copydoc DataStream::tell
- */
- size_t tell(void) const;
- /** @copydoc DataStream::eof
- */
- bool eof(void) const;
- /** @copydoc DataStream::close
- */
- void close(void);
-
-
- };
- /** @} */
- }
|