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

lump.cpp

Go to the documentation of this file.
00001 // libdoomwad: manipulates Doom wad files.
00002 // Copyright (C) 2005  John Gaughan
00003 //
00004 // This library is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser General Public
00006 // License as published by the Free Software Foundation; either
00007 // version 2.1 of the License, or (at your option) any later version.
00008 //
00009 // This library is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 // Lesser General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU Lesser General Public
00015 // License along with this library; if not, write to the Free Software
00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017 //
00018 // This library is distributed with the full text of the LGPL. Please see
00019 // the accompanying file named COPYING.
00020 // 
00021 // You may contact the author at john@johngaughan.net
00022 
00028 // C++ required.
00029 #if !defined __cplusplus
00030 #error C++ compiler required
00031 #endif
00032 
00033 // Windows header for memory functions
00034 #if defined WINDOWS
00035 #include <windows.h>
00036 #endif
00037 
00038 // C++ headers
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 // Doom headers
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 // Constants
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   // Set up member variables to default settings.
00093   this->m_size = 0;
00094   this->m_data = NULL;
00095 
00096   // If the source lump is not empty, copy data.
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   // Set up member variables to default settings.
00139   this->m_size = 0;
00140   this->m_data = NULL;
00141 
00142   if (length > 0)
00143   {
00144 
00145     // Attempt to allocate memory.
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     // Memory allocation succeeded. Assign buffer and size, set buffer to nulls.
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   // Set up member variables to default settings.
00191   this->m_size = 0;
00192   this->m_data = NULL;
00193 
00194   // Beer good, null pointer bad!
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   // Check for invalid pointer
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   // Only allocate if the size is positive
00217   if (length > 0)
00218   {
00219 
00220     // Attempt to allocate memory.
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     // Memory allocation succeeded. Assign buffer and size, copy buffer.
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   // Check for self-assignment
00400   if (this == &lump) return *this;
00401 
00402   // If the source is empty.
00403   if (lump.m_size == 0)
00404   {
00405     this->clearData ();
00406   }
00407 
00408   // Otherwise, it is not empty, copy the data.
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   // Copy the name last.
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   // Ensure the new size is not a size_t overflow
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   // Only append if there is data to append.
00482   if (lump.m_size > 0)
00483   {
00484 
00485     // If this object is empty, just copy the data over.
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     // Neither Lump empty. Concatenate.
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   // Ensure the new size is not a size_t overflow
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   // If this is empty but lump is not, assign lump.
00563   if ((this->m_size == 0) && (lump.m_size != 0))
00564   {
00565     temp = lump;
00566     temp.m_name = this->m_name;
00567   }
00568 
00569   // If lump is empty but this is not, assign this.
00570   else if ((this->m_size != 0) && (lump.m_size == 0))
00571   {
00572     temp = *this;
00573   }
00574 
00575   // If neither is empty, concatenate.
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   // Ensure the new size is not a size_t overflow. Be careful when checking so
00776   // the "if" statement does not overflow either.
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   // If the new size is zero, do nothing
00787   if (length > 0)
00788   {
00789 
00790     // Hurry up and throw the damn exception
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     // Check for invalid pointer
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     // Allocate and copy memory
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     // Assign to this
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   // Should not happen
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   // Null pointer.
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   // Check for invalid pointer
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   // Clear data.
00912   if (length == 0)
00913   {
00914     return this->clearData ();
00915   }
00916 
00917   // Size is positive, pointer is not null. Create temporary buffer. Pass
00918   // bad_alloc exception through to calling process.
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   // Should not be possible
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   // 26 Nov 2004 (JTG): fixed bug with string overflow on 8 character strings.
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   // Check for range error.
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   // Call setSize() and do not handle bad_alloc: pass it through to caller.
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   // Check for range error.
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   // Call setSize() and do not handle bad_alloc: pass it through to caller.
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   // Check for zero size.
01079   if (length == 0)
01080   {
01081     this->clearData ();
01082   }
01083 
01084   // Check for same size.
01085   if (this->m_size != length)
01086   {
01087 
01088     // Try to allocate the new buffer.
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     // If the size is shrinking, only copy part of the buffer.
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     // If the size is growing, copy the whole buffer and pad with nulls.
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     // Reassign pointer and size.
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   // Not all istreams are random access, so we must read sequentially into a
01151   // buffer and append this buffer. 32kb chunks are realistically efficient for
01152   // wad lumps because they are generally not all that big. If a Linedef takes
01153   // 14 bytes, a 32kb buffer can store 2,340 Linedefs.
01154 
01155   // Only read if the stream is ready
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   // Only write if the stream is ready to accept output
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   // Only write if the stream is ready to accept output.
01362   if (stream)
01363   {
01364 
01365     // Print each character, substituting nonprinting characters.
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 }

Generated on Fri Jun 10 19:38:51 2005 for libdoomwad by  doxygen 1.4.0