00001 #ifndef H_SDLPP_LLIO
00002 #define H_SDLPP_LLIO
00003
00004 #include <iosfwd>
00005 #include <boost/iostreams/categories.hpp>
00006 #include <boost/iostreams/positioning.hpp>
00007 #include <boost/iostreams/concepts.hpp>
00008 #include <boost/iostreams/stream.hpp>
00009 #include <boost/iostreams/stream_buffer.hpp>
00010 #include <boost/shared_ptr.hpp>
00011
00012 namespace io = boost::iostreams;
00013
00014 namespace SDLPP {
00015
00016 struct seekable_source_tag : virtual io::device_tag, virtual io::input_seekable { };
00017 typedef boost::shared_ptr<std::ifstream> ifstream_ptr;
00018
00019 class block_source
00020 {
00021 ifstream_ptr m_File;
00022 std::streamsize m_TotalBytes;
00023 std::streamsize m_BasePosition;
00024
00025
00026
00027 public:
00028 typedef char char_type;
00029 typedef seekable_source_tag category;
00030
00031 block_source(std::ifstream* f, unsigned bytes)
00032 : m_File(f),
00033 m_TotalBytes(bytes),
00034 m_BasePosition(f->tellg())
00035 {}
00036
00037
00038
00039 std::streamsize read(char* s, std::streamsize n)
00040 {
00041 std::streamsize pos=m_File->tellg();
00042 std::streamsize consumed=pos-m_BasePosition;
00043 std::streamsize left=m_TotalBytes-consumed;
00044 n=Min(n,left);
00045 m_File->read(s,n);
00046 return m_File->gcount();
00047 }
00048
00049 std::streamsize seek(std::streamsize off, std::ios_base::seekdir way)
00050 {
00051 std::streamsize abs_offset=m_BasePosition+off;
00052 if (way==std::ios_base::cur) abs_offset=std::streamsize(m_File->tellg())+off;
00053 if (way==std::ios_base::end) abs_offset=m_BasePosition+m_TotalBytes+off;
00054 return abs_seek(abs_offset) - m_BasePosition;
00055 }
00056
00057 private:
00058 std::streamsize abs_seek(std::streamsize abs_offset)
00059 {
00060 abs_offset=Max(abs_offset,m_BasePosition);
00061 abs_offset=Min(abs_offset,m_BasePosition+m_TotalBytes);
00062 m_File->seekg(abs_offset);
00063 return m_File->tellg();
00064 }
00065 };
00066
00067 class block_stream : public io::stream<block_source>
00068 {
00069 block_source m_Source;
00070 public:
00071 block_stream(std::ifstream* f, unsigned bytes)
00072 : m_Source(f,bytes)
00073 {
00074 open(m_Source);
00075 }
00076 };
00077
00078 }
00079
00080
00081 #endif // H_SDLPP_LLIO
00082