aboutsummaryrefslogtreecommitdiffstats
path: root/addons/ooh323c/src/perutil.c
diff options
context:
space:
mode:
Diffstat (limited to 'addons/ooh323c/src/perutil.c')
-rw-r--r--addons/ooh323c/src/perutil.c287
1 files changed, 287 insertions, 0 deletions
diff --git a/addons/ooh323c/src/perutil.c b/addons/ooh323c/src/perutil.c
new file mode 100644
index 000000000..c3c7b3696
--- /dev/null
+++ b/addons/ooh323c/src/perutil.c
@@ -0,0 +1,287 @@
+/*
+ * Copyright (C) 1997-2005 by Objective Systems, Inc.
+ *
+ * This software is furnished under an open source license and may be
+ * used and copied only in accordance with the terms of this license.
+ * The text of the license may generally be found in the root
+ * directory of this installation in the COPYING file. It
+ * can also be viewed online at the following URL:
+ *
+ * http://www.obj-sys.com/open/license.html
+ *
+ * Any redistributions of this file including modified versions must
+ * maintain this copyright notice.
+ *
+ *****************************************************************************/
+
+#include "ooasn1.h"
+#include "ooper.h"
+
+ASN1BOOL isExtendableSize (Asn1SizeCnst* pSizeList);
+static ASN1BOOL isFixedSize (Asn1SizeCnst* pSizeList);
+
+ASN1BOOL alignCharStr
+(OOCTXT* pctxt, ASN1UINT len, ASN1UINT nbits, Asn1SizeCnst* pSize)
+{
+ if (TRUE) {
+ ASN1UINT lower, upper;
+ ASN1BOOL doAlign = (len > 0), extendable;
+
+ pSize = checkSize (pSize, len, &extendable);
+
+ if (0 != pSize) {
+ lower = pSize->lower;
+ upper = pSize->upper;
+ }
+ else {
+ lower = 0;
+ upper = ASN1UINT_MAX;
+ }
+
+ if (!extendable && upper < 65536) {
+ ASN1UINT bitRange = upper * nbits;
+ if (upper == lower) {
+ /* X.691, clause 26.5.6 */
+ if (bitRange <= 16) doAlign = FALSE;
+ }
+ else {
+ /* X.691, clause 26.5.7 */
+ if (bitRange < 16) doAlign = FALSE;
+ }
+ }
+
+ return doAlign;
+ }
+ else
+ return FALSE;
+}
+
+int bitAndOctetStringAlignmentTest (Asn1SizeCnst* pSizeList,
+ ASN1UINT itemCount,
+ ASN1BOOL bitStrFlag,
+ ASN1BOOL* pAlignFlag)
+{
+ ASN1UINT threshold = (bitStrFlag) ? 16 : 2;
+
+ if (pSizeList == 0 || itemCount > threshold)
+ *pAlignFlag = TRUE;
+ else if (isFixedSize(pSizeList))
+ *pAlignFlag = FALSE;
+ else {
+
+ /* Variable length case: check size.. no alignment required if */
+ /* lower == upper and not extended.. */
+
+ ASN1BOOL extended;
+ Asn1SizeCnst* pSize = checkSize (pSizeList, itemCount, &extended);
+
+ if (pSize != 0)
+ *pAlignFlag = ((pSize->upper != pSize->lower) || pSize->extended);
+ else {
+ /* Note: we never should get here because constraint */
+ /* violation should have been caught when length was encoded */
+ /* or decoded.. */
+ return (ASN_E_CONSVIO);
+ }
+ }
+
+ return (ASN_OK);
+}
+
+Asn1SizeCnst* checkSize (Asn1SizeCnst* pSizeList,
+ ASN1UINT value,
+ ASN1BOOL* pExtendable)
+{
+ Asn1SizeCnst* lpSize = pSizeList;
+ *pExtendable = isExtendableSize (lpSize);
+
+ while (lpSize) {
+ if (value >= lpSize->lower && value <= lpSize->upper) {
+ return (lpSize);
+ }
+ else lpSize = lpSize->next;
+ }
+
+ return 0;
+}
+
+int getPERMsgLen (OOCTXT* pctxt)
+{
+ return (pctxt->buffer.bitOffset == 8) ?
+ pctxt->buffer.byteIndex : pctxt->buffer.byteIndex + 1;
+}
+
+int addSizeConstraint (OOCTXT* pctxt, Asn1SizeCnst* pSize)
+{
+ Asn1SizeCnst* lpSize;
+ int stat = ASN_OK;
+
+ /* If constraint does not already exist, add it */
+
+ if (!pctxt->pSizeConstraint) {
+ pctxt->pSizeConstraint = pSize;
+ }
+
+ /* Otherwise, check to make sure given constraint is larger than */
+ /* the existing constraint.. */
+
+ else {
+ lpSize = pSize;
+ while (lpSize) {
+ if (pctxt->pSizeConstraint->lower <= lpSize->lower ||
+ pctxt->pSizeConstraint->upper >= lpSize->upper)
+ {
+ /* Set the extension flag to the value of the size */
+ /* constraint structure that the item falls within.. */
+
+ /* pctxt->pSizeConstraint->extended = lpSize->extended; */
+
+ break;
+ }
+ lpSize = lpSize->next;
+ }
+
+ if (!lpSize)
+ stat = ASN_E_CONSVIO;
+ }
+
+ return stat;
+}
+
+Asn1SizeCnst* getSizeConstraint (OOCTXT* pctxt, ASN1BOOL extbit)
+{
+ Asn1SizeCnst* lpSize = pctxt->pSizeConstraint;
+
+ while (lpSize) {
+ if (lpSize->extended == extbit)
+ return lpSize;
+ else
+ lpSize = lpSize->next;
+ }
+
+ return NULL;
+}
+
+int checkSizeConstraint(OOCTXT* pctxt, int size)
+{
+ Asn1SizeCnst* pSize;
+ ASN1UINT lower, upper;
+ ASN1BOOL extbit;
+ int stat;
+
+ /* If size constraint is present and extendable, decode extension */
+ /* bit.. */
+
+ if (isExtendableSize(pctxt->pSizeConstraint)) {
+ stat = DE_BIT (pctxt, &extbit);
+ if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);
+ }
+ else extbit = 0;
+
+ /* Now use the value of the extension bit to select the proper */
+ /* size constraint range specification.. */
+
+ pSize = getSizeConstraint (pctxt, extbit);
+
+ lower = (pSize) ? pSize->lower : 0;
+ upper = (pSize) ? pSize->upper : ASN1UINT_MAX;
+
+ if (upper < (ASN1UINT)size) {
+ return LOG_ASN1ERR (pctxt, ASN_E_CONSVIO);
+ }
+
+ return ASN_OK;
+}
+
+ASN1UINT getUIntBitCount (ASN1UINT value)
+{
+ /* Binary search - decision tree (5 tests, rarely 6) */
+ return
+ ((value < 1<<15) ?
+ ((value < 1<<7) ?
+ ((value < 1<<3) ?
+ ((value < 1<<1) ? ((value < 1<<0) ? 0 : 1) :
+ ((value < 1<<2) ? 2 : 3)) :
+ ((value < 1<<5) ? ((value < 1<<4) ? 4 : 5) :
+ ((value < 1<<6) ? 6 : 7))) :
+ ((value < 1<<11) ?
+ ((value < 1<<9) ? ((value < 1<<8) ? 8 : 9) :
+ ((value < 1<<10) ? 10 : 11)) :
+ ((value < 1<<13) ? ((value < 1<<12) ? 12 : 13) :
+ ((value < 1<<14) ? 14 : 15)))) :
+ ((value < 1<<23) ?
+ ((value < 1<<19) ?
+ ((value < 1<<17) ? ((value < 1<<16) ? 16 : 17) :
+ ((value < 1<<18) ? 18 : 19)) :
+ ((value < 1<<21) ? ((value < 1<<20) ? 20 : 21) :
+ ((value < 1<<22) ? 22 : 23))) :
+ ((value < 1<<27) ?
+ ((value < 1<<25) ? ((value < 1<<24) ? 24 : 25) :
+ ((value < 1<<26) ? 26 : 27)) :
+ ((value < 1<<29) ? ((value < 1<<28) ? 28 : 29) :
+ ((value < 1<<30) ? 30 :
+ ((value < 1UL<<31) ? 31 : 32))))));
+}
+
+void init16BitCharSet (Asn116BitCharSet* pCharSet, ASN116BITCHAR first,
+ ASN116BITCHAR last, ASN1UINT abits, ASN1UINT ubits)
+{
+ pCharSet->charSet.nchars = 0;
+ pCharSet->charSet.data = 0;
+ pCharSet->firstChar = first;
+ pCharSet->lastChar = last;
+ pCharSet->unalignedBits = ubits;
+ pCharSet->alignedBits = abits;
+}
+
+ASN1BOOL isExtendableSize (Asn1SizeCnst* pSizeList)
+{
+ Asn1SizeCnst* lpSize = pSizeList;
+ while (lpSize) {
+ if (lpSize->extended)
+ return TRUE;
+ else
+ lpSize = lpSize->next;
+ }
+ return FALSE;
+}
+
+static ASN1BOOL isFixedSize (Asn1SizeCnst* pSizeList)
+{
+ Asn1SizeCnst* lpSize = pSizeList;
+ if (lpSize && !lpSize->extended && !lpSize->next) {
+ return (ASN1BOOL) (lpSize->lower == lpSize->upper);
+ }
+ return FALSE;
+}
+
+void set16BitCharSet
+(OOCTXT* pctxt, Asn116BitCharSet* pCharSet, Asn116BitCharSet* pAlphabet)
+{
+ /* Permitted alphabet range can either be specified as a range of */
+ /* characters or as a discrete set.. */
+
+ if (pAlphabet->charSet.data) {
+ int nocts = pAlphabet->charSet.nchars * 2;
+ pCharSet->charSet.nchars = pAlphabet->charSet.nchars;
+
+ pCharSet->charSet.data =
+ (ASN116BITCHAR*) ASN1MALLOC (pctxt, nocts);
+
+ if (pCharSet->charSet.data != NULL)
+ memcpy (pCharSet->charSet.data, pAlphabet->charSet.data, nocts);
+ }
+ else {
+ pCharSet->firstChar = pAlphabet->firstChar;
+ pCharSet->lastChar = pAlphabet->lastChar;
+ pCharSet->charSet.nchars = pCharSet->lastChar - pCharSet->firstChar;
+ }
+
+ pCharSet->unalignedBits = getUIntBitCount (pCharSet->charSet.nchars);
+
+ pCharSet->alignedBits = 1;
+ while (pCharSet->unalignedBits > pCharSet->alignedBits)
+ pCharSet->alignedBits <<= 1;
+
+}
+