Thanks :)

I will make the conversion to CC_LONG to be more clear, but about the bug, I
mean it will be impossible to happen on this case, since the max length will
be always 64kb :)

About the remote thing, I mean its more low level things, the HD is just
mounted as an Volume (on /Volumes/Wilker-1), so, I mean the handling on this
case should be transparent, the low level drivers should take care of it :)

I learned a lot from this thread, thanks :)
---
Wilker LĂșcio
http://about.me/wilkerlucio/bio
Kajabi Consultant
+55 81 82556600



On Wed, Jun 29, 2011 at 5:31 PM, Quincey Morris <quinceymor...@earthlink.net
> wrote:

> On Jun 29, 2011, at 12:26, Wilker wrote:
>
> > +(NSString *)generateHashFromPath:(NSString *)path {
> >     const NSUInteger CHUNK_SIZE = 65536;
> >
> >     NSError *error = nil;
> >     NSData *fileData = [NSData dataWithContentsOfFile:path
> options:NSDataReadingMapped | NSDataReadingUncached error:&error];
> >
> >     if (error) {
> >         return nil;
> >     }
> >
> >     const uint8_t* buffer = [fileData bytes];
> >
> >     NSUInteger byteLength = [fileData length];
> >     NSUInteger byteOffset = 0;
> >
> >     if (byteLength > CHUNK_SIZE) {
> >         byteOffset = byteLength - CHUNK_SIZE;
> >         byteLength = CHUNK_SIZE;
> >     }
> >
> >     CC_MD5_CTX md5;
> >     CC_MD5_Init(&md5);
> >
> >     CC_MD5_Update(&md5, buffer, (unsigned int) byteLength);
> >     CC_MD5_Update(&md5, buffer + byteOffset, (unsigned int) byteLength);
> >
> >     unsigned char digest[CC_MD5_DIGEST_LENGTH];
> >
> >     CC_MD5_Final(digest, &md5);
> >
> >     NSMutableString *ret = [NSMutableString
> stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
> >
> >     for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
> >         [ret appendFormat:@"%02x", digest[i]];
> >     }
> >
> >     return [ret lowercaseString];
> > }
>
> This looks good to me, but since we're noodling around various topics here,
> let me nitpick at some details:
>
> 1. Format specifier '%x' produces lower case letters, so you don't need to
> lowercase the returned string. If you'd happened to want uppercase, there's
> '%X'.
>
> If you're just trying to return an immutable string, there are three
> possible answers:
>
> a. Don't bother. It's almost always fine to return a NSMutableString when
> your method's API's return type says NSString.
>
> b. Return '[ret copy]'. That allows NSString to do the fastest copy of the
> character data that it's capable of. The result is an immutable string.
>
> c. Go back to the way you first did it, where you spelled out the entire
> format string, so you don't ever create a NSMutableString.
>
> 2. There still a flashing danger signal in your code. Pretty much any time
> you have to cast a scalar type, your code gets smelly (
> http://en.wikipedia.org/wiki/Code_smell).
>
> If you consult the CC_MD5 man page, you'll see that the length parameter
> type is officially CC_LONG.  What happens if byteLength is bigger than the
> largest possible CC_LONG? (In other words, what happens if your file is
> bigger than 4GB?)
>
> WIth this code, the consequences would not be catastrophic, but the wrong
> digest would likely be calculated.
>
> So, declare 'byteLength' as type CC_LONG and get rid of those ad hoc casts.
> You might still need a cast, but pair it with a safety check:
>
>        CC_LONG byteLength = (CC_LONG) ([file length] > CHUNK_SIZE ?
> CHUNK_SIZE : [file length]);
>
> That messes up the setting of byteOffset, so you need to change that to
> something like:
>
>        NSUInteger byteOffset = [file length] > CHUNK_SIZE ? [file length] -
> CHUNK_SIZE : 0;
>
> Depending on your aesthetic tastes, you might actually want to do:
>
>        NSUInteger fileLength = [fileData length];
>        CC_LONG byteLength = (CC_LONG) (fileLength > CHUNK_SIZE ? CHUNK_SIZE
> : fileLength);
>        NSUInteger byteOffset = fileLength > CHUNK_SIZE ? fileLength -
> CHUNK_SIZE : 0;
>
> Anyone reading your code can now see that the cast is harmless, because
> you've explicitly checked for the error condition.
>
> > I tried it against a video of 8.5GB, stored on external drive (at wifi
> with Airport Extreme), and it's blazing fast :)
>
> This is a remarkable statement, if you think about it. My pitch for
> 'NSDataReadingMapped' relied on the assumption that the file was local. If
> NSData is really providing the effect of memory mapping with a remote file,
> it's really doing a *lot* of heavy lifting for you.
>
> That's really quite a surprising result.
>
>
>
>
>
_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to