blob: 89b92c4886acf4689e4aeb9e4e0e226685da5190 [file] [log] [blame]
/*******************************************************************************
* Copyright Statement:
* --------------------
* This software is protected by Copyright and the information contained
* herein is confidential. The software may not be copied and the information
* contained herein may not be used or disclosed except with the written
* permission of MediaTek Inc. (C) 2011
*
* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
*
* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
*
* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
*
*****************************************************************************/
/****************************************************************************
*
* COMPONENT: ASN
* MODULE: ASN_COMMON
* DESCRIPTION: Auto generated by MTK ASN.1 Compiler
*
****************************************************************************/
/*****************************************************************************
* removed!
*
* removed!
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
****************************************************************************/
#include <setjmp.h>
#include <assert.h>
#include "kal_public_api.h"
#include "asn_common.h"
#include "asn_memory.h"
#ifdef MCD_DLL_EXPORT
#include <stdarg.h>
#if defined(__COSIM_BYPASS_DRV__)
void MDM_ASSERT(kal_uint32 e1, kal_uint32 e2, kal_uint32 e3)
{
while(1);/* YY Hsieh */
}
#endif
void AsnFreeString( char *string )
{
if( string )
{
asnMemFree( (void **)&string );
}
}
void InitAsnBuf( AsnContext *pContext )
{
pContext->printBufSize = ASNBUF_BLOCKSIZE;
pContext->pMemAllocFunc=NULL;
pContext->pMemFreeFunc =NULL;
asnMemAlloc(pContext,(void**)&pContext->printBufStart, pContext->printBufSize);
pContext->printBufNext = pContext->printBufStart;
}
void AsnPrint( AsnContext *pContext, char *fmt, ... )
{
va_list va;
char *new_buf;
if( (unsigned)(pContext->printBufNext - pContext->printBufStart) > pContext->printBufSize - ASNBUF_RESERVE )
{
/* Buffer usage has crossed the watermark - need to allocate another
buffer one block size bigger */
pContext->printBufSize += ASNBUF_BLOCKSIZE;
asnMemAlloc(pContext,(void**)&new_buf, pContext->printBufSize );
/* Copy everything from the old buffer to the new buffer */
memcpy( new_buf, pContext->printBufStart, pContext->printBufNext - pContext->printBufStart );
pContext->printBufNext = pContext->printBufNext - pContext->printBufStart + new_buf;
/* Free the old buffer */
if( pContext->printBufStart )
asnMemFree( (void**)&pContext->printBufStart );
pContext->printBufStart = new_buf;
}
va_start( va, fmt );
pContext->printBufNext += vsprintf( pContext->printBufNext, fmt, va );
va_end( va );
}
void AsnPrintNull( AsnContext *pContext )
{
AsnPrint( pContext, "NULL" );
}
void AsnPrintInteger( AsnContext *pContext, S32 value )
{
AsnPrint( pContext, "%d", value );
}
void AsnPrintBoolean( AsnContext *pContext, Bool boolean )
{
if( boolean == TRUE )
{
AsnPrint( pContext, "TRUE" );
}
else
{
AsnPrint( pContext, "FALSE" );
}
}
void AsnPrintOctetString( AsnContext *pContext, U8 *buffer, U32 length )
{
unsigned int i;
AsnPrint( pContext, "'" );
for( i = 0; i < length; i++ )
{
AsnPrint( pContext, "%02X", buffer[i] );
}
AsnPrint( pContext, "'H" );
}
void AsnPrintBitString( AsnContext *pContext, U8 *buffer, U32 length )
{
unsigned int i;
U8 mask[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
AsnPrint( pContext, "'" );
for( i = 0; i < length; i++ )
{
if( buffer[ i/8 ] & mask[ i%8 ] )
AsnPrint( pContext, "1" );
else
AsnPrint( pContext, "0" );
}
AsnPrint( pContext, "'B" );
}
void AsnPrintCharacterString( AsnContext *pContext, char *string )
{
AsnPrint( pContext, "\"" );
AsnPrint( pContext, "%s", string );
AsnPrint( pContext, "\"" );
}
void AsnPrintOneByteString( AsnContext *pContext, U8 *buffer, U32 length )
{
unsigned int i;
AsnPrint( pContext, "'" );
for( i = 0; i < length; i++ )
{
AsnPrint( pContext, "%c", buffer[i] );
}
AsnPrint( pContext, "'" );
}
void AsnPrintVisibleString( AsnContext *pContext, asn_VisibleString* pType )
{
AsnPrintOneByteString( pContext, pType->value, pType->valueLen );
}
void AsnPrintIA5String( AsnContext *pContext, asn_IA5String* pType )
{
AsnPrintOneByteString( pContext, pType->value, pType->valueLen );
}
#endif //MCD_DLL_EXPORT
U16 GetUperLengthDeterminant( AsnContext *pContext )
{
U16 length = 0;
if( ! getShortBits( pContext, 1 ) )
{
/* 7 bit length */
length = (U16)getShortBits( pContext, 7 );
}
else
if( !getShortBits( pContext, 1 ) )
{
/* 14 bit length */
length = (U16)getShortBits( pContext, 14 );
}
else
{
/* Unsupported length format */
UA1_ERROR( 1 );
}
return length;
}
void PutUperLengthDeterminant( AsnContext *pContext, U16 length )
{
if( length < 128 )
{
/* 8 bit length determinant */
putShortBits( pContext, 8, length );
}
else
if( length < 16384 )
{
/* 16 bit length determinant */
putShortBits( pContext, 16, length | 0x8000 );
}
else
{
/* Unsupported length */
UA1_ERROR( 2 );
}
}
void AsnFreeDecoded( void *pType, PAsnMemFreeCallBack pFreeFunc)
{
AsnDecodeFree( ( AllocRecord *)pType - 1, pFreeFunc);
}
void AsnFreeEncoded( U8 *pEncoded, PAsnMemFreeCallBack pFreeFunc)
{
AsnEncodeFree( pEncoded, pFreeFunc);
}
void AsnRootDecodeAlloc( AsnContext *pContext, void **ppType, int size )
{
if( !(*ppType) )
{
#if defined(__UMTS_RAT__) || defined(__LTE_RAT__)
int i;
#endif
size += sizeof( AllocRecord );
asnMemAlloc(pContext, (void**) &pContext->decodeAlloc, size );
pContext->decodeAlloc->ppEnd = &(pContext->decodeAlloc->pMemBlock[0]) + sizeof( pContext->decodeAlloc->pMemBlock ) / sizeof( pContext->decodeAlloc->pMemBlock[0] );
pContext->decodeAlloc->ppNext = &(pContext->decodeAlloc->pMemBlock[0]);
*ppType = pContext->decodeAlloc + 1;
#if defined(__UMTS_RAT__) || defined(__LTE_RAT__)
/*nick for block reset*/
pContext->decodeAlloc->blocknum = 0;
for ( i = 0 ; i < ASN_BLOCK_FREE_NUM ;i ++) {
pContext->decodeAlloc->start[i] = NULL;
pContext->decodeAlloc->count[i] = 0;
}
#endif
}
}
void AsnDecodeAlloc( AsnContext *pContext, void **ppMem, int size )
{
if( !pContext->decodeAlloc )
{
/* Attempt to allocate memory when decoding to a user supplied buffer */
UA1_ERROR( 3 );
}
if( pContext->decodeAlloc->ppNext >= pContext->decodeAlloc->ppEnd )
{
/* Limit of runtime allocated decode memory blocks reached */
//printf("Limit of runtime allocated decode memory blocks reached");
UA1_ERROR( 4 );
}
asnMemAlloc(pContext, ppMem, size );
*pContext->decodeAlloc->ppNext++ = *ppMem;
}
void AsnDecodeFree( AllocRecord *decodeAlloc, PAsnMemFreeCallBack pFreeFunc)
{
void **ppFree;
if( decodeAlloc )
{
for( ppFree = decodeAlloc->pMemBlock; ppFree < decodeAlloc->ppNext; ppFree++ )
{
if (pFreeFunc == NULL)
{
asnMemFree( ppFree );
}
else
{
pFreeFunc( ppFree );
}
}
if (pFreeFunc == NULL)
{
asnMemFree((void**)&decodeAlloc);
}
else
{
pFreeFunc((void**)&decodeAlloc);
}
}
}
#if defined(__UMTS_RAT__) || defined(__LTE_RAT__)
/* nick integrate from old asn */
void AsnDecodeFreeWithCallback( AllocRecord *decodeAlloc, PAsnMemFreeCallBack pFreeFunc)
{
void **ppFree;
if( decodeAlloc )
{
for( ppFree = decodeAlloc->pMemBlock; ppFree < decodeAlloc->ppNext; ppFree++ )
{
if (pFreeFunc == NULL)
{
asnMemFree( ppFree );
}
else
{
pFreeFunc( ppFree );
}
}
if (pFreeFunc == NULL)
{
asnMemFree((void**)&decodeAlloc);
}
else
{
pFreeFunc((void**)&decodeAlloc);
}
}
}
/*nick for block free */
static void AsnDecodeFreeWithBlock( AllocRecord *decodeAlloc, PAsnMemFreeCallBack pFreeFunc)
{
void **ppFree;
if( decodeAlloc )
{
for( ppFree = decodeAlloc->pMemBlock; ppFree < decodeAlloc->ppNext; ppFree++ )
{
int i = 0;
int found = 0;
for (i=0; i <ASN_BLOCK_FREE_NUM ; i++) {
if (!decodeAlloc->start[i]) break;
if (decodeAlloc->start[i] &&
decodeAlloc->count[i] &&
*ppFree == decodeAlloc->start[i] ) {
ppFree += ( decodeAlloc->count[i] -1 );
found = 1;
break;
}
}
if (found ) continue;
if (pFreeFunc == NULL)
{
asnMemFree((void**)ppFree );
}
else
{
pFreeFunc((void**)ppFree );
}
}
if (pFreeFunc == NULL)
{
asnMemFree((void**)&decodeAlloc);
}
else
{
pFreeFunc((void**)&decodeAlloc);
}
}
}
static void AsnDecodeFreeSetBlock( AllocRecord *decodeAlloc, PAsnMemFreeCallBack pFreeFunc, void *start, int count )
{
//void **ppFree;
if( decodeAlloc )
{
/*EXT_ASSERT(start && count);*/
/*EXT_ASSERT(decodeAlloc->blocknum < ASN_BLOCK_FREE_NUM);*/
if (1) { /* no constrain here */
decodeAlloc->start[decodeAlloc->blocknum] = start;
decodeAlloc->count[decodeAlloc->blocknum] = count;
decodeAlloc->blocknum++;
}
if (pFreeFunc == NULL) {
/* do nothing*/
} else {
/* do nothing*/
}
}
}
void AsnFreeDecodedWithBlock( void *pType , PAsnMemFreeCallBack pFreeFunc)
{
AsnDecodeFreeWithBlock( (AllocRecord *)pType - 1, pFreeFunc );
}
void AsnFreeDecodedSetBlock( void *pType, PAsnMemFreeCallBack pFreeFunc, void *start, int count)
{
AsnDecodeFreeSetBlock( (AllocRecord *)pType - 1, pFreeFunc, start, count);
}
#endif
void AsnEncodeAlloc( AsnContext *pContext, U8 **ppMem, U32 *pEncodedLength )
{
U32 size;
if (NULL == ppMem)
{
// Encode length test
pContext->pEncoded = NULL;
}
else
{
if( !(*ppMem) )
{
/* Fixed size buffer allocated for encoding, you can change this size by modify the batch command */
size = 4000;
asnMemAlloc(pContext, (void**)&pContext->encodeAlloc, size );
*ppMem = (U8*)pContext->encodeAlloc;
}
NOT_USED( pEncodedLength );
}
}
void AsnEncodeFree( void *pFree, PAsnMemFreeCallBack pFreeFunc)
{
if( pFree )
{
if (pFreeFunc == NULL)
{
asnMemFree( &pFree );
}
else
{
pFreeFunc( &pFree );
}
}
}
#if defined(__UMTS_RAT__) || defined(__LTE_RAT__)
/* nick add it*/
void AsnEncodeFreeWithCallback( void *pFree, PAsnMemFreeCallBack pFreeFunc)
{
if( pFree )
{
if (pFreeFunc == NULL)
{
asnMemFree( &pFree );
}
else
{
pFreeFunc( &pFree );
}
}
}
#endif
void AsnError( AsnContext *pContext, U32 errorCode )
{
pContext->result = errorCode;
longjmp( pContext->env, 1 );
}
extern S32 GetAlphabetIndex(ASN_OneByteAlphabet *pAlphabet, char *pChar)
{
U32 uIndex, left, right;
left = 0;
right = pAlphabet->valueLen - 1;
while(left <= right)
{
uIndex = (left + right) / 2;
if(*(pAlphabet->value+uIndex) == *pChar)
{
return uIndex;
}
else if(*(pAlphabet->value+uIndex) > *pChar)
{
right = uIndex - 1;
}
else
{
left = uIndex + 1;
}
}
return -1;
}
extern U32 GetNumberOctetLength(U32 Data)
{
if (Data <= 0xFF) {
return 1;
}
if (Data > 0xFF &&
Data <= 0xFFFF) {
return 2;
}
if (Data > 0xFFFF &&
Data <= 0xFFFFFF) {
return 3;
}
else if (Data > 0xFFFFFF &&
Data <= 0xFFFFFFFF) {
return 4;
}
else{
return 0;
}
}
extern Bool OIDCompare(OID oidA, U32 length, U32 *pValue)
{
if (oidA.valueLen != length)
{
return (Bool)FALSE;
}
if (0 == asnMemCmp(oidA.value, pValue, length * sizeof(U32)))
{
return (Bool)TRUE;
}
else
{
return (Bool)FALSE;
}
}
static struct {
U8 *pByte;
}SkipedEncodeByte;
extern void SkipEncodeByte(AsnContext *pContext)
{
SkipedEncodeByte.pByte = pContext->pEncoded;
pContext->pEncoded += 1;
}
extern EncodeBeginPoint BeginTestEncodeLen(AsnContext *pContext)
{
if (NULL != pContext->pEncoded)
{
return (EncodeBeginPoint) pContext->pEncoded;
}
else
{
return (EncodeBeginPoint)pContext->shiftRegister;
}
}
extern U32 EndTestEncodeLen(AsnContext *pContext, EncodeBeginPoint BeginPoint)
{
S32 len;
ASSERT(BeginPoint != 0);
if (NULL == pContext->pEncoded)
{
len = (U32)pContext->shiftRegister - (U32)BeginPoint;
}
else
{
len = (U32)pContext->pEncoded - (U32)BeginPoint;
}
len = len > 0 ? len : -len ;
return len;
}
extern U32 testGetShortBits( AsnContext *pContext, U32 numBits)
{
U32 result;
AsnContext TempContext = *pContext;
result = getShortBits(&TempContext, numBits);
return result;
}
extern void PutShortSkipedEncodeByte(AsnContext *pContext, U32 uByte, U32 Data, U32 uAfterSize)
{
AsnContext tempContext;
if (uAfterSize != 0)
{
ASSERT(1 >= uByte);
}
if (1 < uByte)
{
asnMemMove(SkipedEncodeByte.pByte+uByte, SkipedEncodeByte.pByte + 1, uAfterSize);
}
tempContext = *pContext;
pContext->pEncoded = SkipedEncodeByte.pByte;
putShortBits(pContext, uByte * 8, Data);
*pContext = tempContext;
}
#define MAX_BITS_FOR_SHORT (24)
#define BIT_MASK_ARRAY_LENGTH (65)
#if defined (__GNUC__)
static const U64 lsbMask[BIT_MASK_ARRAY_LENGTH]=
{
0X0000000000000000ULL,
0X0000000000000001ULL, 0X0000000000000003ULL, 0X0000000000000007ULL, 0X000000000000000FULL,
0X000000000000001FULL, 0X000000000000003FULL, 0X000000000000007FULL, 0X00000000000000FFULL,
0X00000000000001FFULL, 0X00000000000003FFULL, 0X00000000000007FFULL, 0X0000000000000FFFULL,
0X0000000000001FFFULL, 0X0000000000003FFFULL, 0X0000000000007FFFULL, 0X000000000000FFFFULL,
0X000000000001FFFFULL, 0X000000000003FFFFULL, 0X000000000007FFFFULL, 0X00000000000FFFFFULL,
0X00000000001FFFFFULL, 0X00000000003FFFFFULL, 0X00000000007FFFFFULL, 0X0000000000FFFFFFULL,
0X0000000001FFFFFFULL, 0X0000000003FFFFFFULL, 0X0000000007FFFFFFULL, 0X000000000FFFFFFFULL,
0X000000001FFFFFFFULL, 0X000000003FFFFFFFULL, 0X000000007FFFFFFFULL, 0X00000000FFFFFFFFULL,
0X00000001FFFFFFFFULL, 0X00000003FFFFFFFFULL, 0X00000007FFFFFFFFULL, 0X0000000FFFFFFFFFULL,
0X0000001FFFFFFFFFULL, 0X0000003FFFFFFFFFULL, 0X0000007FFFFFFFFFULL, 0X000000FFFFFFFFFFULL,
0X000001FFFFFFFFFFULL, 0X000003FFFFFFFFFFULL, 0X000007FFFFFFFFFFULL, 0X00000FFFFFFFFFFFULL,
0X00001FFFFFFFFFFFULL, 0X00003FFFFFFFFFFFULL, 0X00007FFFFFFFFFFFULL, 0X0000FFFFFFFFFFFFULL,
0X0001FFFFFFFFFFFFULL, 0X0003FFFFFFFFFFFFULL, 0X0007FFFFFFFFFFFFULL, 0X000FFFFFFFFFFFFFULL,
0X001FFFFFFFFFFFFFULL, 0X003FFFFFFFFFFFFFULL, 0X007FFFFFFFFFFFFFULL, 0X00FFFFFFFFFFFFFFULL,
0X01FFFFFFFFFFFFFFULL, 0X03FFFFFFFFFFFFFFULL, 0X07FFFFFFFFFFFFFFULL, 0X0FFFFFFFFFFFFFFFULL,
0X1FFFFFFFFFFFFFFFULL, 0X3FFFFFFFFFFFFFFFULL, 0X7FFFFFFFFFFFFFFFULL, 0XFFFFFFFFFFFFFFFFULL
};
#else
static const U64 lsbMask[BIT_MASK_ARRAY_LENGTH]=
{
0x0000000000000000,
0x0000000000000001, 0x0000000000000003, 0x0000000000000007, 0x000000000000000f,
0x000000000000001f, 0x000000000000003f, 0x000000000000007f, 0x00000000000000ff,
0x00000000000001ff, 0x00000000000003ff, 0x00000000000007ff, 0x0000000000000fff,
0x0000000000001fff, 0x0000000000003fff, 0x0000000000007fff, 0x000000000000ffff,
0x000000000001ffff, 0x000000000003ffff, 0x000000000007ffff, 0x00000000000fffff,
0x00000000001fffff, 0x00000000003fffff, 0x00000000007fffff, 0x0000000000ffffff,
0x0000000001ffffff, 0x0000000003ffffff, 0x0000000007ffffff, 0x000000000fffffff,
0x000000001fffffff, 0x000000003fffffff, 0x000000007fffffff, 0x00000000ffffffff,
0x00000001ffffffff, 0x00000003ffffffff, 0x00000007ffffffff, 0x0000000fffffffff,
0x0000001fffffffff, 0x0000003fffffffff, 0x0000007fffffffff, 0x000000ffffffffff,
0x000001ffffffffff, 0x000003ffffffffff, 0x000007ffffffffff, 0x00000fffffffffff,
0x00001fffffffffff, 0x00003fffffffffff, 0x00007fffffffffff, 0x0000ffffffffffff,
0x0001ffffffffffff, 0x0003ffffffffffff, 0x0007ffffffffffff, 0x000fffffffffffff,
0x001fffffffffffff, 0x003fffffffffffff, 0x007fffffffffffff, 0x00ffffffffffffff,
0x01ffffffffffffff, 0x03ffffffffffffff, 0x07ffffffffffffff, 0x0fffffffffffffff,
0x1fffffffffffffff, 0x3fffffffffffffff, 0x7fffffffffffffff, 0xffffffffffffffff
};
#endif //defined (__GNUC__)
extern void initFifo( AsnContext *pContext, U8 *buffer, U32 bufferLength )
{
pContext->pEncoded = buffer;
pContext->pEncodedEnd = buffer + bufferLength;
pContext->shiftRegister = pContext->shiftRegisterLength = 0;
pContext->result = 0;
}
extern void flushFifo( AsnContext *pContext )
{
if( pContext->shiftRegisterLength > 0 )
{
if (NULL == pContext->pEncoded)
{
pContext->shiftRegister++;
}
else
{
*pContext->pEncoded++ = (U8)(pContext->shiftRegister >> 24);
}
}
}
extern U32 getShortBits( AsnContext *pContext, U32 numBits )
{
U32 retVal;
ASSERT( numBits <= MAX_BITS_FOR_SHORT );
while ( numBits > pContext->shiftRegisterLength )
{
if( pContext->pEncoded >= pContext->pEncodedEnd )
{
UA1_ERROR( 5 );
}
pContext->shiftRegister |= *pContext->pEncoded++ << (24 - pContext->shiftRegisterLength);
pContext->shiftRegisterLength += 8;
}
retVal = pContext->shiftRegister >> (32 - numBits);
pContext->shiftRegister <<= numBits;
pContext->shiftRegisterLength -= numBits;
return( retVal );
}
extern U32 getBits( AsnContext *pContext, U32 numBits )
{
U32 retVal;
if ( numBits > 32)
{
UA1_ERROR( 7 );
}
else if ( numBits <= MAX_BITS_FOR_SHORT )
{
retVal = (U32)getShortBits( pContext, numBits );
}
else
{
retVal = (U32) getShortBits( pContext, MAX_BITS_FOR_SHORT );
numBits -= MAX_BITS_FOR_SHORT;
/* ASN.1 is big endian so first n bits go at top of word */
retVal <<= numBits;
retVal |= (U32)getShortBits( pContext, numBits );
}
return( retVal );
}
extern void getLongBits( AsnContext *pContext, U32 numBits, U8 *outputBuffer )
{
while ( numBits >= 8 )
{
if( pContext->pEncoded >= pContext->pEncodedEnd )
{
UA1_ERROR( 6 );
}
pContext->shiftRegister |= *pContext->pEncoded++ << (24 - pContext->shiftRegisterLength);
*outputBuffer++ = (U8)(pContext->shiftRegister >> 24);
pContext->shiftRegister <<= 8;
numBits-= 8;
}
if ( numBits )
{
*outputBuffer = (U8)(getShortBits( pContext, numBits ) << (8 - numBits));
}
}
extern U64 getInt64( AsnContext *pContext, U32 numBits )
{
U64 retVal;
ASSERT( numBits <= 64 );
if ( numBits <= 32 )
{
retVal = (U64)getBits( pContext, numBits );
}
else
{
retVal = (U64) getBits( pContext, 32 );
numBits -= 32;
/* ASN.1 is big endian so first n bits go at top of word */
retVal <<= numBits;
retVal |= (U64)getBits( pContext, numBits );
}
return( retVal );
}
extern void putShortBits( AsnContext *pContext, U32 numBits, U32 data )
{
ASSERT( numBits <= MAX_BITS_FOR_SHORT );
ASSERT( 0 == (data & ~lsbMask[numBits]) );
if (NULL != pContext->pEncoded)
{
pContext->shiftRegister |= data << (32 - pContext->shiftRegisterLength - numBits);
}
pContext->shiftRegisterLength += numBits;
while ( pContext->shiftRegisterLength >= 8 )
{
if (NULL == pContext->pEncoded)
{
pContext->shiftRegister++;
}
else
{
if (pContext->pEncoded >= pContext->pEncodedEnd)
{
UA1_ERROR(15);
}
*pContext->pEncoded++ = (U8)(pContext->shiftRegister >> 24);
pContext->shiftRegister <<= 8;
}
pContext->shiftRegisterLength -= 8;
}
}
extern void putBits( AsnContext *pContext, U32 numBits, U32 data )
{
ASSERT( numBits <= 32 );
if( numBits > MAX_BITS_FOR_SHORT )
{
/* Insert top 24 bits */
putShortBits( pContext, MAX_BITS_FOR_SHORT, data >> (numBits - MAX_BITS_FOR_SHORT) );
/* reduce amount to fit, and then mask off bits inserted */
numBits -= MAX_BITS_FOR_SHORT;
data &= lsbMask[numBits];
}
putShortBits( pContext, numBits, data );
}
extern void putInt64( AsnContext *pContext, U32 numBits, U64 data )
{
ASSERT( numBits <= 64 );
if( numBits > 32 )
{
/* Insert top 32 bits */
putBits( pContext, 32, (U32)(data >> (numBits - 32)) );
/* reduce amount to fit, and then mask off bits inserted */
numBits -= 32;
data &= lsbMask[numBits];
}
putBits( pContext, numBits, (U32)(data) );
}
extern void putLongBits( AsnContext *pContext, U32 numBits, U8 *data )
{
while ( numBits >= 8 )
{
if (NULL == pContext->pEncoded)
{
pContext->shiftRegister++;
}
else
{
if (pContext->pEncoded >= pContext->pEncodedEnd)
{
UA1_ERROR(15);
}
pContext->shiftRegister |= *data++ << ( 24 - pContext->shiftRegisterLength );
*pContext->pEncoded++ = (U8)(pContext->shiftRegister >> 24);
pContext->shiftRegister <<= 8;
}
numBits -= 8;
}
if ( numBits && data )
{
putShortBits( pContext, numBits, *data >> (8 - numBits) );
}
}