omemory.cpp 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216
  1. /*====================================================================*
  2. *
  3. * omemory.cpp - omemory class definition;
  4. *
  5. * static memory manipulation methods;
  6. *
  7. * Motley Tools by Charles Maier <cmaier@cmassoc.net>;
  8. * Copyright 2001-2006 by Charles Maier Associates;
  9. * Licensed under the Internet Software Consortium License;
  10. *
  11. *--------------------------------------------------------------------*/
  12. #ifndef oMEMORY_SOURCE
  13. #define oMEMORY_SOURCE
  14. /*====================================================================*
  15. * system header files;
  16. *--------------------------------------------------------------------*/
  17. #include <cstring>
  18. #include <cctype>
  19. /*====================================================================*
  20. * custom header files;
  21. *--------------------------------------------------------------------*/
  22. #include "../classes/omemory.hpp"
  23. #include "../classes/oerror.hpp"
  24. /*====================================================================*
  25. * custom header files;
  26. *--------------------------------------------------------------------*/
  27. char const omemory::digits [] = "0123456789ABCDEF";
  28. char omemory::bin_extender = '-';
  29. char omemory::dec_extender = '.';
  30. char omemory::hex_extender = ':';
  31. char omemory::chr_nonprint = '.';
  32. /*====================================================================*
  33. *
  34. * void endian (void * memory, size_t extent);
  35. *
  36. * reverse the order of bytes within a multi-byte memory region;
  37. * return no value;
  38. *
  39. * Motley Tools by Charles Maier <cmaier@cmassoc.net>;
  40. * Copyright 2001-2006 by Charles Maier Associates;
  41. * Licensed under the Internet Software Consortium License;
  42. *
  43. *--------------------------------------------------------------------*/
  44. void omemory::endian (void * memory, size_t extent)
  45. {
  46. register byte * byte1 = (byte *)(memory);
  47. register byte * byte2 = (byte *)(memory) + extent;
  48. while (byte1 < byte2)
  49. {
  50. register byte byte = *byte1;
  51. *byte1++ = *--byte2;
  52. *byte2 = byte;
  53. }
  54. return;
  55. }
  56. /*====================================================================*
  57. *
  58. * void swap (void * memory1, void * memory2, size_t extent);
  59. *
  60. * exchange the contents of one memory region with that of another;
  61. * return no value;
  62. *
  63. * Motley Tools by Charles Maier <cmaier@cmassoc.net>;
  64. * Copyright 2001-2006 by Charles Maier Associates;
  65. * Licensed under the Internet Software Consortium License;
  66. *
  67. *--------------------------------------------------------------------*/
  68. void omemory::swap (void * memory1, void * memory2, size_t extent)
  69. {
  70. register byte * byte1 = (byte *)(memory1);
  71. register byte * byte2 = (byte *)(memory2);
  72. if (memory1 != memory2) while (extent--)
  73. {
  74. byte byte = *byte1;
  75. *byte1++ = *byte2;
  76. *byte2++ = byte;
  77. }
  78. return;
  79. }
  80. /*====================================================================*
  81. *
  82. * void memtext (char const * string, char buffer [], size_t length);
  83. *
  84. * copy a NUL terminated string to a fixed-length buffer ensuring
  85. * that the buffered string is terminated; truncate and terminate
  86. * the buffered string on overflow; pad the buffer to length with
  87. * NUL on underflow;
  88. *
  89. * Motley Tools by Charles Maier <cmaier@cmassoc.net>;
  90. * Copyright 2001-2006 by Charles Maier Associates;
  91. * Licensed under the Internet Software Consortium License;
  92. *
  93. *--------------------------------------------------------------------*/
  94. void omemory::memtext (char const * string, char buffer [], size_t length)
  95. {
  96. if (length--)
  97. {
  98. while (length--)
  99. {
  100. if ((*buffer++ = *string) != 0)
  101. {
  102. string++;
  103. }
  104. }
  105. *buffer = (char)(0);
  106. }
  107. return;
  108. }
  109. /*====================================================================*
  110. *
  111. * void * encode (void * memory, void const * source, size_t extent);
  112. *
  113. * encode external memory with the contents of some source and
  114. * return the address of the next unencoded memory byte;
  115. *
  116. * use this method to pack a buffer with data stored in various
  117. * locations;
  118. *
  119. * Motley Tools by Charles Maier <cmaier@cmassoc.net>;
  120. * Copyright 2001-2006 by Charles Maier Associates;
  121. * Licensed under the Internet Software Consortium License;
  122. *
  123. *--------------------------------------------------------------------*/
  124. void * omemory::encode (void * memory, void const * source, size_t extent)
  125. {
  126. std::memcpy (memory, source, extent);
  127. return ((byte *)(memory) + extent);
  128. }
  129. /*====================================================================*
  130. *
  131. * void const * decode (void const * memory, void * target, size_t extent);
  132. *
  133. * decode external memory into the contents of some source; return
  134. * the address of the next undecoded memory byte;
  135. *
  136. * use this method to unpack a buffer into data stored in various
  137. * locations;
  138. *
  139. * Motley Tools by Charles Maier <cmaier@cmassoc.net>;
  140. * Copyright 2001-2006 by Charles Maier Associates;
  141. * Licensed under the Internet Software Consortium License;
  142. *
  143. *--------------------------------------------------------------------*/
  144. void const * omemory::decode (void const * memory, void * target, size_t extent)
  145. {
  146. std::memcpy (target, memory, extent);
  147. return ((byte *)(memory) + extent);
  148. }
  149. /*====================================================================*
  150. *
  151. * uint16_t checksum16 (void const * memory, size_t extent, uint16_t checksum);
  152. *
  153. * compute the 16 bit checksum of a memory region; region extent
  154. * is specified in bytes but truncated to a multiple of 2 bytes;
  155. * the checksum is the one's complement of the XOR of all 16 bit
  156. * words in the adjusted region;
  157. *
  158. * passing a checksum of 0 returns the computed checksum; passing
  159. * a computed checksum returns 0 only if the checksum is correct;
  160. *
  161. * Motley Tools by Charles Maier <cmaier@cmassoc.net>;
  162. * Copyright 2001-2006 by Charles Maier Associates;
  163. * Licensed under the Internet Software Consortium License;
  164. *
  165. *--------------------------------------------------------------------*/
  166. uint16_t omemory::checksum16 (void const * memory, register size_t extent, register uint16_t checksum)
  167. {
  168. register byte * offset = (byte *)(memory);
  169. while (extent >= sizeof (checksum))
  170. {
  171. checksum ^= *(uint16_t *)(offset);
  172. offset += sizeof (checksum);
  173. extent -= sizeof (checksum);
  174. }
  175. return (~checksum);
  176. }
  177. /*====================================================================*
  178. *
  179. * uint32_t checksum32 (void const * memory, size_t extent, uint32_t checksum);
  180. *
  181. * compute the 32 bit checksum of a memory region; region extent
  182. * is specified in bytes but truncated to a multiple of 4 bytes;
  183. * the checksum is the one's complement of the XOR of all 32 bit
  184. * words in the adjusted region;
  185. *
  186. * passing a checksum of 0 returns the computed checksum; passing
  187. * a computed checksum returns 0 only if the checksum is correct;
  188. *
  189. * Motley Tools by Charles Maier <cmaier@cmassoc.net>;
  190. * Copyright 2001-2006 by Charles Maier Associates;
  191. * Licensed under the Internet Software Consortium License;
  192. *
  193. *--------------------------------------------------------------------*/
  194. uint32_t omemory::checksum32 (void const * memory, register size_t extent, register uint32_t checksum)
  195. {
  196. register byte * offset = (byte *)(memory);
  197. while (extent >= sizeof (checksum))
  198. {
  199. checksum ^= *(uint32_t *)(offset);
  200. offset += sizeof (checksum);
  201. extent -= sizeof (checksum);
  202. }
  203. return (~checksum);
  204. }
  205. /*====================================================================*
  206. *
  207. * signed memincr (void * memory, size_t extent);
  208. *
  209. * increment a multi-byte memory region; start at 0x00 and reset
  210. * at 0xFF; return -1 once all bytes are 0xFF;
  211. *
  212. * for example,
  213. *
  214. * 0x00 0x00 0x00 --> 0x00 0x00 0x01
  215. * 0xFF 0x00 0xFF --> 0xFF 0x01 0x00
  216. *
  217. * Motley Tools by Charles Maier <cmaier@cmassoc.net>;
  218. * Copyright 2001-2006 by Charles Maier Associates;
  219. * Licensed under the Internet Software Consortium License;
  220. *
  221. *--------------------------------------------------------------------*/
  222. signed omemory::memincr (void * memory, register size_t extent)
  223. {
  224. register byte * offset = (byte *)(memory);
  225. while (extent--)
  226. {
  227. if (++ offset [extent] != 0x00)
  228. {
  229. return (0);
  230. }
  231. }
  232. return (-1);
  233. }
  234. /*====================================================================*
  235. *
  236. * signed strincr (void * memory, size_t extent, byte minimum, byte maximum);
  237. *
  238. * increment a multi-byte memory region; start at min and reset at
  239. * max; return -1 once all bytes are max;
  240. *
  241. * Motley Tools by Charles Maier <cmaier@cmassoc.net>;
  242. * Copyright 2001-2006 by Charles Maier Associates;
  243. * Licensed under the Internet Software Consortium License;
  244. *
  245. *--------------------------------------------------------------------*/
  246. signed omemory::strincr (void * memory, register size_t extent, register byte minimum, register byte maximum)
  247. {
  248. register byte * offset = (byte *)(memory);
  249. while (extent--)
  250. {
  251. if (++ offset [extent] <= maximum)
  252. {
  253. return (0);
  254. }
  255. offset [extent] = minimum;
  256. }
  257. return (-1);
  258. }
  259. /*====================================================================*
  260. *
  261. * signed memdecr (void * memory, size_t extent);
  262. *
  263. * decrement a multi-byte memory region; start at 0xff and reset
  264. * at 0x00; return -1 once all bytes are 0x00;
  265. *
  266. * for example:
  267. *
  268. * 0x00 0x00 0x00 --> 0x00 0x00 0x01
  269. * 0xFF 0x00 0xFF --> 0xFF 0x01 0x00
  270. *
  271. * Motley Tools by Charles Maier <cmaier@cmassoc.net>;
  272. * Copyright 2001-2006 by Charles Maier Associates;
  273. * Licensed under the Internet Software Consortium License;
  274. *
  275. *--------------------------------------------------------------------*/
  276. signed omemory::memdecr (void * memory, register size_t extent)
  277. {
  278. register byte * offset = (byte *)(memory);
  279. while (extent--)
  280. {
  281. if (-- offset [extent] != 0xFF)
  282. {
  283. return (0);
  284. }
  285. }
  286. return (-1);
  287. }
  288. /*====================================================================*
  289. *
  290. * signed strdecr (void * memory, size_t extent, byte minimum, byte maximum);
  291. *
  292. * decrement a multi-byte memory region; start at max and reset at
  293. * min; return -1 once all bytes are min;
  294. *
  295. * Motley Tools by Charles Maier <cmaier@cmassoc.net>;
  296. * Copyright 2001-2006 by Charles Maier Associates;
  297. * Licensed under the Internet Software Consortium License;
  298. *
  299. *--------------------------------------------------------------------*/
  300. signed omemory::strdecr (void * memory, register size_t extent, register byte minimum, register byte maximum)
  301. {
  302. register byte * offset = (byte *)(memory);
  303. while (extent--)
  304. {
  305. if (-- offset [extent] >= minimum)
  306. {
  307. return (0);
  308. }
  309. offset [extent] = maximum;
  310. }
  311. return (-1);
  312. }
  313. /*====================================================================*
  314. *
  315. * size_t binencode (void * memory, size_t extent, char const * string);
  316. *
  317. * encode a binary string into a byte array; return the number of
  318. * bytes encoded on success or -1 on error; permit an optional
  319. * hyphen between successive octets;
  320. *
  321. * string must contain an even multiple of 8 binary digits; bytes
  322. * are fixed width fields; leading zeros are required or an error
  323. * will occur;
  324. *
  325. * Motley Tools by Charles Maier <cmaier@cmassoc.net>;
  326. * Copyright 2001-2006 by Charles Maier Associates;
  327. * Licensed under the Internet Software Consortium License;
  328. *
  329. *--------------------------------------------------------------------*/
  330. size_t omemory::binencode (void * memory, register size_t extent, register char const * string)
  331. {
  332. register byte * origin = (byte *)(memory);
  333. register byte * offset = (byte *)(memory);
  334. while ((extent) && (*string))
  335. {
  336. register unsigned radix = 2;
  337. register unsigned field = 8;
  338. register unsigned value = 0;
  339. register unsigned digit = 0;
  340. if ((offset > origin) && (*string == omemory::bin_extender))
  341. {
  342. string++;
  343. }
  344. while (field--)
  345. {
  346. if ((digit = omemory::todigit (*string)) >= radix)
  347. {
  348. errno = EINVAL;
  349. return (0);
  350. }
  351. value *= radix;
  352. value += digit;
  353. string++;
  354. }
  355. *offset = (byte)(value);
  356. offset++;
  357. extent--;
  358. }
  359. #if defined (WIN32)
  360. while (isspace ((unsigned char)*string))
  361. {
  362. string++;
  363. }
  364. #endif
  365. if ((extent) || (*string))
  366. {
  367. errno = EINVAL;
  368. return (0);
  369. }
  370. return (offset - origin);
  371. }
  372. /*====================================================================*
  373. *
  374. * size_t decencode (void * memory, size_t extent, char const *string);
  375. *
  376. * encode a memory region with a dotted decimal string octet; return
  377. * the number of characters encoded or 0 on error; permit an optional
  378. * period between octets;
  379. *
  380. * Motley Tools by Charles Maier <cmaier@cmassoc.net>;
  381. * Copyright 2001-2006 by Charles Maier Associates;
  382. * Licensed under the Internet Software Consortium License;
  383. *
  384. *--------------------------------------------------------------------*/
  385. size_t omemory::decencode (void * memory, size_t extent, char const * string)
  386. {
  387. register byte * origin = (byte *)(memory);
  388. register byte * offset = (byte *)(memory);
  389. while ((extent) && (*string))
  390. {
  391. unsigned radix = 10;
  392. unsigned field = 3;
  393. unsigned value = 0;
  394. unsigned digit = 0;
  395. if ((offset > origin) && (*string == omemory::dec_extender))
  396. {
  397. string++;
  398. }
  399. while (field--)
  400. {
  401. if ((digit = omemory::todigit (*string)) >= radix)
  402. {
  403. errno = EINVAL;
  404. return (0);
  405. }
  406. value *= radix;
  407. value += digit;
  408. if (value >> 8)
  409. {
  410. errno = ERANGE;
  411. return (0);
  412. }
  413. string++;
  414. }
  415. *offset = (byte)(value);
  416. offset++;
  417. extent--;
  418. }
  419. #if defined (WIN32)
  420. while (isspace ((unsigned char)*string))
  421. {
  422. string++;
  423. }
  424. #endif
  425. if ((extent) || (*string))
  426. {
  427. errno = EINVAL;
  428. return (0);
  429. }
  430. return (offset - origin);
  431. }
  432. /*====================================================================*
  433. *
  434. * size_t hexencode (void * memory, size_t extent, char const * string);
  435. *
  436. * encode a NUL terminated hexadecimal string into a fixed length
  437. * memory region; return the number of bytes encoded or 0 on error;
  438. * an error will occur of the entire region cannot be encoded or
  439. * the entire string cannot be converted due to illegal characters
  440. * or excessive digits;
  441. *
  442. * Motley Tools by Charles Maier <cmaier@cmassoc.net>;
  443. * Copyright 2001-2006 by Charles Maier Associates;
  444. * Licensed under the Internet Software Consortium License;
  445. *
  446. *--------------------------------------------------------------------*/
  447. size_t omemory::hexencode (void * memory, register size_t extent, register char const * string)
  448. {
  449. register byte * origin = (byte *)(memory);
  450. register byte * offset = (byte *)(memory);
  451. while ((extent) && (*string))
  452. {
  453. unsigned radix = 16;
  454. unsigned field = 2;
  455. unsigned value = 0;
  456. unsigned digit = 0;
  457. if ((offset > origin) && (*string == omemory::hex_extender))
  458. {
  459. string++;
  460. }
  461. while (field--)
  462. {
  463. if ((digit = omemory::todigit (*string)) >= radix)
  464. {
  465. errno = EINVAL;
  466. return (0);
  467. }
  468. value *= radix;
  469. value += digit;
  470. string++;
  471. }
  472. *offset = (byte)(value);
  473. offset++;
  474. extent--;
  475. }
  476. #if defined (WIN32)
  477. while (isspace ((unsigned char)*string))
  478. {
  479. string++;
  480. }
  481. #endif
  482. if ((extent) || (*string))
  483. {
  484. errno = EINVAL;
  485. return (0);
  486. }
  487. return (offset - origin);
  488. }
  489. /*====================================================================*
  490. *
  491. * size_t bindecode (void const * memory, size_t extent, char buffer [], size_t length);
  492. *
  493. * decode a memory region as a string of binary digits;
  494. *
  495. * allow 9 characters per byte when allocating the buffer;
  496. *
  497. * Motley Tools by Charles Maier <cmaier@cmassoc.net>;
  498. * Copyright 2001-2006 by Charles Maier Associates;
  499. * Licensed under the Internet Software Consortium License;
  500. *
  501. *--------------------------------------------------------------------*/
  502. size_t omemory::bindecode (void const * memory, register size_t extent, char buffer [], register size_t length)
  503. {
  504. register char * string = (char *)(buffer);
  505. register byte * offset = (byte *)(memory);
  506. if ((length /= 9))
  507. {
  508. while ((length-- > 0) && (extent-- > 0))
  509. {
  510. string = omemory::serial (string, 8, *offset++, 2);
  511. if ((length) && (extent))
  512. {
  513. *string++ = omemory::bin_extender;
  514. }
  515. }
  516. *string = (char) (0);
  517. }
  518. return (string - buffer);
  519. }
  520. /*====================================================================*
  521. *
  522. * size_t decdecode (void const * memory, size_t extent, char buffer [], size_t length);
  523. *
  524. * decode a memory block of given length in bytes as a string of
  525. * separated hexadecimal bytes; terminate once the string fills
  526. * or the memory ends; terminate the string and return the actual
  527. * string bytes;
  528. *
  529. * allow three string characters for each memory byte; this means
  530. * that the buffer must have at least three characters or nothing
  531. * will be decoded; the maximum number of bytes is the lesser of
  532. * chars/3 and bytes;;
  533. *
  534. * Motley Tools by Charles Maier <cmaier@cmassoc.net>;
  535. * Copyright 2001-2006 by Charles Maier Associates;
  536. * Licensed under the Internet Software Consortium License;
  537. *
  538. *--------------------------------------------------------------------*/
  539. size_t omemory::decdecode (void const * memory, register size_t extent, char buffer [], register size_t length)
  540. {
  541. register char * string = (char *)(buffer);
  542. register byte * offset = (byte *)(memory);
  543. if ((length /= 4))
  544. {
  545. while ((length--) && (extent--))
  546. {
  547. string = omemory::serial (string, 3, *offset++, 10);
  548. if ((length) && (extent))
  549. {
  550. *string++ = omemory::dec_extender;
  551. }
  552. }
  553. *string = (char) (0);
  554. }
  555. return (string - buffer);
  556. }
  557. /*====================================================================*
  558. *
  559. * size_t hexdecode (void const * memory, size_t extent, char buffer [], size_t length);
  560. *
  561. * decode a memory region as a string of hex octets separated with
  562. * a colon;
  563. *
  564. * allow three string characters for each memory byte; this means
  565. * that the buffer must hold at least three characters or nothing
  566. * will be decoded; the maximum number of bytes is the lesser of
  567. * chars/3 and bytes;
  568. *
  569. * Motley Tools by Charles Maier <cmaier@cmassoc.net>;
  570. * Copyright 2001-2006 by Charles Maier Associates;
  571. * Licensed under the Internet Software Consortium License;
  572. *
  573. *--------------------------------------------------------------------*/
  574. size_t omemory::hexdecode (void const * memory, register size_t extent, char buffer [], register size_t length)
  575. {
  576. register char * string = (char *)(buffer);
  577. register byte * offset = (byte *)(memory);
  578. if ((length /= 3))
  579. {
  580. while ((length--) && (extent--))
  581. {
  582. *string++ = omemory::digits [(*offset >> 4) & 0x0F];
  583. *string++ = omemory::digits [(*offset >> 0) & 0x0F];
  584. if ((length) && (extent))
  585. {
  586. *string++ = omemory::hex_extender;
  587. }
  588. offset++;
  589. }
  590. *string = (char) (0);
  591. }
  592. return (string - buffer);
  593. }
  594. /*====================================================================*
  595. *
  596. * void hexdump (void const * memory, size_t offset, size_t extent, std::ostream * stream);
  597. *
  598. * print a memory region in dump format showing byte offsets, hex
  599. * byte values and ASCII byte values;
  600. *
  601. * Motley Tools by Charles Maier <cmaier@cmassoc.net>;
  602. * Copyright 2001-2006 by Charles Maier Associates;
  603. * Licensed under the Internet Software Consortium License;
  604. *
  605. *--------------------------------------------------------------------*/
  606. void omemory::hexdump (void const * memory, size_t offset, size_t extent, std::ostream * stream)
  607. {
  608. register byte * origin = (byte *)(memory);
  609. unsigned field = sizeof (extent) + sizeof (extent);
  610. unsigned block = 0x10;
  611. size_t lower = block * (offset / block);
  612. size_t upper = block + lower;
  613. size_t index = 0;
  614. char buffer [sizeof (extent) + sizeof (extent) + 0x48];
  615. char * output;
  616. while (lower < extent)
  617. {
  618. output = omemory::serial (buffer, (size_t)(field), (unsigned)(index), 0x10);
  619. *output++ = ' ';
  620. for (index = lower; index < upper; index++)
  621. {
  622. if (index < offset)
  623. {
  624. *output++ = ' ';
  625. *output++ = ' ';
  626. }
  627. else if (index < extent)
  628. {
  629. *output++ = omemory::digits [(origin [index] >> 4) & 0x0F];
  630. *output++ = omemory::digits [(origin [index] >> 0) & 0x0F];
  631. }
  632. else
  633. {
  634. *output++ = ' ';
  635. *output++ = ' ';
  636. }
  637. *output++ = ' ';
  638. }
  639. for (index = lower; index < upper; index++)
  640. {
  641. if (index < offset)
  642. {
  643. *output++ = ' ';
  644. }
  645. else if (index < extent)
  646. {
  647. unsigned c = origin [index];
  648. *output++ = std::isprint (c)? (char)(c): omemory::chr_nonprint;
  649. }
  650. else
  651. {
  652. *output++ = ' ';
  653. }
  654. }
  655. *output++ = '\n';
  656. stream->write (buffer, (signed)(output - buffer));
  657. lower += block;
  658. upper += block;
  659. }
  660. return;
  661. }
  662. /*====================================================================*
  663. *
  664. * void hexview (void const * memory, size_t offset, size_t extent, std::ostream * stream)
  665. *
  666. * print a memory region in dump format showing byte offsets, hex
  667. * byte values and ASCII byte values;
  668. *
  669. * Motley Tools by Charles Maier <cmaier@cmassoc.net>;
  670. * Copyright 2001-2006 by Charles Maier Associates;
  671. * Licensed under the Internet Software Consortium License;
  672. *
  673. *--------------------------------------------------------------------*/
  674. void omemory::hexview (void const * memory, size_t offset, size_t extent, std::ostream * stream)
  675. {
  676. register byte * origin = (byte *)(memory);
  677. unsigned field = sizeof (extent) + sizeof (extent);
  678. unsigned block = 0x10;
  679. size_t lower = block * (offset / block);
  680. size_t upper = block + lower;
  681. size_t index = 0;
  682. char buffer [sizeof (extent) + sizeof (extent) + 0x48];
  683. char * output;
  684. while (lower < offset + extent)
  685. {
  686. output = omemory::serial (buffer, (size_t)(field), (unsigned)(index), 0x10);
  687. *output++ = ' ';
  688. for (index = lower; index < upper; index++)
  689. {
  690. if (index < offset)
  691. {
  692. *output++ = ' ';
  693. *output++ = ' ';
  694. }
  695. else if (index < offset + extent)
  696. {
  697. *output++ = omemory::digits [(origin [index-offset] >> 4) & 0x0F];
  698. *output++ = omemory::digits [(origin [index-offset] >> 0) & 0x0F];
  699. }
  700. else
  701. {
  702. *output++ = ' ';
  703. *output++ = ' ';
  704. }
  705. *output++ = ' ';
  706. }
  707. for (index = lower; index < upper; index++)
  708. {
  709. if (index < offset)
  710. {
  711. *output++ = ' ';
  712. }
  713. else if (index < offset + extent)
  714. {
  715. unsigned c = origin [index-offset];
  716. *output++ = std::isprint (c)? (char)(c): omemory::chr_nonprint;
  717. }
  718. else
  719. {
  720. *output++ = ' ';
  721. }
  722. }
  723. *output++ = '\n';
  724. stream->write (buffer, (signed)(output - buffer));
  725. lower += block;
  726. upper += block;
  727. }
  728. return;
  729. }
  730. /*====================================================================*
  731. *
  732. * char * binstring ( char buffer [], size_t length, void const * memory, size_t extent);
  733. *
  734. * decode a memory region into a binary character buffer and return
  735. * the buffer address;
  736. *
  737. * allow nine string characters for each memory byte; this means
  738. * that the buffer must hold at least nine characters or nothing
  739. * will be decoded;
  740. *
  741. * Motley Tools by Charles Maier <cmaier@cmassoc.net>;
  742. * Copyright 2001-2006 by Charles Maier Associates;
  743. * Licensed under the Internet Software Consortium License;
  744. *
  745. *--------------------------------------------------------------------*/
  746. char * omemory::binstring (char buffer [], size_t length, void const * memory, size_t extent)
  747. {
  748. omemory::bindecode (memory, extent, buffer, length);
  749. return (buffer);
  750. }
  751. /*====================================================================*
  752. *
  753. * char * decstring ( char buffer [], size_t length, void const * memory, size_t extent);
  754. *
  755. * decode a memory region into a decimal character buffer and
  756. * return the buffer address;
  757. *
  758. * allow four string characters for each memory byte; this means
  759. * that the buffer must hold at least four characters or nothing
  760. * will be decoded;
  761. *
  762. * Motley Tools by Charles Maier <cmaier@cmassoc.net>;
  763. * Copyright 2001-2006 by Charles Maier Associates;
  764. * Licensed under the Internet Software Consortium License;
  765. *
  766. *--------------------------------------------------------------------*/
  767. char * omemory::decstring (char buffer [], size_t length, void const * memory, size_t extent)
  768. {
  769. omemory::decdecode (memory, extent, buffer, length);
  770. return (buffer);
  771. }
  772. /*====================================================================*
  773. *
  774. * char * hexstring ( char buffer [], size_t length, void const * memory, size_t extent);
  775. *
  776. * decode a memory region into a hexadecimal character buffer and
  777. * return the buffer address;
  778. *
  779. * allow three string characters for each memory byte; this means
  780. * that the buffer must hold at least three characters or nothing
  781. * will be decoded;
  782. *
  783. * Motley Tools by Charles Maier <cmaier@cmassoc.net>;
  784. * Copyright 2001-2006 by Charles Maier Associates;
  785. * Licensed under the Internet Software Consortium License;
  786. *
  787. *--------------------------------------------------------------------*/
  788. char * omemory::hexstring (char buffer [], size_t length, void const * memory, size_t extent)
  789. {
  790. omemory::hexdecode (memory, extent, buffer, length);
  791. return (buffer);
  792. }
  793. /*====================================================================*
  794. *
  795. * void binout (void const * memory, size_t extent, signed c, std::ostream * stream);
  796. *
  797. * print a memory region as a series of binary octets separated by
  798. * character c which is normally BIN_EXTENDER defined in number.h;
  799. *
  800. * for example, binout (memory, 6, '-', stdout) would print
  801. *
  802. * 00000000-11010000-01010010-00000000-00000000-00000001
  803. *
  804. * Motley Tools by Charles Maier <cmaier@cmassoc.net>;
  805. * Copyright 2001-2006 by Charles Maier Associates;
  806. * Licensed under the Internet Software Consortium License;
  807. *
  808. *--------------------------------------------------------------------*/
  809. void omemory::binout (void const * memory, size_t extent, signed c, std::ostream * stream)
  810. {
  811. byte * offset = (byte *)(memory);
  812. while (extent--)
  813. {
  814. unsigned bits = 8;
  815. while (bits--)
  816. {
  817. stream->put (omemory::digits [(*offset >> bits) & 1]);
  818. }
  819. if ((extent) && std::isprint (c))
  820. {
  821. stream->put ((char)(c));
  822. }
  823. offset++;
  824. }
  825. return;
  826. }
  827. /*====================================================================*
  828. *
  829. * void decout (void const * memory, size_t extent, signed c, std::ostream * stream);
  830. *
  831. * print a memory region as a series of decimal octets separated
  832. * by character c which is normally DEC_EXTENDER as defined in
  833. * number.h;
  834. *
  835. * for example, decout (memory, 4, '.', stdout) would print
  836. *
  837. * 192.168.101.002
  838. *
  839. * Motley Tools by Charles Maier <cmaier@cmassoc.net>;
  840. * Copyright 2001-2006 by Charles Maier Associates;
  841. * Licensed under the Internet Software Consortium License;
  842. *
  843. *--------------------------------------------------------------------*/
  844. void omemory::decout (void const * memory, size_t extent, signed c, std::ostream * stream)
  845. {
  846. byte * offset = (byte *)(memory);
  847. while (extent--)
  848. {
  849. unsigned order = 100;
  850. while (order)
  851. {
  852. stream->put (omemory::digits [(* offset / order) % 10]);
  853. order /= 10;
  854. }
  855. if ((extent) && std::isprint (c))
  856. {
  857. stream->put ((char)(c));
  858. }
  859. offset++;
  860. }
  861. return;
  862. }
  863. /*====================================================================*
  864. *
  865. * void hexout (void const * memory, size_t extent, signed c, std::ostream * stream);
  866. *
  867. * print a memory region as a series of hexadecimal octets seperated
  868. * by character c which is normally HEX_EXTENDER defined in number.h;
  869. *
  870. * for example, hexout (memory, 6, ':', stdout) would print:
  871. *
  872. * 00:B0:52:00:00:01
  873. *
  874. * Motley Tools by Charles Maier <cmaier@cmassoc.net>;
  875. * Copyright 2001-2006 by Charles Maier Associates;
  876. * Licensed under the Internet Software Consortium License;
  877. *
  878. *--------------------------------------------------------------------*/
  879. void omemory::hexout (void const * memory, size_t extent, signed c, std::ostream * stream)
  880. {
  881. byte * offset = (byte *)(memory);
  882. while (extent--)
  883. {
  884. stream->put (omemory::digits [(* offset >> 4) & 0x0F]);
  885. stream->put (omemory::digits [(* offset >> 0) & 0x0F]);
  886. if ((extent) && std::isprint (c))
  887. {
  888. stream->put ((char)(c));
  889. }
  890. offset++;
  891. }
  892. return;
  893. }
  894. /*====================================================================*
  895. *
  896. * size_t hexin ( void * memory, size_t extent, std::istream * stream)
  897. *
  898. * read a file and convert hexadecimal octets to binary bytes then
  899. * store them in consecutive memory locations up to a given length;
  900. * return the actual number of bytes stored;
  901. *
  902. * digits may be consecutive or separated by white space consisting
  903. * of spaces, tabs, linefeeds, carriage returns, formfeeds or other
  904. * characters such as punctuation; C-style or script-style comments
  905. * are treated as white space;
  906. *
  907. * Motley Tools by Charles Maier <cmaier@cmassoc.net>;
  908. * Copyright 2001-2006 by Charles Maier Associates;
  909. * Licensed under the Internet Software Consortium License;
  910. *
  911. *--------------------------------------------------------------------*/
  912. size_t omemory::hexin (void * memory, size_t extent, std::istream * stream)
  913. {
  914. byte * origin = (byte *)(memory);
  915. byte * offset = (byte *)(memory);
  916. unsigned digits = 0;
  917. signed c;
  918. while (((c = stream->get ()) != EOF) && (c != ';') && (extent))
  919. {
  920. if (c == '#')
  921. {
  922. do
  923. {
  924. c = stream->get ();
  925. }
  926. while ((c != '\n') && (c != EOF));
  927. }
  928. else if (c == '/')
  929. {
  930. c = stream->get ();
  931. if (c == '/')
  932. {
  933. do
  934. {
  935. c = stream->get ();
  936. }
  937. while ((c != '\n') && (c != EOF));
  938. }
  939. else if (c == '*')
  940. {
  941. while ((c != '/') && (c != EOF))
  942. {
  943. while ((c != '*') && (c != EOF))
  944. {
  945. c = stream->get ();
  946. }
  947. c = stream->get ();
  948. }
  949. }
  950. }
  951. else if ((c >= '0') && (c <= '9'))
  952. {
  953. *offset *= 16;
  954. *offset += (byte)(c) - '0';
  955. if (digits++ & 1)
  956. {
  957. offset++;
  958. extent--;
  959. }
  960. }
  961. else if ((c >= 'A') && (c <= 'F'))
  962. {
  963. *offset *= 16;
  964. *offset += 10;
  965. *offset += (byte)(c) - 'A';
  966. if (digits++ & 1)
  967. {
  968. offset++;
  969. extent--;
  970. }
  971. }
  972. else if ((c >= 'a') && (c <= 'f'))
  973. {
  974. *offset *= 16;
  975. *offset += 10;
  976. *offset += (byte)(c) - 'a';
  977. if (digits++ & 1)
  978. {
  979. offset++;
  980. extent--;
  981. }
  982. }
  983. }
  984. if (digits & 1)
  985. {
  986. #ifdef oERROR_HEADER
  987. oerror::error (0, EILSEQ, "Odd number of hex digits in source");
  988. #endif
  989. return ((size_t)(-1));
  990. }
  991. return (offset - origin);
  992. }
  993. /*====================================================================*
  994. *
  995. * char * serial (char buffer [], size_t length field, unsigned value, unsigned radix);
  996. *
  997. * convert an unsigned integer to a numeric string of fixed length
  998. * in the specified radix; return the next unformatted address;
  999. *
  1000. * Motley Tools by Charles Maier <cmaier@cmassoc.net>;
  1001. * Copyright 2001-2006 by Charles Maier Associates;
  1002. * Licensed under the Internet Software Consortium License;
  1003. *
  1004. *--------------------------------------------------------------------*/
  1005. char * omemory::serial (register char buffer [], register size_t length, register unsigned value, register unsigned radix)
  1006. {
  1007. size_t offset = length;
  1008. while (offset--)
  1009. {
  1010. buffer [offset] = omemory::digits [value % radix];
  1011. value /= radix;
  1012. }
  1013. return (buffer + length);
  1014. }
  1015. /*====================================================================*
  1016. *
  1017. * char * serial (char buffer [], size_t length, unsigned value, unsigned radix, unsigned c);
  1018. *
  1019. * convert an unsigned integer to a NUL terminated numeric string
  1020. * of fixed length in the specified radix; return the string start
  1021. * address;
  1022. *
  1023. * Motley Tools by Charles Maier <cmaier@cmassoc.net>;
  1024. * Copyright 2001-2006 by Charles Maier Associates;
  1025. * Licensed under the Internet Software Consortium License;
  1026. *
  1027. *--------------------------------------------------------------------*/
  1028. char * omemory::serial (register char buffer [], register size_t length, register unsigned value, register unsigned radix, unsigned c)
  1029. {
  1030. if (length)
  1031. {
  1032. buffer [length] = (char)(c);
  1033. }
  1034. while (length--)
  1035. {
  1036. buffer [length] = omemory::digits [value % radix];
  1037. value /= radix;
  1038. }
  1039. return (buffer);
  1040. }
  1041. /*====================================================================*
  1042. *
  1043. * signed todigit (signed c);
  1044. *
  1045. * convert an ASCII digit to an integer;
  1046. *
  1047. * Motley Tools by Charles Maier <cmaier@cmassoc.net>;
  1048. * Copyright 2001-2006 by Charles Maier Associates;
  1049. * Licensed under the Internet Software Consortium License;
  1050. *
  1051. *--------------------------------------------------------------------*/
  1052. signed omemory::todigit (signed c)
  1053. {
  1054. if ((c >= '0') && (c <= '9'))
  1055. {
  1056. return (c - '0');
  1057. }
  1058. if ((c >= 'A') && (c <= 'Z'))
  1059. {
  1060. return (c - 'A' + 10);
  1061. }
  1062. if ((c >= 'a') && (c <= 'z'))
  1063. {
  1064. return (c - 'a' + 10);
  1065. }
  1066. return (-1);
  1067. }
  1068. /*====================================================================*
  1069. *
  1070. * omemory::omemory ();
  1071. *
  1072. * Motley Tools by Charles Maier <cmaier@cmassoc.net>;
  1073. * Copyright 2001-2006 by Charles Maier Associates;
  1074. * Licensed under the Internet Software Consortium License;
  1075. *
  1076. *--------------------------------------------------------------------*/
  1077. omemory::omemory ()
  1078. {
  1079. return;
  1080. }
  1081. /*====================================================================*
  1082. *
  1083. * ~omemory();
  1084. *
  1085. * Motley Tools by Charles Maier <cmaier@cmassoc.net>;
  1086. * Copyright 2001-2006 by Charles Maier Associates;
  1087. * Licensed under the Internet Software Consortium License;
  1088. *
  1089. *--------------------------------------------------------------------*/
  1090. omemory::~omemory ()
  1091. {
  1092. return;
  1093. }
  1094. /*====================================================================*
  1095. * end definition;
  1096. *--------------------------------------------------------------------*/
  1097. #endif