Automated Way of Displaying a Hex Dump of a Binary File in a UITextView

I'm working through the book "iPhone SDK Application Development" by Jonathan Zdziarski and working on the "Further Study" section of the TableDemo example in Chapter 3. The item says:

- Add a new view controller that displays the contents of the file in a UITextView. If the file is binary, display a hexadecimal readout. When the user taps on a file, a new view controller should be pushed onto the navigation controller's stack that displays the contents of the file. The new view controller should have a Back button.

There were other requests on in this "Further Study" section and I have this example worked through, all except for how to display a hex dump of the file. ie:


0000: 31 32 33 34 35 36 37 38 12345678
.....


Right now, I have the program set to read the file into an NSString and load it into the UITextView. This works fine for text files, but it doesn't work well for binary files. I'm currently using the following code to load the file:


UITextView *textView = [[UITextView alloc] initWithFrame:bounds];
textView.editable = NO;
NSString *string = [NSString stringWithContentsOfFile:currentFile encoding:NSASCIIStringEncoding error:NULL];
textView.text = string;


Looking at UITextView.h and the UITextView Class Reference, I don't see anything that looks like it has this functionality built-in. Just curious if I'm missing some built-in way to accomplish this (maybe it's somewhere else in the API). I wanted to see if there was an easy way to do this before I brushed off my programming skills and implement this by coding it from scratch.

As far as needing to implement this from scratch, I'm guessing this could be done "relatively" easily by using various NSString methods to reformat the binary data into a hex dump format.

Steve

Message was edited by: Steve Waltner

MacBook Pro, iMac G5, Mac OS X (10.5)

Posted on Mar 16, 2009 5:04 AM

Reply
3 replies

Mar 16, 2009 1:55 PM in response to Steve Waltner

I don't think there's any support in UITextView for dumping binary files. Here's some code to display the first four bytes:

NSData *data = [NSData dataWithContentsOfFile:@"/Users/Ray/abc.txt"];
// start an outer loop here to display the entire file
NSMutableString *displayString = [[NSMutableString alloc] initWithCapacity:80];
[displayString appendString:@"0000: "];
for (int i=0; i<[data length] && i<4; i++) {
unsigned char uChar;
[data getBytes:&uChar range:NSMakeRange(i, 1)];
[displayString appendFormat:@"%02X ", uChar];
}
textView.text = displayString;
[displayString release];

Mar 19, 2009 12:36 PM in response to RayNewbie

Like I said, probably not the cleanest code out there, but it gets the job done.... Thanks again.

Steve


// Read the file into memory and figure out how long the file is
NSData *data = [NSData dataWithContentsOfFile:currentFile];
int dataLength = [data length];

// store a hex dump (ie: "00000000: 12 34 56 78 9a bd de f0 ........") in hexDump
NSMutableString *hexDump = [[NSMutableString alloc] initWithCapacity:dataLength];
// temporary storage for ASCII representation (ie: "........" from above)
NSMutableString *tempAscii = [NSMutableString stringWithCapacity:8];
// Is the file just a plain text file (ie: only containing ASCII values from 32 to 126)
BOOL isPlainText = YES;
// Keep track of position in file
int i;

for (i=0; i<dataLength; i++) {
// Every 8 bytes, print text representation of hex and the current location in the file
if (i % 8 == 0) {
// Don't print the text representation before the first line since we haven't read any data yet
if (i != 0) {
// Print out the ASCII representation and empty out the string for the next line
[hexDump appendFormat:@"% @ ", tempAscii];
[tempAscii setString:@""];
}
// Print the first field in the Output (ie: current location in the file)
[hexDump appendFormat:@"%08X: ", i];
}
unsigned char uChar;
[data getBytes:&uChar range:NSMakeRange(i, 1)];
// Check if the character is a normal printable character
if (uChar >= 32 && uChar <= 126) {
[tempAscii appendFormat:@"%c", uChar];
} else {
// If it isn't, pur a period (.) in the ASCII representation
[tempAscii appendString:@"."];
// and flag this as a non-text file unless this is for a tab, CR, or LF character
if (uChar != 9 && uChar != 10 && uChar != 13) {
isPlainText = NO;
}
}
[hexDump appendFormat:@"%02X ", uChar];
}

// print text for last line here...
// If the last line wasn't a multiple of 8 bytes, pad the line with enough spaces to get the ASCII representation to properly allign
if (i % 8 != 0) {
for (; i % 8 != 0; i++) {
[hexDump appendString:@" "];
}
}
[hexDump appendFormat:@"% @ ", tempAscii];

// If the file just contained plain text, display that, otherwise, display the hex dump that was just created
if (isPlainText) {
if (dataLength == 0) {
textView.text = @"ERROR: this is an empty file";
} else {
// plain text, so reread the file into a NSString and load that into the UITextView
NSString *string = [NSString stringWithContentsOfFile:currentFile encoding:NSASCIIStringEncoding error:NULL];
textView.text = string;
}
} else {
// binary file, so set the font to a fixed width font and load the hex dump into the UITextView
// Set the font on textView to a fixed width font...
UIFont *fixedFont = [UIFont fontWithName:@"Courier New" size:11.0];
textView.font = fixedFont;

textView.text = hexDump;
[hexDump release];
}

This thread has been closed by the system or the community team. You may vote for any posts you find helpful, or search the Community for additional answers.

Automated Way of Displaying a Hex Dump of a Binary File in a UITextView

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple Account.