summaryrefslogtreecommitdiffstats
path: root/lib/libaccess/attrec.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libaccess/attrec.cpp')
-rw-r--r--lib/libaccess/attrec.cpp309
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))));
+}
+