/*
 * Copyright (c) 2011 Apple Inc. All rights reserved.
 *
 * @APPLE_APACHE_LICENSE_HEADER_START@
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @APPLE_APACHE_LICENSE_HEADER_END@
 */

/*=============================================================================
    File:		ALACBitUtilities.h

        $NoKeywords: $
=============================================================================*/

#ifndef __ALACBITUTILITIES_H
#define __ALACBITUTILITIES_H

#include <stdint.h>

#ifndef MIN
#define MIN(x, y) ((x) < (y) ? (x) : (y))
#endif // MIN
#ifndef MAX
#define MAX(x, y) ((x) > (y) ? (x) : (y))
#endif // MAX

#ifndef nil
#define nil NULL
#endif

#define RequireAction(condition, action) \
    if (!(condition)) {                  \
        action                           \
    }
#define RequireActionSilent(condition, action) \
    if (!(condition)) {                        \
        action                                 \
    }
#define RequireNoErr(condition, action) \
    if ((condition)) {                  \
        action                          \
    }

#ifdef __cplusplus
extern "C" {
#endif

enum {
    ALAC_noErr = 0
};

typedef enum {

    ID_SCE = 0, /* Single Channel Element   */
    ID_CPE = 1, /* Channel Pair Element     */
    ID_CCE = 2, /* Coupling Channel Element */
    ID_LFE = 3, /* LFE Channel Element      */
    ID_DSE = 4, /* not yet supported        */
    ID_PCE = 5,
    ID_FIL = 6,
    ID_END = 7
} ELEMENT_TYPE;

// types
typedef struct BitBuffer
{
    uint8_t *cur;
    uint8_t *end;
    uint32_t bitIndex;
    uint32_t byteSize;

} BitBuffer;

/*
        BitBuffer routines
        - these routines take a fixed size buffer and read/write to it
        - bounds checking must be done by the client
*/
void     BitBufferInit(BitBuffer *bits, uint8_t *buffer, uint32_t byteSize);
uint32_t BitBufferRead(BitBuffer *bits, uint8_t numBits); // note: cannot read more than 16 bits at a time
uint8_t  BitBufferReadSmall(BitBuffer *bits, uint8_t numBits);
uint8_t  BitBufferReadOne(BitBuffer *bits);
uint32_t BitBufferPeek(BitBuffer *bits, uint8_t numBits); // note: cannot read more than 16 bits at a time
uint32_t BitBufferPeekOne(BitBuffer *bits);
uint32_t BitBufferUnpackBERSize(BitBuffer *bits);
uint32_t BitBufferGetPosition(BitBuffer *bits);
void     BitBufferByteAlign(BitBuffer *bits, int32_t addZeros);
void     BitBufferAdvance(BitBuffer *bits, uint32_t numBits);
void     BitBufferRewind(BitBuffer *bits, uint32_t numBits);
void     BitBufferWrite(BitBuffer *bits, uint32_t value, uint32_t numBits);
void     BitBufferReset(BitBuffer *bits);

#ifdef __cplusplus
}
#endif

#endif /* __BITUTILITIES_H */
