| // |
| // Copyright 2005 The Android Open Source Project |
| // |
| // Provide a wxInputStream subclass based on the Android Asset class. |
| // This is necessary because some wxWidgets functions require either a |
| // filename or a wxInputStream (e.g. wxImage). |
| // |
| #ifndef _SIM_ASSETSTREAM_H |
| #define _SIM_ASSETSTREAM_H |
| |
| #include "wx/stream.h" |
| #include <utils/Asset.h> |
| |
| /* |
| * There is no sample code or concrete documentation about providing |
| * input streams, but it seems straightforward. The PNG loading code |
| * uses the following: |
| * OnSysTell() |
| * OnSysSeek() |
| * Read() |
| * |
| * The AssetStream takes ownership of the Asset. |
| */ |
| class AssetStream : public wxInputStream { |
| public: |
| AssetStream(android::Asset* pAsset) |
| : mpAsset(pAsset) |
| {} |
| virtual ~AssetStream(void) { |
| delete mpAsset; |
| } |
| |
| virtual wxFileOffset GetLength() const { |
| //printf("## GetLength --> %ld\n", (long) mpAsset->getLength()); |
| return mpAsset->getLength(); |
| } |
| virtual size_t GetSize() const { |
| //printf("## GetSize --> %ld\n", (long) mpAsset->getLength()); |
| return mpAsset->getLength(); |
| } |
| virtual bool IsSeekable() const { return true; } |
| |
| virtual bool Eof() const { |
| //printf("## Eof\n"); |
| return (mpAsset->seek(0, SEEK_CUR) == mpAsset->getLength()); |
| } |
| |
| virtual bool CanRead() const { |
| //printf("## CanRead\n"); |
| return !Eof(); |
| } |
| |
| virtual wxInputStream& Read(void* buffer, size_t size) { |
| OnSysRead(buffer, size); |
| |
| return *this; |
| } |
| |
| protected: |
| /* read data, return number of bytes or 0 if EOF reached */ |
| virtual size_t OnSysRead(void* buffer, size_t size) { |
| ssize_t actual = mpAsset->read(buffer, size); |
| if (actual < 0) { |
| // TODO: flag error |
| actual = 0; |
| } |
| //printf("## OnSysRead(%p %u) --> %d\n", buffer, size, actual); |
| return actual; |
| } |
| |
| /* seek, using wxWidgets-defined values for "whence" */ |
| virtual wxFileOffset OnSysSeek(wxFileOffset seek, wxSeekMode mode) { |
| int whence; |
| off_t newPosn; |
| |
| if (mode == wxFromStart) |
| whence = SEEK_SET; |
| else if (mode == wxFromEnd) |
| whence = SEEK_END; |
| else |
| whence = SEEK_CUR; |
| newPosn = mpAsset->seek(seek, whence); |
| //printf("## OnSysSeek(%ld %d) --> %ld\n", |
| // (long) seek, mode, (long) newPosn); |
| if (newPosn == (off_t) -1) |
| return wxInvalidOffset; |
| else |
| return newPosn; |
| } |
| |
| virtual wxFileOffset OnSysTell() const { |
| //printf("## OnSysTell() --> %ld\n", (long) mpAsset->seek(0, SEEK_CUR)); |
| return mpAsset->seek(0, SEEK_CUR); |
| } |
| |
| private: |
| android::Asset* mpAsset; |
| |
| DECLARE_NO_COPY_CLASS(AssetStream); // private copy-ctor and op= |
| }; |
| |
| #endif // _SIM_ASSETSTREAM_H |