freeswitch/libs/sipcc/cpr/linux/cpr_linux_align.h

83 lines
3.1 KiB
C
Executable File

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef __CPR_LINUX_ALIGN_H__
#define __CPR_LINUX_ALIGN_H__
#include "cpr_types.h"
/*
* Macros to determine how an address is aligned
*/
#define is_16bit_aligned(addr) (!((uint32_t)(addr) & 0x01))
#define is_32bit_aligned(addr) (!((uint32_t)(addr) & 0x03))
#define is_64bit_aligned(addr) (!((uint32_t)(addr) & 0x07))
/*
* Macro to get a mask for a specified byte alignment
*/
#define ALIGN_MASK(alignment) (~((alignment) - 1))
/*
* Macro to set the minimum alignment
*/
#define ALIGN_MIN(align,align_min) (((align) > (align_min)) ? (align) : (align_min))
/*
* Macro to round up or down "val" to be a multiple of "align", assuming
* "align" is a power of 2. if "align" is zero then no action will
* be performed
*/
#ifdef __typeof__
#define ALIGN_UP(val,align) ((align == 0) ? (val) : (__typeof__(val))(((uint32_t)(val) + ((align) - 1)) & ~((align) - 1)))
#define ALIGN_DOWN(val,align) ((align == 0) ? (val) : (__typeof__(val))(((uint32_t)(val)) & ~((align) - 1)))
#else
#define ALIGN_UP(val,align) ((align == 0) ? (val) : (uint32_t)(((uint32_t)(val) + ((align) - 1)) & ~((align) - 1)))
#define ALIGN_DOWN(val,align) ((align == 0) ? (val) : (uint32_t)(((uint32_t)(val)) & ~((align) - 1)))
#endif
/**
* Macro to safely write 4 bytes based on memory alignment setting
*/
#ifndef CPR_MEMORY_LITTLE_ENDIAN
#define WRITE_4BYTES_UNALIGNED(mem, value) \
{ ((char *)mem)[0] = (uint8_t)(((value) & 0xff000000) >> 24); \
((char *)mem)[1] = (uint8_t)(((value) & 0x00ff0000) >> 16); \
((char *)mem)[2] = (uint8_t)(((value) & 0x0000ff00) >> 8); \
((char *)mem)[3] = (uint8_t) ((value) & 0x000000ff); \
}
#else
#define WRITE_4BYTES_UNALIGNED(mem, value) \
{ ((char *)mem)[3] = (uint8_t)(((value) & 0xff000000) >> 24); \
((char *)mem)[2] = (uint8_t)(((value) & 0x00ff0000) >> 16); \
((char *)mem)[1] = (uint8_t)(((value) & 0x0000ff00) >> 8); \
((char *)mem)[0] = (uint8_t) ((value) & 0x000000ff); \
}
#endif
/**
* Macro to safely read 4 bytes based on memory alignment setting
*/
#ifndef CPR_MEMORY_LITTLE_ENDIAN
#ifdef __typeof__
#define READ_4BYTES_UNALIGNED(mem, value) \
__typeof__(value)((((uint8_t *)mem)[0] << 24) | (((uint8_t *)mem)[1] << 16) | \
(((uint8_t *)mem)[2] << 8) | ((uint8_t *)mem)[3])
#else
#define READ_4BYTES_UNALIGNED(mem, value) \
(uint32_t)((((uint8_t *)mem)[0] << 24) | (((uint8_t *)mem)[1] << 16) | \
(((uint8_t *)mem)[2] << 8) | ((uint8_t *)mem)[3])
#endif
#else
#ifdef __typeof__
#define READ_4BYTES_UNALIGNED(mem, value) \
__typeof__(value)((((uint8_t *)mem)[3] << 24) | (((uint8_t *)mem)[2] << 16) | \
(((uint8_t *)mem)[1] << 8) | ((uint8_t *)mem)[0])
#else
#define READ_4BYTES_UNALIGNED(mem, value) \
(uint32_t)((((uint8_t *)mem)[3] << 24) | (((uint8_t *)mem)[2] << 16) | \
(((uint8_t *)mem)[1] << 8) | ((uint8_t *)mem)[0])
#endif
#endif
#endif /* __CPR_LINUX_ALIGN_H__ */