1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.commons.compress.harmony.pack200;
21
22 import java.io.IOException;
23 import java.io.OutputStream;
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.HashMap;
27 import java.util.HashSet;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Set;
31 import java.util.TreeSet;
32 import java.util.function.BiFunction;
33
34 import org.objectweb.asm.Type;
35
36
37
38
39 public class CpBands extends BandSet {
40
41
42 private final Set<String> defaultAttributeNames = new HashSet<>();
43
44 private final Set<CPUTF8> cp_Utf8 = new TreeSet<>();
45 private final Set<CPInt> cp_Int = new TreeSet<>();
46 private final Set<CPFloat> cp_Float = new TreeSet<>();
47 private final Set<CPLong> cp_Long = new TreeSet<>();
48 private final Set<CPDouble> cp_Double = new TreeSet<>();
49 private final Set<CPString> cp_String = new TreeSet<>();
50 private final Set<CPClass> cp_Class = new TreeSet<>();
51 private final Set<CPSignature> cp_Signature = new TreeSet<>();
52 private final Set<CPNameAndType> cp_Descr = new TreeSet<>();
53 private final Set<CPMethodOrField> cp_Field = new TreeSet<>();
54 private final Set<CPMethodOrField> cp_Method = new TreeSet<>();
55 private final Set<CPMethodOrField> cp_Imethod = new TreeSet<>();
56
57 private final Map<String, CPUTF8> stringsToCpUtf8 = new HashMap<>();
58 private final Map<String, CPNameAndType> stringsToCpNameAndType = new HashMap<>();
59 private final Map<String, CPClass> stringsToCpClass = new HashMap<>();
60 private final Map<String, CPSignature> stringsToCpSignature = new HashMap<>();
61 private final Map<String, CPMethodOrField> stringsToCpMethod = new HashMap<>();
62 private final Map<String, CPMethodOrField> stringsToCpField = new HashMap<>();
63 private final Map<String, CPMethodOrField> stringsToCpIMethod = new HashMap<>();
64
65 private final Map<Object, CPConstant<?>> objectsToCPConstant = new HashMap<>();
66
67 private final Segment segment;
68
69 public CpBands(final Segment segment, final int effort) {
70 super(effort, segment.getSegmentHeader());
71 this.segment = segment;
72 defaultAttributeNames.add("AnnotationDefault");
73 defaultAttributeNames.add("RuntimeVisibleAnnotations");
74 defaultAttributeNames.add("RuntimeInvisibleAnnotations");
75 defaultAttributeNames.add("RuntimeVisibleParameterAnnotations");
76 defaultAttributeNames.add("RuntimeInvisibleParameterAnnotations");
77 defaultAttributeNames.add("Code");
78 defaultAttributeNames.add("LineNumberTable");
79 defaultAttributeNames.add("LocalVariableTable");
80 defaultAttributeNames.add("LocalVariableTypeTable");
81 defaultAttributeNames.add("ConstantValue");
82 defaultAttributeNames.add("Deprecated");
83 defaultAttributeNames.add("EnclosingMethod");
84 defaultAttributeNames.add("Exceptions");
85 defaultAttributeNames.add("InnerClasses");
86 defaultAttributeNames.add("Signature");
87 defaultAttributeNames.add("SourceFile");
88 }
89
90 private void addCharacters(final List<Character> chars, final char[] charArray) {
91 for (final char element : charArray) {
92 chars.add(Character.valueOf(element));
93 }
94 }
95
96 public void addCPClass(final String className) {
97 getCPClass(className);
98 }
99
100 void addCPUtf8(final String utf8) {
101 getCPUtf8(utf8);
102 }
103
104 private void addIndices() {
105 for (final Set<? extends ConstantPoolEntry> set : Arrays.asList(cp_Utf8, cp_Int, cp_Float, cp_Long, cp_Double, cp_String, cp_Class, cp_Signature,
106 cp_Descr, cp_Field, cp_Method, cp_Imethod)) {
107 int j = 0;
108 for (final ConstantPoolEntry entry : set) {
109 entry.setIndex(j);
110 j++;
111 }
112 }
113 final BiFunction<? super CPClass, ? super Integer, ? extends Integer> remappingFunction = (k, v) -> v != null ? v + 1 : 1;
114 final Map<CPClass, Integer> classNameToIndex = new HashMap<>();
115 cp_Field.forEach(mOrF -> mOrF.setIndexInClass(classNameToIndex.compute(mOrF.getClassName(), remappingFunction) - 1));
116 classNameToIndex.clear();
117 final Map<CPClass, Integer> classNameToConstructorIndex = new HashMap<>();
118 cp_Method.forEach(mOrF -> {
119 final CPClass cpClassName = mOrF.getClassName();
120 mOrF.setIndexInClass(classNameToIndex.compute(cpClassName, remappingFunction) - 1);
121 if (mOrF.getDesc().getName().equals("<init>")) {
122 mOrF.setIndexInClassForConstructor(classNameToConstructorIndex.compute(cpClassName, remappingFunction) - 1);
123 }
124 });
125 }
126
127 public boolean existsCpClass(final String className) {
128 return stringsToCpClass.containsKey(className);
129 }
130
131
132
133
134
135 public void finaliseBands() {
136 addCPUtf8("");
137 removeSignaturesFromCpUTF8();
138 addIndices();
139 segmentHeader.setCp_Utf8_count(cp_Utf8.size());
140 segmentHeader.setCp_Int_count(cp_Int.size());
141 segmentHeader.setCp_Float_count(cp_Float.size());
142 segmentHeader.setCp_Long_count(cp_Long.size());
143 segmentHeader.setCp_Double_count(cp_Double.size());
144 segmentHeader.setCp_String_count(cp_String.size());
145 segmentHeader.setCp_Class_count(cp_Class.size());
146 segmentHeader.setCp_Signature_count(cp_Signature.size());
147 segmentHeader.setCp_Descr_count(cp_Descr.size());
148 segmentHeader.setCp_Field_count(cp_Field.size());
149 segmentHeader.setCp_Method_count(cp_Method.size());
150 segmentHeader.setCp_Imethod_count(cp_Imethod.size());
151 }
152
153 public CPConstant<?> getConstant(final Object value) {
154 CPConstant<?> constant = objectsToCPConstant.get(value);
155 if (constant == null) {
156 if (value instanceof Integer) {
157 constant = new CPInt(((Integer) value).intValue());
158 cp_Int.add((CPInt) constant);
159 } else if (value instanceof Long) {
160 constant = new CPLong(((Long) value).longValue());
161 cp_Long.add((CPLong) constant);
162 } else if (value instanceof Float) {
163 constant = new CPFloat(((Float) value).floatValue());
164 cp_Float.add((CPFloat) constant);
165 } else if (value instanceof Double) {
166 constant = new CPDouble(((Double) value).doubleValue());
167 cp_Double.add((CPDouble) constant);
168 } else if (value instanceof String) {
169 constant = new CPString(getCPUtf8((String) value));
170 cp_String.add((CPString) constant);
171 } else if (value instanceof Type) {
172 String className = ((Type) value).getClassName();
173 if (className.endsWith("[]")) {
174 className = "[L" + className.substring(0, className.length() - 2);
175 while (className.endsWith("[]")) {
176 className = "[" + className.substring(0, className.length() - 2);
177 }
178 className += ";";
179 }
180 constant = getCPClass(className);
181 }
182 objectsToCPConstant.put(value, constant);
183 }
184 return constant;
185 }
186
187
188
189
190
191
192
193 public CPClass getCPClass(String className) {
194 if (className == null) {
195 return null;
196 }
197 className = className.replace('.', '/');
198 CPClass cpClass = stringsToCpClass.get(className);
199 if (cpClass == null) {
200 final CPUTF8 cpUtf8 = getCPUtf8(className);
201 cpClass = new CPClass(cpUtf8);
202 cp_Class.add(cpClass);
203 stringsToCpClass.put(className, cpClass);
204 }
205 if (cpClass.isInnerClass()) {
206 segment.getClassBands().currentClassReferencesInnerClass(cpClass);
207 }
208 return cpClass;
209 }
210
211 public CPMethodOrField getCPField(final CPClass cpClass, final String name, final String desc) {
212 final String key = cpClass.toString() + ":" + name + ":" + desc;
213 CPMethodOrField cpF = stringsToCpField.get(key);
214 if (cpF == null) {
215 final CPNameAndType nAndT = getCPNameAndType(name, desc);
216 cpF = new CPMethodOrField(cpClass, nAndT);
217 cp_Field.add(cpF);
218 stringsToCpField.put(key, cpF);
219 }
220 return cpF;
221 }
222
223 public CPMethodOrField getCPField(final String owner, final String name, final String desc) {
224 return getCPField(getCPClass(owner), name, desc);
225 }
226
227 public CPMethodOrField getCPIMethod(final CPClass cpClass, final String name, final String desc) {
228 final String key = cpClass.toString() + ":" + name + ":" + desc;
229 CPMethodOrField cpIM = stringsToCpIMethod.get(key);
230 if (cpIM == null) {
231 final CPNameAndType nAndT = getCPNameAndType(name, desc);
232 cpIM = new CPMethodOrField(cpClass, nAndT);
233 cp_Imethod.add(cpIM);
234 stringsToCpIMethod.put(key, cpIM);
235 }
236 return cpIM;
237 }
238
239 public CPMethodOrField getCPIMethod(final String owner, final String name, final String desc) {
240 return getCPIMethod(getCPClass(owner), name, desc);
241 }
242
243 public CPMethodOrField getCPMethod(final CPClass cpClass, final String name, final String desc) {
244 final String key = cpClass.toString() + ":" + name + ":" + desc;
245 CPMethodOrField cpM = stringsToCpMethod.get(key);
246 if (cpM == null) {
247 final CPNameAndType nAndT = getCPNameAndType(name, desc);
248 cpM = new CPMethodOrField(cpClass, nAndT);
249 cp_Method.add(cpM);
250 stringsToCpMethod.put(key, cpM);
251 }
252 return cpM;
253 }
254
255 public CPMethodOrField getCPMethod(final String owner, final String name, final String desc) {
256 return getCPMethod(getCPClass(owner), name, desc);
257 }
258
259 public CPNameAndType getCPNameAndType(final String name, final String signature) {
260 final String descr = name + ":" + signature;
261 CPNameAndType nameAndType = stringsToCpNameAndType.get(descr);
262 if (nameAndType == null) {
263 nameAndType = new CPNameAndType(getCPUtf8(name), getCPSignature(signature));
264 stringsToCpNameAndType.put(descr, nameAndType);
265 cp_Descr.add(nameAndType);
266 }
267 return nameAndType;
268 }
269
270
271
272
273
274
275
276 public CPSignature getCPSignature(final String signature) {
277 if (signature == null) {
278 return null;
279 }
280 CPSignature cpS = stringsToCpSignature.get(signature);
281 if (cpS == null) {
282 final List<CPClass> cpClasses = new ArrayList<>();
283 final CPUTF8 signatureUTF8;
284 if (signature.length() > 1 && signature.indexOf('L') != -1) {
285 final List<String> classes = new ArrayList<>();
286 final char[] chars = signature.toCharArray();
287 final StringBuilder signatureString = new StringBuilder();
288 for (int i = 0; i < chars.length; i++) {
289 signatureString.append(chars[i]);
290 if (chars[i] == 'L') {
291 final StringBuilder className = new StringBuilder();
292 for (int j = i + 1; j < chars.length; j++) {
293 final char c = chars[j];
294 if (!Character.isLetter(c) && !Character.isDigit(c) && c != '/' && c != '$' && c != '_') {
295 classes.add(className.toString());
296 i = j - 1;
297 break;
298 }
299 className.append(c);
300 }
301 }
302 }
303 removeCpUtf8(signature);
304 for (String className : classes) {
305 CPClass cpClass = null;
306 if (className != null) {
307 className = className.replace('.', '/');
308 cpClass = stringsToCpClass.get(className);
309 if (cpClass == null) {
310 final CPUTF8 cpUtf8 = getCPUtf8(className);
311 cpClass = new CPClass(cpUtf8);
312 cp_Class.add(cpClass);
313 stringsToCpClass.put(className, cpClass);
314 }
315 }
316 cpClasses.add(cpClass);
317 }
318
319 signatureUTF8 = getCPUtf8(signatureString.toString());
320 } else {
321 signatureUTF8 = getCPUtf8(signature);
322 }
323 cpS = new CPSignature(signature, signatureUTF8, cpClasses);
324 cp_Signature.add(cpS);
325 stringsToCpSignature.put(signature, cpS);
326 }
327 return cpS;
328 }
329
330 public CPUTF8 getCPUtf8(final String utf8) {
331 if (utf8 == null) {
332 return null;
333 }
334 CPUTF8 cpUtf8 = stringsToCpUtf8.get(utf8);
335 if (cpUtf8 == null) {
336 cpUtf8 = new CPUTF8(utf8);
337 cp_Utf8.add(cpUtf8);
338 stringsToCpUtf8.put(utf8, cpUtf8);
339 }
340 return cpUtf8;
341 }
342
343 @Override
344 public void pack(final OutputStream out) throws IOException, Pack200Exception {
345 PackingUtils.log("Writing constant pool bands...");
346 writeCpUtf8(out);
347 writeCpInt(out);
348 writeCpFloat(out);
349 writeCpLong(out);
350 writeCpDouble(out);
351 writeCpString(out);
352 writeCpClass(out);
353 writeCpSignature(out);
354 writeCpDescr(out);
355 writeCpMethodOrField(cp_Field, out, "cp_Field");
356 writeCpMethodOrField(cp_Method, out, "cp_Method");
357 writeCpMethodOrField(cp_Imethod, out, "cp_Imethod");
358 }
359
360 private void removeCpUtf8(final String string) {
361 final CPUTF8 utf8 = stringsToCpUtf8.get(string);
362 if (utf8 != null && stringsToCpClass.get(string) == null) {
363 stringsToCpUtf8.remove(string);
364 cp_Utf8.remove(utf8);
365 }
366 }
367
368 private void removeSignaturesFromCpUTF8() {
369 cp_Signature.forEach(signature -> {
370 final String sigStr = signature.getUnderlyingString();
371 final CPUTF8 utf8 = signature.getSignatureForm();
372 final String form = utf8.getUnderlyingString();
373 if (!sigStr.equals(form)) {
374 removeCpUtf8(sigStr);
375 }
376 });
377 }
378
379 private void writeCpClass(final OutputStream out) throws IOException, Pack200Exception {
380 PackingUtils.log("Writing " + cp_Class.size() + " Class entries...");
381 final int[] cpClass = new int[cp_Class.size()];
382 int i = 0;
383 for (final CPClass cpCl : cp_Class) {
384 cpClass[i] = cpCl.getIndexInCpUtf8();
385 i++;
386 }
387 final byte[] encodedBand = encodeBandInt("cpClass", cpClass, Codec.UDELTA5);
388 out.write(encodedBand);
389 PackingUtils.log("Wrote " + encodedBand.length + " bytes from cpClass[" + cpClass.length + "]");
390 }
391
392 private void writeCpDescr(final OutputStream out) throws IOException, Pack200Exception {
393 PackingUtils.log("Writing " + cp_Descr.size() + " Descriptor entries...");
394 final int[] cpDescrName = new int[cp_Descr.size()];
395 final int[] cpDescrType = new int[cp_Descr.size()];
396 int i = 0;
397 for (final CPNameAndType nameAndType : cp_Descr) {
398 cpDescrName[i] = nameAndType.getNameIndex();
399 cpDescrType[i] = nameAndType.getTypeIndex();
400 i++;
401 }
402
403 byte[] encodedBand = encodeBandInt("cp_Descr_Name", cpDescrName, Codec.DELTA5);
404 out.write(encodedBand);
405 PackingUtils.log("Wrote " + encodedBand.length + " bytes from cp_Descr_Name[" + cpDescrName.length + "]");
406
407 encodedBand = encodeBandInt("cp_Descr_Type", cpDescrType, Codec.UDELTA5);
408 out.write(encodedBand);
409 PackingUtils.log("Wrote " + encodedBand.length + " bytes from cp_Descr_Type[" + cpDescrType.length + "]");
410 }
411
412 private void writeCpDouble(final OutputStream out) throws IOException, Pack200Exception {
413 PackingUtils.log("Writing " + cp_Double.size() + " Double entries...");
414 final int[] highBits = new int[cp_Double.size()];
415 final int[] loBits = new int[cp_Double.size()];
416 int i = 0;
417 for (final CPDouble dbl : cp_Double) {
418 final long l = Double.doubleToLongBits(dbl.getDouble());
419 highBits[i] = (int) (l >> 32);
420 loBits[i] = (int) l;
421 i++;
422 }
423 byte[] encodedBand = encodeBandInt("cp_Double_hi", highBits, Codec.UDELTA5);
424 out.write(encodedBand);
425 PackingUtils.log("Wrote " + encodedBand.length + " bytes from cp_Double_hi[" + highBits.length + "]");
426
427 encodedBand = encodeBandInt("cp_Double_lo", loBits, Codec.DELTA5);
428 out.write(encodedBand);
429 PackingUtils.log("Wrote " + encodedBand.length + " bytes from cp_Double_lo[" + loBits.length + "]");
430 }
431
432 private void writeCpFloat(final OutputStream out) throws IOException, Pack200Exception {
433 PackingUtils.log("Writing " + cp_Float.size() + " Float entries...");
434 final int[] cpFloat = new int[cp_Float.size()];
435 int i = 0;
436 for (final CPFloat fl : cp_Float) {
437 cpFloat[i] = Float.floatToIntBits(fl.getFloat());
438 i++;
439 }
440 final byte[] encodedBand = encodeBandInt("cp_Float", cpFloat, Codec.UDELTA5);
441 out.write(encodedBand);
442 PackingUtils.log("Wrote " + encodedBand.length + " bytes from cp_Float[" + cpFloat.length + "]");
443 }
444
445 private void writeCpInt(final OutputStream out) throws IOException, Pack200Exception {
446 PackingUtils.log("Writing " + cp_Int.size() + " Integer entries...");
447 final int[] cpInt = new int[cp_Int.size()];
448 int i = 0;
449 for (final CPInt integer : cp_Int) {
450 cpInt[i] = integer.getInt();
451 i++;
452 }
453 final byte[] encodedBand = encodeBandInt("cp_Int", cpInt, Codec.UDELTA5);
454 out.write(encodedBand);
455 PackingUtils.log("Wrote " + encodedBand.length + " bytes from cp_Int[" + cpInt.length + "]");
456 }
457
458 private void writeCpLong(final OutputStream out) throws IOException, Pack200Exception {
459 PackingUtils.log("Writing " + cp_Long.size() + " Long entries...");
460 final int[] highBits = new int[cp_Long.size()];
461 final int[] loBits = new int[cp_Long.size()];
462 int i = 0;
463 for (final CPLong lng : cp_Long) {
464 final long l = lng.getLong();
465 highBits[i] = (int) (l >> 32);
466 loBits[i] = (int) l;
467 i++;
468 }
469 byte[] encodedBand = encodeBandInt("cp_Long_hi", highBits, Codec.UDELTA5);
470 out.write(encodedBand);
471 PackingUtils.log("Wrote " + encodedBand.length + " bytes from cp_Long_hi[" + highBits.length + "]");
472
473 encodedBand = encodeBandInt("cp_Long_lo", loBits, Codec.DELTA5);
474 out.write(encodedBand);
475 PackingUtils.log("Wrote " + encodedBand.length + " bytes from cp_Long_lo[" + loBits.length + "]");
476 }
477
478 private void writeCpMethodOrField(final Set<CPMethodOrField> cp, final OutputStream out, final String name) throws IOException, Pack200Exception {
479 PackingUtils.log("Writing " + cp.size() + " Method and Field entries...");
480 final int[] cp_methodOrField_class = new int[cp.size()];
481 final int[] cp_methodOrField_desc = new int[cp.size()];
482 int i = 0;
483 for (final CPMethodOrField mOrF : cp) {
484 cp_methodOrField_class[i] = mOrF.getClassIndex();
485 cp_methodOrField_desc[i] = mOrF.getDescIndex();
486 i++;
487 }
488 byte[] encodedBand = encodeBandInt(name + "_class", cp_methodOrField_class, Codec.DELTA5);
489 out.write(encodedBand);
490 PackingUtils.log("Wrote " + encodedBand.length + " bytes from " + name + "_class[" + cp_methodOrField_class.length + "]");
491
492 encodedBand = encodeBandInt(name + "_desc", cp_methodOrField_desc, Codec.UDELTA5);
493 out.write(encodedBand);
494 PackingUtils.log("Wrote " + encodedBand.length + " bytes from " + name + "_desc[" + cp_methodOrField_desc.length + "]");
495 }
496
497 private void writeCpSignature(final OutputStream out) throws IOException, Pack200Exception {
498 PackingUtils.log("Writing " + cp_Signature.size() + " Signature entries...");
499 final int[] cpSignatureForm = new int[cp_Signature.size()];
500 final List<CPClass> classes = new ArrayList<>();
501 int i = 0;
502 for (final CPSignature cpS : cp_Signature) {
503 classes.addAll(cpS.getClasses());
504 cpSignatureForm[i] = cpS.getIndexInCpUtf8();
505 i++;
506 }
507 final int[] cpSignatureClasses = new int[classes.size()];
508 Arrays.setAll(cpSignatureClasses, j -> classes.get(j).getIndex());
509
510 byte[] encodedBand = encodeBandInt("cpSignatureForm", cpSignatureForm, Codec.DELTA5);
511 out.write(encodedBand);
512 PackingUtils.log("Wrote " + encodedBand.length + " bytes from cpSignatureForm[" + cpSignatureForm.length + "]");
513
514 encodedBand = encodeBandInt("cpSignatureClasses", cpSignatureClasses, Codec.UDELTA5);
515 out.write(encodedBand);
516 PackingUtils.log("Wrote " + encodedBand.length + " bytes from cpSignatureClasses[" + cpSignatureClasses.length + "]");
517 }
518
519 private void writeCpString(final OutputStream out) throws IOException, Pack200Exception {
520 PackingUtils.log("Writing " + cp_String.size() + " String entries...");
521 final int[] cpString = new int[cp_String.size()];
522 int i = 0;
523 for (final CPString cpStr : cp_String) {
524 cpString[i] = cpStr.getIndexInCpUtf8();
525 i++;
526 }
527 final byte[] encodedBand = encodeBandInt("cpString", cpString, Codec.UDELTA5);
528 out.write(encodedBand);
529 PackingUtils.log("Wrote " + encodedBand.length + " bytes from cpString[" + cpString.length + "]");
530 }
531
532 private void writeCpUtf8(final OutputStream out) throws IOException, Pack200Exception {
533 PackingUtils.log("Writing " + cp_Utf8.size() + " UTF8 entries...");
534 final int[] cpUtf8Prefix = new int[cp_Utf8.size() - 2];
535 final int[] cpUtf8Suffix = new int[cp_Utf8.size() - 1];
536 final List<Character> chars = new ArrayList<>();
537 final List<Integer> bigSuffix = new ArrayList<>();
538 final List<Character> bigChars = new ArrayList<>();
539 final Object[] cpUtf8Array = cp_Utf8.toArray();
540 final String first = ((CPUTF8) cpUtf8Array[1]).getUnderlyingString();
541 cpUtf8Suffix[0] = first.length();
542 addCharacters(chars, first.toCharArray());
543 for (int i = 2; i < cpUtf8Array.length; i++) {
544 final char[] previous = ((CPUTF8) cpUtf8Array[i - 1]).getUnderlyingString().toCharArray();
545 String currentStr = ((CPUTF8) cpUtf8Array[i]).getUnderlyingString();
546 final char[] current = currentStr.toCharArray();
547 int prefix = 0;
548 for (int j = 0; j < previous.length; j++) {
549 if (previous[j] != current[j]) {
550 break;
551 }
552 prefix++;
553 }
554 cpUtf8Prefix[i - 2] = prefix;
555 currentStr = currentStr.substring(prefix);
556 final char[] suffix = currentStr.toCharArray();
557 if (suffix.length > 1000) {
558
559 cpUtf8Suffix[i - 1] = 0;
560 bigSuffix.add(Integer.valueOf(suffix.length));
561 addCharacters(bigChars, suffix);
562 } else {
563 cpUtf8Suffix[i - 1] = suffix.length;
564 addCharacters(chars, suffix);
565 }
566 }
567 final int[] cpUtf8Chars = new int[chars.size()];
568 final int[] cpUtf8BigSuffix = new int[bigSuffix.size()];
569 final int[][] cpUtf8BigChars = new int[bigSuffix.size()][];
570 Arrays.setAll(cpUtf8Chars, i -> chars.get(i).charValue());
571 for (int i = 0; i < cpUtf8BigSuffix.length; i++) {
572 final int numBigChars = bigSuffix.get(i).intValue();
573 cpUtf8BigSuffix[i] = numBigChars;
574 cpUtf8BigChars[i] = new int[numBigChars];
575 Arrays.setAll(cpUtf8BigChars[i], j -> bigChars.remove(0).charValue());
576 }
577
578 byte[] encodedBand = encodeBandInt("cpUtf8Prefix", cpUtf8Prefix, Codec.DELTA5);
579 out.write(encodedBand);
580 PackingUtils.log("Wrote " + encodedBand.length + " bytes from cpUtf8Prefix[" + cpUtf8Prefix.length + "]");
581
582 encodedBand = encodeBandInt("cpUtf8Suffix", cpUtf8Suffix, Codec.UNSIGNED5);
583 out.write(encodedBand);
584 PackingUtils.log("Wrote " + encodedBand.length + " bytes from cpUtf8Suffix[" + cpUtf8Suffix.length + "]");
585
586 encodedBand = encodeBandInt("cpUtf8Chars", cpUtf8Chars, Codec.CHAR3);
587 out.write(encodedBand);
588 PackingUtils.log("Wrote " + encodedBand.length + " bytes from cpUtf8Chars[" + cpUtf8Chars.length + "]");
589
590 encodedBand = encodeBandInt("cpUtf8BigSuffix", cpUtf8BigSuffix, Codec.DELTA5);
591 out.write(encodedBand);
592 PackingUtils.log("Wrote " + encodedBand.length + " bytes from cpUtf8BigSuffix[" + cpUtf8BigSuffix.length + "]");
593
594 for (int i = 0; i < cpUtf8BigChars.length; i++) {
595 encodedBand = encodeBandInt("cpUtf8BigChars " + i, cpUtf8BigChars[i], Codec.DELTA5);
596 out.write(encodedBand);
597 PackingUtils.log("Wrote " + encodedBand.length + " bytes from cpUtf8BigChars" + i + "[" + cpUtf8BigChars[i].length + "]");
598 }
599 }
600
601 }