Commit be359013 authored by Oleg.Korshul's avatar Oleg.Korshul Committed by Alexander Trofimov

CompoundDocument reader/writer

git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@57649 954022d7-b5bf-4e40-9824-e11837661b57
parent 97a1a37e
...@@ -317,6 +317,8 @@ Common/ASCDocxFormat/Lib/Release/Common.lib svn_mime_002dtype=application%2Focte ...@@ -317,6 +317,8 @@ Common/ASCDocxFormat/Lib/Release/Common.lib svn_mime_002dtype=application%2Focte
Common/ASCDocxFormat/Lib/Release/DocxFormat.lib svn_mime_002dtype=application%2Foctet-stream Common/ASCDocxFormat/Lib/Release/DocxFormat.lib svn_mime_002dtype=application%2Foctet-stream
Common/ASCDocxFormat/Lib/Release/Utility.lib svn_mime_002dtype=application%2Foctet-stream Common/ASCDocxFormat/Lib/Release/Utility.lib svn_mime_002dtype=application%2Foctet-stream
Common/ASCDocxFormat/Lib/Release/XML.lib svn_mime_002dtype=application%2Foctet-stream Common/ASCDocxFormat/Lib/Release/XML.lib svn_mime_002dtype=application%2Foctet-stream
Common/DocxFormat/Source/CompoundDocument svnc_tsvn_003alogminsize=5
Common/DocxFormat/Source/CompoundDocument/detail svnc_tsvn_003alogminsize=5
Common/DocxFormat/Source/SystemUtility/Solution/FileSystemTest/app.ico svn_mime_002dtype=application%2Foctet-stream Common/DocxFormat/Source/SystemUtility/Solution/FileSystemTest/app.ico svn_mime_002dtype=application%2Foctet-stream
Common/DocxFormat/Source/XML/libxml2/LIBXML2_LIB_TEST svnc_tsvn_003alogminsize=5 Common/DocxFormat/Source/XML/libxml2/LIBXML2_LIB_TEST svnc_tsvn_003alogminsize=5
Common/DocxFormat/Source/XML/libxml2/XML/doc/DOM.gif svn_mime_002dtype=application%2Foctet-stream Common/DocxFormat/Source/XML/libxml2/XML/doc/DOM.gif svn_mime_002dtype=application%2Foctet-stream
......
/* POLE - Portable C++ library to access OLE Storage
Copyright (C) 2005-2006 Jorge Lodos Vigil
Copyright (C) 2002-2005 Ariya Hidayat <ariya@kde.org>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the authors nor the names of its contributors may be
used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.
*/
// AllocTableT header
#pragma once
#include <iostream>
#include <vector>
#include "util.hpp"
namespace POLE
{
template<typename _>
class AllocTableT
{
public:
static const ULONG32 Eof;
static const ULONG32 Avail;
static const ULONG32 Bat;
static const ULONG32 MetaBat;
// Construction/destruction
public:
AllocTableT(ULONG32 block_size = 4096) { set_block_size(block_size); }
// Attributes
public:
size_t count() const { return _data.size(); } // number of blocks
ULONG32 block_size() const { return _block_size; } // block size
ULONG32 operator[]( size_t index ) const { return _data[index]; }
bool follow( ULONG32 start, std::vector<ULONG32>& chain ) const;
// Operations
public:
void set_block_size(ULONG32 size) { _block_size = size; _data.clear(); resize( 128 ); }
void set_chain( const std::vector<ULONG32>& chain );
bool load( const unsigned char* buffer, size_t len );
bool save( unsigned char* buffer, size_t len );
#ifndef NDEBUG
void debug() const;
#endif
// Implementation
private:
void resize( size_t newsize ) { _data.resize( newsize, Avail); }
size_t unused();
void preserve( size_t n ) { unused(); }
void set( size_t index, ULONG32 val );
std::vector<ULONG32> _data;
ULONG32 _block_size;
AllocTableT( const AllocTableT& ); // No copy construction
AllocTableT& operator=( const AllocTableT& ); // No copy operator
};
typedef AllocTableT<void> AllocTable;
// =========== AllocTableT Implementation ==========
template<typename _>
const ULONG32 AllocTableT<_>::Avail = 0xffffffff;
template<typename _>
const ULONG32 AllocTableT<_>::Eof = 0xfffffffe;
template<typename _>
const ULONG32 AllocTableT<_>::Bat = 0xfffffffd;
template<typename _>
const ULONG32 AllocTableT<_>::MetaBat = 0xfffffffc;
template<typename _>
void AllocTableT<_>::set( size_t index, ULONG32 value )
{
if ( index >= count() )
resize( index + 1);
_data[ index ] = value;
}
template<typename _>
void AllocTableT<_>::set_chain( const std::vector<ULONG32>& chain )
{
size_t chain_size = chain.size();
if ( chain_size )
{
for( size_t i = 0; i<chain_size-1; i++ )
set( chain[i], chain[i+1] );
set( chain[ chain_size-1 ], Eof );
}
}
// follow
template<typename _>
bool AllocTableT<_>::follow( ULONG32 start, std::vector<ULONG32>& chain ) const
{
//assert(chain.size() == 0);
size_t blocks = count();
if( start >= blocks )
return false;
ULONG32 p = start;
chain.reserve(blocks);
for (size_t loop_control = 0; p < blocks; ++loop_control)
{
if (loop_control >= blocks)
return false;
chain.push_back( p );
p = _data[ p ];
}
return true;
}
template<typename _>
size_t AllocTableT<_>::unused()
{
// find first available block
size_t blocks = count();
for( size_t i = 0; i < blocks; i++ )
if( _data[i] == Avail )
return i;
// completely full, so enlarge the table
resize( blocks + 10 );
return count();
}
template<typename _>
bool AllocTableT<_>::load( const unsigned char* buffer, size_t len )
{
if (len%4 || !buffer)
return false;
resize( len / 4 );
size_t blocks = count();
for( size_t i = 0; i < blocks; i++ )
_data[ i ] = readU32( buffer + i*4 );
return true;
}
template<typename _>
bool AllocTableT<_>::save( unsigned char* buffer, size_t len )
{
if (len < 4*count() || !buffer)
return false;
size_t blocks = count();
for( size_t i = 0; i < blocks; i++ )
writeU32( buffer + i*4, _data[i] );
return true;
}
#ifndef NDEBUG
template<typename _>
void AllocTableT<_>::debug() const
{
std::cout << "block size " << _data.size() << std::endl;
for( size_t i=0; i< _data.size(); i++ )
{
if( _data[i] == Avail )
continue;
std::cout << i << ": ";
if( _data[i] == Eof )
std::cout << "[eof]";
else if( _data[i] == Bat )
std::cout << "[bat]";
else if( _data[i] == MetaBat )
std::cout << "[metabat]";
else std::cout << _data[i];
std::cout << std::endl;
}
}
#endif
} // namespace POLE
This diff is collapsed.
/* POLE - Portable C++ library to access OLE Storage
Copyright (C) 2005-2006 Jorge Lodos Vigil
Copyright (C) 2002-2005 Ariya Hidayat <ariya@kde.org>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the authors nor the names of its contributors may be
used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.
*/
// header.hpp
#pragma once
#include "alloctable.hpp"
namespace POLE
{
template<typename _>
class HeaderT
{
public:
static const unsigned char pole_magic[];
// Construction/destruction
public:
HeaderT();
// Attributes
public:
const unsigned char* id() const { return _id; }
unsigned b_shift() const { return _b_shift; }
unsigned s_shift() const { return _s_shift; }
unsigned num_bat() const { return _num_bat; }
unsigned dirent_start() const { return _dirent_start; }
unsigned threshold() const { return _threshold; }
unsigned sbat_start() const { return _sbat_start; }
unsigned num_sbat() const { return _num_sbat; }
unsigned mbat_start() const { return _mbat_start; }
unsigned num_mbat() const { return _num_mbat; }
const ULONG32* bb_blocks() const { return _bb_blocks; }
bool valid() const;
bool is_ole() const;
// Operations
public:
bool load( const unsigned char* buffer, size_t len );
bool save( unsigned char* buffer, size_t len );
#ifndef NDEBUG
void debug() const;
#endif
// Implementation
private:
unsigned char _id[8]; // signature, or magic identifier
unsigned _b_shift; // bbat->blockSize = 1 << b_shift [_uSectorShift]
unsigned _s_shift; // sbat->blockSize = 1 << s_shift [_uMiniSectorShift]
unsigned _num_bat; // blocks allocated for big bat [_csectFat]
unsigned _dirent_start; // starting block for directory info [_secDirStart]
unsigned _threshold; // switch from small to big file (usually 4K) [_ulMiniSectorCutoff]
unsigned _sbat_start; // starting block index to store small bat [_sectMiniFatStart]
unsigned _num_sbat; // blocks allocated for small bat [_csectMiniFat]
unsigned _mbat_start; // starting block to store meta bat [_sectDifStart]
unsigned _num_mbat; // blocks allocated for meta bat [_csectDif]
ULONG32 _bb_blocks[109]; // [_sectFat]
};
typedef HeaderT<void> Header;
// =========== HeaderT ==========
template<typename _>
const unsigned char HeaderT<_>::pole_magic[] = { 0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1 };
template<typename _>
HeaderT<_>::HeaderT()
{
_b_shift = 9;
_s_shift = 6;
_num_bat = 0;
_dirent_start = 0;
_threshold = 4096;
_sbat_start = 0;
_num_sbat = 0;
_mbat_start = 0;
_num_mbat = 0;
unsigned i = 0;
for(; i < 8; i++ )
_id[i] = pole_magic[i];
for( i=0; i<109; i++ )
_bb_blocks[i] = AllocTable::Avail;
}
template<typename _>
bool HeaderT<_>::valid() const
{
if( _threshold != 4096 ) return false;
if( _num_bat == 0 ) return false; //ok
if( (_num_bat > 109) && (_num_bat > ((_num_mbat * 127) + 109))) return false; //ok
if( (_num_bat < 109) && (_num_mbat != 0) ) return false; //ok
if( _s_shift > _b_shift ) return false;
if( _b_shift <= 6 ) return false;
if( _b_shift >=31 ) return false;
return true;
}
template<typename _>
bool HeaderT<_>::is_ole() const
{
for( unsigned i=0; i<8; i++ )
if( _id[i] != pole_magic[i] )
return false;
return true;
}
template<typename _>
bool HeaderT<_>::load( const unsigned char* buffer, size_t len )
{
if (len < 0x4C+109 * 4 || !buffer)
return false;
_b_shift = readU16( buffer + 0x1e );
_s_shift = readU16( buffer + 0x20 );
_num_bat = readU32( buffer + 0x2c );
_dirent_start = readU32( buffer + 0x30 );
_threshold = readU32( buffer + 0x38 );
_sbat_start = readU32( buffer + 0x3c );
_num_sbat = readU32( buffer + 0x40 );
_mbat_start = readU32( buffer + 0x44 );
_num_mbat = readU32( buffer + 0x48 );
unsigned int i = 0;
for( ; i < 8; i++ )
_id[i] = buffer[i];
for( i=0; i<109; i++ )
_bb_blocks[i] = readU32( buffer + 0x4C+i*4 );
return true;
}
template<typename _>
bool HeaderT<_>::save( unsigned char* buffer, size_t len )
{
if (len<0x4C+109*4 || !buffer)
return false;
memset( buffer, 0, 0x4c );
memcpy( buffer, pole_magic, 8 ); // ole signature
writeU32( buffer + 8, 0 ); // unknown
writeU32( buffer + 12, 0 ); // unknown
writeU32( buffer + 16, 0 ); // unknown
writeU16( buffer + 24, 0x003e ); // revision ?
writeU16( buffer + 26, 3 ); // version ?
writeU16( buffer + 28, 0xfffe ); // unknown
writeU16( buffer + 0x1e, _b_shift );
writeU16( buffer + 0x20, _s_shift );
writeU32( buffer + 0x2c, _num_bat );
writeU32( buffer + 0x30, _dirent_start );
writeU32( buffer + 0x38, _threshold );
writeU32( buffer + 0x3c, _sbat_start );
writeU32( buffer + 0x40, _num_sbat );
writeU32( buffer + 0x44, _mbat_start );
writeU32( buffer + 0x48, _num_mbat );
for( unsigned i=0; i<109; i++ )
writeU32( buffer + 0x4C+i*4, _bb_blocks[i] );
return true;
}
#ifndef NDEBUG
template<typename _>
void HeaderT<_>::debug() const
{
std::cout << std::endl;
std::cout << "b_shift " << _b_shift << std::endl;
std::cout << "s_shift " << _s_shift << std::endl;
std::cout << "num_bat " << _num_bat << std::endl;
std::cout << "dirent_start " << _dirent_start << std::endl;
std::cout << "threshold " << _threshold << std::endl;
std::cout << "sbat_start " << _sbat_start << std::endl;
std::cout << "num_sbat " << _num_sbat << std::endl;
std::cout << "mbat_start " << _mbat_start << std::endl;
std::cout << "num_mbat " << _num_mbat << std::endl;
unsigned s = (_num_bat<=109) ? _num_bat : 109;
std::cout << "bat blocks: ";
for( unsigned i = 0; i < s; i++ )
std::cout << _bb_blocks[i] << " ";
std::cout << std::endl;
}
#endif
}
This diff is collapsed.
This diff is collapsed.
/* POLE - Portable C++ library to access OLE Storage
Copyright (C) 2005-2006 Jorge Lodos Vigil
Copyright (C) 2002-2005 Ariya Hidayat <ariya@kde.org>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the authors nor the names of its contributors may be
used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.
*/
// util header
#pragma once
namespace POLE
{
typedef unsigned char ULONG8;
typedef unsigned short ULONG16;
typedef unsigned long ULONG32;
inline ULONG32 readU32( const unsigned char* ptr )
{
return ptr[0]+(ptr[1]<<8)+(ptr[2]<<16)+(ptr[3]<<24);
}
inline void writeU32( unsigned char* ptr, ULONG32 data )
{
ptr[0] = (unsigned char)(data & 0xff);
ptr[1] = (unsigned char)((data >> 8) & 0xff);
ptr[2] = (unsigned char)((data >> 16) & 0xff);
ptr[3] = (unsigned char)((data >> 24) & 0xff);
}
inline ULONG16 readU16( const unsigned char* ptr )
{
return ptr[0]+(ptr[1]<<8);
}
inline void writeU16( unsigned char* ptr, ULONG16 data )
{
ptr[0] = (unsigned char)(data & 0xff);
ptr[1] = (unsigned char)((data >> 8) & 0xff);
}
}
/* POLE - Portable C++ library to access OLE Storage
Copyright (C) 2005-2006 Jorge Lodos Vigil
Copyright (C) 2002-2005 Ariya Hidayat <ariya@kde.org>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the authors nor the names of its contributors may be
used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef POLE_H
#define POLE_H
#pragma once
#include "./detail/stream.hpp"
namespace POLE
{
class Stream;
template<typename _>
class StorageT
{
public:
enum { Ok, OpenFailed, OpenSmallFatFailed, NotOLE, BadOLE, UnknownError, StupidWorkaroundForBrokenCompiler=255 };
// Constructs a storage with name filename.
StorageT( const char* filename, std::ios_base::openmode mode = std::ios_base::in, bool create = false )
{
io = new StorageIO( filename, mode, create );
}
StorageT( const std::wstring& filename, std::ios_base::openmode mode = std::ios_base::in, bool create = false )
{
io = new StorageIO( filename, mode, create );
}
// Constructs a storage from a stream.
StorageT( std::iostream& stream )
{
io = new StorageIO( &stream );
}
// Destroys the storage.
~StorageT()
{
delete io;
std::list<Stream*>::iterator it;
for( it = streams.begin(); it != streams.end(); ++it )
delete *it;
}
// Attributes
public:
// Returns the error code of last operation.
int result() const
{
return io->result();
}
void fullName( const DirEntry* entry, std::string& name) const
{
io->fullName( entry, name);
}
// Returns the current path.
void current_path( std::string& result) const
{
io->current_path(result);
}
// Returns the root entry.
const DirEntry* root_entry() const
{
return io->root_entry();
}
// Returns the current entry.
const DirEntry* current_entry() const
{
return io->current_entry();
}
const DirEntry* getEntry(const std::string& name) const
{
return io->entry( name );
}
void listEntries(std::vector<const DirEntry*>& result) const
{
io->listEntries(result);
}
void listAll(std::vector<const DirEntry*>& result) const
{
io->listAll(result);
}
// Operations
public:
// Changes path to directory. Returns true if no error occurs.
bool enterDirectory( const std::string& directory )
{
return io->enterDirectory( directory );
}
// Goes to one directory up.
void leaveDirectory()
{
io->leaveDirectory();
}
// Finds and returns a stream with the specified name.
Stream* stream( const std::string& name, bool reuse = false );
// If there is a stream using this entry it will be corrupted.
// Any existent entry list is not valid anymore
bool delete_entry(const std::string& path)
{
return io->delete_entry(path);
}
bool flush()
{
return io->flush();
}
#ifndef NDEBUG
void debug() const
{
io->debug();
}
#endif
private:
StorageIO* io;
std::list<Stream*> streams;
// no copy or assign
StorageT( const StorageT<_>& );
StorageT<_>& operator=( const StorageT<_>& );
};
typedef StorageT<void> Storage;
class Stream
{
friend class StorageT<void>;
public: // Attributes
// Returns the path for this stream.
const std::string& path() const
{
return impl ? impl->path() : StreamImpl::null_path;
}
// Returns the stream size.
std::streamsize size() const
{
return impl ? impl->size() : 0;
}
// Returns the read pointer.
std::streampos tellg() const
{
return impl ? impl->tellg() : 0;
}
// Returns the write pointer.
std::streampos tellp() const
{
return impl ? impl->tellp() : 0;
}
// Return the Eof state of the stream
bool eof() const
{
return impl ? impl->eof() : true;
}
// Return the fail state of the Stream
bool fail() const
{
return impl ? impl->fail() : true;
}
public: // Operations
// Sets the read position.
std::streampos seek( std::streampos pos, std::ios_base::seekdir origin, std::ios_base::openmode mode )
{
if( impl ) return impl->seek( pos, origin, mode );
return 0;
}
// Sets the read position.
void seekg( std::streampos pos, std::ios_base::seekdir origin = std::ios_base::beg )
{
if( impl ) impl->seekg( pos, origin );
}
// Sets the write position.
void seekp( std::streampos pos, std::ios_base::seekdir origin = std::ios_base::beg )
{
if( impl ) impl->seekp( pos, origin );
}
// Reads a byte.
int getch()
{
return impl ? impl->getch() : 0;
}
// Reads a block of data.
std::streamsize read( unsigned char* data, std::streamsize maxlen )
{
return impl ? impl->read( data, maxlen ) : 0;
}
// Write a block of data
std::streamsize write(const unsigned char* data, std::streamsize len)
{
return impl ? impl->write( data, len ) : 0;
}
// Make the size grow to size. If size is less than current size no
// action will be taken.
bool reserve(std::streamsize size)
{
return impl ? impl->reserve( size ) : false;
}
// Make the size exactly size. If size is less than current size the
// extra bytes will be truncated. If it is greater the new data will
// be filled with val.
bool resize(std::streamsize size, char val = 0)
{
return impl ? impl->resize( size, val ) : false;
}
private:
Stream(StreamImpl* i) { impl = i; }
~Stream() { delete impl; }
// no default, copy or assign
Stream();
Stream( const Stream& );
Stream& operator=( const Stream& );
StreamImpl* impl;
};
// =========== StorageT ==========
template<typename _>
Stream* StorageT<_>::stream( const std::string& name, bool reuse )
{
// sanity check
if( !name.length() ) return (Stream*)0;
if( !io ) return (Stream*)0;
// make absolute if necesary
std::string fullName = name;
std::string path_;
current_path(path_);
if( name[0] != '/' ) fullName.insert( 0, path_ + "/" );
// If a stream for this path already exists return it
if (reuse)
{
std::list<Stream*>::iterator it;
for( it = streams.begin(); it != streams.end(); ++it )
if ((*it)->path() == name)
return *it;
}
const DirEntry* entry = io->entry( name );
if( !entry ) return (Stream*)0;
// We create the StreamImpl here instead of in the constructor to avoid
// passing implementation parameters in the constructor.
// The created StreamImpl will be deleted in the Stream destructor.
StreamImpl* i = new StreamImpl( io, entry );
Stream* s = new Stream(i);
streams.push_back( s );
return s;
}
}
#endif // POLE_H
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment