00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "byte_formatter.h"
00016 #include "parser_bits.h"
00017 #include "string_manipulation.h"
00018
00019 #include <basis/functions.h>
00020 #include <structures/bit_vector.h>
00021 #include <structures/string_array.h>
00022
00023
00024
00025
00026 #undef LOG
00027 #ifdef DEBUG_BYTE_FORMAT
00028 #define LOG(s) printf("%s\n", astring(s).s())
00029 #else
00030 #define LOG(s) {}
00031 #endif
00032
00033 #define LINE_SIZE 80
00034
00035 using namespace basis;
00036 using namespace structures;
00037
00038 namespace textual {
00039
00040 void byte_formatter::print_char(abyte to_print, astring &out, char replace)
00041 {
00042 int temp = to_print % 128;
00043 if (!parser_bits::is_printable_ascii(to_print)) out += replace;
00044 else out += char(temp);
00045 }
00046
00047 void byte_formatter::print_chars(const abyte *to_print, int len, astring &out, char replace)
00048 {
00049 for (int i = 0; i < len; i++)
00050 print_char(to_print[i], out, replace);
00051 }
00052
00053 void byte_formatter::make_eight(basis::un_int num, astring &out)
00054 {
00055 basis::un_int thresh = 0x10000000;
00056 while (thresh >= 0x10) {
00057 if (num < thresh)
00058 out += '0';
00059 thresh >>= 4;
00060 }
00061 }
00062
00063 astring byte_formatter::text_dump(const abyte *location, basis::un_int length, basis::un_int label,
00064 const char *eol)
00065 {
00066 astring to_return;
00067 text_dump(to_return, location, length, label, eol);
00068 return to_return;
00069 }
00070
00071 void byte_formatter::text_dump(astring &output, const byte_array &to_dump, basis::un_int label,
00072 const char *eol)
00073 {
00074 text_dump(output, to_dump.observe(), to_dump.length(), label, eol);
00075 }
00076
00077 astring byte_formatter::text_dump(const byte_array &to_dump, basis::un_int label, const char *eol)
00078 {
00079 astring output;
00080 text_dump(output, to_dump.observe(), to_dump.length(), label, eol);
00081 return output;
00082 }
00083
00084
00085 void byte_formatter::text_dump(astring &to_return, const abyte *location, basis::un_int length,
00086 basis::un_int label, const char *eol)
00087 {
00088 to_return = "";
00089 int entry_size = 4;
00090 int preamble = 14;
00091
00092 basis::un_int entries_per_line = (LINE_SIZE - preamble) / entry_size;
00093
00094 for (basis::un_int i = 0; i < length; i += entries_per_line) {
00095 make_eight(i + label, to_return);
00096 to_return += astring(astring::SPRINTF, "%x", i + label) + astring(" | ");
00097 for (basis::un_int j = 0; j < entries_per_line; j++) {
00098 if (i + j >= length) {
00099
00100 to_return += " ";
00101 } else {
00102 int ord_of_current_char = *(location + i + j) & 0xFF;
00103 if (ord_of_current_char < 0x10) to_return += '0';
00104 to_return += astring(astring::SPRINTF, "%x", int(ord_of_current_char));
00105 to_return += ' ';
00106 }
00107 }
00108
00109 to_return += "| ";
00110 for (basis::un_int k = i; k < i + entries_per_line; k++) {
00111 if (k >= length) to_return += ' ';
00112
00113 else print_char(*(location + k), to_return);
00114 }
00115 to_return += astring(" |") + eol;
00116 }
00117 }
00118
00119 void byte_formatter::parse_dump(const astring &dumped_form, byte_array &bytes_found)
00120 {
00121 bytes_found.reset();
00122 string_array lines_found;
00123
00124 for (int i = 0; i < dumped_form.length(); i++) {
00125 int indy = dumped_form.find('\n', i);
00126
00127
00128 if (negative(indy)) {
00129
00130 if (i < dumped_form.length() - 1) {
00131
00132 lines_found += dumped_form.substring(i, dumped_form.length() - 1);
00133 }
00134 break;
00135 }
00136
00137
00138 lines_found += dumped_form.substring(i, indy - 1);
00139 i = indy + 1;
00140 }
00141
00142 for (int j = 0; j < lines_found.length(); j++) {
00143
00144
00145 astring &s = lines_found[j];
00146 int bar_one = s.find('|', 0);
00147 if (negative(bar_one)) continue;
00148
00149
00150 int bar_two = s.find('|', bar_one + 1);
00151 if (negative(bar_two)) continue;
00152 astring s2 = s.substring(bar_one + 1, bar_two - 1);
00153 byte_array this_part;
00154 string_to_bytes(s2, this_part);
00155 bytes_found += this_part;
00156 }
00157 }
00158
00160
00161 void byte_formatter::bytes_to_string(const abyte *to_convert, int length, astring &as_string,
00162 bool space_delimited)
00163 {
00164 if (!to_convert || !length) return;
00165 if (negative(length)) return;
00166 as_string = "";
00167
00168
00169 astring pattern("%02x");
00170 if (space_delimited) pattern += " ";
00171
00172
00173 for (int i = 0; i < length; i++)
00174 as_string += astring(astring::SPRINTF, pattern.s(), to_convert[i]);
00175 }
00176
00177
00178
00179 bool byte_formatter::in_hex_range(char to_check)
00180
00181 {
00182 return ( (to_check <= '9') && (to_check >= '0') )
00183 || ( (to_check <= 'f') && (to_check >= 'a') )
00184 || ( (to_check <= 'F') && (to_check >= 'A') );
00185 }
00186
00187 void byte_formatter::string_to_bytes(const char *to_convert, byte_array &as_array)
00188 {
00189 as_array.reset();
00190 const int len = int(strlen(to_convert));
00191
00192
00193 enum states { FINDING_HEX, IGNORING_JUNK };
00194 states state = IGNORING_JUNK;
00195
00196 int digits = 0;
00197 int accumulator = 0;
00198
00199
00200 for (int i = 0; i < len; i++) {
00201 switch (state) {
00202 case IGNORING_JUNK: {
00203 if (in_hex_range(to_convert[i])) {
00204 i--;
00205 state = FINDING_HEX;
00206 continue;
00207 }
00208
00209 break;
00210 }
00211 case FINDING_HEX: {
00212 if (digits >= 2) {
00213
00214 as_array += abyte(accumulator);
00215 accumulator = 0;
00216 digits = 0;
00217 i--;
00218 state = IGNORING_JUNK;
00219 continue;
00220 }
00221
00222
00223 accumulator <<= 4;
00224 digits++;
00225 accumulator += string_manipulation::char_to_hex(to_convert[i]);
00226
00227
00228 if (!in_hex_range(to_convert[i+1])) {
00229
00230 if (digits) {
00231
00232 digits = 2;
00233 continue;
00234 }
00235
00236 state = IGNORING_JUNK;
00237 continue;
00238 }
00239 break;
00240 }
00241 }
00242 }
00243 if (digits) {
00244
00245 as_array += abyte(accumulator);
00246 }
00247 }
00248
00249 void byte_formatter::bytes_to_string(const byte_array &to_convert, astring &as_string,
00250 bool space_delimited)
00251 {
00252 bytes_to_string(to_convert.observe(), to_convert.length(), as_string,
00253 space_delimited);
00254 }
00255
00256 void byte_formatter::string_to_bytes(const astring &to_convert, byte_array &as_array)
00257 { string_to_bytes(to_convert.s(), as_array); }
00258
00259 void byte_formatter::bytes_to_shifted_string(const byte_array &to_convert, astring &as_string)
00260 {
00261 #ifdef DEBUG_BYTE_FORMAT
00262 FUNCDEF("bytes_to_shifted_string");
00263 #endif
00264 bit_vector splitter(8 * to_convert.length(), to_convert.observe());
00265 int i;
00266 for (i = 0; i < splitter.bits(); i += 7) {
00267 abyte curr = 1;
00268 for (int j = i; j < i + 7; j++) {
00269 curr <<= 1;
00270 if (j < splitter.bits())
00271 curr |= abyte(splitter.on(j));
00272 }
00273 as_string += char(curr);
00274 }
00275 #ifdef DEBUG_BYTE_FORMAT
00276 LOG(a_sprintf("%d bytes comes out as %d char string.",
00277 to_convert.length(), as_string.length()).s());
00278 #endif
00279 }
00280
00281 void byte_formatter::shifted_string_to_bytes(const astring &to_convert, byte_array &as_array)
00282 {
00283 #ifdef DEBUG_BYTE_FORMAT
00284 FUNCDEF("shifted_string_to_bytes");
00285 #endif
00286 bit_vector accumulator;
00287
00288 for (int i = 0; i < to_convert.length(); i++) {
00289 abyte current = abyte(to_convert[i]) & 0x7F;
00290
00291 accumulator.resize(accumulator.bits() + 7);
00292
00293 for (int j = 0; j < 7; j++) {
00294
00295 current <<= 1;
00296 abyte set_here = current & 0x80;
00297
00298 accumulator.set_bit(i * 7 + j, bool(set_here));
00299 }
00300 }
00301
00302 int remainder = accumulator.bits() % 8;
00303 accumulator.resize(accumulator.bits() - remainder);
00304
00305
00306 #ifdef DEBUG_BYTE_FORMAT
00307
00308
00309 if (accumulator.bits() % 8)
00310 deadly_error("byte_formatter", func, "number of bits is erroneous.");
00311 #endif
00312
00313 const byte_array &accumref = accumulator;
00314 for (int q = 0; q < accumulator.bits() / 8; q++)
00315 as_array += accumref[q];
00316
00317 #ifdef DEBUG_BYTE_FORMAT
00318 LOG(a_sprintf("%d chars comes out as %d bytes.",
00319 to_convert.length(), as_array.length()).s());
00320 #endif
00321 }
00322
00323 }
00324