Uli's Web Site
[ Zathras.de - Uli's Web Site ]
Other Sites: Stories
Pix
Abi 2000
Stargate: Resurgence
Lost? Site Map!
 
 
     home | articles | moose | programming | articles >> blog

 Blog
 
 Blog Topics
 
 Archive
 

15 Most Recent [RSS]

 Uli's source code is on Github!
2010-03-05 @986
 
 Downtime on Friday
2010-03-04 @025
 
 Hacking the Press - A point for usability in press kits
2010-02-18 @404
 
 So. Git.
2010-02-15 @498
 
 Helpful Xcode User Scripts
2010-02-14 @485
 
 CocoaHeads München: Xcode Tiefergelegt Folien
2010-02-10 @995
 
 Debugging Assembler on Mac OS X
2010-02-07 @600
 
 The iPad
2010-01-29 @417
 
 Double click is a shortcut
2010-01-16 @621
 
 Removing transparency from NSImage
2010-01-16 @581
 
 Garbage collection, work of the devil?
2009-12-20 @881
 
 Let's talk about Coding Style
2009-12-15 @459
 
 The iPhone Reality Show
2009-12-13 @589
 
 The Sinus Curve of Life
2009-11-26 @430
 
 AppleScripting Cocoa a little
2009-11-26 @003
 

More...

Moving Cocoa from PPCMacs to IntelMacs

Still trying to digest what Steve Jobs just announced, and the repercussions of that (Microsoft moves the XBox to PPC, and Apple drops the platform like it had the plague ... coincidence?). To while away the time, I thought I'd start investigating changes needed to my apps to make them Intel-ready.

The first thing that came to mind was endian-ness. Most parts of the app should just work fine. Property lists and other XML stuff are insulated against endian-issues, being text and UTF-8 and all that, and I'd suppose the binary variants contain a byte-order marker.

But if you're writing out your own binary data, you'll want to use the macros in Endian.h to swap your numbers from on-disk format (big-endian) to the platform's native format. Here's a table of which functions to use:

C TypeTo DiskFrom Disk
unsigned shortEndianU16_NtoB()EndianU16_BtoN()
signed shortEndianS16_NtoB()EndianS16_BtoN()
unsigned longEndianU32_NtoB()EndianU32_BtoN()
signed longEndianS32_NtoB()EndianS32_BtoN()
unsigned long longEndianU64_NtoB()EndianU64_BtoN()
signed long longEndianS64_NtoB()EndianS64_BtoN()


Note that if you're just starting to write your app and want your binary file format to be optimal for Intel Little-Endian numbers from the start, you may want to replace the "B"s in the above function calls with "L"s. That way, you'll make your app write out Intel-style little-endian data from the start. And of course, all these macros map to no-ops if you're trying to convert big-endian data to big-endian, or little-endian to little-endian.

Or, if you want to be compatible at less performance cost, save a byte-order marker at the start of your files (e.g. a short set to "1" -- if it's not 1, it probably needs to be swapped), and only perform swapping as necessary.

If you have flags in one of your own persistent classes, you probably used the following non-endian-safe construct to get your flags saved in an extensible way:
     struct UKDVFlags
     {
         unsigned int    flag1:1;
         unsigned int    flag2:1;
         unsigned int    flag3:1;
         unsigned int    reservedFlags:29;
     };
This lumps all these bit-flags together in one unsigned int. If I save this to disk, instead of the first 3 bits, my flags will end up in the last 3 on a little-endian system like Intel. So, what do we do? Well, the party-line that NSView.h demonstrates is to change this into:
     struct UKDVFlags
     {
      #ifdef __BIG_ENDIAN__
         unsigned int    flag1:1;
         unsigned int    flag2:1;
         unsigned int    flag3:1;
         unsigned int    reservedFlags:29;
      #else
         unsigned int    reservedFlags:29;
         unsigned int    flag3:1;
         unsigned int    flag2:1;
         unsigned int    flag1:1;
      #endif
     };
Your old flags go in the __BIG_ENDIAN__ clause, while the little-endian version gets the flags in reverse order. That's all. You can even wrap this in a union, such as
    union UKDVFlagsUnion
    {
        unsigned int        allFlags;
        struct UKDVFlags    bits;
    }
And you'll always get the same value in allFlags, and the same bitfield members in bits will be set, so if you save allFlags using an NSNumber, your flags will survive endian-conversion just fine.

Update: For some odd reason, I claimed allFlags would have a different number, but the same bytes. Nonsense. Changed.
 
Created: 2005-06-06 @892 Last change: 2005-06-07 @626 | Home | Admin | Edit
© Copyright 2003-2010 by M. Uli Kusterer, all rights reserved.