Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/share/jdwp/ByteBuffer.java
41161 views
/*1* Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223package nsk.share.jdwp;2425import java.io.*;26import nsk.share.*;2728/**29* This class represents a byte buffer of variable size.30*/31public class ByteBuffer {3233/**34* Empty byte value (zero).35*/36private static final byte EMPTY_BYTE = (byte)0;3738/**39* Current number of bytes in the buffer.40*/41private int CurrentSize;4243/**44* Delta to increase buffer size.45*/46private int Delta;4748/**49* Current offset from the buffer begin during parsing packet.50*/51int parseOffset;5253/**54* Array of bytes in the buffer.55*/56protected byte[] bytes;5758/**59* Make an empty <code>ByteBuffer</code> object.60*/61public ByteBuffer() {62this(128, 128);63}6465/**66* Make an empty <code>ByteBuffer</code> object with given initial capacity.67* When there is no space for a new byte in a buffer it's capacity68* grows by Delta.69*/70public ByteBuffer(int InitialSize, int Delta) {71if (Delta <= 0)72Delta = 16;73this.Delta = Delta;74CurrentSize = 0;75bytes = new byte[InitialSize];76parseOffset = 0;77}7879/**80* Make a copy of specified byte buffer.81*/82public ByteBuffer(ByteBuffer buffer) {83int InitialSize = buffer.bytes.length;84Delta = buffer.Delta;85CurrentSize = buffer.CurrentSize;86bytes = new byte[InitialSize];87for (int i = 0; i < CurrentSize; i++ ) {88bytes[i] = buffer.bytes[i];89}90parseOffset = 0;91}9293/**94* Return number of bytes in this buffer.95*/96public int length() {97return CurrentSize;98}99100/**101* Return array of bytes in this buffer.102*/103public byte[] getBytes() {104return bytes;105}106107//////////////////////////////////////////////////////////////////////////108109/**110* Replace the byte at the specified offset in this buffer with the111* less significant byte from the int value.112*113* @throws BoundException if specified offset is out of buffer bounds114*/115public void putByte(int off, byte value) throws BoundException {116117if ((off < 0) || (off >= CurrentSize))118throw new BoundException("Unable to put one byte at " + offsetString(off));119120bytes[off] = value;121}122123/**124* Replace len bytes starting at offset off with the bytes from the125* given byte array.126*127* @throws BoundException if offset and length are out of buffer bounds128*/129public void putBytes(int off, byte[] value, int start, int len) throws BoundException {130if (len > (CurrentSize - off)) {131throw new BoundException("Unable to put " + len + " bytes at " + offsetString(off) +132" (available bytes: " + (CurrentSize - off) + ")" );133}134try {135for (int i = 0; i < len; i++)136putByte(off++, value[start++]);137} catch (BoundException e) {138throw new Failure("Caught unexpected bound exception while putting " + len +139"bytes at " + offsetString(off) + ":\n\t" + e);140}141}142143/**144* Replace count (1 - 8) bytes starting at offset off with the less145* significant bytes from the specified ID value.146*147* @throws BoundException if offset and count are out of buffer bounds148*/149public void putID(int off, long value, int count) throws BoundException {150151if ((count <= 0) || (count > 8))152throw new TestBug("Illegal number of bytes of ID value to put: " + count);153154if (count > CurrentSize - off) {155throw new BoundException("Unable to put " + count + " bytes of ID value at " +156offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" );157}158159try {160putValueBytes(off, value, count);161} catch (BoundException e) {162throw new Failure("Caught unexpected bound exception while putting " + count +163"bytes of ID value at " + offsetString(off) + ":\n\t" + e);164}165}166167/**168* Replace four bytes starting at offset off with the bytes from the169* specified int value.170*171* @throws BoundException if offset is out of buffer bounds172*/173public void putInt(int off, int value) throws BoundException {174final int count = JDWP.TypeSize.INT;175176if (count > CurrentSize - off) {177throw new BoundException("Unable to put " + count + " bytes of int value at " +178offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" );179}180181try {182putValueBytes(off, value, count);183} catch (BoundException e) {184throw new Failure("Caught unexpected bound exception while putting " + count +185"bytes of int value at " + offsetString(off) + ":\n\t" + e);186}187}188189/**190* Replace two bytes starting at offset off with the bytes191* from the specified short value.192*193* @throws BoundException if offset is out of buffer bounds194*/195public void putShort(int off, short value) throws BoundException {196final int count = JDWP.TypeSize.SHORT;197198if (count > CurrentSize - off) {199throw new BoundException("Unable to put " + count + " bytes of short value at " +200offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" );201}202203try {204putValueBytes(off, value, count);205} catch (BoundException e) {206throw new Failure("Caught unexpected bound exception while putting " + count +207"bytes of short value at " + offsetString(off) + ":\n\t" + e);208}209}210211/**212* Replace eight bytes starting at offset off with the bytes213* from the specified long value.214*215* @throws BoundException if offset is out of buffer bounds216*/217public void putLong(int off, long value) throws BoundException {218final int count = JDWP.TypeSize.LONG;219220if (count > CurrentSize - off) {221throw new BoundException("Unable to put " + count + " bytes of long value at " +222offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" );223}224225try {226putValueBytes(off, value, count);227} catch (BoundException e) {228throw new Failure("Caught unexpected bound exception while putting " + count +229"bytes of long value at " + offsetString(off) + ":\n\t" + e);230}231}232233/**234* Replace four bytes starting at offset off with the bytes235* from the specified float value.236*237* @throws BoundException if offset is out of buffer bounds238*/239public void putFloat(int off, float value) throws BoundException {240final int count = JDWP.TypeSize.FLOAT;241242if (count > CurrentSize - off) {243throw new BoundException("Unable to put " + count + " bytes of float value at " +244offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" );245}246247try {248long l = Float.floatToIntBits(value);249putValueBytes(off, l, count);250} catch (BoundException e) {251throw new Failure("Caught unexpected bound exception while putting " + count +252"bytes of float value at " + offsetString(off) + ":\n\t" + e);253}254}255256/**257* Replace eight bytes starting at offset off with the bytes258* from the specified double value.259*260* @throws BoundException if offset is out of buffer bounds261*/262public void putDouble(int off, double value) throws BoundException {263final int count = JDWP.TypeSize.DOUBLE;264265if (count > CurrentSize - off) {266throw new BoundException("Unable to put " + count + " bytes of double value at " +267offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" );268}269270try {271long l = Double.doubleToLongBits(value);272putValueBytes(off, l, count);273} catch (BoundException e) {274throw new Failure("Caught unexpected bound exception while putting " + count +275"bytes of double value at " + offsetString(off) + ": \n\t" + e);276}277}278279/**280* Replace two bytes starting at offset off with the bytes281* from the specified char value.282*283* @throws BoundException if offset is out of buffer bounds284*/285public void putChar(int off, char value) throws BoundException {286final int count = JDWP.TypeSize.CHAR;287288if (count > CurrentSize - off) {289throw new BoundException("Unable to put " + count + " bytes of char value at " +290offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" );291}292293try {294long l = (long)value;295putValueBytes(off, l, count);296} catch (BoundException e) {297throw new Failure("Caught unexpected bound exception while putting " + count +298"bytes of char value at " + offsetString(off) + ":\n\t" + e);299}300}301302//////////////////////////////////////////////////////////////////////////303304/**305* Append the specified byte to the end of this buffer.306*/307public void addByte(byte value) {308checkSpace(1);309310int where = CurrentSize;311CurrentSize++;312313try {314putByte(where, value);315}316catch (BoundException e) {317throw new TestBug("Caught unexpected bound exception while adding one byte:\n\t"318+ e);319};320}321322/**323* Append specified byte value repeated count to the end of this buffer.324*/325public void addBytes(byte value, int count) {326checkSpace(count);327for (int i = 0; i < count; i++) {328addByte(value);329}330}331332/**333* Append the bytes from the specified byte array to the end of this buffer.334*/335public void addBytes(byte[] value, int start, int len) {336checkSpace(len);337338int where = CurrentSize;339CurrentSize = CurrentSize + len;340341try {342putBytes(where, value, start, len);343}344catch (BoundException e) {345throw new TestBug("Caught unexpected bound exception while adding " +346len + " bytes:\n\t" + e);347};348}349350/**351* Appends the count (1 - 8) less significant bytes from the352* specified ID value to the end of this buffer.353*/354public void addID(long value, int count) {355if ((count <= 0) || (count > 8))356throw new TestBug("Illegal number bytes of ID value to add: " + count);357358final int where = CurrentSize;359addBytes(EMPTY_BYTE, count);360361try {362putID(where, value, count);363}364catch (BoundException e) {365throw new TestBug("Caught unexpected bound exception while adding " +366count + " bytes of ID value:\n\t" + e);367};368}369370/**371* Append four bytes from the specified int value to the372* end of this buffer.373*/374public void addInt(int value) {375final int count = JDWP.TypeSize.INT;376final int where = CurrentSize;377addBytes(EMPTY_BYTE, count);378379try {380putInt(where, value);381}382catch (BoundException e) {383throw new TestBug("Caught unexpected bound exception while adding " +384count + " bytes of int value:\n\t" + e);385};386}387388/**389* Append two bytes from the specified int value to the390* end of this buffer.391*/392public void addShort(short value) {393final int count = JDWP.TypeSize.SHORT;394final int where = CurrentSize;395addBytes(EMPTY_BYTE, count);396try {397putShort(where, value);398}399catch (BoundException e) {400throw new TestBug("Caught unexpected bound exception while adding " +401count + " bytes of short value:\n\t" + e);402};403}404405/**406* Appends eight bytes from the specified long407* value to the end of this buffer.408*/409public void addLong(long value) {410final int count = JDWP.TypeSize.LONG;411final int where = CurrentSize;412addBytes(EMPTY_BYTE, count);413try {414putLong(where, value);415}416catch (BoundException e) {417throw new TestBug("Caught unexpected bound exception while adding " +418count + " bytes of long value:\n\t" + e);419};420}421422/**423* Appends four bytes from the specified float424* value to the end of this buffer.425*/426public void addFloat(float value) {427final int count = JDWP.TypeSize.FLOAT;428final int where = CurrentSize;429addBytes(EMPTY_BYTE, count);430try {431putFloat(where, value);432}433catch (BoundException e) {434throw new TestBug("Caught unexpected bound exception while adding " +435count + " bytes of float value:\n\t" + e);436};437}438439/**440* Appends eight bytes from the specified double441* value to the end of this buffer.442*/443public void addDouble(double value) {444final int count = JDWP.TypeSize.DOUBLE;445final int where = CurrentSize;446addBytes(EMPTY_BYTE, count);447try {448putDouble(where, value);449}450catch (BoundException e) {451throw new TestBug("Caught unexpected bound exception while adding " +452count + " bytes of double value:\n\t" + e);453};454}455456/**457* Appends four bytes from the specified char458* value to the end of this buffer.459*/460public void addChar(char value) {461final int count = JDWP.TypeSize.CHAR;462final int where = CurrentSize;463addBytes(EMPTY_BYTE, count);464try {465putChar(where, value);466}467catch (BoundException e) {468throw new TestBug("Caught unexpected bound exception while adding " +469count + " bytes of float value:\n\t" + e);470};471}472473//////////////////////////////////////////////////////////////////////////474475/**476* Read a byte value from this buffer at the specified position.477*478* @throws BoundException if there are no bytes at this position479*/480public byte getByte(int off) throws BoundException {481if (off < 0 || off >= CurrentSize) {482throw new BoundException("Unable to get one byte at " + offsetString(off) +483": no bytes available");484}485return bytes[off];486}487488/**489* Read count bytes (1-8) from this buffer at the specified490* position and returns a long value composed of these bytes.491*492* @throws BoundException if there are no so many bytes at this position493*/494public long getID(int off, int count) throws BoundException {495if ((count <= 0) || (count > 8))496throw new TestBug("Illegal number of bytes of ID value to get: " + count);497498if (count > CurrentSize - off) {499throw new BoundException("Unable to get " + count + " bytes of ID value at " +500offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" );501}502503try {504return getValueBytes(off, count);505}506catch (BoundException e) {507throw new TestBug("Caught unexpected bound exception while getting " +508count + " bytes of ID value at " + offsetString(off) + ":\n\t" + e);509}510}511512/**513* Read four bytes from this buffer at the specified514* position and returns an integer value composed of these bytes.515*516* @throws BoundException if there are no so many bytes at this position517*/518public int getInt(int off) throws BoundException {519final int count = JDWP.TypeSize.INT;520if (count > CurrentSize - off) {521throw new BoundException("Unable to get " + count + " bytes of int value at " +522offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" );523}524525try {526return (int)getValueBytes(off, count);527}528catch (BoundException e) {529throw new TestBug("Caught unexpected bound exception while getting " +530count + " bytes of int value at " + offsetString(off) + ":\n\t" + e);531}532}533534/**535* Read two bytes from this buffer at the specified536* position and returns a short value composed of these bytes.537*538* @throws BoundException if there are no so many bytes at this position539*/540public short getShort(int off) throws BoundException {541final int count = JDWP.TypeSize.SHORT;542if (count > CurrentSize - off) {543throw new BoundException("Unable to get " + count + " bytes of short value at " +544offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" );545}546547try {548return (short)getValueBytes(off, count);549}550catch (BoundException e) {551throw new TestBug("Caught unexpected bound exception while getting " +552count + " bytes of short value at " + offsetString(off) + ":\n\t" + e);553}554}555556/**557* Read eight bytes from this buffer at the specified558* position and returns a long value composed of these bytes.559*560* @throws BoundException if there are no so many bytes at this position561*/562public long getLong(int off) throws BoundException {563final int count = JDWP.TypeSize.LONG;564if (count > CurrentSize - off) {565throw new BoundException("Unable to get " + count + " bytes of long value at " +566offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" );567}568569try {570return getValueBytes(off, count);571}572catch (BoundException e) {573throw new TestBug("Caught unexpected bound exception while getting " +574count + " bytes of long value at " + offsetString(off) + ":\n\t" + e);575}576}577578/**579* Read eight bytes from this buffer at the specified580* position and returns a double value composed of these bytes.581*582* @throws BoundException if there are no so many bytes at this position583*/584public double getDouble(int off) throws BoundException {585final int count = JDWP.TypeSize.DOUBLE;586if (count > CurrentSize - off) {587throw new BoundException("Unable to get " + count + " bytes of double value at " +588offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" );589}590591try {592long value = getValueBytes(off, count);593return Double.longBitsToDouble(value);594}595catch (BoundException e) {596throw new TestBug("Caught unexpected bound exception while getting " +597count + " bytes of long value at " + offsetString(off) + ":\n\t" + e);598}599}600601/**602* Read four bytes from this buffer at the specified603* position and returns a float value composed of these bytes.604*605* @throws BoundException if there are no so many bytes at this position606*/607public float getFloat(int off) throws BoundException {608final int count = JDWP.TypeSize.FLOAT;609if (count > CurrentSize - off) {610throw new BoundException("Unable to get " + count + " bytes of float value at " +611offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" );612}613614try {615int value = (int)getValueBytes(off, count);616return Float.intBitsToFloat(value);617}618catch (BoundException e) {619throw new TestBug("Caught unexpected bound exception while getting " +620count + " bytes of float value at " + offsetString(off) + ":\n\t" + e);621}622}623624/**625* Read two bytes from this buffer at the specified626* position and returns a char value composed of these bytes.627*628* @throws BoundException if there are no so many bytes at this position629*/630public char getChar(int off) throws BoundException {631final int count = JDWP.TypeSize.CHAR;632if (count > CurrentSize - off) {633throw new BoundException("Unable to get " + count + " bytes of char value at " +634offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" );635}636637try {638int value = (int)getValueBytes(off, count);639return (char)value;640}641catch (BoundException e) {642throw new TestBug("Caught unexpected bound exception while getting " +643count + " bytes of char value at " + offsetString(off) + ":\n\t" + e);644}645}646647//////////////////////////////////////////////////////////////////////////648649/**650* Set the current parser position to 0.651*/652public void resetPosition() {653resetPosition(0);654}655656/**657* Set the current parser position to the specified value.658*/659public void resetPosition(int i) {660parseOffset = i;661}662663/**664* Return current parser position.665*/666public int currentPosition() {667return parseOffset;668}669670/**671* Return true if the parser pointer is set to the end of buffer.672*/673public boolean isParsed() {674return (parseOffset == CurrentSize);675}676677/**678* Read a byte value from this buffer at the current parser position.679*680* @throws BoundException if there are no more bytes in the buffer681*/682public byte getByte() throws BoundException {683return getByte(parseOffset++);684}685686/**687* Read count bytes (1-8) from this buffer at the current parser688* position and returns a long value composed of these bytes.689*690* @throws BoundException if there are no so many bytes in the buffer691*/692public long getID(int count) throws BoundException {693long value = getID(parseOffset, count);694parseOffset += count;695return value;696}697698/**699* Read four bytes from this buffer at the current parser700* position and returns an integer value composed of these bytes.701*702* @throws BoundException if there are no so many bytes in the buffer703*/704public int getInt() throws BoundException {705final int count = JDWP.TypeSize.INT;706int value = getInt(parseOffset);707parseOffset += count;708return value;709}710711/**712* Read two bytes from this buffer at the current parser713* position and returns a short value composed of these bytes.714*715* @throws BoundException if there are no so many bytes in the buffer716*/717public short getShort() throws BoundException {718final int count = JDWP.TypeSize.SHORT;719short value = getShort(parseOffset);720parseOffset += count;721return value;722}723724/**725* Read eight bytes from this buffer at the current parser726* position and returns a long value composed of these bytes.727*728* @throws BoundException if there are no so many bytes in the buffer729*/730public long getLong() throws BoundException {731final int count = JDWP.TypeSize.LONG;732long value = getLong(parseOffset);733parseOffset += count;734return value;735}736737/**738* Read eight bytes from this buffer at the current parser739* position and returns a double value composed of these bytes.740*741* @throws BoundException if there are no so many bytes in the buffer742*/743public double getDouble() throws BoundException {744final int count = JDWP.TypeSize.DOUBLE;745double value = getDouble(parseOffset);746parseOffset += count;747return value;748}749750/**751* Read four bytes from this buffer at the current parser752* position and returns a float value composed of these bytes.753*754* @throws BoundException if there are no so many bytes in the buffer755*/756public float getFloat() throws BoundException {757final int count = JDWP.TypeSize.FLOAT;758float value = getFloat(parseOffset);759parseOffset += count;760return value;761}762763/**764* Read two bytes from this buffer at the current parser765* position and returns a char value composed of these bytes.766*767* @throws BoundException if there are no so many bytes in the buffer768*/769public char getChar() throws BoundException {770final int count = JDWP.TypeSize.CHAR;771char value = getChar(parseOffset);772parseOffset += count;773return value;774}775776/**777* Remove at least first count bytes from the buffer.778*/779780public void deleteBytes(int count) {781int j = 0;782while (count < CurrentSize)783bytes[j++] = bytes[count++];784785CurrentSize = j;786}787788/**789* Clear the buffer.790*/791public void resetBuffer() {792CurrentSize = 0;793}794795/**796* Return string representation of the buffer starting at given offset.797*/798public String toString(int start) {799800String Result = "", HexLine = "", DisplayLine = "";801802int j = 0;803804for (int i = start; i < length(); i++) {805806HexLine = HexLine + toHexString(bytes[i], 2) + " ";807808String ch = ".";809if (bytes[i] >= 0x20 && bytes[i] < 0x80) {810try {811ch = new String(bytes, i, 1, "US-ASCII");812} catch (UnsupportedEncodingException ignore) {813}814}815DisplayLine = DisplayLine + ch;816817if ((i == length() - 1) || (((i - start) & 0x0F) == 0x0F)) {818Result = Result +819" " +820toHexString(j, 4) + ": " +821PadR(HexLine, 48) + " " +822DisplayLine + "\n";823HexLine = "";824DisplayLine = "";825j = j + 16;826}827}828return Result;829}830831/**832* Return string representation of the buffer.833*/834public String toString() {835return toString(0);836}837838/**839* Return string with hexadecimal representation of bytes.840*/841public static String toHexString(long b, int length) {842return Right(Long.toHexString(b), length).replace(' ', '0');843}844845/**846* Return string with hexadecimal representation of bytes.847*/848public static String toHexDecString(long b, int length) {849return toHexString(b, length) + " (" + b + ")";850}851852// -----853854/**855* Return string with hexadecimal representation of offset.856*/857public static String offsetString(int off) {858return "0x" + toHexString(off, 4);859}860861/**862* Return string with hexadecimal representation of the current offset.863*/864public String offsetString() {865return offsetString(currentPosition());866}867868// -----869870/**871* Check if there space for new bytes in the buffer.872*/873protected void checkSpace(int space) {874875int newSize = CurrentSize + space;876877if (bytes.length >= newSize)878return;879880byte[] newBytes = new byte[newSize];881882for (int i = 0; i < CurrentSize; i++)883newBytes[i] = bytes[i];884885bytes = newBytes;886}887888/**889* Replace count (1 - 8) bytes starting at offset off with the less890* significant bytes from the specified long value.891*892* @throws BoundException if offset and count are out of buffer bounds893*/894protected void putValueBytes(int off, long value, int count) throws BoundException {895if ((count <= 0) || (count > 8))896throw new TestBug("Illegal number of bytes of value to put: " + count);897898if (count > CurrentSize - off) {899throw new BoundException("Unable to put " + count + " bytes of value at " +900off + " (available bytes: " + (CurrentSize - off) + ")" );901}902903int shift = (count - 1) * 8;904for (int i = 0; i < count; i++) {905putByte(off++, (byte) ((value >>> shift) & 0xFF));906shift = shift - 8;907}908}909/**910* Appends the count (1 - 8) less significant bytes from the911* specified long value to the end of this buffer.912*/913protected void addValueBytes(long value, int count) throws BoundException {914if ((count <= 0) || (count > 8))915throw new TestBug("Illegal number of bytes of value to add: " + count);916917checkSpace(count);918919int where = CurrentSize;920CurrentSize += count;921922putValueBytes(where, value, count);923}924925/**926* Read count bytes (1-8) from this buffer at the specified927* position and returns a long value composed of these bytes.928*929* @throws BoundException if there are no so many bytes in the buffer930*/931public long getValueBytes(int off, int count) throws BoundException {932if ((count <= 0) || (count > 8))933throw new TestBug("Illegal number of bytes of value to get: " + count);934935long l = 0;936937for (int i = 0; i < count; i++) {938l = (l * 0x100) + ((long) getByte(off + i) & 0xFF);939}940941return l;942}943944/**945* Read count bytes (1-8) from this buffer at the current parser946* position and returns a long value composed of these bytes.947*948* @throws BoundException if there are no so many bytes in the buffer949*/950/*951protected long getValueBytes(int count) throws BoundException {952long value = getValueBytes(parseOffset);953parseOffset += count;954return value;955}956*/957958// ---959960private static String PadL(String source, int length, String what) {961962if (length <= 0)963return "";964965if (source.length() > length)966return PadL("", length, "*");967968while (source.length() < length)969source = what + source;970971return source;972}973974975private static String PadL(String source, int length) {976return PadL(source, length, " ");977}978979private static String PadR(String source, int length, String what) {980981if (length <= 0)982return "";983984if (source.length() > length)985return PadR("", length, "*");986987while (source.length() < length)988source = source + what;989990return source;991}992993private static String PadR(String source, int length) {994return PadR(source, length, " ");995}996997private static String Left(String source, int length) {998999if (length <= 0)1000return "";10011002if (length <= source.length())1003return source.substring(0, length);1004else1005return PadR(source, length);1006}10071008private static String Right(String source, int length) {10091010if (length <= 0)1011return "";10121013if (length <= source.length())1014return source.substring(source.length() - length, source.length());1015else1016return PadL(source, length);1017}10181019}102010211022