]> git.saurik.com Git - apple/security.git/blob - SecuritySNACCRuntime/c++-lib/c++/asn-int.cpp
Security-54.tar.gz
[apple/security.git] / SecuritySNACCRuntime / c++-lib / c++ / asn-int.cpp
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
8 * using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
16 */
17
18
19 // file: .../c++-lib/src/asn-int.C - methods for AsnInt (ASN.1 INTEGER) class
20 //
21 // MS 92/06/16
22 // Copyright (C) 1992 Michael Sample and the University of British Columbia
23 //
24 // This library is free software; you can redistribute it and/or
25 // modify it provided that this copyright/license information is retained
26 // in original form.
27 //
28 // If you modify this file, you must clearly indicate your changes.
29 //
30 // This source code is distributed in the hope that it will be
31 // useful, but WITHOUT ANY WARRANTY; without even the implied warranty
32 // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
33 //
34 // $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c++-lib/c++/asn-int.cpp,v 1.3 2002/03/21 05:38:44 dmitch Exp $
35 // $Log: asn-int.cpp,v $
36 // Revision 1.3 2002/03/21 05:38:44 dmitch
37 // Radar 2868524: no more setjmp/longjmp in SNACC-generated code.
38 //
39 // Revision 1.2.44.1 2002/03/20 00:36:49 dmitch
40 // Radar 2868524: SNACC-generated code now uses throw/catch instead of setjmp/longjmp.
41 //
42 // Revision 1.2 2001/06/27 23:09:14 dmitch
43 // Pusuant to Radar 2664258, avoid all cerr-based output in NDEBUG configuration.
44 //
45 // Revision 1.1.1.1 2001/05/18 23:14:05 mb
46 // Move from private repository to open source repository
47 //
48 // Revision 1.2 2001/05/05 00:59:17 rmurphy
49 // Adding darwin license headers
50 //
51 // Revision 1.1 2000/06/15 18:44:57 dmitch
52 // These snacc-generated source files are now checked in to allow cross-platform build.
53 //
54 // Revision 1.2 2000/06/08 20:05:35 dmitch
55 // Mods for X port. These files are actually machine generated and probably don't need to be in CVS....
56 //
57 // Revision 1.1.1.1 2000/03/09 01:00:06 rmurphy
58 // Base Fortissimo Tree
59 //
60 // Revision 1.2 1999/03/21 02:07:36 mb
61 // Added Copy to every AsnType.
62 //
63 // Revision 1.1 1999/02/25 05:21:51 mb
64 // Added snacc c++ library
65 //
66 // Revision 1.7 1997/02/28 13:39:45 wan
67 // Modifications collected for new version 1.3: Bug fixes, tk4.2.
68 //
69 // Revision 1.6 1995/09/07 18:55:50 rj
70 // (unsigned) long int replaced by newly introduced Asn(U)IntType at a lot of places.
71 // they shall provide 32 bit integer types on all platforms.
72 //
73 // Revision 1.5 1995/07/24 20:17:32 rj
74 // #if TCL ... #endif wrapped into #if META ... #endif
75 //
76 // call constructor with additional pdu and create arguments.
77 //
78 // changed `_' to `-' in file names.
79 //
80 // Revision 1.4 1995/02/18 16:48:05 rj
81 // denote a long if we want a long
82 //
83 // Revision 1.3 1994/10/08 04:18:23 rj
84 // code for meta structures added (provides information about the generated code itself).
85 //
86 // code for Tcl interface added (makes use of the above mentioned meta code).
87 //
88 // virtual inline functions (the destructor, the Clone() function, BEnc(), BDec() and Print()) moved from inc/*.h to src/*.C because g++ turns every one of them into a static non-inline function in every file where the .h file gets included.
89 //
90 // made Print() const (and some other, mainly comparison functions).
91 //
92 // several `unsigned long int' turned into `size_t'.
93 //
94 // Revision 1.2 1994/08/28 10:01:12 rj
95 // comment leader fixed.
96 //
97 // Revision 1.1 1994/08/28 09:20:59 rj
98 // first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
99
100 #include "asn-config.h"
101 #include "asn-len.h"
102 #include "asn-tag.h"
103 #include "asn-type.h"
104 #include "asn-int.h"
105
106 AsnType *AsnInt::Clone() const
107 {
108 return new AsnInt;
109 }
110
111 AsnType *AsnInt::Copy() const
112 {
113 return new AsnInt (*this);
114 }
115
116 // Encodes BER content of this AsnInt to the given buffer.
117 // Returns the number of octets written to the buffer.
118 AsnLen AsnInt::BEncContent (BUF_TYPE b)
119 {
120 AsnLen len;
121 unsigned i;
122 AsnUIntType mask;
123 AsnUIntType dataCpy;
124
125 #define MASK (0x7f80L << ((sizeof (AsnIntType) - 2) * 8))
126
127 dataCpy = value;
128
129 /*
130 * calculate encoded length of the integer (content)
131 */
132 mask = MASK;
133 if ((AsnIntType)dataCpy < 0)
134 for (len = sizeof (AsnIntType); len > 1; --len)
135 {
136 if ((dataCpy & mask) == mask)
137 mask >>= 8;
138 else
139 break;
140 }
141 else
142 for (len = sizeof (AsnIntType); len > 1; --len)
143 {
144 if ((dataCpy & mask) == 0)
145 mask >>= 8;
146 else
147 break;
148 }
149
150 /*
151 * write the BER integer
152 */
153 for (i = 0; i < len; i++)
154 {
155 b.PutByteRvs (dataCpy);
156 dataCpy >>= 8;
157 }
158
159 return len;
160 }
161
162 // Decodes the content of a BER INTEGER from the given buffer.
163 // The value is placed in this object. tagId is ignored.
164 // bytesDecoded is incremented by the number of bytes read for this
165 // integer value.
166 void AsnInt::BDecContent (BUF_TYPE b, AsnTag tagId, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env)
167 {
168 unsigned i;
169 AsnUIntType byte;
170
171 if (elmtLen > sizeof (AsnIntType))
172 {
173 Asn1Error << "AsnInt::BDecContent: ERROR - integer is too big to decode." << endl;
174 #if SNACC_EXCEPTION_ENABLE
175 SnaccExcep::throwMe(-7);
176 #else
177 longjmp (env, -7);
178 #endif
179 }
180
181 /*
182 * look at integer value
183 */
184 byte = (AsnUIntType) b.GetByte();
185
186 if (byte & 0x80) /* top bit of first byte is sign bit */
187 value = (-1 << 8) | byte;
188 else
189 value = byte;
190
191 /*
192 * write from buffer into AsnIntType
193 */
194 for (i = 1; i < elmtLen; i++)
195 value = (value << 8) | (AsnUIntType)(b.GetByte());
196
197 bytesDecoded += elmtLen;
198
199 if (b.ReadError())
200 {
201 Asn1Error << "AsnInt::BDecContent: ERROR - decoded past end of data." << endl;
202 #if SNACC_EXCEPTION_ENABLE
203 SnaccExcep::throwMe(-8);
204 #else
205 longjmp (env, -8);
206 #endif
207 }
208
209
210 } /* AsnInt::BDecContent */
211
212 AsnLen AsnInt::BEnc (BUF_TYPE b)
213 {
214 AsnLen l;
215 l = BEncContent (b);
216 BEncDefLenTo127 (b, l);
217 l++;
218 l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
219 return l;
220 }
221
222 void AsnInt::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
223 {
224 AsnLen elmtLen;
225 if (BDecTag (b, bytesDecoded, env) != MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
226 {
227 Asn1Error << "AsnInt::BDec: ERROR tag on INTEGER is wrong." << endl;
228 #if SNACC_EXCEPTION_ENABLE
229 SnaccExcep::throwMe(-53);
230 #else
231 longjmp (env,-53);
232 #endif
233 }
234
235 elmtLen = BDecLen (b, bytesDecoded, env);
236 BDecContent (b, MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE), elmtLen, bytesDecoded, env);
237 }
238
239 void AsnInt::Print (ostream &os) const
240 {
241 #ifndef NDEBUG
242 os << value;
243 #endif
244 }
245
246 #if META
247
248 const AsnIntTypeDesc AsnInt::_desc (NULL, NULL, false, AsnTypeDesc::INTEGER, NULL, NULL);
249
250 const AsnTypeDesc *AsnInt::_getdesc() const
251 {
252 return &_desc;
253 }
254
255 #if TCL
256
257 #define RETURN_NAME_INSTEAD_OF_VALUE 0
258
259 int AsnInt::TclGetVal (Tcl_Interp *interp) const
260 {
261 #if RETURN_NAME_INSTEAD_OF_VALUE
262 const AsnNameDesc *n = _getdesc()->getnames();
263 if (n)
264 for (; n->name; n++)
265 if (n->value == value)
266 {
267 Tcl_SetResult (interp, n->name, TCL_STATIC);
268 return TCL_OK;
269 }
270 #endif
271
272 char buf[32];
273 sprintf (buf, "%d", value);
274 Tcl_SetResult (interp, buf, TCL_VOLATILE);
275 return TCL_OK;
276 }
277
278 int AsnInt::TclSetVal (Tcl_Interp *interp, const char *valstr)
279 {
280 const AsnNameDesc *n = _getdesc()->getnames();
281 if (n)
282 for (; n->name; n++)
283 if (!strcmp (n->name, valstr))
284 {
285 value = n->value;
286 return TCL_OK;
287 }
288
289 int valval;
290 if (Tcl_GetInt (interp, (char*)valstr, &valval) != TCL_OK)
291 return TCL_ERROR;
292 value = valval;
293 return TCL_OK;
294 }
295
296 #endif /* TCL */
297 #endif /* META */