Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

chunck.cpp

Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2002 Xavier Trochu
00003 
00004 This software is provided 'as-is', without any express or implied warranty. In no event
00005 will the authors be held liable for any damages arising from the use of this software.
00006 
00007 Permission is granted to anyone to use this software for any purpose, including commercial
00008 applications, and to alter it and redistribute it freely, subject to the following
00009 restrictions:
00010 
00011 1. The origin of this software must not be misrepresented; you must not claim that you
00012    wrote the original software. If you use this software in a product, an acknowledgment
00013    in the product documentation would be appreciated but is not required.
00014 
00015 2. Altered source versions must be plainly marked as such, and must not be misrepresented 
00016    as being the original software.
00017 
00018 3. This notice may not be removed or altered from any source distribution.
00019 */
00020 #include <sstream>
00021 #include <fstream>
00022 #include <stdexcept>
00023 #include "endian.h"
00024 #include "chunck.h"
00025 
00026 //~ #include <iostream>
00027 
00028 using namespace std;
00029 
00034 class file_ptr {
00035     ifstream _ifs;
00036 public:
00037     file_ptr(const string & fname) {
00038         _ifs.open(fname.c_str(), ios::binary);
00039     }
00040     ~file_ptr() {
00041         _ifs.close();
00042     }
00043     int tell() {
00044         return _ifs.tellg();
00045     }
00046     bool seek(int pos) {
00047         _ifs.seekg(pos);
00048         return true;
00049     }
00050     bool read(void * ptr, int size) {
00051         _ifs.read(static_cast<char*>(ptr), size);
00052         return true;
00053     }
00054 };
00055 
00056 string chunck::chunck_string(chunck::type t) {
00057     ostringstream oss;
00058     oss << "TYPE:" 
00059         << static_cast<char>((t >> 24) & 0xFF) 
00060         << static_cast<char>((t >> 16) & 0xFF) 
00061         << static_cast<char>((t >> 8) & 0xFF) 
00062         << static_cast<char>(t & 0xFF);
00063     return oss.str();
00064 }
00065 
00066 
00067 file_chunck::file_chunck() throw() : _data(0), _type(0), _size(0), _cur_pos(0) {
00068 }
00069 
00070 //~ chunck::chunck(const chunck & b) throw() : _data(b._data), _type(b._type), _size(b._size), _offset(b._offset), _cur_pos(0) {
00071 //~ }
00072 
00073 file_chunck::file_chunck(const string & fname) throw(exception) {
00074     _data = new file_ptr(fname);
00075     _data->read(&_type, 4);
00076     _type = from_big_endian(_type);
00077     _data->read(&_size, 4);
00078     _size = from_big_endian(_size);
00079     _offset = _data->tell();
00080     _cur_pos = 0;
00081 }
00082 
00083 //~ chunck & chunck::operator=(const chunck& b) {
00084     //~ _data = b._data;
00085     //~ _type = b._type;
00086     //~ _size = b._size;
00087     //~ _offset = b._offset;
00088     //~ _cur_pos = 0;
00089     //~ return *this;
00090 //~ }
00091 
00092 chunck::type file_chunck::get_type() const throw() { 
00093     return _type; 
00094 }
00095 
00096 unsigned int file_chunck::get_size() const throw() { 
00097     return _size; 
00098 }
00099 
00100 chunck * file_chunck::sub_block() throw(exception) {
00101     file_chunck * ptr = new file_chunck;
00102     ptr->_data = _data;
00103     _data->seek(_offset+_cur_pos);
00104     unsigned int temp;
00105     _data->read(&temp, 4);
00106     ptr->_type = from_big_endian(temp);
00107     _data->read(&temp, 4);
00108     ptr->_size = from_big_endian(temp);
00109     ptr->_offset = _offset + _cur_pos + 8;
00110     ptr->_cur_pos = 0;
00111     //~ cout << chunck_string(ptr._type) << ", " << ptr._size << endl;
00112     seek(8 + ptr->get_size());
00113     return ptr;
00114 }
00115 
00116 bool file_chunck::eof() const throw() { 
00117     return _cur_pos >= _size; 
00118 }
00119 
00120 unsigned int file_chunck::tell() const throw() { 
00121     return _cur_pos; 
00122 }
00123 
00124 bool file_chunck::seek(int delta, ios::seekdir dir) throw (exception) {
00125     switch(dir) {
00126         case ios::cur:
00127             _cur_pos += delta;
00128             break;
00129         case ios::beg:
00130             if(delta < 0) throw runtime_error("invalid seek request");
00131             _cur_pos = static_cast<unsigned int>(delta);
00132             break;
00133         case ios::end:
00134             if(delta > 0 || (_size + delta) < 0) throw runtime_error("invalid seek request");
00135             _cur_pos = static_cast<unsigned int>(_size + delta);
00136             break;
00137     }
00138     if(_cur_pos > _size) {
00139         ostringstream oss;
00140         oss << "invalid seek request : " << _cur_pos << " > " << _size << "(delta == " << delta << ")";
00141         throw runtime_error(oss.str());
00142     }
00143     return true;
00144 }
00145 
00146 bool file_chunck::read(void * buffer, unsigned int size) throw(exception) {
00147     if(size <= 0 || (_cur_pos + size) > _size) throw runtime_error("invalid buffer read request");
00148     _data->seek(_offset + _cur_pos);
00149     _data->read(buffer, size);
00150     _cur_pos += size;
00151     return true;
00152 }
00153 
00154 char file_chunck::get_char() throw(exception) {
00155     if(_cur_pos >= _size) throw runtime_error("invalid char read request");
00156     _data->seek(_offset + _cur_pos);
00157     char buffer;
00158     _data->read(&buffer, sizeof(buffer));
00159     _cur_pos+= sizeof(buffer);
00160     return buffer;
00161 }
00162 
00163 unsigned char file_chunck::get_byte() throw(exception) {
00164     if(_cur_pos >= _size) throw runtime_error("invalid byte read request");
00165     _data->seek(_offset + _cur_pos);
00166     unsigned char buffer;
00167     _data->read(&buffer, sizeof(buffer));
00168     _cur_pos+= sizeof(buffer);
00169     return buffer;
00170 }
00171 
00172 short file_chunck::get_short() throw(exception) {
00173     if(_cur_pos >= _size-1) throw runtime_error("invalid short read request");
00174     _data->seek(_offset + _cur_pos);
00175     short buffer;
00176     _data->read(&buffer, sizeof(buffer));
00177     _cur_pos+= sizeof(buffer);
00178     return buffer;
00179 }
00180 
00181 unsigned short file_chunck::get_word() throw(exception) {
00182     if(_cur_pos >= _size-1) throw runtime_error("invalid word read request");
00183     _data->seek(_offset + _cur_pos);
00184     unsigned short buffer;
00185     _data->read(&buffer, sizeof(buffer));
00186     _cur_pos+= sizeof(buffer);
00187     return buffer;
00188 }
00189 
00190 unsigned int file_chunck::get_dword() throw(exception) {
00191     if(_cur_pos >= _size-3) throw runtime_error("invalid dword read request");
00192     //~ unsigned int * ptr = reinterpret_cast<unsigned int *>(_data + _cur_pos);
00193     //~ _cur_pos += 4;
00194     //~ return *ptr;
00195     _data->seek(_offset + _cur_pos);
00196     unsigned int buffer;
00197     _data->read(&buffer, sizeof(buffer));
00198     _cur_pos+= sizeof(buffer);
00199     return buffer;
00200 }
00201 
00202 //~ cont_chunck::cont_chunck() throw() : _data(0), _type(0), _size(0), _cur_pos(0) {
00203 //~ }
00204 
00205 //~ cont_chunck::cont_chunck(const cont_chunck & b) throw() : _data(b._data), _type(b._type), _size(b._size), _cur_pos(0) {
00206 //~ }
00207 
00208 cont_chunck::cont_chunck(char * data) throw(exception) {
00209     if(data == 0) throw(logic_error("chunck() called with NULL pointer"));
00210     _type = from_big_endian(reinterpret_cast<chunck::type*>(data)[0]);
00211     _size = from_big_endian(reinterpret_cast<unsigned int*>(data)[1]);
00212     _data = data + sizeof(chunck::type) + sizeof(unsigned int);
00213     _cur_pos = 0;
00214 }
00215 
00216 //~ cont_chunck & cont_chunck::operator=(const cont_chunck& b) {
00217     //~ _data = b._data;
00218     //~ _type = b._type;
00219     //~ _size = b._size;
00220     //~ _cur_pos = 0;
00221     //~ return *this;
00222 //~ }
00223 
00224 chunck::type cont_chunck::get_type() const throw() { 
00225     return _type; 
00226 }
00227 
00228 unsigned int cont_chunck::get_size() const throw() { 
00229     return _size; 
00230 }
00231 
00232 chunck * cont_chunck::sub_block() throw(exception) {
00233     cont_chunck * ptr = new cont_chunck(_data + _cur_pos);
00234     seek(sizeof(chunck::type) + sizeof(unsigned int) + ptr->get_size());
00235     return ptr;
00236 }
00237 
00238 bool cont_chunck::eof() const throw() { 
00239     return _cur_pos >= _size; 
00240 }
00241 
00242 unsigned int cont_chunck::tell() const throw() { 
00243     return _cur_pos; 
00244 }
00245 
00246 bool cont_chunck::seek(int delta, ios::seekdir dir) throw (exception) {
00247     switch(dir) {
00248         case ios::cur:
00249             _cur_pos += delta;
00250             break;
00251         case ios::beg:
00252             if(delta < 0) throw runtime_error("invalid seek request");
00253             _cur_pos = static_cast<unsigned int>(delta);
00254             break;
00255         case ios::end:
00256             if(delta > 0 || (_size + delta) < 0) throw runtime_error("invalid seek request");
00257             _cur_pos = static_cast<unsigned int>(_size + delta);
00258             break;
00259     }
00260     if(_cur_pos > _size) {
00261         ostringstream oss;
00262         oss << "invalid seek request : " << _cur_pos << " > " << _size << "(delta == " << delta << ")";
00263         throw runtime_error(oss.str());
00264     }
00265     return true;
00266 }
00267 
00268 bool cont_chunck::read(void * buffer, unsigned int size) throw(exception) {
00269     if(size <= 0 || (_cur_pos + size) > _size) throw runtime_error("invalid buffer read request");
00270     memcpy(buffer, _data + _cur_pos, size);
00271     _cur_pos += size;
00272     return true;
00273 }
00274 
00275 char cont_chunck::get_char() throw(exception) {
00276     if(_cur_pos >= _size) throw runtime_error("invalid char read request");
00277     return _data[_cur_pos++];
00278 }
00279 
00280 unsigned char cont_chunck::get_byte() throw(exception) {
00281     if(_cur_pos >= _size) throw runtime_error("invalid byte read request");
00282     unsigned char * ptr = reinterpret_cast<unsigned char *>(_data + _cur_pos);
00283     _cur_pos += 1;
00284     return *ptr;
00285 }
00286 
00287 short cont_chunck::get_short() throw(exception) {
00288     if(_cur_pos >= _size-1) throw runtime_error("invalid short read request");
00289     short * ptr = reinterpret_cast<short *>(_data + _cur_pos);
00290     _cur_pos += 2;
00291     return *ptr;
00292 }
00293 
00294 unsigned short cont_chunck::get_word() throw(exception) {
00295     if(_cur_pos >= _size-1) throw runtime_error("invalid word read request");
00296     unsigned short * ptr = reinterpret_cast<unsigned short *>(_data + _cur_pos);
00297     _cur_pos += 2;
00298     return *ptr;
00299 }
00300 
00301 unsigned int cont_chunck::get_dword() throw(exception) {
00302     if(_cur_pos >= _size-3) throw runtime_error("invalid dword read request");
00303     unsigned int * ptr = reinterpret_cast<unsigned int *>(_data + _cur_pos);
00304     _cur_pos += 4;
00305     return *ptr;
00306 }

Generated on Fri Aug 9 22:54:29 2002 for san_player by doxygen1.2.16