History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/com/sun/jmx/snmp/BerEncoder.java (1 of 18352 files). Show all

Unified · Split

java/pkg/com/sun/jmx/snmp/BerEncoder.java+477−0
@@ -0,0 +1,477 @@
1/*
2 * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26
27package com.sun.jmx.snmp;
28
29
30/**
31 * The <CODE>BerEncoder</CODE> class is used for encoding data using BER.
32 *
33 * A <CODE>BerEncoder</CODE> needs to be set up with a byte buffer. The encoded
34 * data are stored in this byte buffer.
35 * <P>
36 * NOTE : the buffer is filled from end to start. This means the caller
37 * needs to encode its data in the reverse order.
38 *
39 *
40 * <p><b>This API is a Sun Microsystems internal API and is subject
41 * to change without notice.</b></p>
42 *
43 * @since 1.5
44 */
45
46public class BerEncoder {
47
48 /**
49 * Constructs a new encoder and attaches it to the specified byte string.
50 *
51 * @param b The byte string containing the encoded data.
52 */
53
54 public BerEncoder(byte b[]) {
55 bytes = b ;
56 start = b.length ;
57 stackTop = 0 ;
58 }
59
60
61 /**
62 * Trim the encoding data and returns the length of the encoding.
63 *
64 * The encoder does backward encoding : so the bytes buffer is
65 * filled from end to start. The encoded data must be shift before
66 * the buffer can be used. This is the purpose of the <CODE>trim</CODE> method.
67 *
68 * After a call to the <CODE>trim</CODE> method, the encoder is reinitialized and <CODE>putXXX</CODE>
69 * overwrite any existing encoded data.
70 *
71 * @return The length of the encoded data.
72 */
73
74 public int trim() {
75 final int result = bytes.length - start ;
76
77 // for (int i = start ; i < bytes.length ; i++) {
78 // bytes[i-start] = bytes[i] ;
79 // }
80 if (result > 0)
81 java.lang.System.arraycopy(bytes,start,bytes,0,result);
82
83 start = bytes.length ;
84 stackTop = 0 ;
85
86 return result ;
87 }
88
89 /**
90 * Put an integer.
91 *
92 * @param v The integer to encode.
93 */
94
95 public void putInteger(int v) {
96 putInteger(v, IntegerTag) ;
97 }
98
99
100 /**
101 * Put an integer with the specified tag.
102 *
103 * @param v The integer to encode.
104 * @param tag The tag to encode.
105 */
106
107 public void putInteger(int v, int tag) {
108 putIntegerValue(v) ;
109 putTag(tag) ;
110 }
111
112
113
114 /**
115 * Put an integer expressed as a long.
116 *
117 * @param v The long to encode.
118 */
119
120 public void putInteger(long v) {
121 putInteger(v, IntegerTag) ;
122 }
123
124
125 /**
126 * Put an integer expressed as a long with the specified tag.
127 *
128 * @param v The long to encode
129 * @param tag The tag to encode.
130 */
131
132 public void putInteger(long v, int tag) {
133 putIntegerValue(v) ;
134 putTag(tag) ;
135 }
136
137
138
139 /**
140 * Put an octet string.
141 *
142 * @param s The bytes to encode
143 */
144
145 public void putOctetString(byte[] s) {
146 putOctetString(s, OctetStringTag) ;
147 }
148
149
150 /**
151 * Put an octet string with a specified tag.
152 *
153 * @param s The bytes to encode
154 * @param tag The tag to encode.
155 */
156
157 public void putOctetString(byte[] s, int tag) {
158 putStringValue(s) ;
159 putTag(tag) ;
160 }
161
162
163 /**
164 * Put an object identifier.
165 *
166 * @param s The oid to encode.
167 */
168
169 public void putOid(long[] s) {
170 putOid(s, OidTag) ;
171 }
172
173
174 /**
175 * Put an object identifier with a specified tag.
176 *
177 * @param s The integer to encode.
178 * @param tag The tag to encode.
179 */
180
181 public void putOid(long[] s, int tag) {
182 putOidValue(s) ;
183 putTag(tag) ;
184 }
185
186
187 /**
188 * Put a <CODE>NULL</CODE> value.
189 */
190
191 public void putNull() {
192 putNull(NullTag) ;
193 }
194
195
196 /**
197 * Put a <CODE>NULL</CODE> value with a specified tag.
198 *
199 * @param tag The tag to encode.
200 */
201
202 public void putNull(int tag) {
203 putLength(0) ;
204 putTag(tag) ;
205 }
206
207
208
209 /**
210 * Put an <CODE>ANY</CODE> value. In fact, this method does not encode anything.
211 * It simply copies the specified bytes into the encoding.
212 *
213 * @param s The encoding of the <CODE>ANY</CODE> value.
214 */
215
216 public void putAny(byte[] s) {
217 putAny(s, s.length) ;
218 }
219
220
221 /**
222 * Put an <CODE>ANY</CODE> value. Only the first <CODE>byteCount</CODE> are considered.
223 *
224 * @param s The encoding of the <CODE>ANY</CODE> value.
225 * @param byteCount The number of bytes of the encoding.
226 */
227
228 public void putAny(byte[] s, int byteCount) {
229 java.lang.System.arraycopy(s,0,bytes,start-byteCount,byteCount);
230 start -= byteCount;
231 // for (int i = byteCount - 1 ; i >= 0 ; i--) {
232 // bytes[--start] = s[i] ;
233 // }
234 }
235
236
237 /**
238 * Open a sequence.
239 * The encoder push the current position on its stack.
240 */
241
242 public void openSequence() {
243 stackBuf[stackTop++] = start ;
244 }
245
246
247 /**
248 * Close a sequence.
249 * The decode pull the stack to know the end of the current sequence.
250 */
251
252 public void closeSequence() {
253 closeSequence(SequenceTag) ;
254 }
255
256
257 /**
258 * Close a sequence with the specified tag.
259 */
260
261 public void closeSequence(int tag) {
262 final int end = stackBuf[--stackTop] ;
263 putLength(end - start) ;
264 putTag(tag) ;
265 }
266
267
268 //
269 // Some standard tags
270 //
271 public final static int BooleanTag = 1 ;
272 public final static int IntegerTag = 2 ;
273 public final static int OctetStringTag = 4 ;
274 public final static int NullTag = 5 ;
275 public final static int OidTag = 6 ;
276 public final static int SequenceTag = 0x30 ;
277
278
279
280
281 ////////////////////////// PROTECTED ///////////////////////////////
282
283
284
285 /**
286 * Put a tag and move the current position backward.
287 *
288 * @param tag The tag to encode.
289 */
290
291 protected final void putTag(int tag) {
292 if (tag < 256) {
293 bytes[--start] = (byte)tag ;
294 }
295 else {
296 while (tag != 0) {
297 bytes[--start] = (byte)(tag & 127) ;
298 tag = tag << 7 ;
299 }
300 }
301 }
302
303
304 /**
305 * Put a length and move the current position backward.
306 *
307 * @param length The length to encode.
308 */
309
310 protected final void putLength(final int length) {
311 if (length < 0) {
312 throw new IllegalArgumentException() ;
313 }
314 else if (length < 128) {
315 bytes[--start] = (byte)length ;
316 }
317 else if (length < 256) {
318 bytes[--start] = (byte)length ;
319 bytes[--start] = (byte)0x81 ;
320 }
321 else if (length < 65536) {
322 bytes[--start] = (byte)(length) ;
323 bytes[--start] = (byte)(length >> 8) ;
324 bytes[--start] = (byte)0x82 ;
325 }
326 else if (length < 16777126) {
327 bytes[--start] = (byte)(length) ;
328 bytes[--start] = (byte)(length >> 8) ;
329 bytes[--start] = (byte)(length >> 16) ;
330 bytes[--start] = (byte)0x83 ;
331 }
332 else {
333 bytes[--start] = (byte)(length) ;
334 bytes[--start] = (byte)(length >> 8) ;
335 bytes[--start] = (byte)(length >> 16) ;
336 bytes[--start] = (byte)(length >> 24) ;
337 bytes[--start] = (byte)0x84 ;
338 }
339 }
340
341
342 /**
343 * Put an integer value and move the current position backward.
344 *
345 * @param v The integer to encode.
346 */
347
348 protected final void putIntegerValue(int v) {
349 final int end = start ;
350 int mask = 0x7f800000 ;
351 int byteNeeded = 4 ;
352 if (v < 0) {
353 while (((mask & v) == mask) && (byteNeeded > 1)) {
354 mask = mask >> 8 ;
355 byteNeeded-- ;
356 }
357 }
358 else {
359 while (((mask & v) == 0) && (byteNeeded > 1)) {
360 mask = mask >> 8 ;
361 byteNeeded-- ;
362 }
363 }
364 for (int i = 0 ; i < byteNeeded ; i++) {
365 bytes[--start] = (byte)v ;
366 v = v >> 8 ;
367 }
368 putLength(end - start) ;
369 }
370
371
372 /**
373 * Put an integer value expressed as a long.
374 *
375 * @param v The integer to encode.
376 */
377
378 protected final void putIntegerValue(long v) {
379 final int end = start ;
380 long mask = 0x7f80000000000000L ;
381 int byteNeeded = 8 ;
382 if (v < 0) {
383 while (((mask & v) == mask) && (byteNeeded > 1)) {
384 mask = mask >> 8 ;
385 byteNeeded-- ;
386 }
387 }
388 else {
389 while (((mask & v) == 0) && (byteNeeded > 1)) {
390 mask = mask >> 8 ;
391 byteNeeded-- ;
392 }
393 }
394 for (int i = 0 ; i < byteNeeded ; i++) {
395 bytes[--start] = (byte)v ;
396 v = v >> 8 ;
397 }
398 putLength(end - start) ;
399 }
400
401
402 /**
403 * Put a byte string and move the current position backward.
404 *
405 * @param s The byte string to encode.
406 */
407
408 protected final void putStringValue(byte[] s) {
409 final int datalen = s.length;
410 java.lang.System.arraycopy(s,0,bytes,start-datalen,datalen);
411 start -= datalen;
412 // for (int i = s.length - 1 ; i >= 0 ; i--) {
413 // bytes[--start] = s[i] ;
414 // }
415 putLength(datalen) ;
416 }
417
418
419
420 /**
421 * Put an oid and move the current position backward.
422 *
423 * @param s The oid to encode.
424 */
425
426 protected final void putOidValue(final long[] s) {
427 final int end = start ;
428 final int slength = s.length;
429
430 // bugId 4641746: 0, 1, and 2 are legal values.
431 if ((slength < 2) || (s[0] > 2) || (s[1] >= 40)) {
432 throw new IllegalArgumentException() ;
433 }
434 for (int i = slength - 1 ; i >= 2 ; i--) {
435 long c = s[i] ;
436 if (c < 0) {
437 throw new IllegalArgumentException() ;
438 }
439 else if (c < 128) {
440 bytes[--start] = (byte)c ;
441 }
442 else {
443 bytes[--start] = (byte)(c & 127) ;
444 c = c >> 7 ;
445 while (c != 0) {
446 bytes[--start] = (byte)(c | 128) ;
447 c = c >> 7 ;
448 }
449 }
450 }
451 bytes[--start] = (byte)(s[0] * 40 + s[1]) ;
452 putLength(end - start) ;
453 }
454
455
456 //
457 // This is the byte array containing the encoding.
458 //
459 protected final byte bytes[];
460
461 //
462 // This is the index of the first byte of the encoding.
463 // It is initialized to <CODE>bytes.length</CODE> and decrease each time
464 // an value is put in the encoder.
465 //
466 protected int start = -1 ;
467
468 //
469 // This is the stack where end of sequences are kept.
470 // A value is computed and pushed in it each time the <CODE>openSequence</CODE> method
471 // is invoked.
472 // A value is pulled and checked each time the <CODE>closeSequence</CODE> method is called.
473 //
474 protected final int stackBuf[] = new int[200] ;
475 protected int stackTop = 0 ;
476
477}