libs/EDocBFD/Section.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002 
00003    Copyright (C) 2007 Brendon Costa
00004 
00005    This code is free software; you can redistribute it and/or modify 
00006    it under the terms of the GNU General Public License as published by
00007    the Free Software Foundation; either version 2, or (at your option)
00008    any later version.
00009 
00010    This code is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013    GNU General Public License for more details.
00014 
00015    You should have received a copy of the GNU General Public License
00016    along with this code; see the file COPYING.  If not, write to
00017    the Free Software Foundation, 59 Temple Place - Suite 330,
00018    Boston, MA 02111-1307, USA.
00019 
00020 *******************************************************************************/
00021 #include "config.h"
00022 #include "EDocBFD/Section.h"
00023 
00024 #include "EDocBFD/exceptions.h"
00025 #include <bfd.h>
00026 
00027 
00028 #ifdef HAVE_STRING_H
00029    #include <string.h>
00030 #endif
00031 
00032 
00033 namespace EDocBFD
00034 {
00035    //===========================================================================
00036    Section::Section(bfd* abfd_in, asection* asect_in) :
00037       abfd(abfd_in),
00038       asect(asect_in),
00039       file_pos(0)
00040    {
00041       // @@@Brendon seems this is just used by get section size.
00042       //sectsize = bfd_get_section_size_before_reloc(asect);
00043       sectsize = bfd_section_size(bfd, asect);
00044    }
00045    //===========================================================================
00046    ssize_t Section::Write(unsigned char data)
00047    {
00048       return Write(&data, 1);
00049    }
00050    //===========================================================================
00051    ssize_t Section::Write(const void* data, size_t len)
00052    {
00053       if (len + file_pos > sectsize)
00054       {
00055          len = sectsize - file_pos;
00056       }
00057 
00058       if (len == 0)
00059       {
00060          EDOC_THROW_EXCEPTION(EDoc::EOFException, "End of section.", "");
00061       }
00062 
00063       if (!bfd_set_section_contents(abfd, asect, data, file_pos, len))
00064       {
00065          bfd_error_type error_code = bfd_get_error();
00066          EDOC_THROW_EXCEPTION(BFDException, bfd_errmsg(error_code), 
00067             "section name: " << asect->name 
00068             << ", file_pos: " << file_pos
00069             << ", len: " << len
00070             << ", sectsize: " << sectsize);
00071       }
00072       return len;
00073    }
00074    //===========================================================================
00075    std::string Section::Read(size_t max_size)
00076    {
00077       if (max_size == 0)
00078       {
00079          return "";
00080       }
00081 
00082       if (max_size == 0xFFFFFFFF)
00083       {
00084          max_size = sectsize;
00085       }
00086 
00087       if ((max_size + file_pos) > sectsize)
00088       {
00089          max_size = sectsize - file_pos;
00090       }
00091 
00092       char* sectbuf = new char[max_size + 1];
00093       memset(sectbuf, 0, max_size + 1);
00094 
00095       try
00096       {
00097          ssize_t result = Read(sectbuf, max_size);
00098 
00099          std::string ret(sectbuf, result);
00100          delete [] sectbuf;
00101          sectbuf = NULL;
00102          return ret;
00103       }
00104       catch(...)
00105       {
00106          delete [] sectbuf;
00107          sectbuf = NULL;
00108          throw;
00109       }
00110    }
00111    //===========================================================================
00112    ssize_t Section::Read(void* sectbuf, size_t max_size)
00113    {
00114       if (max_size == 0)
00115       {
00116          return 0;
00117       }
00118 
00119       if ((max_size + file_pos) > sectsize)
00120       {
00121          max_size = sectsize - file_pos;
00122       }
00123 
00124       if (max_size == 0)
00125       {
00126          EDOC_THROW_EXCEPTION(EDoc::EOFException, "End of section.", 
00127             "file_pos: " << file_pos 
00128             << ", sectsize: " << sectsize 
00129             << ", name: " << asect->name);
00130       }
00131 
00132       memset(sectbuf, 0, max_size + 1);
00133       if (!bfd_get_section_contents(abfd, asect, sectbuf, file_pos, max_size))
00134       {
00135          bfd_error_type error_code = bfd_get_error();
00136          EDOC_THROW_EXCEPTION(BFDException, bfd_errmsg(error_code), 
00137             "section name: " << asect->name 
00138             << ", file_pos: " << file_pos
00139             << ", max_size: " << max_size
00140             << ", sectsize: " << sectsize);
00141       }
00142 
00143       file_pos += max_size;
00144       return max_size;
00145    }
00146    //===========================================================================
00147    std::string Section::ReadEx(size_t max_size)
00148    {
00149       std::string ret = Read(max_size);
00150       if ((max_size != 0xFFFFFFFF) && (ret.size() != max_size))
00151       {
00152          EDOC_THROW_EXCEPTION(BFDException, "Insufficient data.", 
00153             "section name: " << asect->name 
00154             << ", file_pos: " << file_pos
00155             << ", max_size: " << max_size
00156             << ", sectsize: " << sectsize
00157             << ", data size: " << ret.size()
00158             << ", data: " << ret);
00159       }
00160       return ret;
00161    }
00162    //===========================================================================
00163    ssize_t Section::ReadEx(void* sectbuf, size_t max_size)
00164    {
00165       ssize_t ret = Read(sectbuf, max_size);
00166       if ((max_size != 0xFFFFFFFFUL) && (ret != (ssize_t)max_size))
00167       {
00168          EDOC_THROW_EXCEPTION(BFDException, "Insufficient data.", 
00169             "section name: " << asect->name 
00170             << ", file_pos: " << file_pos
00171             << ", max_size: " << max_size
00172             << ", sectsize: " << sectsize
00173             << ", data size: " << ret);
00174       }
00175       return ret;
00176    }
00177    //===========================================================================
00178 }
00179 

Generated on Tue Jan 20 18:26:07 2009 for EDoc-0.2.1 by  doxygen 1.5.1