archivelib.h

Go to the documentation of this file.
00001 /*
00002  Copyright (C) 2001-2006, William Joseph.
00003  All Rights Reserved.
00004 
00005  This file is part of GtkRadiant.
00006 
00007  GtkRadiant is free software; you can redistribute it and/or modify
00008  it under the terms of the GNU General Public License as published by
00009  the Free Software Foundation; either version 2 of the License, or
00010  (at your option) any later version.
00011 
00012  GtkRadiant is distributed in the hope that it will be useful,
00013  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  GNU General Public License for more details.
00016 
00017  You should have received a copy of the GNU General Public License
00018  along with GtkRadiant; if not, write to the Free Software
00019  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020  */
00021 
00022 #if !defined (INCLUDED_ARCHIVELIB_H)
00023 #define INCLUDED_ARCHIVELIB_H
00024 
00025 #include "debugging/debugging.h"
00026 #include "iarchive.h"
00027 #include "stream/filestream.h"
00028 #include "stream/textfilestream.h"
00029 #include "memory/allocator.h"
00030 #include "string/string.h"
00031 
00035 template<typename InputStreamType, int SIZE = 1024>
00036 class SingleByteInputStream
00037 {
00038         typedef typename InputStreamType::byte_type byte_type;
00039 
00040         InputStreamType& m_inputStream;
00041         byte_type m_buffer[SIZE];
00042         byte_type* m_cur;
00043         byte_type* m_end;
00044 
00045     public:
00046 
00047         SingleByteInputStream (InputStreamType& inputStream) :
00048             m_inputStream(inputStream), m_cur(m_buffer + SIZE), m_end(m_cur)
00049         {
00050         }
00051         bool readByte (byte_type& b)
00052         {
00053             if (m_cur == m_end) {
00054                 if (m_end != m_buffer + SIZE) {
00055                     return false;
00056                 }
00057 
00058                 m_end = m_buffer + m_inputStream.read(m_buffer, SIZE);
00059                 m_cur = m_buffer;
00060 
00061                 if (m_end == m_buffer) {
00062                     return false;
00063                 }
00064             }
00065 
00066             b = *m_cur++;
00067 
00068             return true;
00069         }
00070 };
00071 
00074 template<typename BinaryInputStreamType>
00075 class BinaryToTextInputStream: public TextInputStream
00076 {
00077         SingleByteInputStream<BinaryInputStreamType> m_inputStream;
00078     public:
00079         BinaryToTextInputStream (BinaryInputStreamType& inputStream) :
00080             m_inputStream(inputStream)
00081         {
00082         }
00083         std::size_t read (char* buffer, std::size_t length)
00084         {
00085             char* p = buffer;
00086             for (;;) {
00087                 if (length != 0 && m_inputStream.readByte(
00088                         *reinterpret_cast<typename BinaryInputStreamType::byte_type*> (p))) {
00089                     if (*p != '\r') {
00090                         ++p;
00091                         --length;
00092                     }
00093                 } else {
00094                     return p - buffer;
00095                 }
00096             }
00097         }
00098 };
00099 
00101 class StoredArchiveFile: public ArchiveFile
00102 {
00103         std::string m_name;
00104         FileInputStream m_filestream;
00105         SubFileInputStream m_substream;
00106         FileInputStream::size_type m_size;
00107     public:
00108         typedef FileInputStream::size_type size_type;
00109         typedef FileInputStream::position_type position_type;
00110 
00111         StoredArchiveFile (const std::string& name, const std::string& archiveName, position_type position,
00112                 size_type stream_size, size_type file_size) :
00113             m_name(name), m_filestream(archiveName), m_substream(m_filestream, position, stream_size),
00114                     m_size(file_size)
00115         {
00116         }
00117 
00118         static StoredArchiveFile* create (const char* name, const char* archiveName, position_type position,
00119                 size_type stream_size, size_type file_size)
00120         {
00121             return New<StoredArchiveFile> ().scalar(name, archiveName, position, stream_size, file_size);
00122         }
00123 
00124         size_type size () const
00125         {
00126             return m_size;
00127         }
00128         const std::string getName () const
00129         {
00130             return m_name;
00131         }
00132         InputStream& getInputStream ()
00133         {
00134             return m_substream;
00135         }
00136 };
00137 
00139 class StoredArchiveTextFile: public ArchiveTextFile
00140 {
00141         std::string m_name;
00142         FileInputStream m_filestream;
00143         SubFileInputStream m_substream;
00144         BinaryToTextInputStream<SubFileInputStream> m_textStream;
00145 
00146     public:
00147         typedef FileInputStream::size_type size_type;
00148         typedef FileInputStream::position_type position_type;
00149 
00153         StoredArchiveTextFile (const std::string& name, const std::string& archiveName, position_type position,
00154                 size_type stream_size) :
00155             m_name(name), m_filestream(archiveName), m_substream(m_filestream, position, stream_size), m_textStream(
00156                     m_substream)
00157         {
00158         }
00159 
00160         const std::string getName () const
00161         {
00162             return m_name;
00163         }
00164         std::size_t size ()
00165         {
00166             return m_filestream.size();
00167         }
00168         TextInputStream& getInputStream ()
00169         {
00170             return m_textStream;
00171         }
00172 };
00173 
00175 class DirectoryArchiveFile: public ArchiveFile
00176 {
00177         std::string m_name;
00178         FileInputStream m_istream;
00179         FileInputStream::size_type m_size;
00180     public:
00181         typedef FileInputStream::size_type size_type;
00182 
00183         DirectoryArchiveFile (const std::string& name, const std::string& filename) :
00184             m_name(name), m_istream(filename)
00185         {
00186             if (!failed()) {
00187                 m_istream.seek(0, FileInputStream::end);
00188                 m_size = m_istream.tell();
00189                 m_istream.seek(0);
00190             } else {
00191                 m_size = 0;
00192             }
00193         }
00194         bool failed () const
00195         {
00196             return m_istream.failed();
00197         }
00198 
00199         size_type size () const
00200         {
00201             return m_size;
00202         }
00203         const std::string getName () const
00204         {
00205             return m_name;
00206         }
00207         InputStream& getInputStream ()
00208         {
00209             return m_istream;
00210         }
00211 };
00212 
00214 class DirectoryArchiveTextFile: public ArchiveTextFile
00215 {
00216         std::string m_name;
00217         TextFileInputStream m_inputStream;
00218     public:
00219 
00220         DirectoryArchiveTextFile (const std::string& name, const std::string& filename) :
00221             m_name(name), m_inputStream(filename)
00222         {
00223         }
00224         bool failed () const
00225         {
00226             return m_inputStream.failed();
00227         }
00228 
00229         std::size_t size ()
00230         {
00231             return m_inputStream.size();
00232         }
00233         const std::string getName () const
00234         {
00235             return m_name;
00236         }
00237         TextInputStream& getInputStream ()
00238         {
00239             return m_inputStream;
00240         }
00241 };
00242 
00243 #endif

Generated by  doxygen 1.6.2