00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef WIPAL_TOOL_HEXDUMP_HXX_
00024 # define WIPAL_TOOL_HEXDUMP_HXX_
00025
00026 #include <string>
00027 #include <sstream>
00028 #include <iomanip>
00029 #include <locale>
00030 #include <stdexcept>
00031 #include <cassert>
00032
00033 #include <wipal/tool/hexdump.hh>
00034
00035 namespace wpl
00036 {
00037
00038 namespace tool
00039 {
00040
00041 namespace fmt
00042 {
00043
00044
00045
00046
00047
00048 inline
00049 std::ostream&
00050 raw::begin(std::ostream& os) const
00051 {
00052 return os;
00053 }
00054
00055 inline
00056 std::ostream&
00057 raw::end(std::ostream& os) const
00058 {
00059 return os;
00060 }
00061
00062 inline
00063 std::ostream&
00064 raw::bold_begin(std::ostream& os) const
00065 {
00066 return os;
00067 }
00068
00069 inline
00070 std::ostream&
00071 raw::bold_end(std::ostream& os) const
00072 {
00073 return os;
00074 }
00075
00076 inline
00077 std::ostream&
00078 raw::encode(std::ostream& os, char c) const
00079 {
00080 return os << c;
00081 }
00082
00083
00084
00085
00086
00087 inline
00088 std::ostream&
00089 printable::encode(std::ostream& os, char c) const
00090 {
00091 return os << (std::isprint(c)? c: '.');
00092 }
00093
00094
00095
00096
00097
00098 inline
00099 std::ostream&
00100 html::begin(std::ostream& os) const
00101 {
00102 return os << "<pre>";
00103 }
00104
00105 inline
00106 std::ostream&
00107 html::end(std::ostream& os) const
00108 {
00109 return os << "</pre>";
00110 }
00111
00112 inline
00113 std::ostream&
00114 html::bold_begin(std::ostream& os) const
00115 {
00116 return os << "<b>";
00117 }
00118
00119 inline
00120 std::ostream&
00121 html::bold_end(std::ostream& os) const
00122 {
00123 return os << "</b>";
00124 }
00125
00126 inline
00127 std::ostream&
00128 html::encode(std::ostream& os, char c) const
00129 {
00130 if (std::isprint(c))
00131 switch (c)
00132 {
00133 case '<':
00134 return os << "<";
00135 case '>':
00136 return os << ">";
00137 default:
00138 return os << c;
00139 }
00140 else
00141 return os << '.';
00142 }
00143
00144 }
00145
00146 namespace hex
00147 {
00148
00149 template <class Params, class Format>
00150 std::string
00151 dump(const void* data, size_t len, const Format& f)
00152 {
00153 const unsigned char* const b = static_cast<const unsigned char*>
00154 (data);
00155 const unsigned char* const e = b + len;
00156
00157 std::ostringstream os;
00158
00159 f.begin(os) << std::hex << std::uppercase;
00160 for (const unsigned char* c = b; c < e; c += Params::lwidth)
00161 {
00162 if (Params::p_addr)
00163 f.bold_end(f.bold_begin(os)
00164 << std::setfill ('0') << std::setw (8) << (c - b));
00165 if (Params::p_hex)
00166 for (unsigned i = 0; i < Params::lwidth; i += Params::bwidth)
00167 {
00168 if (Params::p_addr or i)
00169 os << Params::bigsep;
00170 for (unsigned j = 0;
00171 j < Params::bwidth and c + i + j < e;
00172 ++j)
00173 {
00174 if (j)
00175 os << Params::smallsep;
00176 os << std::setfill ('0') << std::setw (2)
00177 << unsigned (c[i + j]);
00178 }
00179 if (Params::p_char)
00180 for (int j = Params::bwidth - 1;
00181 j >= 0 and c + i + j >= e;
00182 --j)
00183 {
00184 if (j)
00185 os << Params::smallsep;
00186 os << " ";
00187 }
00188 }
00189 if (Params::p_char)
00190 {
00191 f.bold_end(f.bold_begin(os << Params::bigsep)
00192 << Params::colsep);
00193 for (unsigned i = 0; i < Params::lwidth; ++i)
00194 f.encode(os, c + i < e ? c[i] : ' ');
00195 f.bold_end(f.bold_begin(os) << Params::colsep);
00196 }
00197 if (Params::endl)
00198 os << '\n';
00199 }
00200 f.end(os);
00201 return os.str();
00202 }
00203
00204 inline
00205 std::vector<uint8_t>
00206 read(const std::string& s)
00207 {
00208 typedef std::vector<uint8_t> vector;
00209
00210 if (s.size() % 2)
00211 throw std::invalid_argument ("Hexadecimal strings must have an even "
00212 "number of digits");
00213
00214 const size_t size = s.size() / 2;
00215
00216 vector res (size);
00217 std::string::const_iterator cur = s.begin();
00218
00219 for (size_t i = 0; i < size; ++i)
00220 {
00221 uint8_t t = 0;
00222
00223 for (size_t j = 0; j < 2; ++j, ++cur)
00224 {
00225 assert(cur != s.end());
00226 t = t << 4;
00227 if ('0' <= *cur and *cur <= '9')
00228 t |= *cur - '0';
00229 else if ('a' <= *cur and *cur <= 'f')
00230 t |= *cur - 'a' + 10;
00231 else if ('A' <= *cur and *cur <= 'F')
00232 t |= *cur - 'A' + 10;
00233 else
00234 throw std::invalid_argument ("Not an hexadecimal string");
00235 }
00236 res[i] = t;
00237 }
00238 assert(cur == s.end());
00239 return res;
00240 }
00241
00242 }
00243
00244 }
00245
00246 }
00247
00248 #endif // ! WIPAL_TOOL_HEXDUMP_HXX_