diff options
Diffstat (limited to 'lib/libaccess/attrec.cpp')
-rw-r--r-- | lib/libaccess/attrec.cpp | 309 |
1 files changed, 309 insertions, 0 deletions
diff --git a/lib/libaccess/attrec.cpp b/lib/libaccess/attrec.cpp new file mode 100644 index 00000000..8911e896 --- /dev/null +++ b/lib/libaccess/attrec.cpp @@ -0,0 +1,309 @@ +/** BEGIN COPYRIGHT BLOCK + * Copyright 2001 Sun Microsystems, Inc. + * Portions copyright 1999, 2001-2003 Netscape Communications Corporation. + * All rights reserved. + * END COPYRIGHT BLOCK **/ + +/* + * Description (attrec.c) + * + * This module contains routines for encoding and decoding + * attribute records. See attrec.h for a description of attribute + * records. + */ + +#include "base/systems.h" +#include "netsite.h" +#include "assert.h" +#define __PRIVATE_ATTREC +#include "libaccess/attrec.h" + +/* + * Description (NTS_Length) + * + * This function returns the length of a null-terminated string. + * The length includes the terminating null octet. + * + * Use of the NTSLENGTH() macro is recommended (see attrec.h). + * + * Arguments: + * + * nts - a pointer to the null-terminate string + * (may be null) + * + * Returns: + * + * The length of the string. If 'nts' is null, the value is one, + * since there is always a null octet. + */ + +int NTS_Length(NTS_t nts) +{ + return ((nts) ? strlen((const char *)nts) + 1 : 1); +} + +/* + * Description (NTS_Decode) + * + * This function decodes a null-terminated string from a specified + * attribute record buffer. It copies the string into a dynamically + * allocated buffer, if 'pnts' is not null, and returns a pointer + * to it. The return value of the function is a pointer to the + * octet following the NTS in the attribute record buffer. + * + * Use of the NTSDECODE() macro is recommended (see attrec.h). + * + * Arguments: + * + * cp - pointer into the attribute record buffer + * pnts - pointer to returned reference to decoded + * NTS, or null, if the decoded NTS is not + * to be copied to a dynamic buffer + * + * Returns: + * + * The function return value is a pointer to the octet following + * the NTS in the attribute record buffer. A pointer to a + * dynamically allocated buffer containing the decoded NTS will + * be returned through 'pnts', if it is non-null. This returned + * pointer will be null if the NTS contains only a terminating + * octet. + */ + +ATR_t NTS_Decode(ATR_t cp, NTS_t * pnts) +{ + NTS_t nts = 0; + int len = NTSLENGTH(cp); /* length of the string */ + + /* Are we going to return a copy of the string? */ + if (pnts) { + + /* Yes, is it more than just a null octet? */ + if (len > 1) { + + /* Yes, allocate a buffer and copy the string to it */ + nts = (NTS_t)MALLOC(len); + if (nts) { + memcpy((void *)nts, (void *)cp, len); + } + } + + /* Return a pointer to the copied string, or null */ + *pnts = nts; + } + + /* Return pointer to octet after string */ + return cp + len; +} + +/* + * Description (NTS_Encode) + * + * This function encodes a null-terminated string into a specified + * attribute record buffer. It returns a pointer to the octet + * following the encoding. + * + * Use of the NTSENCODE() macro is recommended (see attrec.h). + * + * Arguments: + * + * cp - pointer into the attribute record buffer + * nts - pointer to the string to be encoded + * + * Returns: + * + * A pointer to the octet following the encoding in the attribute + * record buffer is returned. + */ + +ATR_t NTS_Encode(ATR_t cp, NTS_t nts) +{ + + /* Is the string pointer null? */ + if (nts) { + int len = NTSLENGTH(nts); + + /* No, copy the string to the attribute record buffer */ + memcpy((void *)cp, (void *)nts, len); + + /* Get pointer to octet after it */ + cp += len; + } + else { + + /* A null pointer indicates an empty NTS, i.e. just a null octet */ + *cp++ = 0; + } + + /* Return a pointer to the octet after the encoding */ + return cp; +} + +/* + * Description (USI_Decode) + * + * This function decodes an unsigned integer value from a specified + * attribute record buffer. + * + * Use of the USIDECODE() macro is recommended (see attrec.h). + * + * Arguments: + * + * cp - pointer into the attribute record buffer + * pval - pointer to returned integer value + * + * Returns: + * + * If 'pval' is not null, the decoded integer value is returned + * in the referenced location. The function return value is a + * pointer to the octet following the USI encoding in the attribute + * record buffer. + */ + +ATR_t USI_Decode(ATR_t cp, USI_t * pval) +{ + int val; + + /* Is this a length value? */ + if (*(cp) & 0x80) { + int i; + int len; + + /* Yes, build the value from the indicated number of octets */ + len = *cp++ & 0x7; + val = 0; + for (i = 0; i < len; ++i) { + val <<= 8; + val |= (cp[i] & 0xff); + } + cp += len; + } + else { + + /* This octet is the value */ + val = *cp++; + } + + /* Return the value if there's a place to put it */ + if (pval) *pval = val; + + /* Return a pointer to the next item in the attribute record */ + return cp; +} + +/* + * Description (USI_Encode) + * + * This function encodes an unsigned integer value into a specified + * attribute record buffer. + * + * Use of the USIENCODE() macro is recommended (see attrec.h). + * + * Arguments: + * + * cp - pointer into the attribute record buffer + * val - the value to be encoded + * + * Returns: + * + * A pointer to the octet following the generated encoding in the + * attribute record buffer is returned. + */ + +ATR_t USI_Encode(ATR_t cp, USI_t val) +{ + /* Check size of value to be encoded */ + if (val <= 0x7f) *cp++ = val; + else if (val <= 0xff) { + /* Length plus 8-bit value */ + *cp++ = 0x81; + *cp++ = val; + } + else if (val <= 0xffff) { + /* Length plus 16-bit value */ + *cp++ = 0x82; + cp[1] = val & 0xff; + val >>= 8; + cp[0] = val & 0xff; + cp += 2; + } + else if (val <= 0xffffff) { + /* Length plus 24-bit value */ + *cp++ = 0x83; + cp[2] = val & 0xff; + val >>= 8; + cp[1] = val & 0xff; + val >>= 8; + cp[0] = val & 0xff; + cp += 3; + } + else { + /* Length plus 32-bit value */ + *cp++ = 0x84; + cp[3] = val & 0xff; + val >>= 8; + cp[2] = val & 0xff; + val >>= 8; + cp[1] = val & 0xff; + val >>= 8; + cp[0] = val & 0xff; + cp += 4; + } + + /* Return a pointer to the next position in the attribute record */ + return cp; +} + +/* + * Description (USI_Insert) + * + * This function is a variation of USI_Encode() that always generates + * the maximum-length encoding for USI value, regardless of the + * actual specified value. For arguments, returns, see USI_Encode(). + * + * Use of the USIINSERT() macro is recommended. The USIALLOC() macro + * returns the number of octets that USIINSERT() will generate. + */ + +ATR_t USI_Insert(ATR_t cp, USI_t val) +{ + int i; + + assert(USIALLOC() == 5); + + *cp++ = 0x84; + for (i = 3; i >= 0; --i) { + cp[i] = val & 0xff; + val >>= 8; + } + + return cp + 5; +} + +/* + * Description (USI_Length) + * + * This function returns the number of octets required to encode + * an unsigned integer value. + * + * Use of the USILENGTH() macro is recommended (see attrec.h). + * + * Arguments: + * + * val - the unsigned integer value + * + * Returns: + * + * The number of octets required to encode the specified value is + * returned. + */ + +int USI_Length(USI_t val) +{ + return (((USI_t)(val) <= 0x7f) ? 1 + : (((USI_t)(val) <= 0xff) ? 2 + : (((USI_t)(val) <= 0xffff) ? 3 + : (((USI_t)(val) <= 0xffffff) ? 4 + : 5)))); +} + |