Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/com/sun/jmx/snmp/BerEncoder.java
38924 views
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
}
478
479