/* Copyright (C) 1994 - 2001 by Telelogic AB.
Copyright (C) 1991, 1992, 1993, 1994 by Telelogic Malmoe AB.
Copyright (C) 1990, 1991, 1999 by Telesoft Europe AB.
This Program is owned by Telelogic and is protected by national
copyright laws and international copyright treaties. Telelogic
grants you the right to use this Program on one computer or in
one local computer network at any one time.
Under this License you may only modify the source code for the purpose
of adapting it to your environment. You must reproduce and include
any copyright and trademark notices on all copies of the source code.
You may not use, copy, merge, modify or transfer the Program except as
provided in this License.
Telelogic does not warrant that the Program will meet your
requirements or that the operation of the Program will be
uninterrupted and error free. You are solely responsible that the
selection of the Program and the modification of the source code
will achieve your intended result and that the results are actually
obtained. */

#ifndef __bms_user_h
#define __bms_user_h

#ifdef CODER_USE_USERBUF

#ifdef CODER_BMS_USERBUF

#define BufInitBuf(c, buftype)                        UserBufInitBuf(&c)
#define BufCloseBuf(c)                                UserBufCloseBuf(&c)

#define BufInitBufWithMemory(c, buftype, usermemory)  UserBufInitBufWithMemory(&c, usermemory)
#define BufCloseBufToMemory(c, usermemory)            UserBufCloseBufToMemory(&c, usermemory)

#define BufGetBufType(c)                              bms_UserBuffer

#define BufGetDataLen(c)                              UserBufGetLength(c, bms_DataLength)
#define BufGetDataBitLen(c)                           UserBufGetLength(c, bms_DataBitLength)
#define BufGetReadDataLen(c)                          UserBufGetLength(c, bms_ReadDataLength)
#define BufGetReadDataBitLen(c)                       UserBufGetLength(c, bms_ReadDataBitLength)
#define BufGetValueLen(c)                             UserBufGetLength(c, bms_ValueLength)
#define BufGetValueBitLen(c)                          UserBufGetLength(c, bms_ValueBitLength)

#define BufGetMemory(c, rlen)                         UserBufGetMemory(c, rlen)
#define BufAppendMemory(c, len)                       UserBufAppendMemory(c, len)

#define BufGetDataCurr(c, rbitcurr)                   UserBufGetDataCurr(c, rbitcurr)
#define BufSetDataCurr(c, len, bitcurr)               UserBufSetDataCurr(c, len, bitcurr)
#define BufGetDataEnd(c, rbitend)                     UserBufGetDataEnd(c, rbitend)
#define BufSetDataEnd(c, len, bitend)                 UserBufSetDataEnd(c, len, bitend)

#ifndef CODER_BMS_TINY

#define BufCopyBuf(dst, srs)                          UserBufCopyBuf(dst, srs)

#define BufInitWriteMode(c)                           UserBufInitWriteMode(c)
#define BufCloseWriteMode(c)                          UserBufCloseWriteMode(c)

#define BufInitReadMode(c)                            UserBufInitReadMode(c)
#define BufCloseReadMode(c)                           UserBufCloseReadMode(c)
#define BufCloseDeleteReadMode(c)                     UserBufCloseDeleteReadMode(c)

#define BufGetByte(c)                                 UserBufGetByte(c)
#define BufPeekByte(c)                                UserBufPeekByte(c)
#define BufPutByte(c, byte)                           UserBufPutByte(c, byte)

#define BufGetSeg(c, lenPtr)                          UserBufGetSeg(c, lenPtr)
#define BufSkipSeg(c,lenPtr)                          UserBufSkipSeg(c, lenPtr)
#define BufPeekSeg(c,lenPtr)                          UserBufPeekSeg(c, lenPtr)
#define BufPutSeg(c, data, len)                       UserBufPutSeg(c, data, len)

#define BufPutBit(c, bit)                             UserBufPutBit(c, bit)
#define BufGetBit(c)                                  UserBufGetBit(c)
#define BufPutBits(c, bits, num)                      UserBufPutBits(c, bits, num)
#define BufGetBits(c, num)                            UserBufGetBits(c, num)

