attrec.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. /** BEGIN COPYRIGHT BLOCK
  2. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  3. * Copyright (C) 2005 Red Hat, Inc.
  4. * All rights reserved.
  5. * END COPYRIGHT BLOCK **/
  6. /*
  7. * Description (attrec.c)
  8. *
  9. * This module contains routines for encoding and decoding
  10. * attribute records. See attrec.h for a description of attribute
  11. * records.
  12. */
  13. #include "base/systems.h"
  14. #include "netsite.h"
  15. #include "assert.h"
  16. #define __PRIVATE_ATTREC
  17. #include "libaccess/attrec.h"
  18. /*
  19. * Description (NTS_Length)
  20. *
  21. * This function returns the length of a null-terminated string.
  22. * The length includes the terminating null octet.
  23. *
  24. * Use of the NTSLENGTH() macro is recommended (see attrec.h).
  25. *
  26. * Arguments:
  27. *
  28. * nts - a pointer to the null-terminate string
  29. * (may be null)
  30. *
  31. * Returns:
  32. *
  33. * The length of the string. If 'nts' is null, the value is one,
  34. * since there is always a null octet.
  35. */
  36. int NTS_Length(NTS_t nts)
  37. {
  38. return ((nts) ? strlen((const char *)nts) + 1 : 1);
  39. }
  40. /*
  41. * Description (NTS_Decode)
  42. *
  43. * This function decodes a null-terminated string from a specified
  44. * attribute record buffer. It copies the string into a dynamically
  45. * allocated buffer, if 'pnts' is not null, and returns a pointer
  46. * to it. The return value of the function is a pointer to the
  47. * octet following the NTS in the attribute record buffer.
  48. *
  49. * Use of the NTSDECODE() macro is recommended (see attrec.h).
  50. *
  51. * Arguments:
  52. *
  53. * cp - pointer into the attribute record buffer
  54. * pnts - pointer to returned reference to decoded
  55. * NTS, or null, if the decoded NTS is not
  56. * to be copied to a dynamic buffer
  57. *
  58. * Returns:
  59. *
  60. * The function return value is a pointer to the octet following
  61. * the NTS in the attribute record buffer. A pointer to a
  62. * dynamically allocated buffer containing the decoded NTS will
  63. * be returned through 'pnts', if it is non-null. This returned
  64. * pointer will be null if the NTS contains only a terminating
  65. * octet.
  66. */
  67. ATR_t NTS_Decode(ATR_t cp, NTS_t * pnts)
  68. {
  69. NTS_t nts = 0;
  70. int len = NTSLENGTH(cp); /* length of the string */
  71. /* Are we going to return a copy of the string? */
  72. if (pnts) {
  73. /* Yes, is it more than just a null octet? */
  74. if (len > 1) {
  75. /* Yes, allocate a buffer and copy the string to it */
  76. nts = (NTS_t)MALLOC(len);
  77. if (nts) {
  78. memcpy((void *)nts, (void *)cp, len);
  79. }
  80. }
  81. /* Return a pointer to the copied string, or null */
  82. *pnts = nts;
  83. }
  84. /* Return pointer to octet after string */
  85. return cp + len;
  86. }
  87. /*
  88. * Description (NTS_Encode)
  89. *
  90. * This function encodes a null-terminated string into a specified
  91. * attribute record buffer. It returns a pointer to the octet
  92. * following the encoding.
  93. *
  94. * Use of the NTSENCODE() macro is recommended (see attrec.h).
  95. *
  96. * Arguments:
  97. *
  98. * cp - pointer into the attribute record buffer
  99. * nts - pointer to the string to be encoded
  100. *
  101. * Returns:
  102. *
  103. * A pointer to the octet following the encoding in the attribute
  104. * record buffer is returned.
  105. */
  106. ATR_t NTS_Encode(ATR_t cp, NTS_t nts)
  107. {
  108. /* Is the string pointer null? */
  109. if (nts) {
  110. int len = NTSLENGTH(nts);
  111. /* No, copy the string to the attribute record buffer */
  112. memcpy((void *)cp, (void *)nts, len);
  113. /* Get pointer to octet after it */
  114. cp += len;
  115. }
  116. else {
  117. /* A null pointer indicates an empty NTS, i.e. just a null octet */
  118. *cp++ = 0;
  119. }
  120. /* Return a pointer to the octet after the encoding */
  121. return cp;
  122. }
  123. /*
  124. * Description (USI_Decode)
  125. *
  126. * This function decodes an unsigned integer value from a specified
  127. * attribute record buffer.
  128. *
  129. * Use of the USIDECODE() macro is recommended (see attrec.h).
  130. *
  131. * Arguments:
  132. *
  133. * cp - pointer into the attribute record buffer
  134. * pval - pointer to returned integer value
  135. *
  136. * Returns:
  137. *
  138. * If 'pval' is not null, the decoded integer value is returned
  139. * in the referenced location. The function return value is a
  140. * pointer to the octet following the USI encoding in the attribute
  141. * record buffer.
  142. */
  143. ATR_t USI_Decode(ATR_t cp, USI_t * pval)
  144. {
  145. int val;
  146. /* Is this a length value? */
  147. if (*(cp) & 0x80) {
  148. int i;
  149. int len;
  150. /* Yes, build the value from the indicated number of octets */
  151. len = *cp++ & 0x7;
  152. val = 0;
  153. for (i = 0; i < len; ++i) {
  154. val <<= 8;
  155. val |= (cp[i] & 0xff);
  156. }
  157. cp += len;
  158. }
  159. else {
  160. /* This octet is the value */
  161. val = *cp++;
  162. }
  163. /* Return the value if there's a place to put it */
  164. if (pval) *pval = val;
  165. /* Return a pointer to the next item in the attribute record */
  166. return cp;
  167. }
  168. /*
  169. * Description (USI_Encode)
  170. *
  171. * This function encodes an unsigned integer value into a specified
  172. * attribute record buffer.
  173. *
  174. * Use of the USIENCODE() macro is recommended (see attrec.h).
  175. *
  176. * Arguments:
  177. *
  178. * cp - pointer into the attribute record buffer
  179. * val - the value to be encoded
  180. *
  181. * Returns:
  182. *
  183. * A pointer to the octet following the generated encoding in the
  184. * attribute record buffer is returned.
  185. */
  186. ATR_t USI_Encode(ATR_t cp, USI_t val)
  187. {
  188. /* Check size of value to be encoded */
  189. if (val <= 0x7f) *cp++ = val;
  190. else if (val <= 0xff) {
  191. /* Length plus 8-bit value */
  192. *cp++ = 0x81;
  193. *cp++ = val;
  194. }
  195. else if (val <= 0xffff) {
  196. /* Length plus 16-bit value */
  197. *cp++ = 0x82;
  198. cp[1] = val & 0xff;
  199. val >>= 8;
  200. cp[0] = val & 0xff;
  201. cp += 2;
  202. }
  203. else if (val <= 0xffffff) {
  204. /* Length plus 24-bit value */
  205. *cp++ = 0x83;
  206. cp[2] = val & 0xff;
  207. val >>= 8;
  208. cp[1] = val & 0xff;
  209. val >>= 8;
  210. cp[0] = val & 0xff;
  211. cp += 3;
  212. }
  213. else {
  214. /* Length plus 32-bit value */
  215. *cp++ = 0x84;
  216. cp[3] = val & 0xff;
  217. val >>= 8;
  218. cp[2] = val & 0xff;
  219. val >>= 8;
  220. cp[1] = val & 0xff;
  221. val >>= 8;
  222. cp[0] = val & 0xff;
  223. cp += 4;
  224. }
  225. /* Return a pointer to the next position in the attribute record */
  226. return cp;
  227. }
  228. /*
  229. * Description (USI_Insert)
  230. *
  231. * This function is a variation of USI_Encode() that always generates
  232. * the maximum-length encoding for USI value, regardless of the
  233. * actual specified value. For arguments, returns, see USI_Encode().
  234. *
  235. * Use of the USIINSERT() macro is recommended. The USIALLOC() macro
  236. * returns the number of octets that USIINSERT() will generate.
  237. */
  238. ATR_t USI_Insert(ATR_t cp, USI_t val)
  239. {
  240. int i;
  241. assert(USIALLOC() == 5);
  242. *cp++ = 0x84;
  243. for (i = 3; i >= 0; --i) {
  244. cp[i] = val & 0xff;
  245. val >>= 8;
  246. }
  247. return cp + 5;
  248. }
  249. /*
  250. * Description (USI_Length)
  251. *
  252. * This function returns the number of octets required to encode
  253. * an unsigned integer value.
  254. *
  255. * Use of the USILENGTH() macro is recommended (see attrec.h).
  256. *
  257. * Arguments:
  258. *
  259. * val - the unsigned integer value
  260. *
  261. * Returns:
  262. *
  263. * The number of octets required to encode the specified value is
  264. * returned.
  265. */
  266. int USI_Length(USI_t val)
  267. {
  268. return (((USI_t)(val) <= 0x7f) ? 1
  269. : (((USI_t)(val) <= 0xff) ? 2
  270. : (((USI_t)(val) <= 0xffff) ? 3
  271. : (((USI_t)(val) <= 0xffffff) ? 4
  272. : 5))));
  273. }