{"id":279,"date":"2007-02-14T11:59:08","date_gmt":"2007-02-14T18:59:08","guid":{"rendered":"http:\/\/www.red-sweater.com\/blog\/279\/hexy-little-thing"},"modified":"2007-02-14T12:09:53","modified_gmt":"2007-02-14T19:09:53","slug":"hexy-little-thing","status":"publish","type":"post","link":"https:\/\/redsweater.com\/blog\/279\/hexy-little-thing","title":{"rendered":"Hexy Little Thing"},"content":{"rendered":"<p>I&#8217;m working on an application now that uses a custom document format. Since my code manipulates this format and spits it back out to disk, I find myself frequently examining the resulting documents using Peter Ammon&#8217;s excellent <a href=\"http:\/\/ridiculousfish.com\/hexfiend\/\">Hex Fiend<\/a> to examine the resulting files, and make sure the content is still format-compliant.<\/p>\n<p>\nBut while I&#8217;m debugging the code that actually does the manipulation, I find myself stuck doing stupid stuff like:\n<\/p>\n<p><pre>\n(gdb) p\/x ((char*)[imageData bytes])[14]\n$1 = 0x28\n<\/pre>\n<\/p>\n<p>\nUgh! That&#8217;s no way to win the software wars. It occurred to me today that what I really want is something like Hex Fiend built right into the debugger. Why shouldn&#8217;t I be able to hex-dump my NSData objects directly from the console? It turns out I wasn&#8217;t alone in this wish, because Dan Wood <a href=\"http:\/\/gigliwood.com\/weblog\/Cocoa\/Better_description_.html\">recently published<\/a> a category on NSData that allows just that.\n<\/p>\n<p>\nBy simply compiling the NSData category into a given application, you give NSData&#8217;s debugging description superpowers. For instance, here&#8217;s me at the gdb console, examining the contents of the favicon.ico response I just received from NSURLConnection:<\/p>\n<pre style=\"font-size:1em;\">\n<code>\n(gdb) po imageData\nNSData 350 bytes:\n00 00 01 00 01 00 10 10 10 00 00 00 00 00 28 01 | ..............(.\n00 00 16 00 00 00 28 00 00 00 10 00 00 00 20 00 | ......(....... .\n00 00 01 00 04 00 00 00 00 00 C0 00 00 00 00 00 | ................\n00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF | ................\nFF 00 00 00 FF 00 00 00 EF 00 00 00 DE 00 00 00 | ................\nCE 00 00 00 BD 00 00 00 AD 00 00 00 9C 00 00 00 | ................\n8C 00 00 00 7B 00 00 00 52 00 00 00 42 00 00 00 | ....{...R...B...\n29 00 00 00 10 00 00 00 00 00 00 00 00 00 11 11 | )...............\n11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 | ................\n11 11 11 11 11 11 13 31 11 11 12 55 21 11 1B B1 | .......1...U!...\n13 D8 7F FF FB 31 1B B1 6F D4 FB 65 9F D2 1B DB | ....1..o..e....\nFB 21 84 11 15 F5 1B FF FC 41 12 78 8D D1 1B B1 | .!.......A.x....\n3C C1 2D FF FB 51 1B B1 1A D1 5F 71 11 11 1B C5 | < .-..Q...._q....\nBF 81 1C C7 58 61 1A FF C6 11 12 BF FF 81 12 54 | ....Xa.........T\n11 11 11 13 52 11 11 11 11 11 11 11 11 11 11 11 | ....R...........\n11 11 11 11 11 11 11 11 11 11 11 11 11 11 00 00 | ................\n00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................\n00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................\n00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................\n00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................\n00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................\n00 00 00 00 00 00 00 00 00 00 00 00 00 00       | ..............\nCurrent language:  auto; currently objective-c\n(gdb)\n<\/code>\n<\/code><\/pre>\n<\/p>\n<p>\nDan&#8217;s code is pretty much perfect as-is, but I couldn&#8217;t resist tacking on some additional features. His category hardcodes the dumped data to 1024 bytes, but in my case there are times when I&#8217;m interested in seeing more. I added two category methods to the mix:\n<\/p>\n<p><pre style=\"font-size:1em;\">\n<code>\n\/\/ startOffset may be negative, indicating offset from end of data\n- (NSString *)descriptionFromOffset:(int)startOffset;\n- (NSString *)descriptionFromOffset:(int)startOffset\n\t\t\t\tlimitingToByteCount:(unsigned int)maxBytes;\n<\/code>\n<\/pre>\n<\/p>\n<p>\nNow I can peek at a specific subrange, or expand the default limit of 1024 bytes. I can even peek at the end of a chunk of data, by specifying a negative offset:\n<\/p>\n<p><pre style=\"font-size:1em;\">\n<code>\n(gdb) po [mDocumentData descriptionFromOffset:-11]\nNSData 109 bytes (showing bytes 98 through 109):\n02 43 41 54 41 54 4F 4E 49 43 00                | .CATATONIC.\n(gdb) \n<\/code>\n<\/pre>\n<\/p>\n<p>\nWow! This is a pretty huge addition to my debugging and development toolbelt. Many thanks to Dan Wood for providing the ready-made code to speed up my implementation.\n<\/p>\n<p>\n<a href=\"http:\/\/www.red-sweater.com\/blog\/downloads\/NSData+RSHexDump.zip\">NSData+RSHexDump<\/a> is freely available to you, under an MIT license.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;m working on an application now that uses a custom document format. Since my code manipulates this format and spits it back out to disk, I find myself frequently examining the resulting documents using Peter Ammon&#8217;s excellent Hex Fiend to examine the resulting files, and make sure the content is still format-compliant. But while I&#8217;m [&hellip;]<\/p>\n","protected":false},"author":10,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11,2,29,20,15,19,5],"tags":[],"class_list":["post-279","post","type-post","status-publish","format-standard","hentry","category-cocoa","category-debugging","category-free-code","category-hacking","category-programming","category-technology","category-xcode"],"_links":{"self":[{"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/posts\/279","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/users\/10"}],"replies":[{"embeddable":true,"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/comments?post=279"}],"version-history":[{"count":0,"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/posts\/279\/revisions"}],"wp:attachment":[{"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/media?parent=279"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/categories?post=279"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/tags?post=279"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}