std :: ifstreamを使用できないのは正しいですが、同様の方法で使用できるアセットストリームを作成することはできます。例えば:
class asset_streambuf: public std::streambuf
{
public:
asset_streambuf(AAssetManager* manager, const std::string& filename)
: manager(manager)
{
asset = AAssetManager_open(manager, filename.c_str(), AASSET_MODE_STREAMING);
buffer.resize(1024);
setg(0, 0, 0);
setp(&buffer.front(), &buffer.front() + buffer.size());
}
virtual ~asset_streambuf()
{
sync();
AAsset_close(asset);
}
std::streambuf::int_type underflow() override
{
auto bufferPtr = &buffer.front();
auto counter = AAsset_read(asset, bufferPtr, buffer.size());
if(counter == 0)
return traits_type::eof();
if(counter < 0) //error, what to do now?
return traits_type::eof();
setg(bufferPtr, bufferPtr, bufferPtr + counter);
return traits_type::to_int_type(*gptr());
}
std::streambuf::int_type overflow(std::streambuf::int_type value) override
{
return traits_type::eof();
};
int sync() override
{
std::streambuf::int_type result = overflow(traits_type::eof());
return traits_type::eq_int_type(result, traits_type::eof()) ? -1 : 0;
}
private:
AAssetManager* manager;
AAsset* asset;
std::vector<char> buffer;
};
class assetistream: public std::istream
{
public:
assetistream(AAssetManager* manager, const std::string& file)
: std::istream(new asset_streambuf(manager, file))
{
}
assetistream(const std::string& file)
: std::istream(new asset_streambuf(manager, file))
{
}
virtual ~assetistream()
{
delete rdbuf();
}
static void setAssetManager(AAssetManager* m)
{
manager = m;
}
private:
static AAssetManager* manager;
};
void foo(AAssetManager* manager)
{
assetistream::setAssetManager(manager);
assetistream as("text/tmp.txt");
std::string s;
std::getline(as, s);
}
改善は大歓迎です。