#define BufAlign(c)                                   UserBufAlign(c)

#endif /* CODER_BMS_TINY */

#endif /* CODER_BMS_USERBUF */

#ifndef CODER_USERBUF_SIZE
#define CODER_USERBUF_SIZE  0x1000
#endif

typedef struct
{
  unsigned char* MemStart;
  unsigned char* MemEnd;
  unsigned char* DataStart;
  unsigned char* DataEnd;
  unsigned char* DataCurr;
  unsigned char  BitStart;
  unsigned char  BitEnd;
  unsigned char  BitCurr;
  unsigned char  IsAssigned;
} tBMSUserBuffer;

int UserBufInitBuf(tCoder** Coder);
int UserBufCloseBuf(tCoder** Coder);

int UserBufInitBufWithMemory(tCoder** Coder, tBMSUserMemory* UserMemory);
int UserBufCloseBufToMemory(tCoder** Coder, tBMSUserMemory* UserMemory);

tBMSLength UserBufGetLength(tCoder* Coder, tBMSLengthType LengthType);

unsigned char* UserBufGetMemory(tCoder* Coder, tBMSLength* rLength);
unsigned char* UserBufAppendMemory(tCoder* Coder, tBMSLength AppendLen);

unsigned char* UserBufGetDataCurr(tCoder* Coder, unsigned char* rBitCurr);
void           UserBufSetDataCurr(tCoder* Coder, tBMSLength Length, unsigned char BitCurr);
unsigned char* UserBufGetDataEnd (tCoder* Coder, unsigned char* rBitEnd);
void           UserBufSetDataEnd (tCoder* Coder, tBMSLength Length, unsigned char BitEnd);

#ifndef CODER_BMS_TINY

int UserBufCopyBuf(tCoder* Dst, tCoder* Src);

int UserBufInitWriteMode(tCoder* Coder);
int UserBufCloseWriteMode(tCoder* Coder);

int UserBufInitReadMode(tCoder* Coder);
int UserBufCloseReadMode(tCoder* Coder);
int UserBufCloseDeleteReadMode(tCoder* Coder);

unsigned char UserBufGetByte(tCoder* Coder);
unsigned char UserBufPeekByte(tCoder* Coder);
void          UserBufPutByte(tCoder* Coder, unsigned char byte);

unsigned char* UserBufGetSeg(tCoder* Coder, tBMSLength lenPtr);
void           UserBufSkipSeg(tCoder* Coder, tBMSLength lenPtr);
unsigned char* UserBufPeekSeg(tCoder* Coder, tBMSLength lenPtr);
void           UserBufPutSeg(tCoder* Coder, unsigned char* data, tBMSLength len);

unsigned char UserBufGetBit(tCoder* Coder);
void          UserBufPutBit(tCoder* Coder, unsigned char bit);
unsigned long UserBufGetBits(tCoder* Coder, unsigned char num);
void          UserBufPutBits(tCoder* Coder, unsigned long bits, unsigned char num);

void UserBufAlign(tCoder* Coder);

#endif /* CODER_BMS_TINY */

#if !defined(CODER_CHECK_NONE) && !defined(CODER_CHECK_NONE_BUFFER)

#define USERBUF_ERROR_HANDLER_EXP(exp, coder, action, errorcode, args) \
  if (exp) \
    { \
      CUCFErrorHandler(coder, errorcode args); \
      action; \
    }
#define USERBUF_ERROR_HANDLER(coder, action, errorcode, args) \
  { \
    CUCFErrorHandler(coder, errorcode args); \
    action; \
  }
#else
#define USERBUF_ERROR_HANDLER_EXP(exp, coder, action, errorcode, args)
#define USERBUF_ERROR_HANDLER(coder, action, errorcode, args)
#endif

#endif /* CODER_USE_USERBUF */

#endif /* __bms_user_h */
