Hi, I'm trying to implement a custom InputStream but I'm having trouble doing so.
I seem to be opening the zip file just fine, and the library I'm using (
https://bitbucket.org/wbenny/ziplib/wiki/Home) automatically gives me an istream* to the
data.
Yet I keep failing when I try to load the texture with the stream through:
texture.loadFromStream
Any ideas as to what I'm doing incorrectly?
P.S. I'm currently trying to develop this to be able to open password protected zip files.
This is code for a game engine I'm currently building and my users seem to want the
added security - hence I can't just use physfs or some other pre-existing library.
Here's my implementation:
Header)
#include <ZipFile.h>
namespace lvn
{
class NStream : public sf::InputStream
{
private:
ZipArchiveEntry::Ptr m_entry;
std::shared_ptr<std::istream> m_File = nullptr;
std::string m_filename;
//bool m_file_is_open = false;
public:
static bool ReadTxtFile( std::string filepath, tstring& textbuffer );
NStream( std::string pathName="" );
virtual ~NStream();
bool isOpen() const;
bool open( std::string pathName );
void close();
virtual sf::Int64 read( void* data, sf::Int64 size );
virtual sf::Int64 seek( sf::Int64 position );
virtual sf::Int64 tell();
virtual sf::Int64 getSize();
};
}
CPP)
#include <ZipFile.h>
#include "NStream.h"
namespace lvn
{
NStream::NStream( std::string pathName )
//: m_File( 0x00 )
{
using namespace std;
open( pathName );
}
NStream::~NStream( )
{
close( );
}
bool NStream::isOpen( ) const
{
//return (m_File != 0x0);
return ( m_File != nullptr );
}
//Ex. Images//albert.png
bool NStream::open( std::string pathName )
{
using namespace std;
close( );
auto archive_name = pathName.substr( 0, pathName.find( "/" ) ) + (".vndat"); //need to add the archive extension to the name
ZipArchive::Ptr archive = ZipFile::Open( archive_name );
m_entry = archive->GetEntry( pathName );
if ( m_entry == nullptr )
return false;
m_File = make_shared<istream>( nullptr );
m_File->rdbuf( m_entry->GetDecompressionStream()->rdbuf() );
m_filename = pathName;
return isOpen( );
}
void NStream::close( )
{
m_File.reset( );
}
sf::Int64 NStream::read( void* data, sf::Int64 size )
{
if ( !isOpen( ) )
return -1;
auto posPrev = tell();
m_File->read( static_cast<char *>( data ), size );
auto cur = tell();
return tell() - posPrev;
}
sf::Int64 NStream::seek( sf::Int64 position )
{
if ( !isOpen( ) )
return -1;
m_File->seekg( position );
return tell( );
}
sf::Int64 NStream::tell( )
{
if ( !isOpen( ) )
return -1;
// istream returns the offset in bytes or -1 on error just like SFML wants.
return m_File->tellg( );
}
sf::Int64 NStream::getSize( )
{
if ( !isOpen( ) )
return -1;
//get length of file (by seeking to end), then restore original offset
const auto originalIdx = tell( );
m_File->seekg( 0, m_File->end );
const sf::Int64 length = tell( );
seek( originalIdx );
// tell returns length of file or -1 on error just like SFML wants.
return length;
}
}