From: Mikko Rasa Date: Sun, 19 Oct 2014 22:34:17 +0000 (+0300) Subject: Add a class for accessing applications assets X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=bda95f684da98079f4b1fe705d969bacb6d86e12;p=libs%2Fcore.git Add a class for accessing applications assets --- diff --git a/source/io/android/asset.cpp b/source/io/android/asset.cpp new file mode 100644 index 0000000..1b97eae --- /dev/null +++ b/source/io/android/asset.cpp @@ -0,0 +1,66 @@ +#include +#include +#include +#include +#include "asset.h" +#include "file.h" + +using namespace std; + +namespace Msp { +namespace IO { + +struct Asset::Private +{ + AAsset *asset; +}; + +Asset::Asset(const string &name) +{ + AAssetManager *asset_manager = reinterpret_cast(Application::get_data())->get_asset_manager(); + AAsset *asset = AAssetManager_open(asset_manager, name.c_str(), AASSET_MODE_RANDOM); + if(!asset) + throw file_not_found(name); + + priv = new Private; + priv->asset = asset; + + mode = M_READ; +} + +Asset::~Asset() +{ + AAsset_close(priv->asset); + delete priv; +} + +unsigned Asset::do_read(char *buf, unsigned size) +{ + int ret = AAsset_read(priv->asset, buf, size); + if(ret<0) + throw runtime_error("Asset::do_read"); + else if(ret==0) + set_eof(); + + return ret; +} + +SeekOffset Asset::seek(SeekOffset off, SeekType type) +{ + signal_flush_required.emit(); + off = AAsset_seek(priv->asset, off, type); + if(off<0) + throw runtime_error("Asset::seek"); + return off; +} + +SeekOffset Asset::tell() const +{ + SeekOffset off = AAsset_seek(priv->asset, 0, S_CUR); + if(off<0) + throw runtime_error("Asset::tell"); + return off; +} + +} // namespace IO +} // namespace Msp diff --git a/source/io/asset.cpp b/source/io/asset.cpp new file mode 100644 index 0000000..a5ce175 --- /dev/null +++ b/source/io/asset.cpp @@ -0,0 +1,12 @@ +#include "asset.h" + +namespace Msp { +namespace IO { + +unsigned Asset::do_write(const char *, unsigned) +{ + throw invalid_access(M_WRITE); +} + +} // namespace IO +} // namespace Msp diff --git a/source/io/asset.h b/source/io/asset.h new file mode 100644 index 0000000..d1d63b5 --- /dev/null +++ b/source/io/asset.h @@ -0,0 +1,37 @@ +#ifndef MSP_IO_ASSET_H_ +#define MSP_IO_ASSET_H_ + +#include "seekable.h" + +namespace Msp { +namespace IO { + +/** +Opens a file from the application's assets. On Android, this means the assets +contained within the APK. On other platfoms, assets are located in the +directory indicated by FS::get_sys_data_dir(). Assets are always read-only. +*/ +class Asset: public Seekable +{ +private: + struct Private; + + Private *priv; + +public: + Asset(const std::string &); + ~Asset(); + +private: + virtual unsigned do_write(const char *, unsigned); + virtual unsigned do_read(char *, unsigned); + +public: + virtual SeekOffset seek(SeekOffset, SeekType); + virtual SeekOffset tell() const; +}; + +} // namespace IO +} // namespace Msp + +#endif diff --git a/source/io/unix/asset.cpp b/source/io/unix/asset.cpp new file mode 100644 index 0000000..7971f1b --- /dev/null +++ b/source/io/unix/asset.cpp @@ -0,0 +1,47 @@ +#include +#include "asset.h" +#include "file.h" + +using namespace std; + +namespace Msp { +namespace IO { + +struct Asset::Private +{ + Seekable *file; +}; + +Asset::Asset(const string &name) +{ + Seekable *file = new BufferedFile((FS::get_sys_data_dir()/name).str()); + + priv = new Private; + priv->file = file; + + priv->file->signal_flush_required.connect(signal_flush_required); +} + +Asset::~Asset() +{ + delete priv->file; + delete priv; +} + +unsigned Asset::do_read(char *buf, unsigned size) +{ + return priv->file->read(buf, size); +} + +SeekOffset Asset::seek(SeekOffset off, SeekType type) +{ + return priv->file->seek(off, type); +} + +SeekOffset Asset::tell() const +{ + return priv->file->tell(); +} + +} // namespace IO +} // namespace Msp