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

 Blog
 
 Archive
 
 Blog Topics
 

15 Most Recent [RSS]

 Less work through Xcode and shell scripts
2011-12-16 @600
 
 iTunesCantComplain released
2011-10-28 @954
 
 Dennis Ritchie deceased
2011-10-13 @359
 
 Thank you, Steve.
2011-10-06 @374
 
 Cocoa Text System everywhere...
2011-03-27 @788
 
 Blog migration
2011-01-29 @520
 
 All you need to know about the Mac keyboard
2010-08-09 @488
 
 Review: Sherlock
2010-07-31 @978
 
 Playing with Objective C on Debian
2010-05-08 @456
 
 Fruit vs. Obst
2010-05-08 @439
 
 Mixed-language ambiguity
2010-04-15 @994
 
 Uli's 12:07 AM Law
2010-04-12 @881
 
 Uli's 1:24 AM Law
2010-04-12 @874
 
 Uli's 6:28 AM Law
2010-04-12 @869
 
 Uli's 3:57 PM Law
2010-04-12 @867
 

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-2014 by M. Uli Kusterer, all rights reserved.