00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00028
00029 #if !defined __cplusplus
00030 #error C++ compiler required
00031 #endif
00032
00033
00034 #if defined WINDOWS
00035 #include <windows.h>
00036 #endif
00037
00038
00039 #include <cstring>
00040 #include <exception>
00041 #include <iostream>
00042 #include <iterator>
00043 #include <fstream>
00044 #include <memory>
00045 #include <new>
00046 #include <sstream>
00047 #include <stdexcept>
00048 #include <string>
00049
00050
00051 #include "global.hpp"
00052 #include "eventlog.hpp"
00053 #include "lump.hpp"
00054 #include "util.hpp"
00055 #include "wadentry.hpp"
00056
00057 using namespace Doomwad;
00058
00059
00060 const size_t Lump::MAX_SIZE = std::numeric_limits<size_t>::max ();
00061 const size_t Lump::MIN_SIZE = std::numeric_limits<size_t>::min ();
00062
00068 Lump::Lump (void) throw () : m_name (), m_size (0), m_data (NULL)
00069 {
00070 }
00071
00088 Lump::Lump (const Lump &lump) throw (std::bad_alloc)
00089 {
00090 value_type *temp;
00091
00092
00093 this->m_size = 0;
00094 this->m_data = NULL;
00095
00096
00097 if (lump.m_size > 0)
00098 {
00099 try
00100 {
00101 temp = new value_type[lump.m_size];
00102 }
00103 catch (std::bad_alloc &e)
00104 {
00105 std::ostringstream str;
00106 str << "Caught std::bad_alloc in Lump copy constructor at " << __FILE__ ":" << __LINE__ << ". this=" << (reinterpret_cast<size_t> (this));
00107 std::string string (str.str ());
00108 EventLog::printLine (string);
00109 throw (e);
00110 }
00111 this->m_data = temp;
00112 this->m_size = lump.m_size;
00113 std::memcpy (this->m_data, lump.m_data, this->m_size);
00114 }
00115
00116 this->m_name = lump.m_name;
00117
00118 return;
00119 }
00120
00134 Lump::Lump (const std::string &name, size_t length) throw (std::bad_alloc)
00135 {
00136 value_type *temp;
00137
00138
00139 this->m_size = 0;
00140 this->m_data = NULL;
00141
00142 if (length > 0)
00143 {
00144
00145
00146 try
00147 {
00148 temp = new value_type[length];
00149 }
00150 catch (std::bad_alloc &e)
00151 {
00152 std::ostringstream str;
00153 str << "Caught std::bad_alloc in Lump constructor at " << __FILE__ ":" << __LINE__ << ". this=" << (reinterpret_cast<size_t> (this));
00154 std::string string (str.str ());
00155 EventLog::printLine (string);
00156 throw (e);
00157 }
00158
00159
00160 this->m_data = temp;
00161 this->m_size = length;
00162 std::memset (this->m_data, 0, this->m_size);
00163 }
00164
00165 this->m_name = name;
00166
00167 return;
00168 }
00169
00186 Lump::Lump (const std::string &name, size_t length, const_pointer data) throw (std::bad_alloc, std::invalid_argument)
00187 {
00188 value_type *temp;
00189
00190
00191 this->m_size = 0;
00192 this->m_data = NULL;
00193
00194
00195 if ((data == NULL) && (length > 0))
00196 {
00197 std::ostringstream str;
00198 str << "Throwing std::invalid_argument in Lump constructor at " << __FILE__ ":" << __LINE__ << " because a null pointer was passed in. this=" << (reinterpret_cast<size_t> (this));
00199 std::string string (str.str ());
00200 EventLog::printLine (string);
00201 throw (std::invalid_argument ( exceptionString ("Null pointer passed to Lump constructor.", __FILE__, __LINE__)));
00202 }
00203
00204
00205 #if defined WINDOWS
00206 if (IsBadReadPtr (data, length))
00207 {
00208 std::ostringstream str;
00209 str << "Throwing std::invalid_argument in Lump constructor at " << __FILE__ ":" << __LINE__ << " because an invalid pointer was passed in. this=" << (reinterpret_cast<size_t> (this));
00210 std::string string (str.str ());
00211 EventLog::printLine (string);
00212 throw (std::invalid_argument ( exceptionString ("Invalid pointer passed to Lump constructor.", __FILE__, __LINE__)));
00213 }
00214 #endif
00215
00216
00217 if (length > 0)
00218 {
00219
00220
00221 try
00222 {
00223 temp = new value_type[length];
00224 }
00225 catch (std::bad_alloc &e)
00226 {
00227 std::ostringstream str;
00228 str << "Caught std::bad_alloc in Lump constructor at " << __FILE__ ":" << __LINE__ << ". this=" << (reinterpret_cast<size_t> (this));
00229 std::string string (str.str ());
00230 EventLog::printLine (string);
00231 throw (e);
00232 }
00233
00234
00235 this->m_data = temp;
00236 this->m_size = length;
00237 std::memcpy (this->m_data, data, this->m_size);
00238 }
00239
00240 this->m_name = name;
00241
00242 return;
00243 }
00244
00257 Lump::Lump (const_iterator &first, const_iterator &last) throw ()
00258 {
00259 this->assign (first, last);
00260 return;
00261 }
00262
00268 Lump::Lump (const WadEntry &we) throw ()
00269 {
00270 (*this) = we.toLump ();
00271 return;
00272 }
00273
00280 Lump::~Lump (void) throw ()
00281 {
00282 this->clear ();
00283 return;
00284 }
00285
00293 Lump::iterator Lump::begin (void) throw ()
00294 {
00295 return iterator (this->m_data);
00296 }
00297
00305 Lump::iterator Lump::end (void) throw ()
00306 {
00307 return iterator (&this->m_data[this->m_size]);
00308 }
00309
00317 Lump::const_iterator Lump::begin (void) const throw ()
00318 {
00319 return const_iterator (this->m_data);
00320 }
00321
00329 Lump::const_iterator Lump::end (void) const throw ()
00330 {
00331 return const_iterator (&this->m_data[this->m_size]);
00332 }
00333
00341 Lump::reverse_iterator Lump::rbegin (void) throw ()
00342 {
00343 return reverse_iterator (this->end ());
00344 }
00345
00353 Lump::reverse_iterator Lump::rend (void) throw ()
00354 {
00355 return reverse_iterator (this->begin ());
00356 }
00357
00365 Lump::const_reverse_iterator Lump::rbegin (void) const throw ()
00366 {
00367 return const_reverse_iterator (this->end ());
00368 }
00369
00377 Lump::const_reverse_iterator Lump::rend (void) const throw ()
00378 {
00379 return const_reverse_iterator (this->begin ());
00380 }
00381
00395 Lump& Lump::operator= (const Lump &lump) throw (std::bad_alloc)
00396 {
00397 pointer temp;
00398
00399
00400 if (this == &lump) return *this;
00401
00402
00403 if (lump.m_size == 0)
00404 {
00405 this->clearData ();
00406 }
00407
00408
00409 else
00410 {
00411 try
00412 {
00413 temp = new value_type[lump.m_size];
00414 }
00415 catch (std::bad_alloc &e)
00416 {
00417 std::ostringstream str;
00418 str << "Caught std::bad_alloc in Lump::operator= at " << __FILE__ ":" << __LINE__ << ". this=" << (reinterpret_cast<size_t> (this));
00419 std::string string (str.str ());
00420 EventLog::printLine (string);
00421 throw (e);
00422 }
00423 std::memcpy (temp, lump.m_data, lump.m_size);
00424 this->clearData ();
00425 this->m_data = temp;
00426 this->m_size = lump.m_size;
00427 }
00428
00429
00430 this->m_name = lump.m_name;
00431
00432 return *this;
00433 }
00434
00444 Lump& Lump::operator= (const WadEntry &we) throw (std::bad_alloc)
00445 {
00446 *this = we.toLump ();
00447 return *this;
00448 }
00449
00466 Lump& Lump::operator+= (const Lump &lump) throw (std::bad_alloc, std::range_error)
00467 {
00468 pointer temp;
00469 size_t length;
00470
00471
00472 if ((MAX_SIZE - this->m_size) < lump.m_size)
00473 {
00474 std::ostringstream str;
00475 str << "Throwing std::range_error in Lump::operator+=() at " << __FILE__ ":" << __LINE__ << " because the index is out of bounds. this=" << (reinterpret_cast<size_t> (this));
00476 std::string string (str.str ());
00477 EventLog::printLine (string);
00478 throw (std::range_error (exceptionString ("New size too large in Lump::operator+=().", __FILE__, __LINE__)));
00479 }
00480
00481
00482 if (lump.m_size > 0)
00483 {
00484
00485
00486 if (this->m_size == 0)
00487 {
00488 try
00489 {
00490 this->m_data = new value_type[lump.m_size];
00491 }
00492 catch (std::bad_alloc &e)
00493 {
00494 std::ostringstream str;
00495 str << "Caught std::bad_alloc in Lump::operator+= at " << __FILE__ ":" << __LINE__ << ". this=" << (reinterpret_cast<size_t> (this));
00496 std::string string (str.str ());
00497 EventLog::printLine (string);
00498 this->m_data = NULL;
00499 throw (e);
00500 }
00501 this->m_size = lump.m_size;
00502 std::memcpy (this->m_data, lump.m_data, this->m_size);
00503 }
00504
00505
00506 else
00507 {
00508 try
00509 {
00510 temp = new value_type[this->m_size + lump.m_size];
00511 }
00512 catch (std::bad_alloc &e)
00513 {
00514 std::ostringstream str;
00515 str << "Caught std::bad_alloc in Lump::operator+= at " << __FILE__ ":" << __LINE__ << ". this=" << (reinterpret_cast<size_t> (this));
00516 std::string string (str.str ());
00517 EventLog::printLine (string);
00518 throw (e);
00519 }
00520
00521 std::memcpy (temp, this->m_data, this->m_size);
00522 std::memcpy (&temp[this->m_size], lump.m_data, lump.m_size);
00523 length = this->m_size + lump.m_size;
00524
00525 this->clearData ();
00526 this->m_data = temp;
00527 this->m_size = length;
00528 }
00529 }
00530
00531 return *this;
00532 }
00533
00547 Lump Lump::operator+ (const Lump &lump) const throw (std::bad_alloc, std::range_error)
00548 {
00549 Lump temp;
00550 pointer buffer;
00551
00552
00553 if ((MAX_SIZE - this->m_size) < lump.m_size)
00554 {
00555 std::ostringstream str;
00556 str << "Throwing std::range_error in Lump operator+ at " << __FILE__ ":" << __LINE__ << " because the new Lump size is too large. this=" << (reinterpret_cast<size_t> (this));
00557 std::string string (str.str ());
00558 EventLog::printLine (string);
00559 throw (std::range_error (exceptionString ("New size too large in Lump::operator+().", __FILE__, __LINE__)));
00560 }
00561
00562
00563 if ((this->m_size == 0) && (lump.m_size != 0))
00564 {
00565 temp = lump;
00566 temp.m_name = this->m_name;
00567 }
00568
00569
00570 else if ((this->m_size != 0) && (lump.m_size == 0))
00571 {
00572 temp = *this;
00573 }
00574
00575
00576 else if ((this->m_size != 0) && (lump.m_size != 0))
00577 {
00578 try
00579 {
00580 buffer = new value_type[this->m_size + lump.m_size];
00581 }
00582 catch (std::bad_alloc &e)
00583 {
00584 std::ostringstream str;
00585 str << "Caught std::bad_alloc in Lump operator+ at " << __FILE__ ":" << __LINE__ << ". this=" << (reinterpret_cast<size_t> (this));
00586 std::string string (str.str ());
00587 EventLog::printLine (string);
00588 throw (e);
00589 }
00590
00591 std::memcpy (buffer, this->m_data, this->m_size);
00592 std::memcpy (&buffer[this->m_size], lump.m_data, lump.m_size);
00593
00594 temp.m_data = buffer;
00595 temp.m_size = this->m_size + lump.m_size;
00596 temp.m_name = this->m_name;
00597 }
00598
00599 return temp;
00600 }
00601
00613 bool Lump::operator== (const Lump &lump) const throw ()
00614 {
00615 return (this->m_size == lump.m_size) && (this->m_name == lump.m_name) && (std::memcmp (this->m_data, lump.m_data, this->m_size) == 0);
00616 }
00617
00627 bool Lump::operator!= (const Lump &lump) const throw ()
00628 {
00629 return (this->m_size != lump.m_size) || (this->m_name != lump.m_name) || (std::memcmp (this->m_data, lump.m_data, this->m_size) != 0);
00630 }
00631
00639 Lump::operator std::string& (void) throw ()
00640 {
00641 return this->m_name;
00642 }
00643
00651 Lump::operator size_t (void) throw ()
00652 {
00653 return this->m_size;
00654 }
00655
00664 Lump::operator bool (void) throw ()
00665 {
00666 return this->m_size > 0;
00667 }
00668
00679 Lump::reference Lump::operator[] (size_t offset) throw ()
00680 {
00681 return (this->m_data)[offset];
00682 }
00683
00695 Lump::const_reference Lump::operator[] (size_t offset) const throw ()
00696 {
00697 return (this->m_data)[offset];
00698 }
00699
00713 Lump::reference Lump::at (size_t offset) throw (std::out_of_range)
00714 {
00715 if (offset >= this->m_size)
00716 {
00717 std::ostringstream str;
00718 str << "Throwing std::out_of_range in Lump::at() at " << __FILE__ ":" << __LINE__ << " because the index is out of bounds. this=" << (reinterpret_cast<size_t> (this));
00719 std::string string (str.str ());
00720 EventLog::printLine (string);
00721 throw (std::out_of_range (exceptionString ("Index out of bounds in Lump::at().", __FILE__, __LINE__)));
00722 }
00723 return (this->m_data)[offset];
00724 }
00725
00739 Lump::const_reference Lump::at (size_t offset) const throw (std::out_of_range)
00740 {
00741 if (offset >= this->m_size)
00742 {
00743 std::ostringstream str;
00744 str << "Throwing std::out_of_range in Lump::at() at " << __FILE__ ":" << __LINE__ << " because the index is out of bounds. this=" << (reinterpret_cast<size_t> (this));
00745 std::string string (str.str ());
00746 EventLog::printLine (string);
00747 throw (std::out_of_range (exceptionString ("Index out of bounds in Lump::at() const.", __FILE__, __LINE__)));
00748 }
00749 return (this->m_data)[offset];
00750 }
00751
00770 bool Lump::append (const_pointer data, size_t length) throw (std::invalid_argument, std::range_error)
00771 {
00772 pointer temp;
00773 size_t newsize;
00774
00775
00776
00777 if ((MAX_SIZE - this->m_size) < length)
00778 {
00779 std::ostringstream str;
00780 str << "Throwing std::out_of_range in Lump::append() at " << __FILE__ ":" << __LINE__ << " because the new size is too large. this=" << (reinterpret_cast<size_t> (this));
00781 std::string string (str.str ());
00782 EventLog::printLine (string);
00783 throw (std::range_error (exceptionString ("New size too large in Lump::append().", __FILE__, __LINE__)));
00784 }
00785
00786
00787 if (length > 0)
00788 {
00789
00790
00791 if (data == NULL)
00792 {
00793 std::ostringstream str;
00794 str << "Throwing std::invalid_argument in Lump::append() at " << __FILE__ ":" << __LINE__ << " because a null pointer was passed in. this=" << (reinterpret_cast<size_t> (this));
00795 std::string string (str.str ());
00796 EventLog::printLine (string);
00797 throw (std::invalid_argument (exceptionString ("Null pointer passed to Lump::append().", __FILE__, __LINE__)));
00798 }
00799
00800
00801 #if defined WINDOWS
00802 if (IsBadReadPtr (data, length))
00803 {
00804 std::ostringstream str;
00805 str << "Throwing std::invalid_argument in Lump::append() at " << __FILE__ ":" << __LINE__ << " because an invalid pointer was passed in. this=" << (reinterpret_cast<size_t> (this));
00806 std::string string (str.str ());
00807 EventLog::printLine (string);
00808 throw (std::invalid_argument ( exceptionString ("Invalid pointer passed to Lump constructor.", __FILE__, __LINE__)));
00809 }
00810 #endif
00811
00812
00813 newsize = this->m_size + length;
00814 try
00815 {
00816 temp = new value_type[newsize];
00817 }
00818 catch (std::bad_alloc &e)
00819 {
00820 std::ostringstream str;
00821 str << "Caught std::bad_alloc in Lump::append() at " << __FILE__ ":" << __LINE__ << ". this=" << (reinterpret_cast<size_t> (this));
00822 std::string string (str.str ());
00823 EventLog::printLine (string);
00824 return false;
00825 }
00826 std::memcpy (temp, this->m_data, this->m_size);
00827 std::memcpy (&temp[this->m_size], data, length);
00828
00829
00830 this->clearData ();
00831 this->m_data = temp;
00832 this->m_size = newsize;
00833 }
00834
00835 return true;
00836 }
00837
00852 bool Lump::append (const_iterator &first, const_iterator &last) throw (std::range_error)
00853 {
00854 try
00855 {
00856 return this->append (&(*first), std::distance<const_iterator>(first, last));
00857 }
00858
00859
00860 catch (std::invalid_argument &e)
00861 {
00862 }
00863 return false;
00864 }
00865
00885 bool Lump::assign (const_pointer data, size_t length) throw (std::invalid_argument, std::bad_alloc)
00886 {
00887 pointer temp;
00888
00889
00890 if (data == NULL && length > 0)
00891 {
00892 std::ostringstream str;
00893 str << "Throwing std::invalid_argument in Lump::assign() at " << __FILE__ ":" << __LINE__ << " because a null pointer was passed in. this=" << (reinterpret_cast<size_t> (this));
00894 std::string string (str.str ());
00895 EventLog::printLine (string);
00896 throw (std::invalid_argument (exceptionString ("Null pointer passed to Lump::assign().", __FILE__, __LINE__)));
00897 }
00898
00899
00900 #if defined WINDOWS
00901 if (IsBadReadPtr (data, length))
00902 {
00903 std::ostringstream str;
00904 str << "Throwing std::invalid_argument in Lump::assign() at " << __FILE__ ":" << __LINE__ << " because an invalid pointer was passed in. this=" << (reinterpret_cast<size_t> (this));
00905 std::string string (str.str ());
00906 EventLog::printLine (string);
00907 throw (std::invalid_argument ( exceptionString ("Invalid pointer passed to Lump constructor.", __FILE__, __LINE__)));
00908 }
00909 #endif
00910
00911
00912 if (length == 0)
00913 {
00914 return this->clearData ();
00915 }
00916
00917
00918
00919 temp = new value_type[length];
00920 std::memcpy (temp, data, length);
00921
00922 this->clearData ();
00923 this->m_data = temp;
00924 this->m_size = length;
00925
00926 return true;
00927 }
00928
00943 bool Lump::assign (const_iterator &first, const_iterator &last) throw (std::bad_alloc)
00944 {
00945 try
00946 {
00947 return this->assign (&(*first), std::distance<const_iterator>(first, last));
00948 }
00949
00950
00951 catch (std::invalid_argument &e)
00952 {
00953 }
00954 return false;
00955 }
00956
00964 std::string Lump::getName (void) const throw ()
00965 {
00966 return this->m_name;
00967 }
00968
00978 bool Lump::setName (const std::string &name) throw ()
00979 {
00980
00981
00982 this->m_name = name.substr (0, 8);
00983 return true;
00984 }
00985
00993 Lump::const_pointer Lump::getData (void) throw ()
00994 {
00995 return this->m_data;
00996 }
00997
01013 bool Lump::grow (size_t amount) throw (std::range_error, std::bad_alloc)
01014 {
01015
01016
01017 if ((MAX_SIZE - this->m_size) < amount)
01018 {
01019 std::ostringstream str;
01020 str << "Throwing std::range_error in Lump::grow() at " << __FILE__ ":" << __LINE__ << " because the new size is too large. this=" << (reinterpret_cast<size_t> (this));
01021 std::string string (str.str ());
01022 EventLog::printLine (string);
01023 throw (std::range_error (exceptionString ("New size too large in Lump::grow().", __FILE__, __LINE__)));
01024 }
01025
01026
01027 return this->setSize (this->m_size + amount);
01028 }
01029
01044 bool Lump::shrink (size_t amount) throw (std::range_error, std::bad_alloc)
01045 {
01046
01047
01048 if (this->m_size < amount)
01049 {
01050 std::ostringstream str;
01051 str << "Throwing std::range_error in Lump::shrink() at " << __FILE__ ":" << __LINE__ << " because the new size is negative. this=" << (reinterpret_cast<size_t> (this));
01052 std::string string (str.str ());
01053 EventLog::printLine (string);
01054 throw (std::range_error (exceptionString ("New size too small in Lump::shrink().", __FILE__, __LINE__)));
01055 }
01056
01057
01058 return this->setSize (this->m_size - amount);
01059 }
01060
01074 bool Lump::setSize (size_t length) throw (std::bad_alloc)
01075 {
01076 pointer temp;
01077
01078
01079 if (length == 0)
01080 {
01081 this->clearData ();
01082 }
01083
01084
01085 if (this->m_size != length)
01086 {
01087
01088
01089 try
01090 {
01091 temp = new value_type[length];
01092 }
01093 catch (std::bad_alloc &e)
01094 {
01095 std::ostringstream str;
01096 str << "Caught std::bad_alloc in Lump::setSize() at " << __FILE__ ":" << __LINE__ << ". this=" << (reinterpret_cast<size_t> (this));
01097 std::string string (str.str ());
01098 EventLog::printLine (string);
01099 this->m_data = NULL;
01100 throw (e);
01101 }
01102
01103
01104 if (length < this->m_size)
01105 {
01106 std::ostringstream str;
01107 str << "Caught std::bad_alloc in Lump::setSize() at " << __FILE__ ":" << __LINE__ << ". this=" << (reinterpret_cast<size_t> (this));
01108 std::string string (str.str ());
01109 EventLog::printLine (string);
01110 std::memcpy (temp, this->m_data, length);
01111 }
01112
01113
01114 else
01115 {
01116 std::memcpy (temp, this->m_data, this->m_size);
01117 std::memset (&temp[this->m_size], 0, length - this->m_size);
01118 }
01119
01120
01121 this->clearData ();
01122 this->m_data = temp;
01123 this->m_size = length;
01124 }
01125
01126 return true;
01127 }
01128
01144 bool Lump::readFromFile (std::ifstream &file) throw (std::bad_alloc)
01145 {
01146 const size_t buffer_length = 32 * 1024;
01147 value_type buffer[buffer_length];
01148 Lump temp;
01149
01150
01151
01152
01153
01154
01155
01156 if (file.is_open ())
01157 {
01158 while (file.good ())
01159 {
01160 file.read (reinterpret_cast<char *> (buffer), buffer_length);
01161 temp.append (buffer, file.gcount ());
01162 }
01163 }
01164 return this->assign (temp.m_data, temp.m_size);
01165 }
01166
01180 bool Lump::readFromFile (const std::string &filename) throw ()
01181 {
01182 bool result;
01183 std::ifstream in (filename.c_str (), std::ios::binary | std::ios::in);
01184 try
01185 {
01186 result = this->readFromFile (in);
01187 }
01188 catch (std::bad_alloc &e)
01189 {
01190 std::ostringstream str;
01191 str << "Caught std::bad_alloc in Lump::readFromFile() at " << __FILE__ ":" << __LINE__ << ". this=" << (reinterpret_cast<size_t> (this));
01192 std::string string (str.str ());
01193 EventLog::printLine (string);
01194 result = false;
01195 }
01196 return result;
01197 }
01198
01216 bool Lump::writeToFile (std::ofstream &file) const throw ()
01217 {
01218
01219
01220 if (file.is_open () && file.good ())
01221 {
01222 file.write (reinterpret_cast<char *> (this->m_data), this->m_size);
01223 }
01224
01225 else
01226 {
01227 return false;
01228 }
01229
01230 file.flush ();
01231 return true;
01232 }
01233
01246 bool Lump::writeToFile (const std::string &filename) const throw ()
01247 {
01248 std::ofstream out (filename.c_str (), std::ios::binary | std::ios::out | std::ios::trunc);
01249 bool result = this->writeToFile (out);
01250 out.close ();
01251 return result;
01252 }
01253
01270 bool Lump::readFromStream (std::istream &stream, size_t bytes) throw ()
01271 {
01272 value_type *temp = NULL;
01273 if (stream)
01274 {
01275 try
01276 {
01277 temp = new value_type[bytes];
01278 stream.read (reinterpret_cast<char *> (temp), bytes);
01279 }
01280 catch (std::bad_alloc e)
01281 {
01282 std::ostringstream str;
01283 str << "Caught std::bad_alloc in Lump::readFromStream() at " << __FILE__ ":" << __LINE__ << ". this=" << (reinterpret_cast<size_t> (this));
01284 std::string string (str.str ());
01285 EventLog::printLine (string);
01286 return false;
01287 }
01288 catch (...)
01289 {
01290 std::ostringstream str;
01291 str << "Caught unknown exception in Lump::readFromStream() at " << __FILE__ ":" << __LINE__ << ". this=" << (reinterpret_cast<size_t> (this));
01292 std::string string (str.str ());
01293 EventLog::printLine (string);
01294 delete [] temp;
01295 return false;
01296 }
01297 delete [] this->m_data;
01298 this->m_data = temp;
01299 this->m_size = bytes;
01300 }
01301 else
01302 {
01303 return false;
01304 }
01305 return true;
01306 }
01307
01317 bool Lump::writeToStream (std::ostream &stream) const throw ()
01318 {
01319 if (stream)
01320 {
01321 try
01322 {
01323 stream.write (reinterpret_cast<char *> (this->m_data), this->m_size);
01324 }
01325 catch (...)
01326 {
01327 std::ostringstream str;
01328 str << "Caught unknown exception in Lump::writeToStream() at " << __FILE__ ":" << __LINE__ << ". this=" << (reinterpret_cast<size_t> (this));
01329 std::string string (str.str ());
01330 EventLog::printLine (string);
01331 return false;
01332 }
01333 }
01334 else
01335 {
01336 return false;
01337 }
01338 return true;
01339 }
01340
01355 bool Lump::writeToTextStream (std::ostream &stream, size_t wrap, char nonprint) const throw ()
01356 {
01357 const_iterator iter = this->begin ();
01358 const_iterator iter_end = this->end ();
01359 size_t line = 0;
01360
01361
01362 if (stream)
01363 {
01364
01365
01366 for (; iter != iter_end; ++iter, ++line)
01367 {
01368 if ((line == wrap) && (wrap != 0))
01369 {
01370 line = 0;
01371 stream << '\n';
01372 }
01373 stream << (std::isprint (*iter) ? *iter : nonprint);
01374 }
01375 }
01376 else
01377 {
01378 return false;
01379 }
01380 return true;
01381 }
01382
01390 bool Lump::clear (void) throw ()
01391 {
01392 this->clearData ();
01393 this->clearName ();
01394 return true;
01395 }
01396
01404 bool Lump::clearData (void) throw ()
01405 {
01406 if (this->m_size > 0)
01407 {
01408 delete [] this->m_data;
01409 this->m_data = NULL;
01410 this->m_size = 0;
01411 }
01412 return true;
01413 }
01414
01422 bool Lump::clearName (void) throw ()
01423 {
01424 this->m_name.clear ();
01425 return true;
01426 }
01427
01435 bool Lump::empty (void) const throw ()
01436 {
01437 return this->m_size == 0;
01438 }
01439
01447 size_t Lump::size (void) const throw ()
01448 {
01449 return this->m_size;
01450 }
01451
01461 Doomwad::byte Lump::getByte (size_t index) const throw (std::range_error)
01462 {
01463 if (index + sizeof (byte) - 1 >= m_size)
01464 {
01465 std::ostringstream str;
01466 str << "Throwing std::range_error in Lump::getByte() at " << __FILE__ ":" << __LINE__ << " because the index is out of bounds. this=" << (reinterpret_cast<size_t> (this));
01467 std::string string (str.str ());
01468 EventLog::printLine (string);
01469 throw (std::range_error (exceptionString ("Index out of bounds in Lump::getByte().", __FILE__, __LINE__)));
01470 }
01471 return *(reinterpret_cast<byte *> (&this->m_data[index]));
01472 }
01473
01483 word Lump::getWord (size_t index) const throw (std::range_error)
01484 {
01485 if (index + sizeof (word) - 1 >= m_size)
01486 {
01487 std::ostringstream str;
01488 str << "Throwing std::range_error in Lump::getWord() at " << __FILE__ ":" << __LINE__ << " because the index is out of bounds. this=" << (reinterpret_cast<size_t> (this));
01489 std::string string (str.str ());
01490 EventLog::printLine (string);
01491 throw (std::range_error (exceptionString ("Index out of bounds in Lump::getWord().", __FILE__, __LINE__)));
01492 }
01493 return *(reinterpret_cast<word *> (&this->m_data[index]));
01494 }
01495
01505 dword Lump::getDWord (size_t index) const throw (std::range_error)
01506 {
01507 if (index + sizeof (dword) - 1 >= m_size)
01508 {
01509 std::ostringstream str;
01510 str << "Throwing std::range_error in Lump::getDWord() at " << __FILE__ ":" << __LINE__ << " because the index is out of bounds. this=" << (reinterpret_cast<size_t> (this));
01511 std::string string (str.str ());
01512 EventLog::printLine (string);
01513 throw (std::range_error (exceptionString ("Index out of bounds in Lump::getDWord().", __FILE__, __LINE__)));
01514 }
01515 return *(reinterpret_cast<dword *> (&this->m_data[index]));
01516 }
01517
01527 qword Lump::getQWord (size_t index) const throw (std::range_error)
01528 {
01529 if (index + sizeof (qword) - 1 >= m_size)
01530 {
01531 std::ostringstream str;
01532 str << "Throwing std::range_error in Lump::getQWord() at " << __FILE__ ":" << __LINE__ << " because the index is out of bounds. this=" << (reinterpret_cast<size_t> (this));
01533 std::string string (str.str ());
01534 EventLog::printLine (string);
01535 throw (std::range_error (exceptionString ("Index out of bounds in Lump::getQWord().", __FILE__, __LINE__)));
01536 }
01537 return *(reinterpret_cast<qword *> (&this->m_data[index]));
01538 }
01539
01549 int8 Lump::getInt8 (size_t index) const throw (std::range_error)
01550 {
01551 if (index + sizeof (int8) - 1 >= m_size)
01552 {
01553 std::ostringstream str;
01554 str << "Throwing std::range_error in Lump::getInt8() at " << __FILE__ ":" << __LINE__ << " because the index is out of bounds. this=" << (reinterpret_cast<size_t> (this));
01555 std::string string (str.str ());
01556 EventLog::printLine (string);
01557 throw (std::range_error (exceptionString ("Index out of bounds in Lump::getInt8().", __FILE__, __LINE__)));
01558 }
01559 return *(reinterpret_cast<int8 *> (&this->m_data[index]));
01560 }
01561
01571 uint8 Lump::getUInt8 (size_t index) const throw (std::range_error)
01572 {
01573 if (index + sizeof (uint8) - 1 >= m_size)
01574 {
01575 std::ostringstream str;
01576 str << "Throwing std::range_error in Lump::getUInt8() at " << __FILE__ ":" << __LINE__ << " because the index is out of bounds. this=" << (reinterpret_cast<size_t> (this));
01577 std::string string (str.str ());
01578 EventLog::printLine (string);
01579 throw (std::range_error (exceptionString ("Index out of bounds in Lump::getUInt8().", __FILE__, __LINE__)));
01580 }
01581 return *(reinterpret_cast<uint8 *> (&this->m_data[index]));
01582 }
01583
01593 int16 Lump::getInt16 (size_t index) const throw (std::range_error)
01594 {
01595 if (index + sizeof (int16) - 1 >= m_size)
01596 {
01597 std::ostringstream str;
01598 str << "Throwing std::range_error in Lump::getInt16() at " << __FILE__ ":" << __LINE__ << " because the index is out of bounds. this=" << (reinterpret_cast<size_t> (this));
01599 std::string string (str.str ());
01600 EventLog::printLine (string);
01601 throw (std::range_error (exceptionString ("Index out of bounds in Lump::getInt16().", __FILE__, __LINE__)));
01602 }
01603 return *(reinterpret_cast<int16 *> (&this->m_data[index]));
01604 }
01605
01615 uint16 Lump::getUInt16 (size_t index) const throw (std::range_error)
01616 {
01617 if (index + sizeof (uint16) - 1 >= m_size)
01618 {
01619 std::ostringstream str;
01620 str << "Throwing std::range_error in Lump::getUInt16() at " << __FILE__ ":" << __LINE__ << " because the index is out of bounds. this=" << (reinterpret_cast<size_t> (this));
01621 std::string string (str.str ());
01622 EventLog::printLine (string);
01623 throw (std::range_error (exceptionString ("Index out of bounds in Lump::getUInt16().", __FILE__, __LINE__)));
01624 }
01625 return *(reinterpret_cast<uint16 *> (&this->m_data[index]));
01626 }
01627
01637 int32 Lump::getInt32 (size_t index) const throw (std::range_error)
01638 {
01639 if (index + sizeof (int32) - 1 >= m_size)
01640 {
01641 std::ostringstream str;
01642 str << "Throwing std::range_error in Lump::getInt32() at " << __FILE__ ":" << __LINE__ << " because the index is out of bounds. this=" << (reinterpret_cast<size_t> (this));
01643 std::string string (str.str ());
01644 EventLog::printLine (string);
01645 throw (std::range_error (exceptionString ("Index out of bounds in Lump::getInt32().", __FILE__, __LINE__)));
01646 }
01647 return *(reinterpret_cast<int32 *> (&this->m_data[index]));
01648 }
01649
01659 uint32 Lump::getUInt32 (size_t index) const throw (std::range_error)
01660 {
01661 if (index + sizeof (uint32) - 1 >= m_size)
01662 {
01663 std::ostringstream str;
01664 str << "Throwing std::range_error in Lump::getUInt32() at " << __FILE__ ":" << __LINE__ << " because the index is out of bounds. this=" << (reinterpret_cast<size_t> (this));
01665 std::string string (str.str ());
01666 EventLog::printLine (string);
01667 throw (std::range_error (exceptionString ("Index out of bounds in Lump::getUInt32().", __FILE__, __LINE__)));
01668 }
01669 return *(reinterpret_cast<uint32 *> (&this->m_data[index]));
01670 }
01671
01681 int64 Lump::getInt64 (size_t index) const throw (std::range_error)
01682 {
01683 if (index + sizeof (int64) - 1 >= m_size)
01684 {
01685 std::ostringstream str;
01686 str << "Throwing std::range_error in Lump::getInt64() at " << __FILE__ ":" << __LINE__ << " because the index is out of bounds. this=" << (reinterpret_cast<size_t> (this));
01687 std::string string (str.str ());
01688 EventLog::printLine (string);
01689 throw (std::range_error (exceptionString ("Index out of bounds in Lump::getInt64().", __FILE__, __LINE__)));
01690 }
01691 return *(reinterpret_cast<int64 *> (&this->m_data[index]));
01692 }
01693
01703 uint64 Lump::getUInt64 (size_t index) const throw (std::range_error)
01704 {
01705 if (index + sizeof (uint64) - 1 >= m_size)
01706 {
01707 std::ostringstream str;
01708 str << "Throwing std::range_error in Lump::getUInt64() at " << __FILE__ ":" << __LINE__ << " because the index is out of bounds. this=" << (reinterpret_cast<size_t> (this));
01709 std::string string (str.str ());
01710 EventLog::printLine (string);
01711 throw (std::range_error (exceptionString ("Index out of bounds in Lump::getUInt64().", __FILE__, __LINE__)));
01712 }
01713 return *(reinterpret_cast<uint64 *> (&this->m_data[index]));
01714 }
01715
01726 bool Lump::setByte (byte n, size_t index) throw (std::range_error)
01727 {
01728 if (index + sizeof (byte) - 1 >= m_size)
01729 {
01730 std::ostringstream str;
01731 str << "Throwing std::range_error in Lump::setByte() at " << __FILE__ ":" << __LINE__ << " because the index is out of bounds. this=" << (reinterpret_cast<size_t> (this));
01732 std::string string (str.str ());
01733 EventLog::printLine (string);
01734 throw (std::range_error (exceptionString ("Index out of bounds in Lump::setByte().", __FILE__, __LINE__)));
01735 }
01736 *(reinterpret_cast<byte *> (&this->m_data[index])) = n;
01737 return true;
01738 }
01739
01750 bool Lump::setWord (word n, size_t index) throw (std::range_error)
01751 {
01752 if (index + sizeof (word) - 1 >= m_size)
01753 {
01754 std::ostringstream str;
01755 str << "Throwing std::range_error in Lump::setWord() at " << __FILE__ ":" << __LINE__ << " because the index is out of bounds. this=" << (reinterpret_cast<size_t> (this));
01756 std::string string (str.str ());
01757 EventLog::printLine (string);
01758 throw (std::range_error (exceptionString ("Index out of bounds in Lump::setWord().", __FILE__, __LINE__)));
01759 }
01760 *(reinterpret_cast<word *> (&this->m_data[index])) = n;
01761 return true;
01762 }
01763
01774 bool Lump::setDWord (dword n, size_t index) throw (std::range_error)
01775 {
01776 if (index + sizeof (dword) - 1 >= m_size)
01777 {
01778 std::ostringstream str;
01779 str << "Throwing std::range_error in Lump::setDWord() at " << __FILE__ ":" << __LINE__ << " because the index is out of bounds. this=" << (reinterpret_cast<size_t> (this));
01780 std::string string (str.str ());
01781 EventLog::printLine (string);
01782 throw (std::range_error (exceptionString ("Index out of bounds in Lump::setDWord().", __FILE__, __LINE__)));
01783 }
01784 *(reinterpret_cast<dword *> (&this->m_data[index])) = n;
01785 return true;
01786 }
01787
01798 bool Lump::setQWord (qword n, size_t index) throw (std::range_error)
01799 {
01800 if (index + sizeof (qword) - 1 >= m_size)
01801 {
01802 std::ostringstream str;
01803 str << "Throwing std::range_error in Lump::setQWord() at " << __FILE__ ":" << __LINE__ << " because the index is out of bounds. this=" << (reinterpret_cast<size_t> (this));
01804 std::string string (str.str ());
01805 EventLog::printLine (string);
01806 throw (std::range_error (exceptionString ("Index out of bounds in Lump::setQWord().", __FILE__, __LINE__)));
01807 }
01808 *(reinterpret_cast<qword *> (&this->m_data[index])) = n;
01809 return true;
01810 }
01811
01822 bool Lump::setInt8 (int8 n, size_t index) throw (std::range_error)
01823 {
01824 if (index + sizeof (int8) - 1 >= m_size)
01825 {
01826 std::ostringstream str;
01827 str << "Throwing std::range_error in Lump::setInt8() at " << __FILE__ ":" << __LINE__ << " because the index is out of bounds. this=" << (reinterpret_cast<size_t> (this));
01828 std::string string (str.str ());
01829 EventLog::printLine (string);
01830 throw (std::range_error (exceptionString ("Index out of bounds in Lump::setInt8().", __FILE__, __LINE__)));
01831 }
01832 *(reinterpret_cast<int8 *> (&this->m_data[index])) = n;
01833 return true;
01834 }
01835
01846 bool Lump::setUInt8 (uint8 n, size_t index) throw (std::range_error)
01847 {
01848 if (index + sizeof (uint8) - 1 >= m_size)
01849 {
01850 std::ostringstream str;
01851 str << "Throwing std::range_error in Lump::setUInt8() at " << __FILE__ ":" << __LINE__ << " because the index is out of bounds. this=" << (reinterpret_cast<size_t> (this));
01852 std::string string (str.str ());
01853 EventLog::printLine (string);
01854 throw (std::range_error (exceptionString ("Index out of bounds in Lump::setUInt8().", __FILE__, __LINE__)));
01855 }
01856 *(reinterpret_cast<uint8 *> (&this->m_data[index])) = n;
01857 return true;
01858 }
01859
01870 bool Lump::setInt16 (int16 n, size_t index) throw (std::range_error)
01871 {
01872 if (index + sizeof (int16) - 1 >= m_size)
01873 {
01874 std::ostringstream str;
01875 str << "Throwing std::range_error in Lump::setInt16() at " << __FILE__ ":" << __LINE__ << " because the index is out of bounds. this=" << (reinterpret_cast<size_t> (this));
01876 std::string string (str.str ());
01877 EventLog::printLine (string);
01878 throw (std::range_error (exceptionString ("Index out of bounds in Lump::setInt16().", __FILE__, __LINE__)));
01879 }
01880 *(reinterpret_cast<int16 *> (&this->m_data[index])) = n;
01881 return true;
01882 }
01883
01894 bool Lump::setUInt16 (uint16 n, size_t index) throw (std::range_error)
01895 {
01896 if (index + sizeof (uint16) - 1 >= m_size)
01897 {
01898 std::ostringstream str;
01899 str << "Throwing std::range_error in Lump::setUInt16() at " << __FILE__ ":" << __LINE__ << " because the index is out of bounds. this=" << (reinterpret_cast<size_t> (this));
01900 std::string string (str.str ());
01901 EventLog::printLine (string);
01902 throw (std::range_error (exceptionString ("Index out of bounds in Lump::setUInt16().", __FILE__, __LINE__)));
01903 }
01904 *(reinterpret_cast<uint16 *> (&this->m_data[index])) = n;
01905 return true;
01906 }
01907
01918 bool Lump::setInt32 (int32 n, size_t index) throw (std::range_error)
01919 {
01920 if (index + sizeof (int32) - 1 >= m_size)
01921 {
01922 std::ostringstream str;
01923 str << "Throwing std::range_error in Lump::setInt32() at " << __FILE__ ":" << __LINE__ << " because the index is out of bounds. this=" << (reinterpret_cast<size_t> (this));
01924 std::string string (str.str ());
01925 EventLog::printLine (string);
01926 throw (std::range_error (exceptionString ("Index out of bounds in Lump::setInt32().", __FILE__, __LINE__)));
01927 }
01928 *(reinterpret_cast<int32 *> (&this->m_data[index])) = n;
01929 return true;
01930 }
01931
01942 bool Lump::setUInt32 (uint32 n, size_t index) throw (std::range_error)
01943 {
01944 if (index + sizeof (uint32) - 1 >= m_size)
01945 {
01946 std::ostringstream str;
01947 str << "Throwing std::range_error in Lump::setUInt32() at " << __FILE__ ":" << __LINE__ << " because the index is out of bounds. this=" << (reinterpret_cast<size_t> (this));
01948 std::string string (str.str ());
01949 EventLog::printLine (string);
01950 throw (std::range_error (exceptionString ("Index out of bounds in Lump::setUInt32().", __FILE__, __LINE__)));
01951 }
01952 *(reinterpret_cast<uint32 *> (&this->m_data[index])) = n;
01953 return true;
01954 }
01955
01966 bool Lump::setInt64 (int64 n, size_t index) throw (std::range_error)
01967 {
01968 if (index + sizeof (int64) - 1 >= m_size)
01969 {
01970 std::ostringstream str;
01971 str << "Throwing std::range_error in Lump::setInt64() at " << __FILE__ ":" << __LINE__ << " because the index is out of bounds. this=" << (reinterpret_cast<size_t> (this));
01972 std::string string (str.str ());
01973 EventLog::printLine (string);
01974 throw (std::range_error (exceptionString ("Index out of bounds in Lump::setInt64().", __FILE__, __LINE__)));
01975 }
01976 *(reinterpret_cast<int64 *> (&this->m_data[index])) = n;
01977 return true;
01978 }
01979
01990 bool Lump::setUInt64 (uint64 n, size_t index) throw (std::range_error)
01991 {
01992 if (index + sizeof (uint64) - 1 >= m_size)
01993 {
01994 std::ostringstream str;
01995 str << "Throwing std::range_error in Lump::setUInt64() at " << __FILE__ ":" << __LINE__ << " because the index is out of bounds. this=" << (reinterpret_cast<size_t> (this));
01996 std::string string (str.str ());
01997 EventLog::printLine (string);
01998 throw (std::range_error (exceptionString ("Index out of bounds in Lump::setUInt64().", __FILE__, __LINE__)));
01999 }
02000 *(reinterpret_cast<uint64 *> (&this->m_data[index])) = n;
02001 return true;
02002 }
02003
02013 std::string Lump::getString (size_t index) const throw (std::range_error)
02014 {
02015 if (index >= this->m_size)
02016 {
02017 std::ostringstream str;
02018 str << "Throwing std::range_error in Lump::getString() at " << __FILE__ ":" << __LINE__ << " because the index is out of bounds. this=" << (reinterpret_cast<size_t> (this));
02019 std::string string (str.str ());
02020 EventLog::printLine (string);
02021 throw (std::range_error (exceptionString ("Index out of bounds in Lump::getString().", __FILE__, __LINE__)));
02022 }
02023 size_t length = std::strlen (reinterpret_cast<const char *> (&this->m_data[index]));
02024 if (length > this->m_size - index) length = this->m_size - index;
02025 std::string str (reinterpret_cast<std::string::value_type *> (&(this->m_data[index])), length);
02026 return str;
02027 }
02028
02038 std::string Lump::getDString (size_t index) const throw (std::range_error)
02039 {
02040 std::ostringstream out;
02041 if (index + 8 >= this->m_size)
02042 {
02043 std::ostringstream str;
02044 str << "Throwing std::range_error in Lump::getDString() at " << __FILE__ ":" << __LINE__ << " because the index is out of bounds. this=" << (reinterpret_cast<size_t> (this));
02045 std::string string (str.str ());
02046 EventLog::printLine (string);
02047 throw (std::range_error (exceptionString ("Index out of bounds in Lump::getDString().", __FILE__, __LINE__)));
02048 }
02049 for (size_t i = index; i < index + 8 && this->m_data[i] != 0; ++i)
02050 {
02051 out << this->m_data[i];
02052 }
02053 out << '\0';
02054 return out.str ();
02055 }
02056
02067 bool Lump::setString (const std::string &str, size_t index) throw (std::range_error)
02068 {
02069 if (index + str.size () >= this->m_size)
02070 {
02071 std::ostringstream ostr;
02072 ostr << "Throwing std::range_error in Lump::setString() at " << __FILE__ ":" << __LINE__ << " because the index is out of bounds. this=" << (reinterpret_cast<size_t> (this));
02073 std::string string (ostr.str ());
02074 EventLog::printLine (string);
02075 throw (std::range_error (exceptionString ("Index out of bounds in Lump::setString().", __FILE__, __LINE__)));
02076 }
02077 std::strncpy (reinterpret_cast<char *> (&(this->m_data[index])), str.c_str (), this->m_size - index);
02078 return true;
02079 }
02080
02092 bool Lump::setDString (const std::string &str, size_t index) throw (std::range_error)
02093 {
02094 if (index + 8 >= this->m_size)
02095 {
02096 std::ostringstream ostr;
02097 ostr << "Throwing std::range_error in Lump::setDString() at " << __FILE__ ":" << __LINE__ << " because the index is out of bounds. this=" << (reinterpret_cast<size_t> (this));
02098 std::string string (ostr.str ());
02099 EventLog::printLine (string);
02100 throw (std::range_error (exceptionString ("Index out of bounds in Lump::setDString().", __FILE__, __LINE__)));
02101 }
02102
02103 size_t l = index;
02104 std::string::const_iterator s = str.begin ();
02105
02106 for (; l < index + 8 && s != str.end (); ++l, ++s)
02107 {
02108 this->m_data[l] = *s;
02109 }
02110 for (; l < index + 8; ++l)
02111 {
02112 this->m_data[l] = 0;
02113 }
02114
02115 return true;
02116 }