1/*
2 * Copyright (c) 2001, 2013, 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
26package com.sun.java.util.jar.pack;
27
28import com.sun.java.util.jar.pack.ConstantPool.Entry;
29import com.sun.java.util.jar.pack.ConstantPool.Index;
30import com.sun.java.util.jar.pack.Package.Class.Field;
31import java.io.BufferedOutputStream;
32import java.io.ByteArrayInputStream;
33import java.io.ByteArrayOutputStream;
34import java.io.EOFException;
35import java.io.File;
36import java.io.FileOutputStream;
37import java.io.FilterInputStream;
38import java.io.FilterOutputStream;
39import java.io.IOException;
40import java.io.InputStream;
41import java.io.OutputStream;
42import java.io.PrintStream;
43import java.util.ArrayList;
44import java.util.Arrays;
45import java.util.Collections;
46import java.util.HashMap;
47import java.util.List;
48import java.util.Map;
49import java.util.jar.Pack200;
50import static com.sun.java.util.jar.pack.Constants.*;
51import java.util.LinkedList;
52
53/**
54 * Define the structure and ordering of "bands" in a packed file.
55 * @author John Rose
56 */
57abstract
58class BandStructure {
59    static final int MAX_EFFORT = 9;
60    static final int MIN_EFFORT = 1;
61    static final int DEFAULT_EFFORT = 5;
62
63    // Inherit options from Pack200:
64    PropMap p200 = Utils.currentPropMap();
65
66    int verbose = p200.getInteger(Utils.DEBUG_VERBOSE);
67    int effort = p200.getInteger(Pack200.Packer.EFFORT);
68    { if (effort == 0)  effort = DEFAULT_EFFORT; }
69    boolean optDumpBands = p200.getBoolean(Utils.COM_PREFIX+"dump.bands");
70    boolean optDebugBands = p200.getBoolean(Utils.COM_PREFIX+"debug.bands");
71
72    // Various heuristic options.
73    boolean optVaryCodings = !p200.getBoolean(Utils.COM_PREFIX+"no.vary.codings");
74    boolean optBigStrings = !p200.getBoolean(Utils.COM_PREFIX+"no.big.strings");
75
76    protected abstract Index getCPIndex(byte tag);
77
78    // Local copy of highest class version.
79    private Package.Version highestClassVersion = null;
80
81    /** Call this exactly once, early, to specify the archive major version. */
82    public void initHighestClassVersion(Package.Version highestClassVersion) throws IOException {
83        if (this.highestClassVersion != null) {
84            throw new IOException(
85                "Highest class major version is already initialized to " +
86                this.highestClassVersion + "; new setting is " + highestClassVersion);
87        }
88        this.highestClassVersion = highestClassVersion;
89        adjustToClassVersion();
90    }
91
92    public Package.Version getHighestClassVersion() {
93        return highestClassVersion;
94    }
95
96    private final boolean isReader = this instanceof PackageReader;
97
98    protected BandStructure() {}
99
100    static final Coding BYTE1 = Coding.of(1,256);
101
102    static final Coding CHAR3 = Coding.of(3,128);
103    // Note:  Tried sharper (3,16) with no post-zip benefit.
104
105    // This is best used with BCI values:
106    static final Coding BCI5 = Coding.of(5,4);  // mostly 1-byte offsets
107    static final Coding BRANCH5 = Coding.of(5,4,2); // mostly forward branches
108
109    static final Coding UNSIGNED5 = Coding.of(5,64);
110    static final Coding UDELTA5 = UNSIGNED5.getDeltaCoding();
111    // "sharp" (5,64) zips 0.4% better than "medium" (5,128)
112    // It zips 1.1% better than "flat" (5,192)
113
114    static final Coding SIGNED5 = Coding.of(5,64,1);  //sharp
115    static final Coding DELTA5 = SIGNED5.getDeltaCoding();
116    // Note:  Tried (5,128,2) and (5,192,2) with no benefit.
117
118    static final Coding MDELTA5 = Coding.of(5,64,2).getDeltaCoding();
119
120    private static final Coding[] basicCodings = {
121        // Table of "Canonical BHSD Codings" from Pack200 spec.
122        null,  // _meta_default
123
124        // Fixed-length codings:
125        Coding.of(1,256,0),
126        Coding.of(1,256,1),
127        Coding.of(1,256,0).getDeltaCoding(),
128        Coding.of(1,256,1).getDeltaCoding(),
129        Coding.of(2,256,0),
130        Coding.of(2,256,1),
131        Coding.of(2,256,0).getDeltaCoding(),
132        Coding.of(2,256,1).getDeltaCoding(),
133        Coding.of(3,256,0),
134        Coding.of(3,256,1),
135        Coding.of(3,256,0).getDeltaCoding(),
136        Coding.of(3,256,1).getDeltaCoding(),
137        Coding.of(4,256,0),
138        Coding.of(4,256,1),
139        Coding.of(4,256,0).getDeltaCoding(),
140        Coding.of(4,256,1).getDeltaCoding(),
141
142        // Full-range variable-length codings:
143        Coding.of(5,  4,0),
144        Coding.of(5,  4,1),
145        Coding.of(5,  4,2),
146        Coding.of(5, 16,0),
147        Coding.of(5, 16,1),
148        Coding.of(5, 16,2),
149        Coding.of(5, 32,0),
150        Coding.of(5, 32,1),
151        Coding.of(5, 32,2),
152        Coding.of(5, 64,0),
153        Coding.of(5, 64,1),
154        Coding.of(5, 64,2),
155        Coding.of(5,128,0),
156        Coding.of(5,128,1),
157        Coding.of(5,128,2),
158
159        Coding.of(5,  4,0).getDeltaCoding(),
160        Coding.of(5,  4,1).getDeltaCoding(),
161        Coding.of(5,  4,2).getDeltaCoding(),
162        Coding.of(5, 16,0).getDeltaCoding(),
163        Coding.of(5, 16,1).getDeltaCoding(),
164        Coding.of(5, 16,2).getDeltaCoding(),
165        Coding.of(5, 32,0).getDeltaCoding(),
166        Coding.of(5, 32,1).getDeltaCoding(),
167        Coding.of(5, 32,2).getDeltaCoding(),
168        Coding.of(5, 64,0).getDeltaCoding(),
169        Coding.of(5, 64,1).getDeltaCoding(),
170        Coding.of(5, 64,2).getDeltaCoding(),
171        Coding.of(5,128,0).getDeltaCoding(),
172        Coding.of(5,128,1).getDeltaCoding(),
173        Coding.of(5,128,2).getDeltaCoding(),
174
175        // Variable length subrange codings:
176        Coding.of(2,192,0),
177        Coding.of(2,224,0),
178        Coding.of(2,240,0),
179        Coding.of(2,248,0),
180        Coding.of(2,252,0),
181
182        Coding.of(2,  8,0).getDeltaCoding(),
183        Coding.of(2,  8,1).getDeltaCoding(),
184        Coding.of(2, 16,0).getDeltaCoding(),
185        Coding.of(2, 16,1).getDeltaCoding(),
186        Coding.of(2, 32,0).getDeltaCoding(),
187        Coding.of(2, 32,1).getDeltaCoding(),
188        Coding.of(2, 64,0).getDeltaCoding(),
189        Coding.of(2, 64,1).getDeltaCoding(),
190        Coding.of(2,128,0).getDeltaCoding(),
191        Coding.of(2,128,1).getDeltaCoding(),
192        Coding.of(2,192,0).getDeltaCoding(),
193        Coding.of(2,192,1).getDeltaCoding(),
194        Coding.of(2,224,0).getDeltaCoding(),
195        Coding.of(2,224,1).getDeltaCoding(),
196        Coding.of(2,240,0).getDeltaCoding(),
197        Coding.of(2,240,1).getDeltaCoding(),
198        Coding.of(2,248,0).getDeltaCoding(),
199        Coding.of(2,248,1).getDeltaCoding(),
200
201        Coding.of(3,192,0),
202        Coding.of(3,224,0),
203        Coding.of(3,240,0),
204        Coding.of(3,248,0),
205        Coding.of(3,252,0),
206
207        Coding.of(3,  8,0).getDeltaCoding(),
208        Coding.of(3,  8,1).getDeltaCoding(),
209        Coding.of(3, 16,0).getDeltaCoding(),
210        Coding.of(3, 16,1).getDeltaCoding(),
211        Coding.of(3, 32,0).getDeltaCoding(),
212        Coding.of(3, 32,1).getDeltaCoding(),
213        Coding.of(3, 64,0).getDeltaCoding(),
214        Coding.of(3, 64,1).getDeltaCoding(),
215        Coding.of(3,128,0).getDeltaCoding(),
216        Coding.of(3,128,1).getDeltaCoding(),
217        Coding.of(3,192,0).getDeltaCoding(),
218        Coding.of(3,192,1).getDeltaCoding(),
219        Coding.of(3,224,0).getDeltaCoding(),
220        Coding.of(3,224,1).getDeltaCoding(),
221        Coding.of(3,240,0).getDeltaCoding(),
222        Coding.of(3,240,1).getDeltaCoding(),
223        Coding.of(3,248,0).getDeltaCoding(),
224        Coding.of(3,248,1).getDeltaCoding(),
225
226        Coding.of(4,192,0),
227        Coding.of(4,224,0),
228        Coding.of(4,240,0),
229        Coding.of(4,248,0),
230        Coding.of(4,252,0),
231
232        Coding.of(4,  8,0).getDeltaCoding(),
233        Coding.of(4,  8,1).getDeltaCoding(),
234        Coding.of(4, 16,0).getDeltaCoding(),
235        Coding.of(4, 16,1).getDeltaCoding(),
236        Coding.of(4, 32,0).getDeltaCoding(),
237        Coding.of(4, 32,1).getDeltaCoding(),
238        Coding.of(4, 64,0).getDeltaCoding(),
239        Coding.of(4, 64,1).getDeltaCoding(),
240        Coding.of(4,128,0).getDeltaCoding(),
241        Coding.of(4,128,1).getDeltaCoding(),
242        Coding.of(4,192,0).getDeltaCoding(),
243        Coding.of(4,192,1).getDeltaCoding(),
244        Coding.of(4,224,0).getDeltaCoding(),
245        Coding.of(4,224,1).getDeltaCoding(),
246        Coding.of(4,240,0).getDeltaCoding(),
247        Coding.of(4,240,1).getDeltaCoding(),
248        Coding.of(4,248,0).getDeltaCoding(),
249        Coding.of(4,248,1).getDeltaCoding(),
250
251        null
252    };
253    private static final Map<Coding, Integer> basicCodingIndexes;
254    static {
255        assert(basicCodings[_meta_default] == null);
256        assert(basicCodings[_meta_canon_min] != null);
257        assert(basicCodings[_meta_canon_max] != null);
258        Map<Coding, Integer> map = new HashMap<>();
259        for (int i = 0; i < basicCodings.length; i++) {
260            Coding c = basicCodings[i];
261            if (c == null)  continue;
262            assert(i >= _meta_canon_min);
263            assert(i <= _meta_canon_max);
264            map.put(c, i);
265        }
266        basicCodingIndexes = map;
267    }
268    public static Coding codingForIndex(int i) {
269        return i < basicCodings.length ? basicCodings[i] : null;
270    }
271    public static int indexOf(Coding c) {
272        Integer i = basicCodingIndexes.get(c);
273        if (i == null)  return 0;
274        return i.intValue();
275    }
276    public static Coding[] getBasicCodings() {
277        return basicCodings.clone();
278    }
279
280    protected byte[] bandHeaderBytes;    // used for input only
281    protected int    bandHeaderBytePos;  // BHB read pointer, for input only
282    protected int    bandHeaderBytePos0; // for debug
283
284    protected CodingMethod getBandHeader(int XB, Coding regularCoding) {
285        CodingMethod[] res = {null};
286        // push back XB onto the band header bytes
287        bandHeaderBytes[--bandHeaderBytePos] = (byte) XB;
288        bandHeaderBytePos0 = bandHeaderBytePos;
289        // scan forward through XB and any additional band header bytes
290        bandHeaderBytePos = parseMetaCoding(bandHeaderBytes,
291                                            bandHeaderBytePos,
292                                            regularCoding,
293                                            res);
294        return res[0];
295    }
296
297    public static int parseMetaCoding(byte[] bytes, int pos, Coding dflt, CodingMethod[] res) {
298        if ((bytes[pos] & 0xFF) == _meta_default) {
299            res[0] = dflt;
300            return pos+1;
301        }
302        int pos2;
303        pos2 = Coding.parseMetaCoding(bytes, pos, dflt, res);
304        if (pos2 > pos)  return pos2;
305        pos2 = PopulationCoding.parseMetaCoding(bytes, pos, dflt, res);
306        if (pos2 > pos)  return pos2;
307        pos2 = AdaptiveCoding.parseMetaCoding(bytes, pos, dflt, res);
308        if (pos2 > pos)  return pos2;
309        throw new RuntimeException("Bad meta-coding op "+(bytes[pos]&0xFF));
310    }
311
312    static final int SHORT_BAND_HEURISTIC = 100;
313
314    public static final int NO_PHASE        = 0;
315
316    // package writing phases:
317    public static final int COLLECT_PHASE   = 1; // collect data before write
318    public static final int FROZEN_PHASE    = 3; // no longer collecting
319    public static final int WRITE_PHASE     = 5; // ready to write bytes
320
321    // package reading phases:
322    public static final int EXPECT_PHASE    = 2; // gather expected counts
323    public static final int READ_PHASE      = 4; // ready to read bytes
324    public static final int DISBURSE_PHASE  = 6; // pass out data after read
325
326    public static final int DONE_PHASE      = 8; // done writing or reading
327
328    static boolean phaseIsRead(int p) {
329        return (p % 2) == 0;
330    }
331    static int phaseCmp(int p0, int p1) {
332        assert((p0 % 2) == (p1 % 2) || (p0 % 8) == 0 || (p1 % 8) == 0);
333        return p0 - p1;
334    }
335
336    /** The packed file is divided up into a number of segments.
337     *  Most segments are typed as ValueBand, strongly-typed sequences
338     *  of integer values, all interpreted in a single way.
339     *  A few segments are ByteBands, which hetergeneous sequences
340     *  of bytes.
341     *
342     *  The two phases for writing a packed file are COLLECT and WRITE.
343     *  1. When writing a packed file, each band collects
344     *  data in an ad-hoc order.
345     *  2. At the end, each band is assigned a coding scheme,
346     *  and then all the bands are written in their global order.
347     *
348     *  The three phases for reading a packed file are EXPECT, READ,
349     *  and DISBURSE.
350     *  1. For each band, the expected number of integers  is determined.
351     *  2. The data is actually read from the file into the band.
352     *  3. The band pays out its values as requested, in an ad hoc order.
353     *
354     *  When the last phase of a band is done, it is marked so (DONE).
355     *  Clearly, these phases must be properly ordered WRT each other.
356     */
357    abstract class Band {
358        private int    phase = NO_PHASE;
359        private final  String name;
360
361        private int    valuesExpected;
362
363        protected long outputSize = -1;  // cache
364
365        public final Coding regularCoding;
366
367        public final int seqForDebug;
368        public int       elementCountForDebug;
369
370
371        protected Band(String name, Coding regularCoding) {
372            this.name = name;
373            this.regularCoding = regularCoding;
374            this.seqForDebug = ++nextSeqForDebug;
375            if (verbose > 2)
376                Utils.log.fine("Band "+seqForDebug+" is "+name);
377            // caller must call init
378        }
379
380        public Band init() {
381            // Cannot due this from the constructor, because constructor
382            // may wish to initialize some subclass variables.
383            // Set initial phase for reading or writing:
384            if (isReader)
385                readyToExpect();
386            else
387                readyToCollect();
388            return this;
389        }
390
391        // common operations
392        boolean isReader() { return isReader; }
393        int phase() { return phase; }
394        String name() { return name; }
395
396        /** Return -1 if data buffer not allocated, else max length. */
397        public abstract int capacity();
398
399        /** Allocate data buffer to specified length. */
400        protected abstract void setCapacity(int cap);
401
402        /** Return current number of values in buffer, which must exist. */
403        public abstract int length();
404
405        protected abstract int valuesRemainingForDebug();
406
407        public final int valuesExpected() {
408            return valuesExpected;
409        }
410
411        /** Write out bytes, encoding the values. */
412        public final void writeTo(OutputStream out) throws IOException {
413            assert(assertReadyToWriteTo(this, out));
414            setPhase(WRITE_PHASE);
415            // subclasses continue by writing their contents to output
416            writeDataTo(out);
417            doneWriting();
418        }
419
420        abstract void chooseBandCodings() throws IOException;
421
422        public final long outputSize() {
423            if (outputSize >= 0) {
424                long size = outputSize;
425                assert(size == computeOutputSize());
426                return size;
427            }
428            return computeOutputSize();
429        }
430
431        protected abstract long computeOutputSize();
432
433        protected abstract void writeDataTo(OutputStream out) throws IOException;
434
435        /** Expect a certain number of values. */
436        void expectLength(int l) {
437            assert(assertPhase(this, EXPECT_PHASE));
438            assert(valuesExpected == 0);  // all at once
439            assert(l >= 0);
440            valuesExpected = l;
441        }
442        /** Expect more values.  (Multiple calls accumulate.) */
443        void expectMoreLength(int l) {
444            assert(assertPhase(this, EXPECT_PHASE));
445            valuesExpected += l;
446        }
447
448
449        /// Phase change markers.
450
451        private void readyToCollect() { // called implicitly by constructor
452            setCapacity(1);
453            setPhase(COLLECT_PHASE);
454        }
455        protected void doneWriting() {
456            assert(assertPhase(this, WRITE_PHASE));
457            setPhase(DONE_PHASE);
458        }
459        private void readyToExpect() { // called implicitly by constructor
460            setPhase(EXPECT_PHASE);
461        }
462        /** Read in bytes, decoding the values. */
463        public final void readFrom(InputStream in) throws IOException {
464            assert(assertReadyToReadFrom(this, in));
465            setCapacity(valuesExpected());
466            setPhase(READ_PHASE);
467            // subclasses continue by reading their contents from input:
468            readDataFrom(in);
469            readyToDisburse();
470        }
471        protected abstract void readDataFrom(InputStream in) throws IOException;
472        protected void readyToDisburse() {
473            if (verbose > 1)  Utils.log.fine("readyToDisburse "+this);
474            setPhase(DISBURSE_PHASE);
475        }
476        public void doneDisbursing() {
477            assert(assertPhase(this, DISBURSE_PHASE));
478            setPhase(DONE_PHASE);
479        }
480        public final void doneWithUnusedBand() {
481            if (isReader) {
482                assert(assertPhase(this, EXPECT_PHASE));
483                assert(valuesExpected() == 0);
484                // Fast forward:
485                setPhase(READ_PHASE);
486                setPhase(DISBURSE_PHASE);
487                setPhase(DONE_PHASE);
488            } else {
489                setPhase(FROZEN_PHASE);
490            }
491        }
492
493        protected void setPhase(int newPhase) {
494            assert(assertPhaseChangeOK(this, phase, newPhase));
495            this.phase = newPhase;
496        }
497
498        protected int lengthForDebug = -1;  // DEBUG ONLY
499        @Override
500        public String toString() {  // DEBUG ONLY
501            int length = (lengthForDebug != -1 ? lengthForDebug : length());
502            String str = name;
503            if (length != 0)
504                str += "[" + length + "]";
505            if (elementCountForDebug != 0)
506                str += "(" + elementCountForDebug + ")";
507            return str;
508        }
509    }
510
511    class ValueBand extends Band {
512        private int[]  values;   // must be null in EXPECT phase
513        private int    length;
514        private int    valuesDisbursed;
515
516        private CodingMethod bandCoding;
517        private byte[] metaCoding;
518
519        protected ValueBand(String name, Coding regularCoding) {
520            super(name, regularCoding);
521        }
522
523        @Override
524        public int capacity() {
525            return values == null ? -1 : values.length;
526        }
527
528        /** Declare predicted or needed capacity. */
529        @Override
530        protected void setCapacity(int cap) {
531            assert(length <= cap);
532            if (cap == -1) { values = null; return; }
533            values = realloc(values, cap);
534        }
535
536        @Override
537        public int length() {
538            return length;
539        }
540        @Override
541        protected int valuesRemainingForDebug() {
542            return length - valuesDisbursed;
543        }
544        protected int valueAtForDebug(int i) {
545            return values[i];
546        }
547
548        void patchValue(int i, int value) {
549            // Only one use for this.
550            assert(this == archive_header_S);
551            assert(i == AH_ARCHIVE_SIZE_HI || i == AH_ARCHIVE_SIZE_LO);
552            assert(i < length);  // must have already output a dummy
553            values[i] = value;
554            outputSize = -1;  // decache
555        }
556
557        protected void initializeValues(int[] values) {
558            assert(assertCanChangeLength(this));
559            assert(length == 0);
560            this.values = values;
561            this.length = values.length;
562        }
563
564        /** Collect one value, or store one decoded value. */
565        protected void addValue(int x) {
566            assert(assertCanChangeLength(this));
567            if (length == values.length)
568                setCapacity(length < 1000 ? length * 10 : length * 2);
569            values[length++] = x;
570        }
571
572        private boolean canVaryCoding() {
573            if (!optVaryCodings)           return false;
574            if (length == 0)               return false;
575            // Can't read band_headers w/o the archive header:
576            if (this == archive_header_0)  return false;
577            if (this == archive_header_S)  return false;
578            if (this == archive_header_1)  return false;
579            // BYTE1 bands can't vary codings, but the others can.
580            // All that's needed for the initial escape is at least
581            // 256 negative values or more than 256 non-negative values
582            return (regularCoding.min() <= -256 || regularCoding.max() >= 256);
583        }
584
585        private boolean shouldVaryCoding() {
586            assert(canVaryCoding());
587            if (effort < MAX_EFFORT && length < SHORT_BAND_HEURISTIC)
588                return false;
589            return true;
590        }
591
592        @Override
593        protected void chooseBandCodings() throws IOException {
594            boolean canVary = canVaryCoding();
595            if (!canVary || !shouldVaryCoding()) {
596                if (regularCoding.canRepresent(values, 0, length)) {
597                    bandCoding = regularCoding;
598                } else {
599                    assert(canVary);
600                    if (verbose > 1)
601                        Utils.log.fine("regular coding fails in band "+name());
602                    bandCoding = UNSIGNED5;
603                }
604                outputSize = -1;
605            } else {
606                int[] sizes = {0,0};
607                bandCoding = chooseCoding(values, 0, length,
608                                          regularCoding, name(),
609                                          sizes);
610                outputSize = sizes[CodingChooser.BYTE_SIZE];
611                if (outputSize == 0)  // CodingChooser failed to size it.
612                    outputSize = -1;
613            }
614
615            // Compute and save the meta-coding bytes also.
616            if (bandCoding != regularCoding) {
617                metaCoding = bandCoding.getMetaCoding(regularCoding);
618                if (verbose > 1) {
619                    Utils.log.fine("alternate coding "+this+" "+bandCoding);
620                }
621            } else if (canVary &&
622                       decodeEscapeValue(values[0], regularCoding) >= 0) {
623                // Need an explicit default.
624                metaCoding = defaultMetaCoding;
625            } else {
626                // Common case:  Zero bytes of meta coding.
627                metaCoding = noMetaCoding;
628            }
629            if (metaCoding.length > 0
630                && (verbose > 2 || verbose > 1 && metaCoding.length > 1)) {
631                StringBuilder sb = new StringBuilder();
632                for (int i = 0; i < metaCoding.length; i++) {
633                    if (i == 1)  sb.append(" /");
634                    sb.append(" ").append(metaCoding[i] & 0xFF);
635                }
636                Utils.log.fine("   meta-coding "+sb);
637            }
638
639            assert((outputSize < 0) ||
640                   !(bandCoding instanceof Coding) ||
641                   (outputSize == ((Coding)bandCoding)
642                    .getLength(values, 0, length)))
643                : (bandCoding+" : "+
644                   outputSize+" != "+
645                   ((Coding)bandCoding).getLength(values, 0, length)
646                   +" ?= "+getCodingChooser().computeByteSize(bandCoding,values,0,length)
647                   );
648
649            // Compute outputSize of the escape value X, if any.
650            if (metaCoding.length > 0) {
651                // First byte XB of meta-coding is treated specially,
652                // but any other bytes go into the band headers band.
653                // This must be done before any other output happens.
654                if (outputSize >= 0)
655                    outputSize += computeEscapeSize();  // good cache
656                // Other bytes go into band_headers.
657                for (int i = 1; i < metaCoding.length; i++) {
658                    band_headers.putByte(metaCoding[i] & 0xFF);
659                }
660            }
661        }
662
663        @Override
664        protected long computeOutputSize() {
665            outputSize = getCodingChooser().computeByteSize(bandCoding,
666                                                            values, 0, length);
667            assert(outputSize < Integer.MAX_VALUE);
668            outputSize += computeEscapeSize();
669            return outputSize;
670        }
671
672        protected int computeEscapeSize() {
673            if (metaCoding.length == 0)  return 0;
674            int XB = metaCoding[0] & 0xFF;
675            int X = encodeEscapeValue(XB, regularCoding);
676            return regularCoding.setD(0).getLength(X);
677        }
678
679        @Override
680        protected void writeDataTo(OutputStream out) throws IOException {
681            if (length == 0)  return;  // nothing to write
682            long len0 = 0;
683            if (out == outputCounter) {
684                len0 = outputCounter.getCount();
685            }
686            if (metaCoding.length > 0) {
687                int XB = metaCoding[0] & 0xFF;
688                // We need an explicit band header, either because
689                // there is a non-default coding method, or because
690                // the first value would be parsed as an escape value.
691                int X = encodeEscapeValue(XB, regularCoding);
692                //System.out.println("X="+X+" XB="+XB+" in "+this);
693                regularCoding.setD(0).writeTo(out, X);
694            }
695            bandCoding.writeArrayTo(out, values, 0, length);
696            if (out == outputCounter) {
697                assert(outputSize == outputCounter.getCount() - len0)
698                    : (outputSize+" != "+outputCounter.getCount()+"-"+len0);
699            }
700            if (optDumpBands)  dumpBand();
701        }
702
703        @Override
704        protected void readDataFrom(InputStream in) throws IOException {
705            length = valuesExpected();
706            if (length == 0)  return;  // nothing to read
707            if (verbose > 1)
708                Utils.log.fine("Reading band "+this);
709            if (!canVaryCoding()) {
710                bandCoding = regularCoding;
711                metaCoding = noMetaCoding;
712            } else {
713                assert(in.markSupported());  // input must be buffered
714                in.mark(Coding.B_MAX);
715                int X = regularCoding.setD(0).readFrom(in);
716                int XB = decodeEscapeValue(X, regularCoding);
717                if (XB < 0) {
718                    // Do not consume this value.  No alternate coding.
719                    in.reset();
720                    bandCoding = regularCoding;
721                    metaCoding = noMetaCoding;
722                } else if (XB == _meta_default) {
723                    bandCoding = regularCoding;
724                    metaCoding = defaultMetaCoding;
725                } else {
726                    if (verbose > 2)
727                        Utils.log.fine("found X="+X+" => XB="+XB);
728                    bandCoding = getBandHeader(XB, regularCoding);
729                    // This is really used only by dumpBands.
730                    int p0 = bandHeaderBytePos0;
731                    int p1 = bandHeaderBytePos;
732                    metaCoding = new byte[p1-p0];
733                    System.arraycopy(bandHeaderBytes, p0,
734                                     metaCoding, 0, metaCoding.length);
735                }
736            }
737            if (bandCoding != regularCoding) {
738                if (verbose > 1)
739                    Utils.log.fine(name()+": irregular coding "+bandCoding);
740            }
741            bandCoding.readArrayFrom(in, values, 0, length);
742            if (optDumpBands)  dumpBand();
743        }
744
745        @Override
746        public void doneDisbursing() {
747            super.doneDisbursing();
748            values = null;  // for GC
749        }
750
751        private void dumpBand() throws IOException {
752            assert(optDumpBands);
753            try (PrintStream ps = new PrintStream(getDumpStream(this, ".txt"))) {
754                String irr = (bandCoding == regularCoding) ? "" : " irregular";
755                ps.print("# length="+length+
756                         " size="+outputSize()+
757                         irr+" coding="+bandCoding);
758                if (metaCoding != noMetaCoding) {
759                    StringBuilder sb = new StringBuilder();
760                    for (int i = 0; i < metaCoding.length; i++) {
761                        if (i == 1)  sb.append(" /");
762                        sb.append(" ").append(metaCoding[i] & 0xFF);
763                    }
764                    ps.print(" //header: "+sb);
765                }
766                printArrayTo(ps, values, 0, length);
767            }
768            try (OutputStream ds = getDumpStream(this, ".bnd")) {
769                bandCoding.writeArrayTo(ds, values, 0, length);
770            }
771        }
772
773        /** Disburse one value. */
774        protected int getValue() {
775            assert(phase() == DISBURSE_PHASE);
776            // when debugging return a zero if lengths are zero
777            if (optDebugBands && length == 0 && valuesDisbursed == length)
778                return 0;
779            assert(valuesDisbursed <= length);
780            return values[valuesDisbursed++];
781        }
782
783        /** Reset for another pass over the same value set. */
784        public void resetForSecondPass() {
785            assert(phase() == DISBURSE_PHASE);
786            assert(valuesDisbursed == length());  // 1st pass is complete
787            valuesDisbursed = 0;
788        }
789    }
790
791    class ByteBand extends Band {
792        private ByteArrayOutputStream bytes;  // input buffer
793        private ByteArrayOutputStream bytesForDump;
794        private InputStream in;
795
796        public ByteBand(String name) {
797            super(name, BYTE1);
798        }
799
800        @Override
801        public int capacity() {
802            return bytes == null ? -1 : Integer.MAX_VALUE;
803        }
804        @Override
805        protected void setCapacity(int cap) {
806            assert(bytes == null);  // do this just once
807            bytes = new ByteArrayOutputStream(cap);
808        }
809        public void destroy() {
810            lengthForDebug = length();
811            bytes = null;
812        }
813
814        @Override
815        public int length() {
816            return bytes == null ? -1 : bytes.size();
817        }
818        public void reset() {
819            bytes.reset();
820        }
821        @Override
822        protected int valuesRemainingForDebug() {
823            return (bytes == null) ? -1 : ((ByteArrayInputStream)in).available();
824        }
825
826        @Override
827        protected void chooseBandCodings() throws IOException {
828            // No-op.
829            assert(decodeEscapeValue(regularCoding.min(), regularCoding) < 0);
830            assert(decodeEscapeValue(regularCoding.max(), regularCoding) < 0);
831        }
832
833        @Override
834        protected long computeOutputSize() {
835            // do not cache
836            return bytes.size();
837        }
838
839        @Override
840        public void writeDataTo(OutputStream out) throws IOException {
841            if (length() == 0)  return;
842            bytes.writeTo(out);
843            if (optDumpBands)  dumpBand();
844            destroy();  // done with the bits!
845        }
846
847        private void dumpBand() throws IOException {
848            assert(optDumpBands);
849            try (OutputStream ds = getDumpStream(this, ".bnd")) {
850                if (bytesForDump != null)
851                    bytesForDump.writeTo(ds);
852                else
853                    bytes.writeTo(ds);
854            }
855        }
856
857        @Override
858        public void readDataFrom(InputStream in) throws IOException {
859            int vex = valuesExpected();
860            if (vex == 0)  return;
861            if (verbose > 1) {
862                lengthForDebug = vex;
863                Utils.log.fine("Reading band "+this);
864                lengthForDebug = -1;
865            }
866            byte[] buf = new byte[Math.min(vex, 1<<14)];
867            while (vex > 0) {
868                int nr = in.read(buf, 0, Math.min(vex, buf.length));
869                if (nr < 0)  throw new EOFException();
870                bytes.write(buf, 0, nr);
871                vex -= nr;
872            }
873            if (optDumpBands)  dumpBand();
874        }
875
876        @Override
877        public void readyToDisburse() {
878            in = new ByteArrayInputStream(bytes.toByteArray());
879            super.readyToDisburse();
880        }
881
882        @Override
883        public void doneDisbursing() {
884            super.doneDisbursing();
885            if (optDumpBands
886                && bytesForDump != null && bytesForDump.size() > 0) {
887                try {
888                    dumpBand();
889                } catch (IOException ee) {
890                    throw new RuntimeException(ee);
891                }
892            }
893            in = null; // GC
894            bytes = null;  // GC
895            bytesForDump = null;  // GC
896        }
897
898        // alternative to readFrom:
899        public void setInputStreamFrom(InputStream in) throws IOException {
900            assert(bytes == null);
901            assert(assertReadyToReadFrom(this, in));
902            setPhase(READ_PHASE);
903            this.in = in;
904            if (optDumpBands) {
905                // Tap the stream.
906                bytesForDump = new ByteArrayOutputStream();
907                this.in = new FilterInputStream(in) {
908                    @Override
909                    public int read() throws IOException {
910                        int ch = in.read();
911                        if (ch >= 0)  bytesForDump.write(ch);
912                        return ch;
913                    }
914                    @Override
915                    public int read(byte b[], int off, int len) throws IOException {
916                        int nr = in.read(b, off, len);
917                        if (nr >= 0)  bytesForDump.write(b, off, nr);
918                        return nr;
919                    }
920                };
921            }
922            super.readyToDisburse();
923        }
924
925        public OutputStream collectorStream() {
926            assert(phase() == COLLECT_PHASE);
927            assert(bytes != null);
928            return bytes;
929        }
930
931        public InputStream getInputStream() {
932            assert(phase() == DISBURSE_PHASE);
933            assert(in != null);
934            return in;
935        }
936        public int getByte() throws IOException {
937            int b = getInputStream().read();
938            if (b < 0)  throw new EOFException();
939            return b;
940        }
941        public void putByte(int b) throws IOException {
942            assert(b == (b & 0xFF));
943            collectorStream().write(b);
944        }
945        @Override
946        public String toString() {
947            return "byte "+super.toString();
948        }
949    }
950
951    class IntBand extends ValueBand {
952        // The usual coding for bands is 7bit/5byte/delta.
953        public IntBand(String name, Coding regularCoding) {
954            super(name, regularCoding);
955        }
956
957        public void putInt(int x) {
958            assert(phase() == COLLECT_PHASE);
959            addValue(x);
960        }
961
962        public int getInt() {
963            return getValue();
964        }
965        /** Return the sum of all values in this band. */
966        public int getIntTotal() {
967            assert(phase() == DISBURSE_PHASE);
968            // assert that this is the whole pass; no other reads allowed
969            assert(valuesRemainingForDebug() == length());
970            int total = 0;
971            for (int k = length(); k > 0; k--) {
972                total += getInt();
973            }
974            resetForSecondPass();
975            return total;
976        }
977        /** Return the occurrence count of a specific value in this band. */
978        public int getIntCount(int value) {
979            assert(phase() == DISBURSE_PHASE);
980            // assert that this is the whole pass; no other reads allowed
981            assert(valuesRemainingForDebug() == length());
982            int total = 0;
983            for (int k = length(); k > 0; k--) {
984                if (getInt() == value) {
985                    total += 1;
986                }
987            }
988            resetForSecondPass();
989            return total;
990        }
991    }
992
993    static int getIntTotal(int[] values) {
994        int total = 0;
995        for (int i = 0; i < values.length; i++) {
996            total += values[i];
997        }
998        return total;
999    }
1000
1001    class CPRefBand extends ValueBand {
1002        Index index;
1003        boolean nullOK;
1004
1005        public CPRefBand(String name, Coding regularCoding, byte cpTag, boolean nullOK) {
1006            super(name, regularCoding);
1007            this.nullOK = nullOK;
1008            if (cpTag != CONSTANT_None)
1009                setBandIndex(this, cpTag);
1010        }
1011        public CPRefBand(String name, Coding regularCoding, byte cpTag) {
1012            this(name, regularCoding, cpTag, false);
1013        }
1014        public CPRefBand(String name, Coding regularCoding, Object undef) {
1015            this(name, regularCoding, CONSTANT_None, false);
1016        }
1017
1018        public void setIndex(Index index) {
1019            this.index = index;
1020        }
1021
1022        protected void readDataFrom(InputStream in) throws IOException {
1023            super.readDataFrom(in);
1024            assert(assertValidCPRefs(this));
1025        }
1026
1027        /** Write a constant pool reference. */
1028        public void putRef(Entry e) {
1029            addValue(encodeRefOrNull(e, index));
1030        }
1031        public void putRef(Entry e, Index index) {
1032            assert(this.index == null);
1033            addValue(encodeRefOrNull(e, index));
1034        }
1035        public void putRef(Entry e, byte cptag) {
1036            putRef(e, getCPIndex(cptag));
1037        }
1038
1039        public Entry getRef() {
1040            if (index == null)  Utils.log.warning("No index for "+this);
1041            assert(index != null);
1042            return decodeRefOrNull(getValue(), index);
1043        }
1044        public Entry getRef(Index index) {
1045            assert(this.index == null);
1046            return decodeRefOrNull(getValue(), index);
1047        }
1048        public Entry getRef(byte cptag) {
1049            return getRef(getCPIndex(cptag));
1050        }
1051
1052        private int encodeRefOrNull(Entry e, Index index) {
1053            int nonNullCode;  // NNC is the coding which assumes nulls are rare
1054            if (e == null) {
1055                nonNullCode = -1;  // negative values are rare
1056            } else {
1057                nonNullCode = encodeRef(e, index);
1058            }
1059            // If nulls are expected, increment, to make -1 code turn to 0.
1060            return (nullOK ? 1 : 0) + nonNullCode;
1061        }
1062        private Entry decodeRefOrNull(int code, Index index) {
1063            // Inverse to encodeRefOrNull...
1064            int nonNullCode = code - (nullOK ? 1 : 0);
1065            if (nonNullCode == -1) {
1066                return null;
1067            } else {
1068                return decodeRef(nonNullCode, index);
1069            }
1070        }
1071    }
1072
1073    // Bootstrap support for CPRefBands.  These are needed to record
1074    // intended CP indexes, before the CP has been created.
1075    private final List<CPRefBand> allKQBands = new ArrayList<>();
1076    private List<Object[]> needPredefIndex = new ArrayList<>();
1077
1078
1079    int encodeRef(Entry e, Index ix) {
1080        if (ix == null)
1081            throw new RuntimeException("null index for " + e.stringValue());
1082        int coding = ix.indexOf(e);
1083        if (verbose > 2)
1084            Utils.log.fine("putRef "+coding+" => "+e);
1085        return coding;
1086    }
1087
1088    Entry decodeRef(int n, Index ix) {
1089        if (n < 0 || n >= ix.size())
1090            Utils.log.warning("decoding bad ref "+n+" in "+ix);
1091        Entry e = ix.getEntry(n);
1092        if (verbose > 2)
1093            Utils.log.fine("getRef "+n+" => "+e);
1094        return e;
1095    }
1096
1097    private CodingChooser codingChooser;
1098    protected CodingChooser getCodingChooser() {
1099        if (codingChooser == null) {
1100            codingChooser = new CodingChooser(effort, basicCodings);
1101            if (codingChooser.stress != null
1102                && this instanceof PackageWriter) {
1103                // Twist the random state based on my first file.
1104                // This sends each segment off in a different direction.
1105                List<Package.Class> classes = ((PackageWriter)this).pkg.classes;
1106                if (!classes.isEmpty()) {
1107                    Package.Class cls = classes.get(0);
1108                    codingChooser.addStressSeed(cls.getName().hashCode());
1109                }
1110            }
1111        }
1112        return codingChooser;
1113    }
1114
1115    public CodingMethod chooseCoding(int[] values, int start, int end,
1116                                     Coding regular, String bandName,
1117                                     int[] sizes) {
1118        assert(optVaryCodings);
1119        if (effort <= MIN_EFFORT) {
1120            return regular;
1121        }
1122        CodingChooser cc = getCodingChooser();
1123        if (verbose > 1 || cc.verbose > 1) {
1124            Utils.log.fine("--- chooseCoding "+bandName);
1125        }
1126        return cc.choose(values, start, end, regular, sizes);
1127    }
1128
1129    static final byte[] defaultMetaCoding = { _meta_default };
1130    static final byte[] noMetaCoding      = {};
1131
1132    // The first value in a band is always coded with the default coding D.
1133    // If this first value X is an escape value, it actually represents the
1134    // first (and perhaps only) byte of a meta-coding.
1135    //
1136    // If D.S != 0 and D includes the range [-256..-1],
1137    // the escape values are in that range,
1138    // and the first byte XB is -1-X.
1139    //
1140    // If D.S == 0 and D includes the range [(D.L)..(D.L)+255],
1141    // the escape values are in that range,
1142    // and XB is X-(D.L).
1143    //
1144    // This representation is designed so that a band header is unlikely
1145    // to be confused with the initial value of a headerless band,
1146    // and yet so that a band header is likely to occupy only a byte or two.
1147    //
1148    // Result is in [0..255] if XB was successfully extracted, else -1.
1149    // See section "Coding Specifier Meta-Encoding" in the JSR 200 spec.
1150    protected static int decodeEscapeValue(int X, Coding regularCoding) {
1151        // The first value in a band is always coded with the default coding D.
1152        // If this first value X is an escape value, it actually represents the
1153        // first (and perhaps only) byte of a meta-coding.
1154        // Result is in [0..255] if XB was successfully extracted, else -1.
1155        if (regularCoding.B() == 1 || regularCoding.L() == 0)
1156            return -1;  // degenerate regular coding (BYTE1)
1157        if (regularCoding.S() != 0) {
1158            if (-256 <= X && X <= -1 && regularCoding.min() <= -256) {
1159                int XB = -1-X;
1160                assert(XB >= 0 && XB < 256);
1161                return XB;
1162            }
1163        } else {
1164            int L = regularCoding.L();
1165            if (L <= X && X <= L+255 && regularCoding.max() >= L+255) {
1166                int XB = X-L;
1167                assert(XB >= 0 && XB < 256);
1168                return XB;
1169            }
1170        }
1171        return -1;  // negative value for failure
1172    }
1173    // Inverse to decodeEscapeValue().
1174    protected static int encodeEscapeValue(int XB, Coding regularCoding) {
1175        assert(XB >= 0 && XB < 256);
1176        assert(regularCoding.B() > 1 && regularCoding.L() > 0);
1177        int X;
1178        if (regularCoding.S() != 0) {
1179            assert(regularCoding.min() <= -256);
1180            X = -1-XB;
1181        } else {
1182            int L = regularCoding.L();
1183            assert(regularCoding.max() >= L+255);
1184            X = XB+L;
1185        }
1186        assert(decodeEscapeValue(X, regularCoding) == XB)
1187            : (regularCoding+" XB="+XB+" X="+X);
1188        return X;
1189    }
1190
1191    static {
1192        boolean checkXB = false;
1193        assert(checkXB = true);
1194        if (checkXB) {
1195            for (int i = 0; i < basicCodings.length; i++) {
1196                Coding D = basicCodings[i];
1197                if (D == null)   continue;
1198                if (D.B() == 1)  continue;
1199                if (D.L() == 0)  continue;
1200                for (int XB = 0; XB <= 255; XB++) {
1201                    // The following exercises decodeEscapeValue also:
1202                    encodeEscapeValue(XB, D);
1203                }
1204            }
1205        }
1206    }
1207
1208    class MultiBand extends Band {
1209        MultiBand(String name, Coding regularCoding) {
1210            super(name, regularCoding);
1211        }
1212
1213        @Override
1214        public Band init() {
1215            super.init();
1216            // This is all just to keep the asserts happy:
1217            setCapacity(0);
1218            if (phase() == EXPECT_PHASE) {
1219                // Fast forward:
1220                setPhase(READ_PHASE);
1221                setPhase(DISBURSE_PHASE);
1222            }
1223            return this;
1224        }
1225
1226        Band[] bands     = new Band[10];
1227        int    bandCount = 0;
1228
1229        int size() {
1230            return bandCount;
1231        }
1232        Band get(int i) {
1233            assert(i < bandCount);
1234            return bands[i];
1235        }
1236        Band[] toArray() {
1237            return (Band[]) realloc(bands, bandCount);
1238        }
1239
1240        void add(Band b) {
1241            assert(bandCount == 0 || notePrevForAssert(b, bands[bandCount-1]));
1242            if (bandCount == bands.length) {
1243                bands = (Band[]) realloc(bands);
1244            }
1245            bands[bandCount++] = b;
1246        }
1247
1248        ByteBand newByteBand(String name) {
1249            ByteBand b = new ByteBand(name);
1250            b.init(); add(b);
1251            return b;
1252        }
1253        IntBand newIntBand(String name) {
1254            IntBand b = new IntBand(name, regularCoding);
1255            b.init(); add(b);
1256            return b;
1257        }
1258        IntBand newIntBand(String name, Coding regularCoding) {
1259            IntBand b = new IntBand(name, regularCoding);
1260            b.init(); add(b);
1261            return b;
1262        }
1263        MultiBand newMultiBand(String name, Coding regularCoding) {
1264            MultiBand b = new MultiBand(name, regularCoding);
1265            b.init(); add(b);
1266            return b;
1267        }
1268        CPRefBand newCPRefBand(String name, byte cpTag) {
1269            CPRefBand b = new CPRefBand(name, regularCoding, cpTag);
1270            b.init(); add(b);
1271            return b;
1272        }
1273        CPRefBand newCPRefBand(String name, Coding regularCoding,
1274                               byte cpTag) {
1275            CPRefBand b = new CPRefBand(name, regularCoding, cpTag);
1276            b.init(); add(b);
1277            return b;
1278        }
1279        CPRefBand newCPRefBand(String name, Coding regularCoding,
1280                               byte cpTag, boolean nullOK) {
1281            CPRefBand b = new CPRefBand(name, regularCoding, cpTag, nullOK);
1282            b.init(); add(b);
1283            return b;
1284        }
1285
1286        int bandCount() { return bandCount; }
1287
1288        private int cap = -1;
1289        @Override
1290        public int capacity() { return cap; }
1291        @Override
1292        public void setCapacity(int cap) { this.cap = cap; }
1293
1294        @Override
1295        public int length() { return 0; }
1296        @Override
1297        public int valuesRemainingForDebug() { return 0; }
1298
1299        @Override
1300        protected void chooseBandCodings() throws IOException {
1301            // coding decision pass
1302            for (int i = 0; i < bandCount; i++) {
1303                Band b = bands[i];
1304                b.chooseBandCodings();
1305            }
1306        }
1307
1308        @Override
1309        protected long computeOutputSize() {
1310            // coding decision pass
1311            long sum = 0;
1312            for (int i = 0; i < bandCount; i++) {
1313                Band b = bands[i];
1314                long bsize = b.outputSize();
1315                assert(bsize >= 0) : b;
1316                sum += bsize;
1317            }
1318            // do not cache
1319            return sum;
1320        }
1321
1322        @Override
1323        protected void writeDataTo(OutputStream out) throws IOException {
1324            long preCount = 0;
1325            if (outputCounter != null)  preCount = outputCounter.getCount();
1326            for (int i = 0; i < bandCount; i++) {
1327                Band b = bands[i];
1328                b.writeTo(out);
1329                if (outputCounter != null) {
1330                    long postCount = outputCounter.getCount();
1331                    long len = postCount - preCount;
1332                    preCount = postCount;
1333                    if ((verbose > 0 && len > 0) || verbose > 1) {
1334                        Utils.log.info("  ...wrote "+len+" bytes from "+b);
1335                    }
1336                }
1337            }
1338        }
1339
1340        @Override
1341        protected void readDataFrom(InputStream in) throws IOException {
1342            assert(false);  // not called?
1343            for (int i = 0; i < bandCount; i++) {
1344                Band b = bands[i];
1345                b.readFrom(in);
1346                if ((verbose > 0 && b.length() > 0) || verbose > 1) {
1347                    Utils.log.info("  ...read "+b);
1348                }
1349            }
1350        }
1351
1352        @Override
1353        public String toString() {
1354            return "{"+bandCount()+" bands: "+super.toString()+"}";
1355        }
1356    }
1357
1358    /**
1359     * An output stream which counts the number of bytes written.
1360     */
1361    private static
1362    class ByteCounter extends FilterOutputStream {
1363        // (should go public under the name CountingOutputStream?)
1364
1365        private long count;
1366
1367        public ByteCounter(OutputStream out) {
1368            super(out);
1369        }
1370
1371        public long getCount() { return count; }
1372        public void setCount(long c) { count = c; }
1373
1374        @Override
1375        public void write(int b) throws IOException {
1376            count++;
1377            if (out != null)  out.write(b);
1378        }
1379        @Override
1380        public void write(byte b[], int off, int len) throws IOException {
1381            count += len;
1382            if (out != null)  out.write(b, off, len);
1383        }
1384        @Override
1385        public String toString() {
1386            return String.valueOf(getCount());
1387        }
1388    }
1389    ByteCounter outputCounter;
1390
1391    void writeAllBandsTo(OutputStream out) throws IOException {
1392        // Wrap a byte-counter around the output stream.
1393        outputCounter = new ByteCounter(out);
1394        out = outputCounter;
1395        all_bands.writeTo(out);
1396        if (verbose > 0) {
1397            long nbytes = outputCounter.getCount();
1398            Utils.log.info("Wrote total of "+nbytes+" bytes.");
1399            assert(nbytes == archiveSize0+archiveSize1);
1400        }
1401        outputCounter = null;
1402    }
1403
1404    // random AO_XXX bits, decoded from the archive header
1405    protected int archiveOptions;
1406
1407    // archiveSize1 sizes most of the archive [archive_options..file_bits).
1408    protected long archiveSize0; // size through archive_size_lo
1409    protected long archiveSize1; // size reported in archive_header
1410    protected int  archiveNextCount; // reported in archive_header
1411
1412    static final int AH_LENGTH_0 = 3;     // archive_header_0 = {minver, majver, options}
1413    static final int AH_LENGTH_MIN = 15;  // observed in spec {header_0[3], cp_counts[8], class_counts[4]}
1414    // Length contributions from optional archive size fields:
1415    static final int AH_LENGTH_S = 2; // archive_header_S = optional {size_hi, size_lo}
1416    static final int AH_ARCHIVE_SIZE_HI = 0; // offset in archive_header_S
1417    static final int AH_ARCHIVE_SIZE_LO = 1; // offset in archive_header_S
1418    // Length contributions from optional header fields:
1419    static final int AH_FILE_HEADER_LEN = 5; // file_counts = {{size_hi, size_lo}, next, modtime, files}
1420    static final int AH_SPECIAL_FORMAT_LEN = 2; // special_counts = {layouts, band_headers}
1421    static final int AH_CP_NUMBER_LEN = 4;  // cp_number_counts = {int, float, long, double}
1422    static final int AH_CP_EXTRA_LEN = 4;  // cp_attr_counts = {MH, MT, InDy, BSM}
1423
1424    // Common structure of attribute band groups:
1425    static final int AB_FLAGS_HI = 0;
1426    static final int AB_FLAGS_LO = 1;
1427    static final int AB_ATTR_COUNT = 2;
1428    static final int AB_ATTR_INDEXES = 3;
1429    static final int AB_ATTR_CALLS = 4;
1430
1431    static IntBand getAttrBand(MultiBand xxx_attr_bands, int which) {
1432        IntBand b = (IntBand) xxx_attr_bands.get(which);
1433        switch (which) {
1434        case AB_FLAGS_HI:
1435            assert(b.name().endsWith("_flags_hi")); break;
1436        case AB_FLAGS_LO:
1437            assert(b.name().endsWith("_flags_lo")); break;
1438        case AB_ATTR_COUNT:
1439            assert(b.name().endsWith("_attr_count")); break;
1440        case AB_ATTR_INDEXES:
1441            assert(b.name().endsWith("_attr_indexes")); break;
1442        case AB_ATTR_CALLS:
1443            assert(b.name().endsWith("_attr_calls")); break;
1444        default:
1445            assert(false); break;
1446        }
1447        return b;
1448    }
1449
1450    private static final boolean NULL_IS_OK = true;
1451
1452    MultiBand all_bands = (MultiBand) new MultiBand("(package)", UNSIGNED5).init();
1453
1454    // file header (various random bytes)
1455    ByteBand archive_magic = all_bands.newByteBand("archive_magic");
1456    IntBand  archive_header_0 = all_bands.newIntBand("archive_header_0", UNSIGNED5);
1457    IntBand  archive_header_S = all_bands.newIntBand("archive_header_S", UNSIGNED5);
1458    IntBand  archive_header_1 = all_bands.newIntBand("archive_header_1", UNSIGNED5);
1459    ByteBand band_headers = all_bands.newByteBand("band_headers");
1460
1461    // constant pool contents
1462    MultiBand cp_bands = all_bands.newMultiBand("(constant_pool)", DELTA5);
1463    IntBand   cp_Utf8_prefix = cp_bands.newIntBand("cp_Utf8_prefix");
1464    IntBand   cp_Utf8_suffix = cp_bands.newIntBand("cp_Utf8_suffix", UNSIGNED5);
1465    IntBand   cp_Utf8_chars = cp_bands.newIntBand("cp_Utf8_chars", CHAR3);
1466    IntBand   cp_Utf8_big_suffix = cp_bands.newIntBand("cp_Utf8_big_suffix");
1467    MultiBand cp_Utf8_big_chars = cp_bands.newMultiBand("(cp_Utf8_big_chars)", DELTA5);
1468    IntBand   cp_Int = cp_bands.newIntBand("cp_Int", UDELTA5);
1469    IntBand   cp_Float = cp_bands.newIntBand("cp_Float", UDELTA5);
1470    IntBand   cp_Long_hi = cp_bands.newIntBand("cp_Long_hi", UDELTA5);
1471    IntBand   cp_Long_lo = cp_bands.newIntBand("cp_Long_lo");
1472    IntBand   cp_Double_hi = cp_bands.newIntBand("cp_Double_hi", UDELTA5);
1473    IntBand   cp_Double_lo = cp_bands.newIntBand("cp_Double_lo");
1474    CPRefBand cp_String = cp_bands.newCPRefBand("cp_String", UDELTA5, CONSTANT_Utf8);
1475    CPRefBand cp_Class = cp_bands.newCPRefBand("cp_Class", UDELTA5, CONSTANT_Utf8);
1476    CPRefBand cp_Signature_form = cp_bands.newCPRefBand("cp_Signature_form", CONSTANT_Utf8);
1477    CPRefBand cp_Signature_classes = cp_bands.newCPRefBand("cp_Signature_classes", UDELTA5, CONSTANT_Class);
1478    CPRefBand cp_Descr_name = cp_bands.newCPRefBand("cp_Descr_name", CONSTANT_Utf8);
1479    CPRefBand cp_Descr_type = cp_bands.newCPRefBand("cp_Descr_type", UDELTA5, CONSTANT_Signature);
1480    CPRefBand cp_Field_class = cp_bands.newCPRefBand("cp_Field_class", CONSTANT_Class);
1481    CPRefBand cp_Field_desc = cp_bands.newCPRefBand("cp_Field_desc", UDELTA5, CONSTANT_NameandType);
1482    CPRefBand cp_Method_class = cp_bands.newCPRefBand("cp_Method_class", CONSTANT_Class);
1483    CPRefBand cp_Method_desc = cp_bands.newCPRefBand("cp_Method_desc", UDELTA5, CONSTANT_NameandType);
1484    CPRefBand cp_Imethod_class = cp_bands.newCPRefBand("cp_Imethod_class", CONSTANT_Class);
1485    CPRefBand cp_Imethod_desc = cp_bands.newCPRefBand("cp_Imethod_desc", UDELTA5, CONSTANT_NameandType);
1486    IntBand   cp_MethodHandle_refkind = cp_bands.newIntBand("cp_MethodHandle_refkind", DELTA5);
1487    CPRefBand cp_MethodHandle_member = cp_bands.newCPRefBand("cp_MethodHandle_member", UDELTA5, CONSTANT_AnyMember);
1488    CPRefBand cp_MethodType = cp_bands.newCPRefBand("cp_MethodType", UDELTA5, CONSTANT_Signature);
1489    CPRefBand cp_BootstrapMethod_ref = cp_bands.newCPRefBand("cp_BootstrapMethod_ref", DELTA5, CONSTANT_MethodHandle);
1490    IntBand   cp_BootstrapMethod_arg_count = cp_bands.newIntBand("cp_BootstrapMethod_arg_count", UDELTA5);
1491    CPRefBand cp_BootstrapMethod_arg = cp_bands.newCPRefBand("cp_BootstrapMethod_arg", DELTA5, CONSTANT_LoadableValue);
1492    CPRefBand cp_InvokeDynamic_spec = cp_bands.newCPRefBand("cp_InvokeDynamic_spec", DELTA5, CONSTANT_BootstrapMethod);
1493    CPRefBand cp_InvokeDynamic_desc = cp_bands.newCPRefBand("cp_InvokeDynamic_desc", UDELTA5, CONSTANT_NameandType);
1494
1495    // bands for carrying attribute definitions:
1496    MultiBand attr_definition_bands = all_bands.newMultiBand("(attr_definition_bands)", UNSIGNED5);
1497    ByteBand attr_definition_headers = attr_definition_bands.newByteBand("attr_definition_headers");
1498    CPRefBand attr_definition_name = attr_definition_bands.newCPRefBand("attr_definition_name", CONSTANT_Utf8);
1499    CPRefBand attr_definition_layout = attr_definition_bands.newCPRefBand("attr_definition_layout", CONSTANT_Utf8);
1500
1501    // bands for hardwired InnerClasses attribute (shared across the package)
1502    MultiBand ic_bands = all_bands.newMultiBand("(ic_bands)", DELTA5);
1503    CPRefBand ic_this_class = ic_bands.newCPRefBand("ic_this_class", UDELTA5, CONSTANT_Class);
1504    IntBand ic_flags = ic_bands.newIntBand("ic_flags", UNSIGNED5);
1505    // These bands contain data only where flags sets ACC_IC_LONG_FORM:
1506    CPRefBand ic_outer_class = ic_bands.newCPRefBand("ic_outer_class", DELTA5, CONSTANT_Class, NULL_IS_OK);
1507    CPRefBand ic_name = ic_bands.newCPRefBand("ic_name", DELTA5, CONSTANT_Utf8, NULL_IS_OK);
1508
1509    // bands for carrying class schema information:
1510    MultiBand class_bands = all_bands.newMultiBand("(class_bands)", DELTA5);
1511    CPRefBand class_this = class_bands.newCPRefBand("class_this", CONSTANT_Class);
1512    CPRefBand class_super = class_bands.newCPRefBand("class_super", CONSTANT_Class);
1513    IntBand   class_interface_count = class_bands.newIntBand("class_interface_count");
1514    CPRefBand class_interface = class_bands.newCPRefBand("class_interface", CONSTANT_Class);
1515
1516    // bands for class members
1517    IntBand   class_field_count = class_bands.newIntBand("class_field_count");
1518    IntBand   class_method_count = class_bands.newIntBand("class_method_count");
1519
1520    CPRefBand field_descr = class_bands.newCPRefBand("field_descr", CONSTANT_NameandType);
1521    MultiBand field_attr_bands = class_bands.newMultiBand("(field_attr_bands)", UNSIGNED5);
1522    IntBand field_flags_hi = field_attr_bands.newIntBand("field_flags_hi");
1523    IntBand field_flags_lo = field_attr_bands.newIntBand("field_flags_lo");
1524    IntBand field_attr_count = field_attr_bands.newIntBand("field_attr_count");
1525    IntBand field_attr_indexes = field_attr_bands.newIntBand("field_attr_indexes");
1526    IntBand field_attr_calls = field_attr_bands.newIntBand("field_attr_calls");
1527
1528    // bands for predefined field attributes
1529    CPRefBand field_ConstantValue_KQ = field_attr_bands.newCPRefBand("field_ConstantValue_KQ", CONSTANT_FieldSpecific);
1530    CPRefBand field_Signature_RS = field_attr_bands.newCPRefBand("field_Signature_RS", CONSTANT_Signature);
1531    MultiBand field_metadata_bands = field_attr_bands.newMultiBand("(field_metadata_bands)", UNSIGNED5);
1532    MultiBand field_type_metadata_bands = field_attr_bands.newMultiBand("(field_type_metadata_bands)", UNSIGNED5);
1533
1534    CPRefBand method_descr = class_bands.newCPRefBand("method_descr", MDELTA5, CONSTANT_NameandType);
1535    MultiBand method_attr_bands = class_bands.newMultiBand("(method_attr_bands)", UNSIGNED5);
1536    IntBand  method_flags_hi = method_attr_bands.newIntBand("method_flags_hi");
1537    IntBand  method_flags_lo = method_attr_bands.newIntBand("method_flags_lo");
1538    IntBand  method_attr_count = method_attr_bands.newIntBand("method_attr_count");
1539    IntBand  method_attr_indexes = method_attr_bands.newIntBand("method_attr_indexes");
1540    IntBand  method_attr_calls = method_attr_bands.newIntBand("method_attr_calls");
1541    // band for predefined method attributes
1542    IntBand  method_Exceptions_N = method_attr_bands.newIntBand("method_Exceptions_N");
1543    CPRefBand method_Exceptions_RC = method_attr_bands.newCPRefBand("method_Exceptions_RC", CONSTANT_Class);
1544    CPRefBand method_Signature_RS = method_attr_bands.newCPRefBand("method_Signature_RS", CONSTANT_Signature);
1545    MultiBand method_metadata_bands = method_attr_bands.newMultiBand("(method_metadata_bands)", UNSIGNED5);
1546    // band for predefine method parameters
1547    IntBand  method_MethodParameters_NB = method_attr_bands.newIntBand("method_MethodParameters_NB", BYTE1);
1548    CPRefBand method_MethodParameters_name_RUN = method_attr_bands.newCPRefBand("method_MethodParameters_name_RUN", UNSIGNED5, CONSTANT_Utf8, NULL_IS_OK);
1549    IntBand   method_MethodParameters_flag_FH = method_attr_bands.newIntBand("method_MethodParameters_flag_FH");
1550    MultiBand method_type_metadata_bands = method_attr_bands.newMultiBand("(method_type_metadata_bands)", UNSIGNED5);
1551
1552    MultiBand class_attr_bands = class_bands.newMultiBand("(class_attr_bands)", UNSIGNED5);
1553    IntBand class_flags_hi = class_attr_bands.newIntBand("class_flags_hi");
1554    IntBand class_flags_lo = class_attr_bands.newIntBand("class_flags_lo");
1555    IntBand class_attr_count = class_attr_bands.newIntBand("class_attr_count");
1556    IntBand class_attr_indexes = class_attr_bands.newIntBand("class_attr_indexes");
1557    IntBand class_attr_calls = class_attr_bands.newIntBand("class_attr_calls");
1558    // band for predefined SourceFile and other class attributes
1559    CPRefBand class_SourceFile_RUN = class_attr_bands.newCPRefBand("class_SourceFile_RUN", UNSIGNED5, CONSTANT_Utf8, NULL_IS_OK);
1560    CPRefBand class_EnclosingMethod_RC = class_attr_bands.newCPRefBand("class_EnclosingMethod_RC", CONSTANT_Class);
1561    CPRefBand class_EnclosingMethod_RDN = class_attr_bands.newCPRefBand("class_EnclosingMethod_RDN", UNSIGNED5, CONSTANT_NameandType, NULL_IS_OK);
1562    CPRefBand class_Signature_RS = class_attr_bands.newCPRefBand("class_Signature_RS", CONSTANT_Signature);
1563    MultiBand class_metadata_bands = class_attr_bands.newMultiBand("(class_metadata_bands)", UNSIGNED5);
1564    IntBand   class_InnerClasses_N = class_attr_bands.newIntBand("class_InnerClasses_N");
1565    CPRefBand class_InnerClasses_RC = class_attr_bands.newCPRefBand("class_InnerClasses_RC", CONSTANT_Class);
1566    IntBand   class_InnerClasses_F = class_attr_bands.newIntBand("class_InnerClasses_F");
1567    CPRefBand class_InnerClasses_outer_RCN = class_attr_bands.newCPRefBand("class_InnerClasses_outer_RCN", UNSIGNED5, CONSTANT_Class, NULL_IS_OK);
1568    CPRefBand class_InnerClasses_name_RUN = class_attr_bands.newCPRefBand("class_InnerClasses_name_RUN", UNSIGNED5, CONSTANT_Utf8, NULL_IS_OK);
1569    IntBand class_ClassFile_version_minor_H = class_attr_bands.newIntBand("class_ClassFile_version_minor_H");
1570    IntBand class_ClassFile_version_major_H = class_attr_bands.newIntBand("class_ClassFile_version_major_H");
1571    MultiBand class_type_metadata_bands = class_attr_bands.newMultiBand("(class_type_metadata_bands)", UNSIGNED5);
1572
1573    MultiBand code_bands = class_bands.newMultiBand("(code_bands)", UNSIGNED5);
1574    ByteBand  code_headers = code_bands.newByteBand("code_headers"); //BYTE1
1575    IntBand   code_max_stack = code_bands.newIntBand("code_max_stack", UNSIGNED5);
1576    IntBand   code_max_na_locals = code_bands.newIntBand("code_max_na_locals", UNSIGNED5);
1577    IntBand   code_handler_count = code_bands.newIntBand("code_handler_count", UNSIGNED5);
1578    IntBand   code_handler_start_P = code_bands.newIntBand("code_handler_start_P", BCI5);
1579    IntBand   code_handler_end_PO = code_bands.newIntBand("code_handler_end_PO", BRANCH5);
1580    IntBand   code_handler_catch_PO = code_bands.newIntBand("code_handler_catch_PO", BRANCH5);
1581    CPRefBand code_handler_class_RCN = code_bands.newCPRefBand("code_handler_class_RCN", UNSIGNED5, CONSTANT_Class, NULL_IS_OK);
1582
1583    MultiBand code_attr_bands = class_bands.newMultiBand("(code_attr_bands)", UNSIGNED5);
1584    IntBand   code_flags_hi = code_attr_bands.newIntBand("code_flags_hi");
1585    IntBand   code_flags_lo = code_attr_bands.newIntBand("code_flags_lo");
1586    IntBand   code_attr_count = code_attr_bands.newIntBand("code_attr_count");
1587    IntBand   code_attr_indexes = code_attr_bands.newIntBand("code_attr_indexes");
1588    IntBand   code_attr_calls = code_attr_bands.newIntBand("code_attr_calls");
1589
1590    MultiBand stackmap_bands = code_attr_bands.newMultiBand("(StackMapTable_bands)", UNSIGNED5);
1591    IntBand   code_StackMapTable_N = stackmap_bands.newIntBand("code_StackMapTable_N");
1592    IntBand   code_StackMapTable_frame_T = stackmap_bands.newIntBand("code_StackMapTable_frame_T",BYTE1);
1593    IntBand   code_StackMapTable_local_N = stackmap_bands.newIntBand("code_StackMapTable_local_N");
1594    IntBand   code_StackMapTable_stack_N = stackmap_bands.newIntBand("code_StackMapTable_stack_N");
1595    IntBand   code_StackMapTable_offset = stackmap_bands.newIntBand("code_StackMapTable_offset", UNSIGNED5);
1596    IntBand   code_StackMapTable_T = stackmap_bands.newIntBand("code_StackMapTable_T", BYTE1);
1597    CPRefBand code_StackMapTable_RC = stackmap_bands.newCPRefBand("code_StackMapTable_RC", CONSTANT_Class);
1598    IntBand   code_StackMapTable_P = stackmap_bands.newIntBand("code_StackMapTable_P", BCI5);
1599
1600    // bands for predefined LineNumberTable attribute
1601    IntBand   code_LineNumberTable_N = code_attr_bands.newIntBand("code_LineNumberTable_N");
1602    IntBand   code_LineNumberTable_bci_P = code_attr_bands.newIntBand("code_LineNumberTable_bci_P", BCI5);
1603    IntBand   code_LineNumberTable_line = code_attr_bands.newIntBand("code_LineNumberTable_line");
1604
1605    // bands for predefined LocalVariable{Type}Table attributes
1606    IntBand   code_LocalVariableTable_N = code_attr_bands.newIntBand("code_LocalVariableTable_N");
1607    IntBand   code_LocalVariableTable_bci_P = code_attr_bands.newIntBand("code_LocalVariableTable_bci_P", BCI5);
1608    IntBand   code_LocalVariableTable_span_O = code_attr_bands.newIntBand("code_LocalVariableTable_span_O", BRANCH5);
1609    CPRefBand code_LocalVariableTable_name_RU = code_attr_bands.newCPRefBand("code_LocalVariableTable_name_RU", CONSTANT_Utf8);
1610    CPRefBand code_LocalVariableTable_type_RS = code_attr_bands.newCPRefBand("code_LocalVariableTable_type_RS", CONSTANT_Signature);
1611    IntBand   code_LocalVariableTable_slot = code_attr_bands.newIntBand("code_LocalVariableTable_slot");
1612    IntBand   code_LocalVariableTypeTable_N = code_attr_bands.newIntBand("code_LocalVariableTypeTable_N");
1613    IntBand   code_LocalVariableTypeTable_bci_P = code_attr_bands.newIntBand("code_LocalVariableTypeTable_bci_P", BCI5);
1614    IntBand   code_LocalVariableTypeTable_span_O = code_attr_bands.newIntBand("code_LocalVariableTypeTable_span_O", BRANCH5);
1615    CPRefBand code_LocalVariableTypeTable_name_RU = code_attr_bands.newCPRefBand("code_LocalVariableTypeTable_name_RU", CONSTANT_Utf8);
1616    CPRefBand code_LocalVariableTypeTable_type_RS = code_attr_bands.newCPRefBand("code_LocalVariableTypeTable_type_RS", CONSTANT_Signature);
1617    IntBand   code_LocalVariableTypeTable_slot = code_attr_bands.newIntBand("code_LocalVariableTypeTable_slot");
1618    MultiBand code_type_metadata_bands = code_attr_bands.newMultiBand("(code_type_metadata_bands)", UNSIGNED5);
1619
1620    // bands for bytecodes
1621    MultiBand bc_bands = all_bands.newMultiBand("(byte_codes)", UNSIGNED5);
1622    ByteBand  bc_codes = bc_bands.newByteBand("bc_codes"); //BYTE1
1623    // remaining bands provide typed opcode fields required by the bc_codes
1624
1625    IntBand   bc_case_count = bc_bands.newIntBand("bc_case_count");  // *switch
1626    IntBand   bc_case_value = bc_bands.newIntBand("bc_case_value", DELTA5);  // *switch
1627    ByteBand  bc_byte = bc_bands.newByteBand("bc_byte"); //BYTE1   // bipush, iinc, *newarray
1628    IntBand   bc_short = bc_bands.newIntBand("bc_short", DELTA5);  // sipush, wide iinc
1629    IntBand   bc_local = bc_bands.newIntBand("bc_local");    // *load, *store, iinc, ret
1630    IntBand   bc_label = bc_bands.newIntBand("bc_label", BRANCH5);    // if*, goto*, jsr*, *switch
1631
1632    // Most CP refs exhibit some correlation, and benefit from delta coding.
1633    // The notable exceptions are class and method references.
1634
1635    // ldc* operands:
1636    CPRefBand bc_intref = bc_bands.newCPRefBand("bc_intref", DELTA5, CONSTANT_Integer);
1637    CPRefBand bc_floatref = bc_bands.newCPRefBand("bc_floatref", DELTA5, CONSTANT_Float);
1638    CPRefBand bc_longref = bc_bands.newCPRefBand("bc_longref", DELTA5, CONSTANT_Long);
1639    CPRefBand bc_doubleref = bc_bands.newCPRefBand("bc_doubleref", DELTA5, CONSTANT_Double);
1640    CPRefBand bc_stringref = bc_bands.newCPRefBand("bc_stringref", DELTA5, CONSTANT_String);
1641    CPRefBand bc_loadablevalueref = bc_bands.newCPRefBand("bc_loadablevalueref", DELTA5, CONSTANT_LoadableValue);
1642
1643    // nulls produced by bc_classref are taken to mean the current class
1644    CPRefBand bc_classref = bc_bands.newCPRefBand("bc_classref", UNSIGNED5, CONSTANT_Class, NULL_IS_OK);   // new, *anew*, c*cast, i*of, ldc
1645    CPRefBand bc_fieldref = bc_bands.newCPRefBand("bc_fieldref", DELTA5, CONSTANT_Fieldref);   // get*, put*
1646    CPRefBand bc_methodref = bc_bands.newCPRefBand("bc_methodref", CONSTANT_Methodref); // invoke[vs]*
1647    CPRefBand bc_imethodref = bc_bands.newCPRefBand("bc_imethodref", DELTA5, CONSTANT_InterfaceMethodref); // invokeinterface
1648    CPRefBand bc_indyref = bc_bands.newCPRefBand("bc_indyref", DELTA5, CONSTANT_InvokeDynamic); // invokedynamic
1649
1650    // _self_linker_op family
1651    CPRefBand bc_thisfield = bc_bands.newCPRefBand("bc_thisfield", CONSTANT_None);     // any field within cur. class
1652    CPRefBand bc_superfield = bc_bands.newCPRefBand("bc_superfield", CONSTANT_None);   // any field within superclass
1653    CPRefBand bc_thismethod = bc_bands.newCPRefBand("bc_thismethod", CONSTANT_None);   // any method within cur. class
1654    CPRefBand bc_supermethod = bc_bands.newCPRefBand("bc_supermethod", CONSTANT_None); // any method within superclass
1655    // bc_invokeinit family:
1656    IntBand   bc_initref = bc_bands.newIntBand("bc_initref");
1657    // escapes
1658    CPRefBand bc_escref = bc_bands.newCPRefBand("bc_escref", CONSTANT_All);
1659    IntBand   bc_escrefsize = bc_bands.newIntBand("bc_escrefsize");
1660    IntBand   bc_escsize = bc_bands.newIntBand("bc_escsize");
1661    ByteBand  bc_escbyte = bc_bands.newByteBand("bc_escbyte");
1662
1663    // bands for carrying resource files and file attributes:
1664    MultiBand file_bands = all_bands.newMultiBand("(file_bands)", UNSIGNED5);
1665    CPRefBand file_name = file_bands.newCPRefBand("file_name", CONSTANT_Utf8);
1666    IntBand file_size_hi = file_bands.newIntBand("file_size_hi");
1667    IntBand file_size_lo = file_bands.newIntBand("file_size_lo");
1668    IntBand file_modtime = file_bands.newIntBand("file_modtime", DELTA5);
1669    IntBand file_options = file_bands.newIntBand("file_options");
1670    ByteBand file_bits = file_bands.newByteBand("file_bits");
1671
1672    // End of band definitions!
1673
1674    /** Given CP indexes, distribute tag-specific indexes to bands. */
1675    protected void setBandIndexes() {
1676        // Handle prior calls to setBandIndex:
1677        for (Object[] need : needPredefIndex) {
1678            CPRefBand b     = (CPRefBand) need[0];
1679            Byte      which = (Byte)      need[1];
1680            b.setIndex(getCPIndex(which.byteValue()));
1681        }
1682        needPredefIndex = null;  // no more predefs
1683
1684        if (verbose > 3) {
1685            printCDecl(all_bands);
1686        }
1687    }
1688
1689    protected void setBandIndex(CPRefBand b, byte which) {
1690        Object[] need = { b, Byte.valueOf(which) };
1691        if (which == CONSTANT_FieldSpecific) {
1692            // I.e., attribute layouts KQ (no null) or KQN (null ok).
1693            allKQBands.add(b);
1694        } else if (needPredefIndex != null) {
1695            needPredefIndex.add(need);
1696        } else {
1697            // Not in predefinition mode; getCPIndex now works.
1698            b.setIndex(getCPIndex(which));
1699        }
1700    }
1701
1702    protected void setConstantValueIndex(Field f) {
1703        Index ix = null;
1704        if (f != null) {
1705            byte tag = f.getLiteralTag();
1706            ix = getCPIndex(tag);
1707            if (verbose > 2)
1708                Utils.log.fine("setConstantValueIndex "+f+" "+ConstantPool.tagName(tag)+" => "+ix);
1709            assert(ix != null);
1710        }
1711        // Typically, allKQBands is the singleton of field_ConstantValue_KQ.
1712        for (CPRefBand xxx_KQ : allKQBands) {
1713            xxx_KQ.setIndex(ix);
1714        }
1715    }
1716
1717    // Table of bands which contain metadata.
1718    protected MultiBand[] metadataBands = new MultiBand[ATTR_CONTEXT_LIMIT];
1719    {
1720        metadataBands[ATTR_CONTEXT_CLASS] = class_metadata_bands;
1721        metadataBands[ATTR_CONTEXT_FIELD] = field_metadata_bands;
1722        metadataBands[ATTR_CONTEXT_METHOD] = method_metadata_bands;
1723    }
1724    // Table of bands which contains type_metadata (TypeAnnotations)
1725    protected MultiBand[] typeMetadataBands = new MultiBand[ATTR_CONTEXT_LIMIT];
1726    {
1727        typeMetadataBands[ATTR_CONTEXT_CLASS] = class_type_metadata_bands;
1728        typeMetadataBands[ATTR_CONTEXT_FIELD] = field_type_metadata_bands;
1729        typeMetadataBands[ATTR_CONTEXT_METHOD] = method_type_metadata_bands;
1730        typeMetadataBands[ATTR_CONTEXT_CODE]   = code_type_metadata_bands;
1731    }
1732
1733    // Attribute layouts.
1734    public static final int ADH_CONTEXT_MASK   = 0x3;  // (ad_hdr & ADH_CONTEXT_MASK)
1735    public static final int ADH_BIT_SHIFT      = 0x2;  // (ad_hdr >> ADH_BIT_SHIFT)
1736    public static final int ADH_BIT_IS_LSB     = 1;
1737    public static final int ATTR_INDEX_OVERFLOW  = -1;
1738
1739    public int[] attrIndexLimit = new int[ATTR_CONTEXT_LIMIT];
1740    // Each index limit is either 32 or 63, depending on AO_HAVE_XXX_FLAGS_HI.
1741
1742    // Which flag bits are taken over by attributes?
1743    protected long[] attrFlagMask = new long[ATTR_CONTEXT_LIMIT];
1744    // Which flag bits have been taken over explicitly?
1745    protected long[] attrDefSeen = new long[ATTR_CONTEXT_LIMIT];
1746
1747    // What pseudo-attribute bits are there to watch for?
1748    protected int[] attrOverflowMask = new int[ATTR_CONTEXT_LIMIT];
1749    protected int attrClassFileVersionMask;
1750
1751    // Mapping from Attribute.Layout to Band[] (layout element bands).
1752    protected Map<Attribute.Layout, Band[]> attrBandTable = new HashMap<>();
1753
1754    // Well-known attributes:
1755    protected final Attribute.Layout attrCodeEmpty;
1756    protected final Attribute.Layout attrInnerClassesEmpty;
1757    protected final Attribute.Layout attrClassFileVersion;
1758    protected final Attribute.Layout attrConstantValue;
1759
1760    // Mapping from Attribute.Layout to Integer (inverse of attrDefs)
1761    Map<Attribute.Layout, Integer> attrIndexTable = new HashMap<>();
1762
1763    // Mapping from attribute index (<32 are flag bits) to attributes.
1764    protected List<List<Attribute.Layout>> attrDefs =
1765            new FixedList<>(ATTR_CONTEXT_LIMIT);
1766    {
1767        for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
1768            assert(attrIndexLimit[i] == 0);
1769            attrIndexLimit[i] = 32;  // just for the sake of predefs.
1770            attrDefs.set(i, new ArrayList<>(Collections.nCopies(
1771                    attrIndexLimit[i], (Attribute.Layout)null)));
1772
1773        }
1774
1775        // Add predefined attribute definitions:
1776        attrInnerClassesEmpty =
1777        predefineAttribute(CLASS_ATTR_InnerClasses, ATTR_CONTEXT_CLASS, null,
1778                           "InnerClasses", "");
1779        assert(attrInnerClassesEmpty == Package.attrInnerClassesEmpty);
1780        predefineAttribute(CLASS_ATTR_SourceFile, ATTR_CONTEXT_CLASS,
1781                           new Band[] { class_SourceFile_RUN },
1782                           "SourceFile", "RUNH");
1783        predefineAttribute(CLASS_ATTR_EnclosingMethod, ATTR_CONTEXT_CLASS,
1784                           new Band[] {
1785                               class_EnclosingMethod_RC,
1786                               class_EnclosingMethod_RDN
1787                           },
1788                           "EnclosingMethod", "RCHRDNH");
1789        attrClassFileVersion =
1790        predefineAttribute(CLASS_ATTR_ClassFile_version, ATTR_CONTEXT_CLASS,
1791                           new Band[] {
1792                               class_ClassFile_version_minor_H,
1793                               class_ClassFile_version_major_H
1794                           },
1795                           ".ClassFile.version", "HH");
1796        predefineAttribute(X_ATTR_Signature, ATTR_CONTEXT_CLASS,
1797                           new Band[] { class_Signature_RS },
1798                           "Signature", "RSH");
1799        predefineAttribute(X_ATTR_Deprecated, ATTR_CONTEXT_CLASS, null,
1800                           "Deprecated", "");
1801        //predefineAttribute(X_ATTR_Synthetic, ATTR_CONTEXT_CLASS, null,
1802        //                 "Synthetic", "");
1803        predefineAttribute(X_ATTR_OVERFLOW, ATTR_CONTEXT_CLASS, null,
1804                           ".Overflow", "");
1805        attrConstantValue =
1806        predefineAttribute(FIELD_ATTR_ConstantValue, ATTR_CONTEXT_FIELD,
1807                           new Band[] { field_ConstantValue_KQ },
1808                           "ConstantValue", "KQH");
1809        predefineAttribute(X_ATTR_Signature, ATTR_CONTEXT_FIELD,
1810                           new Band[] { field_Signature_RS },
1811                           "Signature", "RSH");
1812        predefineAttribute(X_ATTR_Deprecated, ATTR_CONTEXT_FIELD, null,
1813                           "Deprecated", "");
1814        //predefineAttribute(X_ATTR_Synthetic, ATTR_CONTEXT_FIELD, null,
1815        //                 "Synthetic", "");
1816        predefineAttribute(X_ATTR_OVERFLOW, ATTR_CONTEXT_FIELD, null,
1817                           ".Overflow", "");
1818        attrCodeEmpty =
1819        predefineAttribute(METHOD_ATTR_Code, ATTR_CONTEXT_METHOD, null,
1820                           "Code", "");
1821        predefineAttribute(METHOD_ATTR_Exceptions, ATTR_CONTEXT_METHOD,
1822                           new Band[] {
1823                               method_Exceptions_N,
1824                               method_Exceptions_RC
1825                           },
1826                           "Exceptions", "NH[RCH]");
1827        predefineAttribute(METHOD_ATTR_MethodParameters, ATTR_CONTEXT_METHOD,
1828                           new Band[]{
1829                                method_MethodParameters_NB,
1830                                method_MethodParameters_name_RUN,
1831                                method_MethodParameters_flag_FH
1832                           },
1833                           "MethodParameters", "NB[RUNHFH]");
1834        assert(attrCodeEmpty == Package.attrCodeEmpty);
1835        predefineAttribute(X_ATTR_Signature, ATTR_CONTEXT_METHOD,
1836                           new Band[] { method_Signature_RS },
1837                           "Signature", "RSH");
1838        predefineAttribute(X_ATTR_Deprecated, ATTR_CONTEXT_METHOD, null,
1839                           "Deprecated", "");
1840        //predefineAttribute(X_ATTR_Synthetic, ATTR_CONTEXT_METHOD, null,
1841        //                 "Synthetic", "");
1842        predefineAttribute(X_ATTR_OVERFLOW, ATTR_CONTEXT_METHOD, null,
1843                           ".Overflow", "");
1844
1845        for (int ctype = 0; ctype < ATTR_CONTEXT_LIMIT; ctype++) {
1846            MultiBand xxx_metadata_bands = metadataBands[ctype];
1847            if (ctype != ATTR_CONTEXT_CODE) {
1848                // These arguments cause the bands to be built
1849                // automatically for this complicated layout:
1850                predefineAttribute(X_ATTR_RuntimeVisibleAnnotations,
1851                                   ATTR_CONTEXT_NAME[ctype]+"_RVA_",
1852                                   xxx_metadata_bands,
1853                                   Attribute.lookup(null, ctype,
1854                                                    "RuntimeVisibleAnnotations"));
1855                predefineAttribute(X_ATTR_RuntimeInvisibleAnnotations,
1856                                   ATTR_CONTEXT_NAME[ctype]+"_RIA_",
1857                                   xxx_metadata_bands,
1858                                   Attribute.lookup(null, ctype,
1859                                                    "RuntimeInvisibleAnnotations"));
1860
1861                if (ctype == ATTR_CONTEXT_METHOD) {
1862                    predefineAttribute(METHOD_ATTR_RuntimeVisibleParameterAnnotations,
1863                                       "method_RVPA_", xxx_metadata_bands,
1864                                       Attribute.lookup(null, ctype,
1865                                       "RuntimeVisibleParameterAnnotations"));
1866                    predefineAttribute(METHOD_ATTR_RuntimeInvisibleParameterAnnotations,
1867                                       "method_RIPA_", xxx_metadata_bands,
1868                                       Attribute.lookup(null, ctype,
1869                                       "RuntimeInvisibleParameterAnnotations"));
1870                    predefineAttribute(METHOD_ATTR_AnnotationDefault,
1871                                       "method_AD_", xxx_metadata_bands,
1872                                       Attribute.lookup(null, ctype,
1873                                       "AnnotationDefault"));
1874                }
1875            }
1876            // All contexts have these
1877            MultiBand xxx_type_metadata_bands = typeMetadataBands[ctype];
1878            predefineAttribute(X_ATTR_RuntimeVisibleTypeAnnotations,
1879                    ATTR_CONTEXT_NAME[ctype] + "_RVTA_",
1880                    xxx_type_metadata_bands,
1881                    Attribute.lookup(null, ctype,
1882                    "RuntimeVisibleTypeAnnotations"));
1883            predefineAttribute(X_ATTR_RuntimeInvisibleTypeAnnotations,
1884                    ATTR_CONTEXT_NAME[ctype] + "_RITA_",
1885                    xxx_type_metadata_bands,
1886                    Attribute.lookup(null, ctype,
1887                    "RuntimeInvisibleTypeAnnotations"));
1888        }
1889
1890
1891        Attribute.Layout stackMapDef = Attribute.lookup(null, ATTR_CONTEXT_CODE, "StackMapTable").layout();
1892        predefineAttribute(CODE_ATTR_StackMapTable, ATTR_CONTEXT_CODE,
1893                           stackmap_bands.toArray(),
1894                           stackMapDef.name(), stackMapDef.layout());
1895
1896        predefineAttribute(CODE_ATTR_LineNumberTable, ATTR_CONTEXT_CODE,
1897                           new Band[] {
1898                               code_LineNumberTable_N,
1899                               code_LineNumberTable_bci_P,
1900                               code_LineNumberTable_line
1901                           },
1902                           "LineNumberTable", "NH[PHH]");
1903        predefineAttribute(CODE_ATTR_LocalVariableTable, ATTR_CONTEXT_CODE,
1904                           new Band[] {
1905                               code_LocalVariableTable_N,
1906                               code_LocalVariableTable_bci_P,
1907                               code_LocalVariableTable_span_O,
1908                               code_LocalVariableTable_name_RU,
1909                               code_LocalVariableTable_type_RS,
1910                               code_LocalVariableTable_slot
1911                           },
1912                           "LocalVariableTable", "NH[PHOHRUHRSHH]");
1913        predefineAttribute(CODE_ATTR_LocalVariableTypeTable, ATTR_CONTEXT_CODE,
1914                           new Band[] {
1915                               code_LocalVariableTypeTable_N,
1916                               code_LocalVariableTypeTable_bci_P,
1917                               code_LocalVariableTypeTable_span_O,
1918                               code_LocalVariableTypeTable_name_RU,
1919                               code_LocalVariableTypeTable_type_RS,
1920                               code_LocalVariableTypeTable_slot
1921                           },
1922                           "LocalVariableTypeTable", "NH[PHOHRUHRSHH]");
1923        predefineAttribute(X_ATTR_OVERFLOW, ATTR_CONTEXT_CODE, null,
1924                           ".Overflow", "");
1925
1926        // Clear the record of having seen these definitions,
1927        // so they may be redefined without error.
1928        for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
1929            attrDefSeen[i] = 0;
1930        }
1931
1932        // Set up the special masks:
1933        for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
1934            attrOverflowMask[i] = (1<<X_ATTR_OVERFLOW);
1935            attrIndexLimit[i] = 0;  // will make a final decision later
1936        }
1937        attrClassFileVersionMask = (1<<CLASS_ATTR_ClassFile_version);
1938    }
1939
1940    private void adjustToClassVersion() throws IOException {
1941        if (getHighestClassVersion().lessThan(JAVA6_MAX_CLASS_VERSION)) {
1942            if (verbose > 0)  Utils.log.fine("Legacy package version");
1943            // Revoke definition of pre-1.6 attribute type.
1944            undefineAttribute(CODE_ATTR_StackMapTable, ATTR_CONTEXT_CODE);
1945        }
1946    }
1947
1948    protected void initAttrIndexLimit() {
1949        for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
1950            assert(attrIndexLimit[i] == 0);  // decide on it now!
1951            attrIndexLimit[i] = (haveFlagsHi(i)? 63: 32);
1952            List<Attribute.Layout> defList = attrDefs.get(i);
1953            assert(defList.size() == 32);  // all predef indexes are <32
1954            int addMore = attrIndexLimit[i] - defList.size();
1955            defList.addAll(Collections.nCopies(addMore, (Attribute.Layout) null));
1956        }
1957    }
1958
1959    protected boolean haveFlagsHi(int ctype) {
1960        int mask = 1<<(LG_AO_HAVE_XXX_FLAGS_HI+ctype);
1961        switch (ctype) {
1962        case ATTR_CONTEXT_CLASS:
1963            assert(mask == AO_HAVE_CLASS_FLAGS_HI); break;
1964        case ATTR_CONTEXT_FIELD:
1965            assert(mask == AO_HAVE_FIELD_FLAGS_HI); break;
1966        case ATTR_CONTEXT_METHOD:
1967            assert(mask == AO_HAVE_METHOD_FLAGS_HI); break;
1968        case ATTR_CONTEXT_CODE:
1969            assert(mask == AO_HAVE_CODE_FLAGS_HI); break;
1970        default:
1971            assert(false);
1972        }
1973        return testBit(archiveOptions, mask);
1974    }
1975
1976    protected List<Attribute.Layout> getPredefinedAttrs(int ctype) {
1977        assert(attrIndexLimit[ctype] != 0);
1978        List<Attribute.Layout> res = new ArrayList<>(attrIndexLimit[ctype]);
1979        // Remove nulls and non-predefs.
1980        for (int ai = 0; ai < attrIndexLimit[ctype]; ai++) {
1981            if (testBit(attrDefSeen[ctype], 1L<<ai))  continue;
1982            Attribute.Layout def = attrDefs.get(ctype).get(ai);
1983            if (def == null)  continue;  // unused flag bit
1984            assert(isPredefinedAttr(ctype, ai));
1985            res.add(def);
1986        }
1987        return res;
1988    }
1989
1990    protected boolean isPredefinedAttr(int ctype, int ai) {
1991        assert(attrIndexLimit[ctype] != 0);
1992        // Overflow attrs are never predefined.
1993        if (ai >= attrIndexLimit[ctype])          return false;
1994        // If the bit is set, it was explicitly def'd.
1995        if (testBit(attrDefSeen[ctype], 1L<<ai))  return false;
1996        return (attrDefs.get(ctype).get(ai) != null);
1997    }
1998
1999    protected void adjustSpecialAttrMasks() {
2000        // Clear special masks if new definitions have been seen for them.
2001        attrClassFileVersionMask &= ~ attrDefSeen[ATTR_CONTEXT_CLASS];
2002        // It is possible to clear the overflow mask (bit 16).
2003        for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
2004            attrOverflowMask[i] &= ~ attrDefSeen[i];
2005        }
2006    }
2007
2008    protected Attribute makeClassFileVersionAttr(Package.Version ver) {
2009        return attrClassFileVersion.addContent(ver.asBytes());
2010    }
2011
2012    protected Package.Version parseClassFileVersionAttr(Attribute attr) {
2013        assert(attr.layout() == attrClassFileVersion);
2014        assert(attr.size() == 4);
2015        return Package.Version.of(attr.bytes());
2016    }
2017
2018    private boolean assertBandOKForElems(Band[] ab, Attribute.Layout.Element[] elems) {
2019        for (int i = 0; i < elems.length; i++) {
2020            assert(assertBandOKForElem(ab, elems[i]));
2021        }
2022        return true;
2023    }
2024    private boolean assertBandOKForElem(Band[] ab, Attribute.Layout.Element e) {
2025        Band b = null;
2026        if (e.bandIndex != Attribute.NO_BAND_INDEX)
2027            b = ab[e.bandIndex];
2028        Coding rc = UNSIGNED5;
2029        boolean wantIntBand = true;
2030        switch (e.kind) {
2031        case Attribute.EK_INT:
2032            if (e.flagTest(Attribute.EF_SIGN)) {
2033                rc = SIGNED5;
2034            } else if (e.len == 1) {
2035                rc = BYTE1;
2036            }
2037            break;
2038        case Attribute.EK_BCI:
2039            if (!e.flagTest(Attribute.EF_DELTA)) {
2040                rc = BCI5;
2041            } else {
2042                rc = BRANCH5;
2043            }
2044            break;
2045        case Attribute.EK_BCO:
2046            rc = BRANCH5;
2047            break;
2048        case Attribute.EK_FLAG:
2049            if (e.len == 1)  rc = BYTE1;
2050            break;
2051        case Attribute.EK_REPL:
2052            if (e.len == 1)  rc = BYTE1;
2053            assertBandOKForElems(ab, e.body);
2054            break;
2055        case Attribute.EK_UN:
2056            if (e.flagTest(Attribute.EF_SIGN)) {
2057                rc = SIGNED5;
2058            } else if (e.len == 1) {
2059                rc = BYTE1;
2060            }
2061            assertBandOKForElems(ab, e.body);
2062            break;
2063        case Attribute.EK_CASE:
2064            assert(b == null);
2065            assertBandOKForElems(ab, e.body);
2066            return true;  // no direct band
2067        case Attribute.EK_CALL:
2068            assert(b == null);
2069            return true;  // no direct band
2070        case Attribute.EK_CBLE:
2071            assert(b == null);
2072            assertBandOKForElems(ab, e.body);
2073            return true;  // no direct band
2074        case Attribute.EK_REF:
2075            wantIntBand = false;
2076            assert(b instanceof CPRefBand);
2077            assert(((CPRefBand)b).nullOK == e.flagTest(Attribute.EF_NULL));
2078            break;
2079        default: assert(false);
2080        }
2081        assert(b.regularCoding == rc)
2082            : (e+" // "+b);
2083        if (wantIntBand)
2084            assert(b instanceof IntBand);
2085        return true;
2086    }
2087
2088    private
2089    Attribute.Layout predefineAttribute(int index, int ctype, Band[] ab,
2090                                        String name, String layout) {
2091        // Use Attribute.find to get uniquification of layouts.
2092        Attribute.Layout def = Attribute.find(ctype, name, layout).layout();
2093        //def.predef = true;
2094        if (index >= 0) {
2095            setAttributeLayoutIndex(def, index);
2096        }
2097        if (ab == null) {
2098            ab = new Band[0];
2099        }
2100        assert(attrBandTable.get(def) == null);  // no redef
2101        attrBandTable.put(def, ab);
2102        assert(def.bandCount == ab.length)
2103            : (def+" // "+Arrays.asList(ab));
2104        // Let's make sure the band types match:
2105        assert(assertBandOKForElems(ab, def.elems));
2106        return def;
2107    }
2108
2109    // This version takes bandPrefix/addHere instead of prebuilt Band[] ab.
2110    private
2111    Attribute.Layout predefineAttribute(int index,
2112                                        String bandPrefix, MultiBand addHere,
2113                                        Attribute attr) {
2114        //Attribute.Layout def = Attribute.find(ctype, name, layout).layout();
2115        Attribute.Layout def = attr.layout();
2116        int ctype = def.ctype();
2117        return predefineAttribute(index, ctype,
2118                                  makeNewAttributeBands(bandPrefix, def, addHere),
2119                                  def.name(), def.layout());
2120    }
2121
2122    private
2123    void undefineAttribute(int index, int ctype) {
2124        if (verbose > 1) {
2125            System.out.println("Removing predefined "+ATTR_CONTEXT_NAME[ctype]+
2126                               " attribute on bit "+index);
2127        }
2128        List<Attribute.Layout> defList = attrDefs.get(ctype);
2129        Attribute.Layout def = defList.get(index);
2130        assert(def != null);
2131        defList.set(index, null);
2132        attrIndexTable.put(def, null);
2133        // Clear the def bit.  (For predefs, it's already clear.)
2134        assert(index < 64);
2135        attrDefSeen[ctype]  &= ~(1L<<index);
2136        attrFlagMask[ctype] &= ~(1L<<index);
2137        Band[] ab = attrBandTable.get(def);
2138        for (int j = 0; j < ab.length; j++) {
2139            ab[j].doneWithUnusedBand();
2140        }
2141    }
2142
2143    // Bands which contain non-predefined attrs.
2144    protected MultiBand[] attrBands = new MultiBand[ATTR_CONTEXT_LIMIT];
2145    {
2146        attrBands[ATTR_CONTEXT_CLASS] = class_attr_bands;
2147        attrBands[ATTR_CONTEXT_FIELD] = field_attr_bands;
2148        attrBands[ATTR_CONTEXT_METHOD] = method_attr_bands;
2149        attrBands[ATTR_CONTEXT_CODE] = code_attr_bands;
2150    }
2151
2152    // Create bands for all non-predefined attrs.
2153    void makeNewAttributeBands() {
2154        // Retract special flag bit bindings, if they were taken over.
2155        adjustSpecialAttrMasks();
2156
2157        for (int ctype = 0; ctype < ATTR_CONTEXT_LIMIT; ctype++) {
2158            String cname = ATTR_CONTEXT_NAME[ctype];
2159            MultiBand xxx_attr_bands = attrBands[ctype];
2160            long defSeen = attrDefSeen[ctype];
2161            // Note: attrDefSeen is always a subset of attrFlagMask.
2162            assert((defSeen & ~attrFlagMask[ctype]) == 0);
2163            for (int i = 0; i < attrDefs.get(ctype).size(); i++) {
2164                Attribute.Layout def = attrDefs.get(ctype).get(i);
2165                if (def == null)  continue;  // unused flag bit
2166                if (def.bandCount == 0)  continue;  // empty attr
2167                if (i < attrIndexLimit[ctype] && !testBit(defSeen, 1L<<i)) {
2168                    // There are already predefined bands here.
2169                    assert(attrBandTable.get(def) != null);
2170                    continue;
2171                }
2172                int base = xxx_attr_bands.size();
2173                String pfx = cname+"_"+def.name()+"_";  // debug only
2174                if (verbose > 1)
2175                    Utils.log.fine("Making new bands for "+def);
2176                Band[] newAB  = makeNewAttributeBands(pfx, def,
2177                                                      xxx_attr_bands);
2178                assert(newAB.length == def.bandCount);
2179                Band[] prevAB = attrBandTable.put(def, newAB);
2180                if (prevAB != null) {
2181                    // We won't be using these predefined bands.
2182                    for (int j = 0; j < prevAB.length; j++) {
2183                        prevAB[j].doneWithUnusedBand();
2184                    }
2185                }
2186            }
2187        }
2188        //System.out.println(prevForAssertMap);
2189    }
2190    private
2191    Band[] makeNewAttributeBands(String pfx, Attribute.Layout def,
2192                                 MultiBand addHere) {
2193        int base = addHere.size();
2194        makeNewAttributeBands(pfx, def.elems, addHere);
2195        int nb = addHere.size() - base;
2196        Band[] newAB = new Band[nb];
2197        for (int i = 0; i < nb; i++) {
2198            newAB[i] = addHere.get(base+i);
2199        }
2200        return newAB;
2201    }
2202    // Recursive helper, operates on a "body" or other sequence of elems:
2203    private
2204    void makeNewAttributeBands(String pfx, Attribute.Layout.Element[] elems,
2205                               MultiBand ab) {
2206        for (int i = 0; i < elems.length; i++) {
2207            Attribute.Layout.Element e = elems[i];
2208            String name = pfx+ab.size()+"_"+e.layout;
2209            {
2210                int tem;
2211                if ((tem = name.indexOf('[')) > 0)
2212                    name = name.substring(0, tem);
2213                if ((tem = name.indexOf('(')) > 0)
2214                    name = name.substring(0, tem);
2215                if (name.endsWith("H"))
2216                    name = name.substring(0, name.length()-1);
2217            }
2218            Band nb;
2219            switch (e.kind) {
2220            case Attribute.EK_INT:
2221                nb = newElemBand(e, name, ab);
2222                break;
2223            case Attribute.EK_BCI:
2224                if (!e.flagTest(Attribute.EF_DELTA)) {
2225                    // PH:  transmit R(bci), store bci
2226                    nb = ab.newIntBand(name, BCI5);
2227                } else {
2228                    // POH:  transmit D(R(bci)), store bci
2229                    nb = ab.newIntBand(name, BRANCH5);
2230                }
2231                // Note:  No case for BYTE1 here.
2232                break;
2233            case Attribute.EK_BCO:
2234                // OH:  transmit D(R(bci)), store D(bci)
2235                nb = ab.newIntBand(name, BRANCH5);
2236                // Note:  No case for BYTE1 here.
2237                break;
2238            case Attribute.EK_FLAG:
2239                assert(!e.flagTest(Attribute.EF_SIGN));
2240                nb = newElemBand(e, name, ab);
2241                break;
2242            case Attribute.EK_REPL:
2243                assert(!e.flagTest(Attribute.EF_SIGN));
2244                nb = newElemBand(e, name, ab);
2245                makeNewAttributeBands(pfx, e.body, ab);
2246                break;
2247            case Attribute.EK_UN:
2248                nb = newElemBand(e, name, ab);
2249                makeNewAttributeBands(pfx, e.body, ab);
2250                break;
2251            case Attribute.EK_CASE:
2252                if (!e.flagTest(Attribute.EF_BACK)) {
2253                    // If it's not a duplicate body, make the bands.
2254                    makeNewAttributeBands(pfx, e.body, ab);
2255                }
2256                continue;  // no new band to make
2257            case Attribute.EK_REF:
2258                byte    refKind = e.refKind;
2259                boolean nullOK  = e.flagTest(Attribute.EF_NULL);
2260                nb = ab.newCPRefBand(name, UNSIGNED5, refKind, nullOK);
2261                // Note:  No case for BYTE1 here.
2262                break;
2263            case Attribute.EK_CALL:
2264                continue;  // no new band to make
2265            case Attribute.EK_CBLE:
2266                makeNewAttributeBands(pfx, e.body, ab);
2267                continue;  // no new band to make
2268            default: assert(false); continue;
2269            }
2270            if (verbose > 1) {
2271                Utils.log.fine("New attribute band "+nb);
2272            }
2273        }
2274    }
2275    private
2276    Band newElemBand(Attribute.Layout.Element e, String name, MultiBand ab) {
2277        if (e.flagTest(Attribute.EF_SIGN)) {
2278            return ab.newIntBand(name, SIGNED5);
2279        } else if (e.len == 1) {
2280            return ab.newIntBand(name, BYTE1);  // Not ByteBand, please.
2281        } else {
2282            return ab.newIntBand(name, UNSIGNED5);
2283        }
2284    }
2285
2286    protected int setAttributeLayoutIndex(Attribute.Layout def, int index) {
2287        int ctype = def.ctype;
2288        assert(ATTR_INDEX_OVERFLOW <= index && index < attrIndexLimit[ctype]);
2289        List<Attribute.Layout> defList = attrDefs.get(ctype);
2290        if (index == ATTR_INDEX_OVERFLOW) {
2291            // Overflow attribute.
2292            index = defList.size();
2293            defList.add(def);
2294            if (verbose > 0)
2295                Utils.log.info("Adding new attribute at "+def +": "+index);
2296            attrIndexTable.put(def, index);
2297            return index;
2298        }
2299
2300        // Detect redefinitions:
2301        if (testBit(attrDefSeen[ctype], 1L<<index)) {
2302            throw new RuntimeException("Multiple explicit definition at "+index+": "+def);
2303        }
2304        attrDefSeen[ctype] |= (1L<<index);
2305
2306        // Adding a new fixed attribute.
2307        assert(0 <= index && index < attrIndexLimit[ctype]);
2308        if (verbose > (attrClassFileVersionMask == 0? 2:0))
2309            Utils.log.fine("Fixing new attribute at "+index
2310                               +": "+def
2311                               +(defList.get(index) == null? "":
2312                                 "; replacing "+defList.get(index)));
2313        attrFlagMask[ctype] |= (1L<<index);
2314        // Remove index binding of any previous fixed attr.
2315        attrIndexTable.put(defList.get(index), null);
2316        defList.set(index, def);
2317        attrIndexTable.put(def, index);
2318        return index;
2319    }
2320
2321    // encodings found in the code_headers band
2322    private static final int[][] shortCodeLimits = {
2323        { 12, 12 }, // s<12, l<12, e=0 [1..144]
2324        {  8,  8 }, //  s<8,  l<8, e=1 [145..208]
2325        {  7,  7 }, //  s<7,  l<7, e=2 [209..256]
2326    };
2327    public final int shortCodeHeader_h_limit = shortCodeLimits.length;
2328
2329    // return 0 if it won't encode, else a number in [1..255]
2330    static int shortCodeHeader(Code code) {
2331        int s = code.max_stack;
2332        int l0 = code.max_locals;
2333        int h = code.handler_class.length;
2334        if (h >= shortCodeLimits.length)  return LONG_CODE_HEADER;
2335        int siglen = code.getMethod().getArgumentSize();
2336        assert(l0 >= siglen);  // enough locals for signature!
2337        if (l0 < siglen)  return LONG_CODE_HEADER;
2338        int l1 = l0 - siglen;  // do not count locals required by the signature
2339        int lims = shortCodeLimits[h][0];
2340        int liml = shortCodeLimits[h][1];
2341        if (s >= lims || l1 >= liml)  return LONG_CODE_HEADER;
2342        int sc = shortCodeHeader_h_base(h);
2343        sc += s + lims*l1;
2344        if (sc > 255)  return LONG_CODE_HEADER;
2345        assert(shortCodeHeader_max_stack(sc) == s);
2346        assert(shortCodeHeader_max_na_locals(sc) == l1);
2347        assert(shortCodeHeader_handler_count(sc) == h);
2348        return sc;
2349    }
2350
2351    static final int LONG_CODE_HEADER = 0;
2352    static int shortCodeHeader_handler_count(int sc) {
2353        assert(sc > 0 && sc <= 255);
2354        for (int h = 0; ; h++) {
2355            if (sc < shortCodeHeader_h_base(h+1))
2356                return h;
2357        }
2358    }
2359    static int shortCodeHeader_max_stack(int sc) {
2360        int h = shortCodeHeader_handler_count(sc);
2361        int lims = shortCodeLimits[h][0];
2362        return (sc - shortCodeHeader_h_base(h)) % lims;
2363    }
2364    static int shortCodeHeader_max_na_locals(int sc) {
2365        int h = shortCodeHeader_handler_count(sc);
2366        int lims = shortCodeLimits[h][0];
2367        return (sc - shortCodeHeader_h_base(h)) / lims;
2368    }
2369
2370    private static int shortCodeHeader_h_base(int h) {
2371        assert(h <= shortCodeLimits.length);
2372        int sc = 1;
2373        for (int h0 = 0; h0 < h; h0++) {
2374            int lims = shortCodeLimits[h0][0];
2375            int liml = shortCodeLimits[h0][1];
2376            sc += lims * liml;
2377        }
2378        return sc;
2379    }
2380
2381    // utilities for accessing the bc_label band:
2382    protected void putLabel(IntBand bc_label, Code c, int pc, int targetPC) {
2383        bc_label.putInt(c.encodeBCI(targetPC) - c.encodeBCI(pc));
2384    }
2385    protected int getLabel(IntBand bc_label, Code c, int pc) {
2386        return c.decodeBCI(bc_label.getInt() + c.encodeBCI(pc));
2387    }
2388
2389    protected CPRefBand getCPRefOpBand(int bc) {
2390        switch (Instruction.getCPRefOpTag(bc)) {
2391        case CONSTANT_Class:
2392            return bc_classref;
2393        case CONSTANT_Fieldref:
2394            return bc_fieldref;
2395        case CONSTANT_Methodref:
2396            return bc_methodref;
2397        case CONSTANT_InterfaceMethodref:
2398            return bc_imethodref;
2399        case CONSTANT_InvokeDynamic:
2400            return bc_indyref;
2401        case CONSTANT_LoadableValue:
2402            switch (bc) {
2403            case _ildc: case _ildc_w:
2404                return bc_intref;
2405            case _fldc: case _fldc_w:
2406                return bc_floatref;
2407            case _lldc2_w:
2408                return bc_longref;
2409            case _dldc2_w:
2410                return bc_doubleref;
2411            case _sldc: case _sldc_w:
2412                return bc_stringref;
2413            case _cldc: case _cldc_w:
2414                return bc_classref;
2415            case _qldc: case _qldc_w:
2416                return bc_loadablevalueref;
2417            }
2418            break;
2419        }
2420        assert(false);
2421        return null;
2422    }
2423
2424    protected CPRefBand selfOpRefBand(int self_bc) {
2425        assert(Instruction.isSelfLinkerOp(self_bc));
2426        int idx = (self_bc - _self_linker_op);
2427        boolean isSuper = (idx >= _self_linker_super_flag);
2428        if (isSuper)  idx -= _self_linker_super_flag;
2429        boolean isAload = (idx >= _self_linker_aload_flag);
2430        if (isAload)  idx -= _self_linker_aload_flag;
2431        int origBC = _first_linker_op + idx;
2432        boolean isField = Instruction.isFieldOp(origBC);
2433        if (!isSuper)
2434            return isField? bc_thisfield: bc_thismethod;
2435        else
2436            return isField? bc_superfield: bc_supermethod;
2437    }
2438
2439    ////////////////////////////////////////////////////////////////////
2440
2441    static int nextSeqForDebug;
2442    static File dumpDir = null;
2443    static OutputStream getDumpStream(Band b, String ext) throws IOException {
2444        return getDumpStream(b.name, b.seqForDebug, ext, b);
2445    }
2446    static OutputStream getDumpStream(Index ix, String ext) throws IOException {
2447        if (ix.size() == 0)  return new ByteArrayOutputStream();
2448        int seq = ConstantPool.TAG_ORDER[ix.cpMap[0].tag];
2449        return getDumpStream(ix.debugName, seq, ext, ix);
2450    }
2451    static OutputStream getDumpStream(String name, int seq, String ext, Object b) throws IOException {
2452        if (dumpDir == null) {
2453            dumpDir = File.createTempFile("BD_", "", new File("."));
2454            dumpDir.delete();
2455            if (dumpDir.mkdir())
2456                Utils.log.info("Dumping bands to "+dumpDir);
2457        }
2458        name = name.replace('(', ' ').replace(')', ' ');
2459        name = name.replace('/', ' ');
2460        name = name.replace('*', ' ');
2461        name = name.trim().replace(' ','_');
2462        name = ((10000+seq) + "_" + name).substring(1);
2463        File dumpFile = new File(dumpDir, name+ext);
2464        Utils.log.info("Dumping "+b+" to "+dumpFile);
2465        return new BufferedOutputStream(new FileOutputStream(dumpFile));
2466    }
2467
2468    // DEBUG ONLY:  Validate me at each length change.
2469    static boolean assertCanChangeLength(Band b) {
2470        switch (b.phase) {
2471        case COLLECT_PHASE:
2472        case READ_PHASE:
2473            return true;
2474        }
2475        return false;
2476    }
2477
2478    // DEBUG ONLY:  Validate a phase.
2479    static boolean assertPhase(Band b, int phaseExpected) {
2480        if (b.phase() != phaseExpected) {
2481            Utils.log.warning("phase expected "+phaseExpected+" was "+b.phase()+" in "+b);
2482            return false;
2483        }
2484        return true;
2485    }
2486
2487
2488    // DEBUG ONLY:  Tells whether verbosity is turned on.
2489    static int verbose() {
2490        return Utils.currentPropMap().getInteger(Utils.DEBUG_VERBOSE);
2491    }
2492
2493
2494    // DEBUG ONLY:  Validate me at each phase change.
2495    static boolean assertPhaseChangeOK(Band b, int p0, int p1) {
2496        switch (p0*10+p1) {
2497        /// Writing phases:
2498        case NO_PHASE*10+COLLECT_PHASE:
2499            // Ready to collect data from the input classes.
2500            assert(!b.isReader());
2501            assert(b.capacity() >= 0);
2502            assert(b.length() == 0);
2503            return true;
2504        case COLLECT_PHASE*10+FROZEN_PHASE:
2505        case FROZEN_PHASE*10+FROZEN_PHASE:
2506            assert(b.length() == 0);
2507            return true;
2508        case COLLECT_PHASE*10+WRITE_PHASE:
2509        case FROZEN_PHASE*10+WRITE_PHASE:
2510            // Data is all collected.  Ready to write bytes to disk.
2511            return true;
2512        case WRITE_PHASE*10+DONE_PHASE:
2513            // Done writing to disk.  Ready to reset, in principle.
2514            return true;
2515
2516        /// Reading phases:
2517        case NO_PHASE*10+EXPECT_PHASE:
2518            assert(b.isReader());
2519            assert(b.capacity() < 0);
2520            return true;
2521        case EXPECT_PHASE*10+READ_PHASE:
2522            // Ready to read values from disk.
2523            assert(Math.max(0,b.capacity()) >= b.valuesExpected());
2524            assert(b.length() <= 0);
2525            return true;
2526        case READ_PHASE*10+DISBURSE_PHASE:
2527            // Ready to disburse values.
2528            assert(b.valuesRemainingForDebug() == b.length());
2529            return true;
2530        case DISBURSE_PHASE*10+DONE_PHASE:
2531            // Done disbursing values.  Ready to reset, in principle.
2532            assert(assertDoneDisbursing(b));
2533            return true;
2534        }
2535        if (p0 == p1)
2536            Utils.log.warning("Already in phase "+p0);
2537        else
2538            Utils.log.warning("Unexpected phase "+p0+" -> "+p1);
2539        return false;
2540    }
2541
2542    private static boolean assertDoneDisbursing(Band b) {
2543        if (b.phase != DISBURSE_PHASE) {
2544            Utils.log.warning("assertDoneDisbursing: still in phase "+b.phase+": "+b);
2545            if (verbose() <= 1)  return false;  // fail now
2546        }
2547        int left = b.valuesRemainingForDebug();
2548        if (left > 0) {
2549            Utils.log.warning("assertDoneDisbursing: "+left+" values left in "+b);
2550            if (verbose() <= 1)  return false;  // fail now
2551        }
2552        if (b instanceof MultiBand) {
2553            MultiBand mb = (MultiBand) b;
2554            for (int i = 0; i < mb.bandCount; i++) {
2555                Band sub = mb.bands[i];
2556                if (sub.phase != DONE_PHASE) {
2557                    Utils.log.warning("assertDoneDisbursing: sub-band still in phase "+sub.phase+": "+sub);
2558                    if (verbose() <= 1)  return false;  // fail now
2559                }
2560            }
2561        }
2562        return true;
2563    }
2564
2565    private static void printCDecl(Band b) {
2566        if (b instanceof MultiBand) {
2567            MultiBand mb = (MultiBand) b;
2568            for (int i = 0; i < mb.bandCount; i++) {
2569                printCDecl(mb.bands[i]);
2570            }
2571            return;
2572        }
2573        String ixS = "NULL";
2574        if (b instanceof CPRefBand) {
2575            Index ix = ((CPRefBand)b).index;
2576            if (ix != null)  ixS = "INDEX("+ix.debugName+")";
2577        }
2578        Coding[] knownc = { BYTE1, CHAR3, BCI5, BRANCH5, UNSIGNED5,
2579                            UDELTA5, SIGNED5, DELTA5, MDELTA5 };
2580        String[] knowns = { "BYTE1", "CHAR3", "BCI5", "BRANCH5", "UNSIGNED5",
2581                            "UDELTA5", "SIGNED5", "DELTA5", "MDELTA5" };
2582        Coding rc = b.regularCoding;
2583        int rci = Arrays.asList(knownc).indexOf(rc);
2584        String cstr;
2585        if (rci >= 0)
2586            cstr = knowns[rci];
2587        else
2588            cstr = "CODING"+rc.keyString();
2589        System.out.println("  BAND_INIT(\""+b.name()+"\""
2590                           +", "+cstr+", "+ixS+"),");
2591    }
2592
2593    private Map<Band, Band> prevForAssertMap;
2594
2595    // DEBUG ONLY:  Record something about the band order.
2596    boolean notePrevForAssert(Band b, Band p) {
2597        if (prevForAssertMap == null)
2598            prevForAssertMap = new HashMap<>();
2599        prevForAssertMap.put(b, p);
2600        return true;
2601    }
2602
2603    // DEBUG ONLY:  Validate next input band, ensure bands are read in sequence
2604    private boolean assertReadyToReadFrom(Band b, InputStream in) throws IOException {
2605        Band p = prevForAssertMap.get(b);
2606        // Any previous band must be done reading before this one starts.
2607        if (p != null && phaseCmp(p.phase(), DISBURSE_PHASE) < 0) {
2608            Utils.log.warning("Previous band not done reading.");
2609            Utils.log.info("    Previous band: "+p);
2610            Utils.log.info("        Next band: "+b);
2611            assert(verbose > 0);  // die unless verbose is true
2612        }
2613        String name = b.name;
2614        if (optDebugBands && !name.startsWith("(")) {
2615            assert(bandSequenceList != null);
2616            // Verify synchronization between reader & writer:
2617            String inName = bandSequenceList.removeFirst();
2618            // System.out.println("Reading: " + name);
2619            if (!inName.equals(name)) {
2620                Utils.log.warning("Expected " + name + " but read: " + inName);
2621                return false;
2622            }
2623            Utils.log.info("Read band in sequence: " + name);
2624        }
2625        return true;
2626    }
2627
2628    // DEBUG ONLY:  Make sure a bunch of cprefs are correct.
2629    private boolean assertValidCPRefs(CPRefBand b) {
2630        if (b.index == null)  return true;
2631        int limit = b.index.size()+1;
2632        for (int i = 0; i < b.length(); i++) {
2633            int v = b.valueAtForDebug(i);
2634            if (v < 0 || v >= limit) {
2635                Utils.log.warning("CP ref out of range "+
2636                                   "["+i+"] = "+v+" in "+b);
2637                return false;
2638            }
2639        }
2640        return true;
2641    }
2642
2643    /*
2644     * DEBUG ONLY:  write the bands to a list and read back the list in order,
2645     * this works perfectly if we use the java packer and unpacker, typically
2646     * this will work with --repack or if they are in the same jvm instance.
2647     */
2648    static LinkedList<String> bandSequenceList = null;
2649    private boolean assertReadyToWriteTo(Band b, OutputStream out) throws IOException {
2650        Band p = prevForAssertMap.get(b);
2651        // Any previous band must be done writing before this one starts.
2652        if (p != null && phaseCmp(p.phase(), DONE_PHASE) < 0) {
2653            Utils.log.warning("Previous band not done writing.");
2654            Utils.log.info("    Previous band: "+p);
2655            Utils.log.info("        Next band: "+b);
2656            assert(verbose > 0);  // die unless verbose is true
2657        }
2658        String name = b.name;
2659        if (optDebugBands && !name.startsWith("(")) {
2660            if (bandSequenceList == null)
2661                bandSequenceList = new LinkedList<>();
2662            // Verify synchronization between reader & writer:
2663            bandSequenceList.add(name);
2664            // System.out.println("Writing: " + b);
2665        }
2666        return true;
2667    }
2668
2669    protected static boolean testBit(int flags, int bitMask) {
2670        return (flags & bitMask) != 0;
2671    }
2672    protected static int setBit(int flags, int bitMask, boolean z) {
2673        return z ? (flags | bitMask) : (flags &~ bitMask);
2674    }
2675    protected static boolean testBit(long flags, long bitMask) {
2676        return (flags & bitMask) != 0;
2677    }
2678    protected static long setBit(long flags, long bitMask, boolean z) {
2679        return z ? (flags | bitMask) : (flags &~ bitMask);
2680    }
2681
2682
2683    static void printArrayTo(PrintStream ps, int[] values, int start, int end) {
2684        int len = end-start;
2685        for (int i = 0; i < len; i++) {
2686            if (i % 10 == 0)
2687                ps.println();
2688            else
2689                ps.print(" ");
2690            ps.print(values[start+i]);
2691        }
2692        ps.println();
2693    }
2694
2695    static void printArrayTo(PrintStream ps, Entry[] cpMap, int start, int end) {
2696        printArrayTo(ps, cpMap, start, end, false);
2697    }
2698    static void printArrayTo(PrintStream ps, Entry[] cpMap, int start, int end, boolean showTags) {
2699        StringBuffer buf = new StringBuffer();
2700        int len = end-start;
2701        for (int i = 0; i < len; i++) {
2702            Entry e = cpMap[start+i];
2703            ps.print(start+i); ps.print("=");
2704            if (showTags) { ps.print(e.tag); ps.print(":"); }
2705            String s = e.stringValue();
2706            buf.setLength(0);
2707            for (int j = 0; j < s.length(); j++) {
2708                char ch = s.charAt(j);
2709                if (!(ch < ' ' || ch > '~' || ch == '\\')) {
2710                    buf.append(ch);
2711                } else if (ch == '\\') {
2712                    buf.append("\\\\");
2713                } else if (ch == '\n') {
2714                    buf.append("\\n");
2715                } else if (ch == '\t') {
2716                    buf.append("\\t");
2717                } else if (ch == '\r') {
2718                    buf.append("\\r");
2719                } else {
2720                    String str = "000"+Integer.toHexString(ch);
2721                    buf.append("\\u").append(str.substring(str.length()-4));
2722                }
2723            }
2724            ps.println(buf);
2725        }
2726    }
2727
2728
2729    // Utilities for reallocating:
2730    protected static Object[] realloc(Object[] a, int len) {
2731        java.lang.Class<?> elt = a.getClass().getComponentType();
2732        Object[] na = (Object[]) java.lang.reflect.Array.newInstance(elt, len);
2733        System.arraycopy(a, 0, na, 0, Math.min(a.length, len));
2734        return na;
2735    }
2736    protected static Object[] realloc(Object[] a) {
2737        return realloc(a, Math.max(10, a.length*2));
2738    }
2739
2740    protected static int[] realloc(int[] a, int len) {
2741        if (len == 0)  return noInts;
2742        if (a == null)  return new int[len];
2743        int[] na = new int[len];
2744        System.arraycopy(a, 0, na, 0, Math.min(a.length, len));
2745        return na;
2746    }
2747    protected static int[] realloc(int[] a) {
2748        return realloc(a, Math.max(10, a.length*2));
2749    }
2750
2751    protected static byte[] realloc(byte[] a, int len) {
2752        if (len == 0)  return noBytes;
2753        if (a == null)  return new byte[len];
2754        byte[] na = new byte[len];
2755        System.arraycopy(a, 0, na, 0, Math.min(a.length, len));
2756        return na;
2757    }
2758    protected static byte[] realloc(byte[] a) {
2759        return realloc(a, Math.max(10, a.length*2));
2760    }
2761}
2762