Home | History | Annotate | Download | only in jdwp
      1 /*
      2  * Licensed to the Apache Software Foundation (ASF) under one or more
      3  * contributor license agreements.  See the NOTICE file distributed with
      4  * this work for additional information regarding copyright ownership.
      5  * The ASF licenses this file to You under the Apache License, Version 2.0
      6  * (the "License"); you may not use this file except in compliance with
      7  * the License.  You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *
     15  *  See the License for the specific language governing permissions and
     16  *  limitations under the License.
     17  */
     18 
     19 /**
     20  * @author Khen G. Kim, Aleksey V. Yantsen
     21  */
     22 
     23 /**
     24  * Created on 10.01.2004
     25  */
     26 package org.apache.harmony.jpda.tests.framework.jdwp;
     27 
     28 import java.io.UnsupportedEncodingException;
     29 
     30 import org.apache.harmony.jpda.tests.framework.TestErrorException;
     31 import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants;
     32 import org.apache.harmony.jpda.tests.framework.jdwp.TypesLengths;
     33 
     34 /**
     35  * This base class represents JDWP packet.
     36  */
     37 public class Packet {
     38 
     39     public static final int REPLY_PACKET_FLAG = 0x80;
     40 
     41     public static final int FLAGS_INDEX = 8;
     42 
     43     public static final int HEADER_SIZE = 11;
     44 
     45     /**
     46      * The size in bytes of the BYTE type value.
     47      */
     48     protected static final int BYTE_SIZE = 1;
     49 
     50     /**
     51      * The size in bytes of the SHORT type value.
     52      */
     53     protected static final int SHORT_SIZE = 2;
     54 
     55     /**
     56      * The size in bytes of the INT type value.
     57      */
     58     protected static final int INT_SIZE = 4;
     59 
     60     /**
     61      * The size in bytes of the LONG type value.
     62      */
     63     protected static final int LONG_SIZE = 8;
     64 
     65     private static final int LENGTH_INDEX = 0;
     66 
     67     private static final int ID_INDEX = 4;
     68 
     69     private int id;
     70 
     71     private byte flags;
     72 
     73     private int length;
     74 
     75     private byte data[];
     76 
     77     private int reading_data_index;
     78 
     79     /**
     80      * A constructor that creates an empty CommandPacket with empty header
     81      * fields and no data.
     82      */
     83     public Packet() {
     84         reading_data_index = 0;
     85         data = new byte[0];
     86     }
     87 
     88     /**
     89      * A constructor that creates Packet from array of bytes including header
     90      * and data sections.
     91      *
     92      * @param p array of bytes for new packet.
     93      */
     94     public Packet(byte p[]) {
     95         length = (int) readFromByteArray(p, LENGTH_INDEX, INT_SIZE);
     96         if (length < HEADER_SIZE) {
     97             throw new TestErrorException(
     98                     "Packet creation error: size of packet = " + length
     99                             + "is less than header size = " + HEADER_SIZE);
    100         }
    101         id = (int) readFromByteArray(p, ID_INDEX, INT_SIZE);
    102         flags = p[FLAGS_INDEX];
    103         data = new byte[p.length - HEADER_SIZE];
    104         System.arraycopy(p, HEADER_SIZE, data, 0, p.length - HEADER_SIZE);
    105         reading_data_index = 0;
    106     }
    107 
    108     /**
    109      * Gets the length value of the header of the Packet.
    110      *
    111      * @return the length value of the header of the Packet.
    112      */
    113     public int getLength() {
    114         return length;
    115     }
    116 
    117     /**
    118      * Sets the id value of the header of the Packet.
    119      *
    120      * @param i
    121      *            the id value of the header of the Packet.
    122      */
    123     public void setId(int i) {
    124         id = i;
    125     }
    126 
    127     /**
    128      * Gets the id value of the header of the Packet.
    129      *
    130      * @return the id value of the header of the Packet.
    131      */
    132     public int getId() {
    133         return id;
    134     }
    135 
    136     /**
    137      * Sets the flags value of the header of the Packet.
    138      *
    139      * @param f
    140      *            the flags value of the header of the Packet.
    141      */
    142     public void setFlags(byte f) {
    143         flags = f;
    144     }
    145 
    146     /**
    147      * Gets the flags value of the header of the Packet.
    148      *
    149      * @return the flags value of the header of the Packet.
    150      */
    151     public byte getFlags() {
    152         return flags;
    153     }
    154 
    155     /**
    156      * Gets the flags value from the header of the Packet.
    157      *
    158      * @param tag
    159      *            Type tag (see JDWP.tag)
    160      * @return the flags value of the header of the Packet.
    161      */
    162     public boolean isValuePrimitiveType(byte tag) {
    163         switch (tag) {
    164         case JDWPConstants.Tag.ARRAY_TAG: {
    165             return false;
    166         }
    167         case JDWPConstants.Tag.BYTE_TAG: {
    168             return true;
    169         }
    170         case JDWPConstants.Tag.CHAR_TAG: {
    171             return true;
    172         }
    173         case JDWPConstants.Tag.OBJECT_TAG: {
    174             return false;
    175         }
    176         case JDWPConstants.Tag.FLOAT_TAG: {
    177             return true;
    178         }
    179         case JDWPConstants.Tag.DOUBLE_TAG: {
    180             return true;
    181         }
    182         case JDWPConstants.Tag.INT_TAG: {
    183             return true;
    184         }
    185         case JDWPConstants.Tag.LONG_TAG: {
    186             return true;
    187         }
    188         case JDWPConstants.Tag.SHORT_TAG: {
    189             return true;
    190         }
    191         case JDWPConstants.Tag.VOID_TAG: {
    192             return true;
    193         }
    194         case JDWPConstants.Tag.BOOLEAN_TAG: {
    195             return true;
    196         }
    197         case JDWPConstants.Tag.STRING_TAG: {
    198             return false;
    199         }
    200         case JDWPConstants.Tag.THREAD_TAG: {
    201             return false;
    202         }
    203         case JDWPConstants.Tag.THREAD_GROUP_TAG: {
    204             return false;
    205         }
    206         case JDWPConstants.Tag.CLASS_LOADER_TAG: {
    207             return false;
    208         }
    209         case JDWPConstants.Tag.CLASS_OBJECT_TAG: {
    210             return false;
    211         }
    212         case JDWPConstants.Tag.NO_TAG: {
    213             return true;
    214         }
    215         default: {
    216             throw new TestErrorException("Improper JDWP.tag value = " + tag);
    217         }
    218         }
    219     }
    220 
    221     /**
    222      * Sets the next value of the data of the Packet as byte.
    223      *
    224      * @param val
    225      *            the byte value.
    226      */
    227     public void setNextValueAsByte(byte val) {
    228         int new_data_size = data.length + BYTE_SIZE;
    229         byte data_temp[] = data;
    230         data = new byte[new_data_size];
    231         System.arraycopy(data_temp, 0, data, 0, new_data_size - BYTE_SIZE);
    232         data[new_data_size - BYTE_SIZE] = val;
    233     }
    234 
    235     /**
    236      * Gets the next value of the data of the Packet as byte.
    237      *
    238      * @return the next value of the data of the Packet as byte.
    239      */
    240     public byte getNextValueAsByte() {
    241         reading_data_index = reading_data_index + BYTE_SIZE;
    242         return data[reading_data_index - BYTE_SIZE];
    243     }
    244 
    245     /**
    246      * Sets the next value of the data of the Packet as boolean.
    247      *
    248      * @param val
    249      *            the boolean value.
    250      */
    251     public void setNextValueAsBoolean(boolean val) {
    252         int old_data_size = data.length;
    253         int new_data_size = old_data_size
    254                 + TypesLengths.getTypeLength(TypesLengths.BOOLEAN_ID);
    255         byte data_temp[] = data;
    256         data = new byte[new_data_size];
    257         System.arraycopy(data_temp, 0, data, 0, old_data_size);
    258         if (val) {
    259             data[old_data_size] = 1;
    260         } else {
    261             data[old_data_size] = 0;
    262         }
    263     }
    264 
    265     /**
    266      * Gets the next value of the data of the Packet as boolean.
    267      *
    268      * @return the next value of the data of the Packet as boolean.
    269      */
    270     public boolean getNextValueAsBoolean() {
    271         int res = (int) data[reading_data_index] & 0xFF;
    272         reading_data_index = reading_data_index
    273                 + TypesLengths.getTypeLength(TypesLengths.BOOLEAN_ID);
    274         return (res != 0);
    275     }
    276 
    277     /**
    278      * Sets the next value of the data of the Packet as short.
    279      *
    280      * @param val
    281      *            the short value.
    282      */
    283     public void setNextValueAsShort(short val) {
    284         int new_data_size = data.length
    285                 + TypesLengths.getTypeLength(TypesLengths.SHORT_ID);
    286         byte data_temp[] = data;
    287         data = new byte[new_data_size];
    288         System.arraycopy(data_temp, 0, data, 0, new_data_size
    289                 - TypesLengths.getTypeLength(TypesLengths.SHORT_ID));
    290         this.writeAtByteArray((long) val, data, new_data_size
    291                 - TypesLengths.getTypeLength(TypesLengths.SHORT_ID),
    292                 TypesLengths.getTypeLength(TypesLengths.SHORT_ID));
    293     }
    294 
    295     /**
    296      * Gets the next value of the data of the Packet as short.
    297      *
    298      * @return the next value of the data of the Packet as short.
    299      */
    300     public short getNextValueAsShort() {
    301         reading_data_index = reading_data_index
    302                 + TypesLengths.getTypeLength(TypesLengths.SHORT_ID);
    303         return (short) readFromByteArray(data, reading_data_index
    304                 - TypesLengths.getTypeLength(TypesLengths.SHORT_ID),
    305                 TypesLengths.getTypeLength(TypesLengths.SHORT_ID));
    306     }
    307 
    308     /**
    309      * Sets the next value of the data of the Packet as int.
    310      *
    311      * @param val
    312      *            the int value.
    313      */
    314     public void setNextValueAsInt(int val) {
    315         int new_data_size = data.length
    316                 + TypesLengths.getTypeLength(TypesLengths.INT_ID);
    317         byte data_temp[] = data;
    318         data = new byte[new_data_size];
    319         System.arraycopy(data_temp, 0, data, 0, new_data_size
    320                 - TypesLengths.getTypeLength(TypesLengths.INT_ID));
    321         this.writeAtByteArray((long) val, data, new_data_size
    322                 - TypesLengths.getTypeLength(TypesLengths.INT_ID), TypesLengths
    323                 .getTypeLength(TypesLengths.INT_ID));
    324     }
    325 
    326     /**
    327      * Gets the next value of the data of the Packet as int.
    328      *
    329      * @return the next value of the data of the Packet as int.
    330      */
    331     public int getNextValueAsInt() {
    332         reading_data_index = reading_data_index
    333                 + TypesLengths.getTypeLength(TypesLengths.INT_ID);
    334         return (int) readFromByteArray(data, reading_data_index
    335                 - TypesLengths.getTypeLength(TypesLengths.INT_ID), TypesLengths
    336                 .getTypeLength(TypesLengths.INT_ID));
    337     }
    338 
    339     /**
    340      * Sets the next value of the data of the Packet as double.
    341      *
    342      * @param dval
    343      *            the double value.
    344      */
    345     public void setNextValueAsDouble(double dval) {
    346         int new_data_size = data.length
    347                 + TypesLengths.getTypeLength(TypesLengths.DOUBLE_ID);
    348         byte data_temp[] = data;
    349         long val = Double.doubleToLongBits(dval);
    350         data = new byte[new_data_size];
    351         System.arraycopy(data_temp, 0, data, 0, new_data_size
    352                 - TypesLengths.getTypeLength(TypesLengths.DOUBLE_ID));
    353         this.writeAtByteArray((long) val, data, new_data_size
    354                 - TypesLengths.getTypeLength(TypesLengths.DOUBLE_ID),
    355                 TypesLengths.getTypeLength(TypesLengths.DOUBLE_ID));
    356     }
    357 
    358     /**
    359      * Gets the next value of the data of the Packet as double.
    360      *
    361      * @return the next value of the data of the Packet as double.
    362      */
    363     public double getNextValueAsDouble() {
    364         reading_data_index = reading_data_index
    365                 + TypesLengths.getTypeLength(TypesLengths.DOUBLE_ID);
    366         long res = readFromByteArray(data, reading_data_index
    367                 - TypesLengths.getTypeLength(TypesLengths.DOUBLE_ID),
    368                 TypesLengths.getTypeLength(TypesLengths.DOUBLE_ID));
    369 
    370         return Double.longBitsToDouble(res);
    371     }
    372 
    373     /**
    374      * Sets the next value of the data of the Packet as float.
    375      *
    376      * @param fval
    377      *            the float value.
    378      */
    379     public void setNextValueAsFloat(float fval) {
    380         int new_data_size = data.length
    381                 + TypesLengths.getTypeLength(TypesLengths.FLOAT_ID);
    382         byte data_temp[] = data;
    383         long val = Float.floatToIntBits(fval);
    384         data = new byte[new_data_size];
    385         System.arraycopy(data_temp, 0, data, 0, new_data_size
    386                 - TypesLengths.getTypeLength(TypesLengths.FLOAT_ID));
    387         this.writeAtByteArray((long) val, data, new_data_size
    388                 - TypesLengths.getTypeLength(TypesLengths.FLOAT_ID),
    389                 TypesLengths.getTypeLength(TypesLengths.FLOAT_ID));
    390     }
    391 
    392     /**
    393      * Gets the next value of the data of the Packet as float.
    394      *
    395      * @return the next value of the data of the Packet as float.
    396      */
    397     public float getNextValueAsFloat() {
    398         reading_data_index = reading_data_index
    399                 + TypesLengths.getTypeLength(TypesLengths.FLOAT_ID);
    400         long res = readFromByteArray(data, reading_data_index
    401                 - TypesLengths.getTypeLength(TypesLengths.FLOAT_ID),
    402                 TypesLengths.getTypeLength(TypesLengths.FLOAT_ID));
    403 
    404         return Float.intBitsToFloat((int) res);
    405     }
    406 
    407     /**
    408      * Sets the next value of the data of the Packet as char.
    409      *
    410      * @param val
    411      *            the char value.
    412      */
    413     public void setNextValueAsChar(char val) {
    414         int new_data_size = data.length
    415                 + TypesLengths.getTypeLength(TypesLengths.CHAR_ID);
    416         byte data_temp[] = data;
    417         data = new byte[new_data_size];
    418         System.arraycopy(data_temp, 0, data, 0, new_data_size
    419                 - TypesLengths.getTypeLength(TypesLengths.CHAR_ID));
    420         this.writeAtByteArray((long) val, data, new_data_size
    421                 - TypesLengths.getTypeLength(TypesLengths.CHAR_ID),
    422                 TypesLengths.getTypeLength(TypesLengths.CHAR_ID));
    423     }
    424 
    425     /**
    426      * Gets the next value of the data of the Packet as char.
    427      *
    428      * @return the next value of the data of the Packet as char.
    429      */
    430     public char getNextValueAsChar() {
    431         reading_data_index = reading_data_index
    432                 + TypesLengths.getTypeLength(TypesLengths.CHAR_ID);
    433         return (char) readFromByteArray(data, reading_data_index
    434                 - TypesLengths.getTypeLength(TypesLengths.CHAR_ID),
    435                 TypesLengths.getTypeLength(TypesLengths.CHAR_ID));
    436     }
    437 
    438     /**
    439      * Sets the next value of the data of the Packet as long.
    440      *
    441      * @param val
    442      *            the long value.
    443      */
    444     public void setNextValueAsLong(long val) {
    445         int new_data_size = data.length
    446                 + TypesLengths.getTypeLength(TypesLengths.LONG_ID);
    447         byte data_temp[] = data;
    448         data = new byte[new_data_size];
    449         System.arraycopy(data_temp, 0, data, 0, new_data_size
    450                 - TypesLengths.getTypeLength(TypesLengths.LONG_ID));
    451         this.writeAtByteArray(val, data, new_data_size
    452                 - TypesLengths.getTypeLength(TypesLengths.LONG_ID),
    453                 TypesLengths.getTypeLength(TypesLengths.LONG_ID));
    454     }
    455 
    456     /**
    457      * Gets the next value of the data of the Packet as long.
    458      *
    459      * @return the next value of the data of the Packet as long.
    460      */
    461     public long getNextValueAsLong() {
    462         reading_data_index = reading_data_index
    463                 + TypesLengths.getTypeLength(TypesLengths.LONG_ID);
    464         return readFromByteArray(data, reading_data_index
    465                 - TypesLengths.getTypeLength(TypesLengths.LONG_ID),
    466                 TypesLengths.getTypeLength(TypesLengths.LONG_ID));
    467     }
    468 
    469     /**
    470      * Sets the next value of the data of the Packet as String in the "UTF-8"
    471      * Charset.
    472      *
    473      * @param val
    474      *            the String in the "UTF-8" Charset.
    475      */
    476     public void setNextValueAsString(String val) {
    477         byte data_temp[] = data;
    478         byte val_as_bytes[];
    479         try {
    480             val_as_bytes = val.getBytes("UTF-8");
    481         } catch (UnsupportedEncodingException e) {
    482             throw new TestErrorException(e);
    483         }
    484         int new_data_size = data.length + val_as_bytes.length
    485                 + TypesLengths.getTypeLength(TypesLengths.INT_ID);
    486         data = new byte[new_data_size];
    487         System.arraycopy(data_temp, 0, data, 0, new_data_size
    488                 - val_as_bytes.length
    489                 - TypesLengths.getTypeLength(TypesLengths.INT_ID));
    490         this.writeAtByteArray((long) val_as_bytes.length, data, new_data_size
    491                 - val_as_bytes.length
    492                 - TypesLengths.getTypeLength(TypesLengths.INT_ID), TypesLengths
    493                 .getTypeLength(TypesLengths.INT_ID));
    494         System.arraycopy(val_as_bytes, 0, data, new_data_size
    495                 - val_as_bytes.length, val_as_bytes.length);
    496     }
    497 
    498     /**
    499      * Gets the next value of the data of the Packet as String in the "UTF-8"
    500      * Charset.
    501      *
    502      * @return the next value of the data of the Packet as String in the "UTF-8"
    503      *         Charset.
    504      */
    505     public String getNextValueAsString() {
    506         int string_length = this.getNextValueAsInt();
    507         String res = null;
    508         try {
    509             res = new String(data, reading_data_index, string_length, "UTF-8");
    510         } catch (UnsupportedEncodingException e) {
    511             throw new TestErrorException(e);
    512         }
    513         reading_data_index = reading_data_index + string_length;
    514         return res;
    515     }
    516 
    517     /**
    518      * Sets the next value of the data of the Packet as objectID VM-sensitive
    519      * value. If length is less than 8 bytes, the appropriate high bits in the
    520      * val value will be ignored.
    521      *
    522      * @param val
    523      *            the ObjectID value.
    524      */
    525     public void setNextValueAsObjectID(long val) {
    526         if (TypesLengths.getTypeLength(TypesLengths.OBJECT_ID) < 0
    527                 || TypesLengths.getTypeLength(TypesLengths.OBJECT_ID) > 8) {
    528             throw new TestErrorException("Improper ObjectID value length = "
    529                     + TypesLengths.getTypeLength(TypesLengths.OBJECT_ID));
    530         }
    531         int new_data_size = data.length
    532                 + TypesLengths.getTypeLength(TypesLengths.OBJECT_ID);
    533         byte data_temp[] = data;
    534         data = new byte[new_data_size];
    535         System.arraycopy(data_temp, 0, data, 0, new_data_size
    536                 - TypesLengths.getTypeLength(TypesLengths.OBJECT_ID));
    537         this.writeAtByteArray(val, data, new_data_size
    538                 - TypesLengths.getTypeLength(TypesLengths.OBJECT_ID),
    539                 TypesLengths.getTypeLength(TypesLengths.OBJECT_ID));
    540     }
    541 
    542     /**
    543      * Gets the next value of the data of the Packet as objectID VM-sensitive
    544      * value. If length is less than 8 bytes, the appropriate high bits in the
    545      * returned value can be ignored.
    546      *
    547      * @return the next value of the data of the Packet as VM-sensitive value.
    548      */
    549     public long getNextValueAsObjectID() {
    550         if (TypesLengths.getTypeLength(TypesLengths.OBJECT_ID) < 0
    551                 || TypesLengths.getTypeLength(TypesLengths.OBJECT_ID) > 8) {
    552             throw new TestErrorException("Improper ObjectID value length = "
    553                     + TypesLengths.getTypeLength(TypesLengths.OBJECT_ID) + "!");
    554         }
    555         reading_data_index = reading_data_index
    556                 + TypesLengths.getTypeLength(TypesLengths.OBJECT_ID);
    557         return readFromByteArray(data, reading_data_index
    558                 - TypesLengths.getTypeLength(TypesLengths.OBJECT_ID),
    559                 TypesLengths.getTypeLength(TypesLengths.OBJECT_ID));
    560     }
    561 
    562     /**
    563      * Sets the next value of the data of the Packet as ThreadID VM-sensitive
    564      * value. If length is less than 8 bytes, the appropriate high bits in the
    565      * val value will be ignored.
    566      *
    567      * @param val
    568      *            the ThreadID value.
    569      */
    570     public void setNextValueAsThreadID(long val) {
    571         this.setNextValueAsObjectID(val);
    572     }
    573 
    574     /**
    575      * Gets the next value of the data of the Packet as ThreadID VM-sensitive
    576      * value. If length is less than 8 bytes, the appropriate high bits in the
    577      * returned value can be ignored.
    578      *
    579      * @return the next value of the data of the Packet as VM-sensitive value.
    580      */
    581     public long getNextValueAsThreadID() {
    582         return this.getNextValueAsObjectID();
    583     }
    584 
    585     /**
    586      * Sets the next value of the data of the Packet as ThreadGroupID
    587      * VM-sensitive value. If length is less than 8 bytes, the appropriate high
    588      * bits in the val value will be ignored.
    589      *
    590      * @param val
    591      *            the ThreadGroupID value.
    592      */
    593     public void setNextValueAsThreadGroupID(long val) {
    594         this.setNextValueAsObjectID(val);
    595     }
    596 
    597     /**
    598      * Gets the next value of the data of the Packet as ThreadGroupID
    599      * VM-sensitive value. If length is less than 8 bytes, the appropriate high
    600      * bits in the returned value can be ignored.
    601      *
    602      * @return the next value of the data of the Packet as VM-sensitive value.
    603      */
    604     public long getNextValueAsThreadGroupID() {
    605         return this.getNextValueAsObjectID();
    606     }
    607 
    608     /**
    609      * Sets the next value of the data of the Packet as StringID VM-sensitive
    610      * value. If length is less than 8 bytes, the appropriate high bits in the
    611      * val value will be ignored.
    612      *
    613      * @param val
    614      *            the StringID value.
    615      */
    616     public void setNextValueAsStringID(long val) {
    617         this.setNextValueAsObjectID(val);
    618     }
    619 
    620     /**
    621      * Gets the next value of the data of the Packet as StringID VM-sensitive
    622      * value. If length is less than 8 bytes, the appropriate high bits in the
    623      * returned value can be ignored.
    624      *
    625      * @return the next value of the data of the Packet as VM-sensitive value.
    626      */
    627     public long getNextValueAsStringID() {
    628         return this.getNextValueAsObjectID();
    629     }
    630 
    631     /**
    632      * Sets the next value of the data of the Packet as ClassLoaderID
    633      * VM-sensitive value. If length is less than 8 bytes, the appropriate high
    634      * bits in the val value will be ignored.
    635      *
    636      * @param val
    637      *            the ClassLoaderID value.
    638      */
    639     public void setNextValueAsClassLoaderID(long val) {
    640         this.setNextValueAsObjectID(val);
    641     }
    642 
    643     /**
    644      * Gets the next value of the data of the Packet as ClassLoaderID
    645      * VM-sensitive value. If length is less than 8 bytes, the appropriate high
    646      * bits in the returned value can be ignored.
    647      *
    648      * @return the next value of the data of the Packet as VM-sensitive value.
    649      */
    650     public long getNextValueAsClassLoaderID() {
    651         return this.getNextValueAsObjectID();
    652     }
    653 
    654     /**
    655      * Sets the next value of the data of the Packet as ClassObjectID
    656      * VM-sensitive value. If length is less than 8 bytes, the appropriate high
    657      * bits in the val value will be ignored.
    658      *
    659      * @param val
    660      *            the ClassObjectID value.
    661      */
    662     public void setNextValueAsClassObjectID(long val) {
    663         this.setNextValueAsObjectID(val);
    664     }
    665 
    666     /**
    667      * Gets the next value of the data of the Packet as ClassObjectID
    668      * VM-sensitive value. If length is less than 8 bytes, the appropriate high
    669      * bits in the returned value can be ignored.
    670      *
    671      * @return the next value of the data of the Packet as VM-sensitive value.
    672      */
    673     public long getNextValueAsClassObjectID() {
    674         return this.getNextValueAsObjectID();
    675     }
    676 
    677     /**
    678      * Sets the next value of the data of the Packet as ArrayID VM-sensitive
    679      * value. If length is less than 8 bytes, the appropriate high bits in the
    680      * val value will be ignored.
    681      *
    682      * @param val
    683      *            the ArrayID value.
    684      */
    685     public void setNextValueAsArrayID(long val) {
    686         this.setNextValueAsObjectID(val);
    687     }
    688 
    689     /**
    690      * Gets the next value of the data of the Packet as ArrayID VM-sensitive
    691      * value. If length is less than 8 bytes, the appropriate high bits in the
    692      * returned value can be ignored.
    693      *
    694      * @return the next value of the data of the Packet as VM-sensitive value.
    695      */
    696     public long getNextValueAsClassArrayID() {
    697         return this.getNextValueAsObjectID();
    698     }
    699 
    700     /**
    701      * Sets the next value of the data of the Packet as ReferenceTypeID
    702      * VM-sensitive value. If length is less than 8 bytes, the appropriate high
    703      * bits in the val value will be ignored.
    704      *
    705      * @param val
    706      *            the ReferenceTypeID value.
    707      */
    708     public void setNextValueAsReferenceTypeID(long val) {
    709         final int referenceTypeIdSize = TypesLengths.getTypeLength(TypesLengths.REFERENCE_TYPE_ID);
    710         if (referenceTypeIdSize < 0 || referenceTypeIdSize > 8) {
    711             throw new TestErrorException(
    712                     "Improper ReferenceTypeID value length = " + referenceTypeIdSize);
    713         }
    714         int new_data_size = data.length + referenceTypeIdSize;
    715         byte data_temp[] = data;
    716         data = new byte[new_data_size];
    717         System.arraycopy(data_temp, 0, data, 0, new_data_size - referenceTypeIdSize);
    718         this.writeAtByteArray(val, data, new_data_size - referenceTypeIdSize, referenceTypeIdSize);
    719     }
    720 
    721     /**
    722      * Gets the next value of the data of the Packet as ReferenceTypeID
    723      * VM-sensitive value. If length is less than 8 bytes, the appropriate high
    724      * bits in the returned value can be ignored.
    725      *
    726      * @return the next value of the data of the Packet as VM-sensitive value.
    727      */
    728     public long getNextValueAsReferenceTypeID() {
    729         final int referenceTypeIdSize = TypesLengths.getTypeLength(TypesLengths.REFERENCE_TYPE_ID);
    730         if (referenceTypeIdSize < 0 || referenceTypeIdSize > 8) {
    731             throw new TestErrorException(
    732                     "Improper ReferenceTypeID value length = " + referenceTypeIdSize + "!");
    733         }
    734         reading_data_index = reading_data_index + referenceTypeIdSize;
    735         return readFromByteArray(data, reading_data_index - referenceTypeIdSize,
    736                 referenceTypeIdSize);
    737     }
    738 
    739     /**
    740      * Sets the next value of the data of the Packet as ClassID VM-sensitive
    741      * value. If length is less than 8 bytes, the appropriate high bits in the
    742      * val value will be ignored.
    743      *
    744      * @param val
    745      *            the ClassID value.
    746      */
    747     public void setNextValueAsClassID(long val) {
    748         this.setNextValueAsReferenceTypeID(val);
    749     }
    750 
    751     /**
    752      * Gets the next value of the data of the Packet as ClassID VM-sensitive
    753      * value. If length is less than 8 bytes, the appropriate high bits in the
    754      * returned value can be ignored.
    755      *
    756      * @return the next value of the data of the Packet as VM-sensitive value.
    757      */
    758     public long getNextValueAsClassID() {
    759         return this.getNextValueAsReferenceTypeID();
    760     }
    761 
    762     /**
    763      * Sets the next value of the data of the Packet as InterfaceID VM-sensitive
    764      * value. If length is less than 8 bytes, the appropriate high bits in the
    765      * val value will be ignored.
    766      *
    767      * @param val
    768      *            the InterfaceID value.
    769      */
    770     public void setNextValueAsInterfaceID(long val) {
    771         this.setNextValueAsReferenceTypeID(val);
    772     }
    773 
    774     /**
    775      * Gets the next value of the data of the Packet as InterfaceID VM-sensitive
    776      * value. If length is less than 8 bytes, the appropriate high bits in the
    777      * returned value can be ignored.
    778      *
    779      * @return the next value of the data of the Packet as VM-sensitive value.
    780      */
    781     public long getNextValueAsInterfaceID() {
    782         return this.getNextValueAsReferenceTypeID();
    783     }
    784 
    785     /**
    786      * Sets the next value of the data of the Packet as ArrayTypeID VM-sensitive
    787      * value. If length is less than 8 bytes, the appropriate high bits in the
    788      * val value will be ignored.
    789      *
    790      * @param val
    791      *            the ArrayTypeID value.
    792      */
    793     public void setNextValueAsArrayTypeID(long val) {
    794         this.setNextValueAsReferenceTypeID(val);
    795     }
    796 
    797     /**
    798      * Gets the next value of the data of the Packet as ArrayTypeID VM-sensitive
    799      * value. If length is less than 8 bytes, the appropriate high bits in the
    800      * returned value can be ignored.
    801      *
    802      * @return the next value of the data of the Packet as VM-sensitive value.
    803      */
    804     public long getNextValueAsArrayTypeID() {
    805         return this.getNextValueAsReferenceTypeID();
    806     }
    807 
    808     /**
    809      * Sets the next value of the data of the Packet as tagged-objectID
    810      * VM-sensitive value. If length is less than 8 bytes, the appropriate high
    811      * bits in the val value will be ignored.
    812      *
    813      * @param taggedObject
    814      *            TaggedObject value.
    815      */
    816     public void setNextValueAsTaggedObject(TaggedObject taggedObject) {
    817         this.setNextValueAsByte(taggedObject.tag);
    818         this.setNextValueAsObjectID(taggedObject.objectID);
    819     }
    820 
    821     /**
    822      * Gets the next value of the data of the Packet as tagged-objectID
    823      * VM-sensitive value. If length is less than 8 bytes, the appropriate high
    824      * bits in the returned value can be ignored.
    825      *
    826      * @return the next value of the data of the Packet as VM-sensitive value.
    827      */
    828     public TaggedObject getNextValueAsTaggedObject() {
    829         if (TypesLengths.getTypeLength(TypesLengths.OBJECT_ID) < 0
    830                 || TypesLengths.getTypeLength(TypesLengths.OBJECT_ID) > 8) {
    831             throw new TestErrorException("Improper ObjectID value length = "
    832                     + TypesLengths.getTypeLength(TypesLengths.OBJECT_ID));
    833         }
    834         TaggedObject taggedObject = new TaggedObject();
    835         taggedObject.tag = this.getNextValueAsByte();
    836         taggedObject.objectID = this.getNextValueAsObjectID();
    837         return taggedObject;
    838     }
    839 
    840     /**
    841      * Sets the next value of the data of the Packet as MethodID VM-sensitive
    842      * value. If length is less than 8 bytes, the appropriate high bits in the
    843      * val value will be ignored.
    844      *
    845      * @param methodID
    846      *            MethodID value.
    847      */
    848     public void setNextValueAsMethodID(long methodID) {
    849         if (TypesLengths.getTypeLength(TypesLengths.METHOD_ID) < 0
    850                 || TypesLengths.getTypeLength(TypesLengths.METHOD_ID) > 8) {
    851             throw new TestErrorException("Improper MethodID value length = "
    852                     + TypesLengths.getTypeLength(TypesLengths.METHOD_ID));
    853         }
    854         int new_data_size = data.length
    855                 + TypesLengths.getTypeLength(TypesLengths.METHOD_ID);
    856         byte data_temp[] = data;
    857         data = new byte[new_data_size];
    858         System.arraycopy(data_temp, 0, data, 0, new_data_size
    859                 - TypesLengths.getTypeLength(TypesLengths.METHOD_ID));
    860         this.writeAtByteArray(methodID, data, new_data_size
    861                 - TypesLengths.getTypeLength(TypesLengths.METHOD_ID),
    862                 TypesLengths.getTypeLength(TypesLengths.METHOD_ID));
    863     }
    864 
    865     /**
    866      * Gets the next value of the data of the Packet as MethodID VM-sensitive
    867      * value. If length is less than 8 bytes, the appropriate high bits in the
    868      * returned value can be ignored.
    869      *
    870      * @return the next value of the data of the Packet as VM-sensitive value.
    871      */
    872     public long getNextValueAsMethodID() {
    873         if (TypesLengths.getTypeLength(TypesLengths.METHOD_ID) < 0
    874                 || TypesLengths.getTypeLength(TypesLengths.METHOD_ID) > 8) {
    875             throw new TestErrorException("Improper MethodID value length = "
    876                     + TypesLengths.getTypeLength(TypesLengths.METHOD_ID));
    877         }
    878         reading_data_index = reading_data_index
    879                 + TypesLengths.getTypeLength(TypesLengths.METHOD_ID);
    880         long result = readFromByteArray(data, reading_data_index
    881                 - TypesLengths.getTypeLength(TypesLengths.METHOD_ID),
    882                 TypesLengths.getTypeLength(TypesLengths.METHOD_ID));
    883         return result;
    884     }
    885 
    886     /**
    887      * Sets the next value of the data of the Packet as FieldID VM-sensitive
    888      * value. If length is less than 8 bytes, the appropriate high bits in the
    889      * val value will be ignored.
    890      *
    891      * @param fieldID
    892      *            FieldID value.
    893      */
    894     public void setNextValueAsFieldID(long fieldID) {
    895         if (TypesLengths.getTypeLength(TypesLengths.FIELD_ID) < 0
    896                 || TypesLengths.getTypeLength(TypesLengths.FIELD_ID) > 8) {
    897             throw new TestErrorException("Improper FieldID value length = "
    898                     + TypesLengths.getTypeLength(TypesLengths.FIELD_ID));
    899         }
    900         int new_data_size = data.length
    901                 + TypesLengths.getTypeLength(TypesLengths.FIELD_ID);
    902         byte data_temp[] = data;
    903         data = new byte[new_data_size];
    904         System.arraycopy(data_temp, 0, data, 0, new_data_size
    905                 - TypesLengths.getTypeLength(TypesLengths.FIELD_ID));
    906         this.writeAtByteArray(fieldID, data, new_data_size
    907                 - TypesLengths.getTypeLength(TypesLengths.FIELD_ID),
    908                 TypesLengths.getTypeLength(TypesLengths.FIELD_ID));
    909     }
    910 
    911     /**
    912      * Gets the next value of the data of the Packet as FieldID VM-sensitive
    913      * value. If length is less than 8 bytes, the appropriate high bits in the
    914      * returned value can be ignored.
    915      *
    916      * @return the next value of the data of the Packet as VM-sensitive value.
    917      */
    918     public long getNextValueAsFieldID() {
    919         if (TypesLengths.getTypeLength(TypesLengths.FIELD_ID) < 0
    920                 || TypesLengths.getTypeLength(TypesLengths.FIELD_ID) > 8) {
    921             throw new TestErrorException("Improper FieldID value length = "
    922                     + TypesLengths.getTypeLength(TypesLengths.FIELD_ID));
    923         }
    924         reading_data_index = reading_data_index
    925                 + TypesLengths.getTypeLength(TypesLengths.FIELD_ID);
    926         long result = readFromByteArray(data, reading_data_index
    927                 - TypesLengths.getTypeLength(TypesLengths.FIELD_ID),
    928                 TypesLengths.getTypeLength(TypesLengths.FIELD_ID));
    929         return result;
    930     }
    931 
    932     /**
    933      * Sets the next value of the data of the Packet as FrameID VM-sensitive
    934      * value. If length is less than 8 bytes, the appropriate high bits in the
    935      * val value will be ignored.
    936      *
    937      * @param frameID
    938      *            FrameID value.
    939      */
    940     public void setNextValueAsFrameID(long frameID) {
    941         if (TypesLengths.getTypeLength(TypesLengths.FRAME_ID) < 0
    942                 || TypesLengths.getTypeLength(TypesLengths.FRAME_ID) > 8) {
    943             throw new TestErrorException("Improper FrameID value length = "
    944                     + TypesLengths.getTypeLength(TypesLengths.FRAME_ID));
    945         }
    946         int new_data_size = data.length
    947                 + TypesLengths.getTypeLength(TypesLengths.FRAME_ID);
    948         byte data_temp[] = data;
    949         data = new byte[new_data_size];
    950         System.arraycopy(data_temp, 0, data, 0, new_data_size
    951                 - TypesLengths.getTypeLength(TypesLengths.FRAME_ID));
    952         this.writeAtByteArray(frameID, data, new_data_size
    953                 - TypesLengths.getTypeLength(TypesLengths.FRAME_ID),
    954                 TypesLengths.getTypeLength(TypesLengths.FRAME_ID));
    955     }
    956 
    957     /**
    958      * Gets the next value of the data of the Packet as FrameID VM-sensitive
    959      * value. If length is less than 8 bytes, the appropriate high bits in the
    960      * returned value can be ignored.
    961      *
    962      * @return the next value of the data of the Packet as VM-sensitive value.
    963      */
    964     public long getNextValueAsFrameID() {
    965         if (TypesLengths.getTypeLength(TypesLengths.FRAME_ID) < 0
    966                 || TypesLengths.getTypeLength(TypesLengths.FRAME_ID) > 8) {
    967             throw new TestErrorException("Improper FrameID value length = "
    968                     + TypesLengths.getTypeLength(TypesLengths.FRAME_ID));
    969         }
    970         reading_data_index = reading_data_index
    971                 + TypesLengths.getTypeLength(TypesLengths.FRAME_ID);
    972         long result = readFromByteArray(data, reading_data_index
    973                 - TypesLengths.getTypeLength(TypesLengths.FRAME_ID),
    974                 TypesLengths.getTypeLength(TypesLengths.FRAME_ID));
    975         return result;
    976     }
    977 
    978     /**
    979      * Sets the next value of the data of the Packet as Location VM-sensitive
    980      * value. If length is less than 8 bytes, the appropriate high bits in the
    981      * val value will be ignored.
    982      *
    983      * @param location
    984      *            Location value.
    985      */
    986     public void setNextValueAsLocation(Location location) {
    987         this.setNextValueAsByte(location.tag);
    988         this.setNextValueAsClassID(location.classID);
    989         this.setNextValueAsMethodID(location.methodID);
    990         this.setNextValueAsLong(location.index);
    991     }
    992 
    993     /**
    994      * Gets the next value of the data of the Packet as Location VM-sensitive
    995      * value. If length is less than 8 bytes, the appropriate high bits in the
    996      * returned value can be ignored.
    997      *
    998      * @return the next value of the data of the Packet as VM-sensitive value.
    999      */
   1000     public Location getNextValueAsLocation() {
   1001         Location location = new Location();
   1002         location.tag = this.getNextValueAsByte();
   1003         location.classID = this.getNextValueAsClassID();
   1004         location.methodID = this.getNextValueAsMethodID();
   1005         location.index = this.getNextValueAsLong();
   1006         return location;
   1007     }
   1008 
   1009     /**
   1010      * Sets the next value of the data of the Packet as Value VM-sensitive
   1011      * value. If length is less than 8 bytes, the appropriate high bits in the
   1012      * val value will be ignored.
   1013      *
   1014      * @param value
   1015      *            Value value.
   1016      * @throws UnsupportedEncodingException
   1017      */
   1018     public void setNextValueAsValue(Value value) {
   1019         this.setNextValueAsByte(value.getTag());
   1020         setNextValueAsUntaggedValue(value);
   1021     }
   1022 
   1023     /**
   1024      * Gets the next value of the data of the Packet as Value VM-sensitive
   1025      * value. If length is less than 8 bytes, the appropriate high bits in the
   1026      * returned value can be ignored.
   1027      *
   1028      * @return the next value of the data of the Packet as VM-sensitive value.
   1029      */
   1030     public Value getNextValueAsValue() {
   1031         byte tag = this.getNextValueAsByte();
   1032         return getNextValueAsUntaggedValue(tag);
   1033     }
   1034 
   1035     /**
   1036      * Sets the next value of the data of the Packet as UntaggedValue
   1037      * VM-sensitive value. If length is less than 8 bytes, the appropriate high
   1038      * bits in the val value will be ignored.
   1039      *
   1040      * @param value
   1041      *            UntaggedValue value.
   1042      * @throws UnsupportedEncodingException
   1043      */
   1044     public void setNextValueAsUntaggedValue(Value value) {
   1045         switch (value.getTag()) {
   1046         case JDWPConstants.Tag.BOOLEAN_TAG:
   1047             this.setNextValueAsBoolean(value.getBooleanValue());
   1048             break;
   1049         case JDWPConstants.Tag.BYTE_TAG:
   1050             this.setNextValueAsByte(value.getByteValue());
   1051             break;
   1052         case JDWPConstants.Tag.CHAR_TAG:
   1053             this.setNextValueAsChar(value.getCharValue());
   1054             break;
   1055         case JDWPConstants.Tag.DOUBLE_TAG:
   1056             this.setNextValueAsDouble(value.getDoubleValue());
   1057             break;
   1058         case JDWPConstants.Tag.FLOAT_TAG:
   1059             this.setNextValueAsFloat(value.getFloatValue());
   1060             break;
   1061         case JDWPConstants.Tag.INT_TAG:
   1062             this.setNextValueAsInt(value.getIntValue());
   1063             break;
   1064         case JDWPConstants.Tag.LONG_TAG:
   1065             this.setNextValueAsLong(value.getLongValue());
   1066             break;
   1067         case JDWPConstants.Tag.SHORT_TAG:
   1068             this.setNextValueAsShort(value.getShortValue());
   1069             break;
   1070         case JDWPConstants.Tag.VOID_TAG:
   1071             break;
   1072         case JDWPConstants.Tag.STRING_TAG:
   1073         case JDWPConstants.Tag.ARRAY_TAG:
   1074         case JDWPConstants.Tag.CLASS_LOADER_TAG:
   1075         case JDWPConstants.Tag.CLASS_OBJECT_TAG:
   1076         case JDWPConstants.Tag.OBJECT_TAG:
   1077         case JDWPConstants.Tag.THREAD_GROUP_TAG:
   1078         case JDWPConstants.Tag.THREAD_TAG:
   1079             this.setNextValueAsObjectID(value.getLongValue());
   1080             break;
   1081         default:
   1082             throw new TestErrorException("Illegal tag value = "
   1083                     + value.getTag());
   1084         }
   1085     }
   1086 
   1087     /**
   1088      * Gets the next value of the data of the Packet as UntaggedValue
   1089      * VM-sensitive value. If length is less than 8 bytes, the appropriate high
   1090      * bits in the returned value can be ignored.
   1091      *
   1092      * @return the next value of the data of the Packet as VM-sensitive value.
   1093      */
   1094     public Value getNextValueAsUntaggedValue(byte tag) {
   1095         switch (tag) {
   1096             case JDWPConstants.Tag.BOOLEAN_TAG:
   1097                 return Value.createBoolean(this.getNextValueAsBoolean());
   1098             case JDWPConstants.Tag.BYTE_TAG:
   1099                 return Value.createByte(this.getNextValueAsByte());
   1100             case JDWPConstants.Tag.CHAR_TAG:
   1101                 return Value.createChar(this.getNextValueAsChar());
   1102             case JDWPConstants.Tag.DOUBLE_TAG:
   1103                 return Value.createDouble(this.getNextValueAsDouble());
   1104             case JDWPConstants.Tag.FLOAT_TAG:
   1105                 return Value.createFloat(this.getNextValueAsFloat());
   1106             case JDWPConstants.Tag.INT_TAG:
   1107                 return Value.createInt(this.getNextValueAsInt());
   1108             case JDWPConstants.Tag.LONG_TAG:
   1109                 return Value.createLong(this.getNextValueAsLong());
   1110             case JDWPConstants.Tag.SHORT_TAG:
   1111                 return Value.createShort(this.getNextValueAsShort());
   1112             case JDWPConstants.Tag.STRING_TAG:
   1113             case JDWPConstants.Tag.ARRAY_TAG:
   1114             case JDWPConstants.Tag.CLASS_LOADER_TAG:
   1115             case JDWPConstants.Tag.CLASS_OBJECT_TAG:
   1116             case JDWPConstants.Tag.OBJECT_TAG:
   1117             case JDWPConstants.Tag.THREAD_GROUP_TAG:
   1118             case JDWPConstants.Tag.THREAD_TAG:
   1119                 return Value.createObjectValue(tag, this.getNextValueAsObjectID());
   1120             case JDWPConstants.Tag.VOID_TAG:
   1121                 // no bytes to read.
   1122                 return null;
   1123             default:
   1124                 throw new TestErrorException("Illegal tag value = " + tag);
   1125         }
   1126     }
   1127 
   1128     /**
   1129      * Sets the next value of the data of the Packet as ArrayRegion VM-sensitive
   1130      * value. If length is less than 8 bytes, the appropriate high bits in the
   1131      * val value will be ignored.
   1132      *
   1133      * @param array
   1134      *            ArrayRegion value.
   1135      * @throws UnsupportedEncodingException
   1136      */
   1137     // public void setNextValueAsArrayRegion(ArrayRegion array) throws
   1138     // UnsupportedEncodingException {
   1139     public void setNextValueAsArrayRegion(ArrayRegion array) {
   1140         this.setNextValueAsByte(array.getTag());
   1141         this.setNextValueAsInt(array.getLength());
   1142         for (int i = 0; i < array.getLength(); i++) {
   1143             if (isValuePrimitiveType(array.getTag())) {
   1144                 switch (array.getTag()) {
   1145                 case JDWPConstants.Tag.BOOLEAN_TAG:
   1146                     this.setNextValueAsBoolean(array.getValue(i)
   1147                             .getBooleanValue());
   1148                     break;
   1149                 case JDWPConstants.Tag.BYTE_TAG:
   1150                     this.setNextValueAsByte(array.getValue(i).getByteValue());
   1151                     break;
   1152                 case JDWPConstants.Tag.DOUBLE_TAG:
   1153                     this.setNextValueAsDouble(array.getValue(i)
   1154                             .getDoubleValue());
   1155                     break;
   1156                 case JDWPConstants.Tag.FLOAT_TAG:
   1157                     this.setNextValueAsFloat(array.getValue(i).getFloatValue());
   1158                     break;
   1159                 case JDWPConstants.Tag.INT_TAG:
   1160                     this.setNextValueAsInt(array.getValue(i).getIntValue());
   1161                     break;
   1162                 case JDWPConstants.Tag.LONG_TAG:
   1163                     this.setNextValueAsLong(array.getValue(i).getLongValue());
   1164                     break;
   1165                 case JDWPConstants.Tag.SHORT_TAG:
   1166                     this.setNextValueAsShort(array.getValue(i).getShortValue());
   1167                     break;
   1168                 default:
   1169                     throw new TestErrorException("Illegal tag value = "
   1170                             + array.getTag());
   1171                 }
   1172             } else {
   1173                 this.setNextValueAsValue(array.getValue(i));
   1174             }
   1175         }
   1176     }
   1177 
   1178     /**
   1179      * Gets the next value of the data of the Packet as ArrayRegion VM-sensitive
   1180      * value. If length is less than 8 bytes, the appropriate high bits in the
   1181      * returned value can be ignored.
   1182      *
   1183      * @return the next value of the data of the Packet as VM-sensitive value.
   1184      */
   1185     public ArrayRegion getNextValueAsArrayRegion() {
   1186         byte array_tag = this.getNextValueAsByte();
   1187         int array_length = this.getNextValueAsInt();
   1188 
   1189         ArrayRegion array = new ArrayRegion(array_tag, array_length);
   1190 
   1191         for (int i = 0; i < array_length; i++) {
   1192             if (isValuePrimitiveType(array_tag))
   1193                 array.setValue(i, this.getNextValueAsUntaggedValue(array_tag));
   1194             else
   1195                 array.setValue(i, this.getNextValueAsValue());
   1196         }
   1197         return array;
   1198     }
   1199 
   1200     /**
   1201      * Gets the representation of the Packet as array of bytes in the JDWP
   1202      * format including header and data sections.
   1203      *
   1204      * @return bytes representation of this packet
   1205      */
   1206     public byte[] toBytesArray() {
   1207         byte res[] = new byte[data.length + HEADER_SIZE];
   1208         writeAtByteArray(data.length + HEADER_SIZE, res, LENGTH_INDEX, INT_SIZE);
   1209         writeAtByteArray(id, res, ID_INDEX, INT_SIZE);
   1210         res[FLAGS_INDEX] = flags;
   1211         System.arraycopy(data, 0, res, HEADER_SIZE, data.length);
   1212         return res;
   1213     }
   1214 
   1215     /**
   1216      * Reads value from array of bytes ar[] starting form index and reading size
   1217      * bytes. If size is less than 8, the appropriate high bits in the resulting
   1218      * long value will be zero.
   1219      *
   1220      * @param ar
   1221      *            the array of bytes where the value is read from.
   1222      * @param from
   1223      *            index to start reading bytes.
   1224      * @param size
   1225      *            number of bytes to read
   1226      */
   1227     protected static long readFromByteArray(byte ar[], int from, int size) {
   1228         long res = 0;
   1229         byte temp;
   1230         for (int i = 0; i < size; i++) {
   1231             temp = ar[from + i];
   1232             res = (res << 8) | (((long) temp) & 0xFF);
   1233         }
   1234         return res;
   1235     }
   1236 
   1237     /**
   1238      * Tells whether the packet is reply.
   1239      *
   1240      * @return true if this packet is reply, false if it is command
   1241      */
   1242     public boolean isReply() {
   1243         return (flags & REPLY_PACKET_FLAG) != 0;
   1244     }
   1245 
   1246     /**
   1247      * Checks whether all data has been read from the packet.
   1248      *
   1249      * @return boolean
   1250      */
   1251     public boolean isAllDataRead() {
   1252         return reading_data_index == data.length;
   1253     }
   1254 
   1255     /**
   1256      * Writes value - val to the array of bytes ar[], beginning from index - to,
   1257      * size of value is - size bytes. If size is less than 8, the appropriate
   1258      * high bits in the val value will be ignored.
   1259      *
   1260      * @param val
   1261      *            the value, which will be written in the array.
   1262      * @param ar
   1263      *            the array of bytes where the value is read from.
   1264      * @param to
   1265      *            the beginning index in the array of bytes.
   1266      * @param size
   1267      *            size of value in bytes.
   1268      */
   1269     protected void writeAtByteArray(long val, byte ar[], int to, int size) {
   1270         for (int i = 0; i < size; i++) {
   1271             ar[to + i] = (byte) (val >> 8 * (size - 1 - i));
   1272         }
   1273     }
   1274 
   1275     /**
   1276      * Returns true if this bytes array can be interpreted as reply packet.
   1277      *
   1278      * @param p
   1279      *            bytes representation of packet
   1280      * @return true or false
   1281      */
   1282     public static boolean isReply(byte[] p) {
   1283         if (p.length < FLAGS_INDEX)
   1284             return false;
   1285         return (p[FLAGS_INDEX] & REPLY_PACKET_FLAG) != 0;
   1286     }
   1287 
   1288     /**
   1289      * Returns packet length from header of given packet bytes.
   1290      *
   1291      * @param p
   1292      *            bytes representation of packet
   1293      * @return true or false
   1294      */
   1295     public static int getPacketLength(byte[] p) {
   1296         return (int) readFromByteArray(p, LENGTH_INDEX, INT_SIZE);
   1297     }
   1298 
   1299     /**
   1300      * Enwraps this bytes array either to ReplyPacket or EventPacket instance,
   1301      * according to result of isReply().
   1302      *
   1303      * @param p
   1304      *            bytes array to enwrap into packet
   1305      * @return new created ReplyPacket or CommandPacket
   1306      */
   1307     public static Packet interpretPacket(byte[] p) {
   1308         if (p.length < HEADER_SIZE)
   1309             throw new TestErrorException("Wrong packet");
   1310         if (Packet.isReply(p))
   1311             return new ReplyPacket(p);
   1312         return new EventPacket(p);
   1313     }
   1314 }
   1315