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+
27+package 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+
46+public 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+}