00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
00042
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