Show Align.c syntax highlighted
/****************************************************************************************
Align.c $Revision: 10 $
<http://rentzsch.com/align>
Copyright © 1999-2001 Red Shed Software. All rights reserved.
by Jonathan 'Wolf' Rentzsch (jon at redshed dot net)
************************************************************************************/
#include "Align.h"
#include "require.h"
void
Align2(
void **ptr )
{
RequirePtr( ptr );
RequirePtr( *ptr );
(*(long*)ptr) &= 0xFFFFFFFE; // Strip lower bit.
(*(long*)ptr) += 2; // Move pointer up 2 bytes.
RequirePtrAlign( *ptr, 2 );
}
void*
AlignDirect2(
void *ptr )
{
RequirePtr( ptr );
Align2( &ptr );
RequirePtrAlign( ptr, 2 );
return( ptr );
}
void
Align4(
void **ptr )
{
RequirePtr( ptr );
RequirePtr( *ptr );
(*(long*)ptr) &= 0xFFFFFFFC; // Strip lower 2 bits.
(*(long*)ptr) += 4; // Move pointer up 4 bytes.
RequirePtrAlign( *ptr, 4 );
}
void*
AlignDirect4(
void *ptr )
{
RequirePtr( ptr );
Align4( &ptr );
RequirePtrAlign( ptr, 4 );
return( ptr );
}
void
Align8(
void **ptr )
{
RequirePtr( ptr );
RequirePtr( *ptr );
(*(long*)ptr) &= 0xFFFFFFF8; // Strip lower 3 bits.
(*(long*)ptr) += 8; // Move pointer up 8 bytes.
RequirePtrAlign( *ptr, 8 );
}
void*
AlignDirect8(
void *ptr )
{
RequirePtr( ptr );
Align8( &ptr );
RequirePtrAlign( ptr, 8 );
return( ptr );
}
void
Align16(
void **ptr )
{
RequirePtr( ptr );
RequirePtr( *ptr );
(*(long*)ptr) &= 0xFFFFFFF0; // Strip lower 4 bits.
(*(long*)ptr) += 16; // Move pointer up 16 bytes.
RequirePtrAlign( *ptr, 16 );
}
void*
AlignDirect16(
void *ptr )
{
RequirePtr( ptr );
Align16( &ptr );
RequirePtrAlign( ptr, 16 );
return( ptr );
}
void
AlignX(
void **ptr,
UInt32 alignment )
{
long ptrValue;
RequirePtr( ptr );
RequirePtr( *ptr );
Require( alignment == 2 || alignment == 4 || alignment == 8 || alignment == 16 );
ptrValue = (long) *ptr;
ptrValue &= ~(alignment - 1);
ptrValue += alignment;
RequirePtrAlign( (void*) ptrValue, alignment );
*ptr = (void*) ptrValue;
}
void*
AlignXDirect(
void *ptr,
UInt32 alignment )
{
long ptrValue;
RequirePtr( ptr );
Require( alignment == 2 || alignment == 4 || alignment == 8 || alignment == 16 );
ptrValue = (long) ptr;
ptrValue &= ~(alignment - 1);
ptrValue += alignment;
RequirePtrAlign( (void*) ptrValue, alignment );
return( (void*) ptrValue );
}
/****************************************************************************************
Commenter Date Comment
--------- ----------------- -----------------------------------------------------
wolf Tue, Apr 13, 1999 Created.
wolf Fri, May 7, 1999 Added three more requirements and added another
variable and renamed an existing variable. This was
done to make the code easier to read.
wolf Sun, Jan 30, 2000 Carbonized. The fromSystemHeap must always be set to
false when compiling for Carbon (it's still okay
for Classic apps).
wolf Fri, Mar 3, 2000 Now returns a nil pointer upon allocation failure.
wolf Mon, Mar 5, 2001 Added support for 2 byte aligned pointer allocation.
************************************************************************************/
OSErr
NewAlignedPtr(
UInt32 size,
Boolean fromSystemHeap,
Boolean clearMemory,
UInt8 alignment,
void **ptr )
{
Ptr macPtr, alignedPtr;
long *unalignedPtr;
OSErr err = noErr;
RequireSInt32( size );
Require( alignment == 2 || alignment == 4 || alignment == 8 || alignment == 16 );
RequirePtr( ptr );
// A failure should result in a nil pointer.
*ptr = nil;
// Bump up the size request to factor in the padding.
if( alignment < sizeof( void* ) )
alignment = sizeof( void* ); // Need at least 4 bytes for the pointer.
size += alignment;
// Allocate the Ptr as requested.
#if TARGET_API_MAC_CARBON
Require( fromSystemHeap == false );
if( clearMemory )
macPtr = NewPtrClear( size );
else
macPtr = NewPtr( size );
#else
if( fromSystemHeap ) {
macPtr = clearMemory ? NewPtrSysClear( (SInt32) size ) : NewPtrSys( (SInt32) size );
} else {
macPtr = clearMemory ? NewPtrClear( (SInt32) size ) : NewPtr( (SInt32) size );
}
#endif
err = MemError();
// There's a slight possiblity that NewPtr[Sys|Clear|SysClear] will fail,
// setting macPtr to nil *and* MemError() returning noErr. Here we make sure
// that a failed Ptr allocation gets an appropriate error code.
if( !macPtr && !err )
err = memFullErr;
// Stash the original pointer into the pad zone.
if( !err ) {
RequireMacPtr( macPtr );
alignedPtr = macPtr;
AlignX( (void**) &alignedPtr, alignment );
unalignedPtr = (long*) alignedPtr;
--unalignedPtr;
*unalignedPtr = (long) macPtr;
*ptr = alignedPtr;
RequireMacPtr( GetUnalignedPtr( *ptr ) );
Require( GetUnalignedPtr( *ptr ) == macPtr );
}
return( err );
}
/****************************************************************************************
Commenter Date Comment
--------- ----------------- -----------------------------------------------------
wolf Wed, Feb 17, 1999 Created.
************************************************************************************/
Ptr
GetUnalignedPtr(
void *ptr )
{
long *p = (long*) ptr;
--p;
return( (Ptr) *p );
}
/****************************************************************************************
Commenter Date Comment
--------- ----------------- -----------------------------------------------------
wolf Fri, Feb 18, 2000 Created.
************************************************************************************/
Boolean
IsAligned(
void *ptr,
UInt8 alignment )
{
return( ((long) ptr) % alignment == 0 );
}
See more files for this project here