#include "asn-config.h"
#if TCL
#include <strstream.h>
#endif
#include "asn-len.h"
#include "asn-tag.h"
#include "asn-type.h"
#include "asn-oid.h"
#include "print.h"
AsnOid::~AsnOid()
{
delete oid;
}
AsnType *AsnOid::Clone() const
{
return new AsnOid;
}
AsnType *AsnOid::Copy() const
{
return new AsnOid (*this);
}
#ifndef _IBM_ENC_
void AsnOid::Set (const char *encOid, size_t len)
#else
void AsnOid::Set (const char *encOid, const size_t len)
#endif
{
if (encOid != oid)
{
octetLen = len;
#ifndef _IBM_ENC_
oid = new char[octetLen];
#else
oid = (char *) mem_mgr_ptr->Get (octetLen);
#endif
memcpy (oid, encOid, octetLen);
}
}
void AsnOid::Set (const AsnOid &o)
{
if (&o != this)
{
octetLen = o.octetLen;
#ifndef _IBM_ENC_
oid = new char[octetLen];
#else
oid = (char *) mem_mgr_ptr->Get (octetLen);
#endif
memcpy (oid, o.oid, octetLen);
}
}
void AsnOid::Set (unsigned long int a1, unsigned long int a2, long int a3, long int a4, long int a5, long int a6, long int a7, long int a8, long int a9, long int a10, long int a11)
{
long int arcNumArr[11];
char buf[11*5];
char *tmpBuf;
size_t totalLen;
size_t elmtLen;
long int tmpArcNum;
long int headArcNum;
tmpBuf = buf;
arcNumArr[0] = a1;
arcNumArr[1] = a2;
arcNumArr[2] = a3;
arcNumArr[3] = a4;
arcNumArr[4] = a5;
arcNumArr[5] = a6;
arcNumArr[6] = a7;
arcNumArr[7] = a8;
arcNumArr[8] = a9;
arcNumArr[9] = a10;
arcNumArr[10] = a11;
headArcNum = tmpArcNum = (arcNumArr[0] * 40) + arcNumArr[1];
for (elmtLen = 1; (tmpArcNum >>= 7) != 0; elmtLen++)
;
totalLen = elmtLen;
unsigned i;
for (i = 1; i < elmtLen; i++)
{
*(tmpBuf++) = 0x80 | (headArcNum >> ((elmtLen-i)*7));
}
*(tmpBuf++) = 0x7f & headArcNum;
for (i = 2; (i < 11) && (arcNumArr[i] > 0); i++)
{
tmpArcNum = arcNumArr[i];
for (elmtLen = 1; (tmpArcNum >>= 7) != 0; elmtLen++)
;
totalLen += elmtLen;
tmpArcNum = arcNumArr[i];
for (unsigned j = 1; j < elmtLen; j++)
{
*(tmpBuf++) = 0x80 | (tmpArcNum >> ((elmtLen-j)*7));
}
*(tmpBuf++) = 0x7f & tmpArcNum;
}
#ifndef _IBM_ENC_
oid = Asn1Alloc (totalLen);
#else
oid = (char *) mem_mgr_ptr->Get (totalLen);
#endif
memcpy (oid, buf, totalLen);
octetLen = totalLen;
}
#ifndef _IBM_ENC_
void AsnOid::ReSet (const char *encOid, size_t len)
#else
void AsnOid::ReSet (const char *encOid, const size_t len)
#endif
{
if (encOid != oid)
{
#ifndef _IBM_ENC_
delete oid;
#else
mem_mgr_ptr->Put ((void *) oid);
#endif
Set (encOid, len);
}
}
void AsnOid::ReSet (const AsnOid &o)
{
if (&o != this)
{
#ifndef _IBM_ENC_
delete oid;
#else
mem_mgr_ptr->Put ((void *) oid);
#endif
Set (o);
}
}
void AsnOid::ReSet (unsigned long int a1, unsigned long int a2, long int a3, long int a4, long int a5, long int a6, long int a7, long int a8, long int a9, long int a10, long int a11)
{
#ifndef _IBM_ENC_
delete oid;
#else
mem_mgr_ptr->Put ((void *) oid);
#endif
Set (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);
}
unsigned long int AsnOid::NumArcs() const
{
unsigned i;
int numArcs;
for (numArcs=0, i=0; i < octetLen; )
{
for (; (i < octetLen) && (oid[i] & 0x80); i++)
;
i++;
numArcs++;
}
return numArcs +1;
}
int AsnOid::OidEquiv (const AsnOid &o) const
{
return o.octetLen == octetLen && !strncmp (o.oid, oid, octetLen);
}
void AsnOid::BDecContent (BUF_TYPE b, AsnTag tagId, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env)
{
octetLen = elmtLen;
#ifndef _IBM_ENC_
oid = Asn1Alloc (elmtLen);
#else
oid = (char *) mem_mgr_ptr->Get (elmtLen);
#endif
b.CopyOut (oid, elmtLen);
if (b.ReadError())
{
Asn1Error << "BDecOctetString: ERROR - decoded past end of data" << endl;
#if SNACC_EXCEPTION_ENABLE
SnaccExcep::throwMe(-17);
#else
longjmp (env, -17);
#endif
}
bytesDecoded += elmtLen;
}
AsnLen AsnOid::BEnc (BUF_TYPE b)
{
AsnLen l;
l = BEncContent (b);
l += BEncDefLen (b, l);
l += BEncTag1 (b, UNIV, PRIM, OID_TAG_CODE);
return l;
}
void AsnOid::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
AsnLen elmtLen;
if (BDecTag (b, bytesDecoded, env) != MAKE_TAG_ID (UNIV, PRIM, OID_TAG_CODE))
{
Asn1Error << "AsnOid::BDec: ERROR tag on OBJECT IDENTIFIER is wrong." << endl;
#if SNACC_EXCEPTION_ENABLE
SnaccExcep::throwMe(-57);
#else
longjmp (env,-57);
#endif
}
elmtLen = BDecLen (b, bytesDecoded, env);
BDecContent (b, MAKE_TAG_ID (UNIV, PRIM, OID_TAG_CODE), elmtLen, bytesDecoded, env);
}
AsnLen AsnOid::BEncContent (BUF_TYPE b)
{
b.PutSegRvs (oid, octetLen);
return octetLen;
}
void AsnOid::Print (ostream &os) const
{
#ifndef NDEBUG
unsigned short int firstArcNum;
unsigned long int arcNum;
unsigned i;
os << "{";
if (oid)
{
for (arcNum = 0, i=0; (i < octetLen) && (oid[i] & 0x80); i++)
arcNum = (arcNum << 7) + (oid[i] & 0x7f);
arcNum = (arcNum << 7) + (oid[i] & 0x7f);
i++;
firstArcNum = arcNum/40;
if (firstArcNum > 2)
firstArcNum = 2;
os << firstArcNum << " " << arcNum - (firstArcNum * 40);
for (; i < octetLen; )
{
for (arcNum = 0; (i < octetLen) && (oid[i] & 0x80); i++)
arcNum = (arcNum << 7) + (oid[i] & 0x7f);
arcNum = (arcNum << 7) + (oid[i] & 0x7f);
i++;
os << " " << arcNum;
}
}
else
os << "-- void --";
os << "}";
#endif
}
#if META
const AsnOidTypeDesc AsnOid::_desc (NULL, NULL, false, AsnTypeDesc::OBJECT_IDENTIFIER, NULL);
const AsnTypeDesc *AsnOid::_getdesc() const
{
return &_desc;
}
#if TCL
int AsnOid::TclGetVal (Tcl_Interp *interp) const
{
if (oid)
{
strstream buf;
buf << *this;
buf.str()[strlen(buf.str())-1] = '\0'; Tcl_SetResult (interp, buf.str()+1, TCL_VOLATILE); }
return TCL_OK;
}
int AsnOid::TclSetVal (Tcl_Interp *interp, const char *valstr)
{
if (!*valstr)
{
delete oid;
oid = NULL;
octetLen = 0;
return TCL_OK;
}
Args arc;
if (Tcl_SplitList (interp, (char*)valstr, &arc.c, &arc.v) != TCL_OK)
return TCL_ERROR;
if (arc.c < 2)
{
Tcl_AppendResult (interp, "oid arc must contain at least two numbers", NULL);
Tcl_SetErrorCode (interp, "SNACC", "ILLARC", "<2", NULL);
return TCL_ERROR;
}
if (arc.c > 11)
{
Tcl_AppendResult (interp, "snacc limits oid arcs to no more than 11 numbers", NULL);
Tcl_SetErrorCode (interp, "SNACC", "ILLARC", ">11", NULL);
return TCL_ERROR;
}
int na[11], i;
for (i=0; i<arc.c; i++)
if (Tcl_GetInt (interp, arc.v[i], na+i) != TCL_OK)
return TCL_ERROR;
while (i < 11)
na[i++] = -1;
ReSet (na[0], na[1], na[2], na[3], na[4], na[5], na[6], na[7], na[8], na[9], na[10]);
return TCL_OK;
}
#endif
#endif