120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen/* 220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * Copyright (C) 2016 The Android Open Source Project 320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * 420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * Licensed under the Apache License, Version 2.0 (the "License"); 520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * you may not use this file except in compliance with the License. 620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * You may obtain a copy of the License at 720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * 820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * http://www.apache.org/licenses/LICENSE-2.0 920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * 1020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * Unless required by applicable law or agreed to in writing, software 1120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * distributed under the License is distributed on an "AS IS" BASIS, 1220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * See the License for the specific language governing permissions and 1420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * limitations under the License. 1520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen */ 1620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen 1720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohenpackage android.net.wifi.nan; 1820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen 1920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohenimport libcore.io.Memory; 2020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen 2120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohenimport java.nio.BufferOverflowException; 2220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohenimport java.nio.ByteOrder; 2320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohenimport java.util.Iterator; 2420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen 2520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen/** 2620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * Utility class to construct and parse byte arrays using the TLV format - 2720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * Type/Length/Value format. The utilities accept a configuration of the size of 2820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * the Type field and the Length field. A Type field size of 0 is allowed - 2920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * allowing usage for LV (no T) array formats. 3020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * 3120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * @hide PROPOSED_NAN_API 3220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen */ 3320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohenpublic class TlvBufferUtils { 3420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen private TlvBufferUtils() { 3520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen // no reason to ever create this class 3620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } 3720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen 3820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen /** 3920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * Utility class to construct byte arrays using the TLV format - 4020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * Type/Length/Value. 4120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * <p> 4220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * A constructor is created specifying the size of the Type (T) and Length 4320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * (L) fields. A specification of zero size T field is allowed - resulting 4420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * in LV type format. 4520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * <p> 4620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * The byte array is either provided (using 4720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * {@link TlvConstructor#wrap(byte[])}) or allocated (using 4820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * {@link TlvConstructor#allocate(int)}). 4920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * <p> 5020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * Values are added to the structure using the {@code TlvConstructor.put*()} 5120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * methods. 5220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * <p> 5320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * The final byte array is obtained using {@link TlvConstructor#getArray()} 5420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * and {@link TlvConstructor#getActualLength()} methods. 5520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen */ 5620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen public static class TlvConstructor { 5720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen private int mTypeSize; 5820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen private int mLengthSize; 5920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen 6020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen private byte[] mArray; 6120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen private int mArrayLength; 6220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen private int mPosition; 6320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen 6420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen /** 6520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * Define a TLV constructor with the specified size of the Type (T) and 6620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * Length (L) fields. 6720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * 6820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * @param typeSize Number of bytes used for the Type (T) field. Values 6920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * of 0, 1, or 2 bytes are allowed. A specification of 0 7020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * bytes implies that the field being constructed has the LV 7120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * format rather than the TLV format. 7220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * @param lengthSize Number of bytes used for the Length (L) field. 7320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * Values of 1 or 2 bytes are allowed. 7420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen */ 7520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen public TlvConstructor(int typeSize, int lengthSize) { 7620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen if (typeSize < 0 || typeSize > 2 || lengthSize <= 0 || lengthSize > 2) { 7720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen throw new IllegalArgumentException( 7820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen "Invalid sizes - typeSize=" + typeSize + ", lengthSize=" + lengthSize); 7920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } 8020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen mTypeSize = typeSize; 8120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen mLengthSize = lengthSize; 8220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } 8320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen 8420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen /** 8520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * Set the byte array to be used to construct the TLV. 8620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * 8720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * @param array Byte array to be formatted. 8820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * @return The constructor to facilitate chaining 8920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * {@code ctr.putXXX(..).putXXX(..)}. 9020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen */ 9120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen public TlvConstructor wrap(byte[] array) { 9220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen mArray = array; 9320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen mArrayLength = array.length; 9420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen return this; 9520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } 9620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen 9720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen /** 9820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * Allocates a new byte array to be used ot construct a TLV. 9920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * 10020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * @param capacity The size of the byte array to be allocated. 10120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * @return The constructor to facilitate chaining 10220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * {@code ctr.putXXX(..).putXXX(..)}. 10320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen */ 10420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen public TlvConstructor allocate(int capacity) { 10520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen mArray = new byte[capacity]; 10620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen mArrayLength = capacity; 10720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen return this; 10820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } 10920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen 11020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen /** 11120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * Copies a byte into the TLV with the indicated type. For an LV 11220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * formatted structure (i.e. typeLength=0 in {@link TlvConstructor 11320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * TlvConstructor(int, int)} ) the type field is ignored. 11420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * 11520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * @param type The value to be placed into the Type field. 11620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * @param b The byte to be inserted into the structure. 11720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * @return The constructor to facilitate chaining 11820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * {@code ctr.putXXX(..).putXXX(..)}. 11920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen */ 12020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen public TlvConstructor putByte(int type, byte b) { 12120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen checkLength(1); 12220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen addHeader(type, 1); 12320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen mArray[mPosition++] = b; 12420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen return this; 12520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } 12620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen 12720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen /** 12820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * Copies a byte array into the TLV with the indicated type. For an LV 12920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * formatted structure (i.e. typeLength=0 in {@link TlvConstructor 13020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * TlvConstructor(int, int)} ) the type field is ignored. 13120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * 13220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * @param type The value to be placed into the Type field. 13320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * @param array The array to be copied into the TLV structure. 13420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * @param offset Start copying from the array at the specified offset. 13520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * @param length Copy the specified number (length) of bytes from the 13620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * array. 13720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * @return The constructor to facilitate chaining 13820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * {@code ctr.putXXX(..).putXXX(..)}. 13920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen */ 14020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen public TlvConstructor putByteArray(int type, byte[] array, int offset, int length) { 14120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen checkLength(length); 14220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen addHeader(type, length); 14320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen System.arraycopy(array, offset, mArray, mPosition, length); 14420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen mPosition += length; 14520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen return this; 14620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } 14720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen 14820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen /** 14920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * Copies a byte array into the TLV with the indicated type. For an LV 15020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * formatted structure (i.e. typeLength=0 in {@link TlvConstructor 15120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * TlvConstructor(int, int)} ) the type field is ignored. 15220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * 15320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * @param type The value to be placed into the Type field. 15420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * @param array The array to be copied (in full) into the TLV structure. 15520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * @return The constructor to facilitate chaining 15620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * {@code ctr.putXXX(..).putXXX(..)}. 15720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen */ 15820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen public TlvConstructor putByteArray(int type, byte[] array) { 15920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen return putByteArray(type, array, 0, array.length); 16020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } 16120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen 16220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen /** 16320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * Places a zero length element (i.e. Length field = 0) into the TLV. 16420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * For an LV formatted structure (i.e. typeLength=0 in 16520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * {@link TlvConstructor TlvConstructor(int, int)} ) the type field is 16620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * ignored. 16720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * 16820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * @param type The value to be placed into the Type field. 16920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * @return The constructor to facilitate chaining 17020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * {@code ctr.putXXX(..).putXXX(..)}. 17120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen */ 17220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen public TlvConstructor putZeroLengthElement(int type) { 17320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen checkLength(0); 17420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen addHeader(type, 0); 17520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen return this; 17620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } 17720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen 17820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen /** 17920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * Copies short into the TLV with the indicated type. For an LV 18020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * formatted structure (i.e. typeLength=0 in {@link TlvConstructor 18120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * TlvConstructor(int, int)} ) the type field is ignored. 18220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * 18320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * @param type The value to be placed into the Type field. 18420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * @param data The short to be inserted into the structure. 18520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * @return The constructor to facilitate chaining 18620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * {@code ctr.putXXX(..).putXXX(..)}. 18720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen */ 18820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen public TlvConstructor putShort(int type, short data) { 18920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen checkLength(2); 19020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen addHeader(type, 2); 19120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen Memory.pokeShort(mArray, mPosition, data, ByteOrder.BIG_ENDIAN); 19220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen mPosition += 2; 19320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen return this; 19420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } 19520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen 19620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen /** 19720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * Copies integer into the TLV with the indicated type. For an LV 19820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * formatted structure (i.e. typeLength=0 in {@link TlvConstructor 19920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * TlvConstructor(int, int)} ) the type field is ignored. 20020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * 20120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * @param type The value to be placed into the Type field. 20220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * @param data The integer to be inserted into the structure. 20320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * @return The constructor to facilitate chaining 20420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * {@code ctr.putXXX(..).putXXX(..)}. 20520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen */ 20620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen public TlvConstructor putInt(int type, int data) { 20720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen checkLength(4); 20820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen addHeader(type, 4); 20920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen Memory.pokeInt(mArray, mPosition, data, ByteOrder.BIG_ENDIAN); 21020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen mPosition += 4; 21120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen return this; 21220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } 21320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen 21420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen /** 21520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * Copies a String's byte representation into the TLV with the indicated 21620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * type. For an LV formatted structure (i.e. typeLength=0 in 21720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * {@link TlvConstructor TlvConstructor(int, int)} ) the type field is 21820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * ignored. 21920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * 22020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * @param type The value to be placed into the Type field. 22120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * @param data The string whose bytes are to be inserted into the 22220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * structure. 22320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * @return The constructor to facilitate chaining 22420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * {@code ctr.putXXX(..).putXXX(..)}. 22520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen */ 22620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen public TlvConstructor putString(int type, String data) { 22720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen return putByteArray(type, data.getBytes(), 0, data.length()); 22820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } 22920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen 23020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen /** 23120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * Returns the constructed TLV formatted byte-array. Note that the 23220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * returned array is the fully wrapped ( 23320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * {@link TlvConstructor#wrap(byte[])}) or allocated ( 23420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * {@link TlvConstructor#allocate(int)}) array - which isn't necessarily 23520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * the actual size of the formatted data. Use 23620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * {@link TlvConstructor#getActualLength()} to obtain the size of the 23720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * formatted data. 23820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * 23920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * @return The byte array containing the TLV formatted structure. 24020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen */ 24120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen public byte[] getArray() { 24220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen return mArray; 24320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } 24420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen 24520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen /** 24620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * Returns the size of the TLV formatted portion of the wrapped or 24720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * allocated byte array. The array itself is returned with 24820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * {@link TlvConstructor#getArray()}. 24920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * 25020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * @return The size of the TLV formatted portion of the byte array. 25120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen */ 25220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen public int getActualLength() { 25320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen return mPosition; 25420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } 25520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen 25620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen private void checkLength(int dataLength) { 25720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen if (mPosition + mTypeSize + mLengthSize + dataLength > mArrayLength) { 25820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen throw new BufferOverflowException(); 25920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } 26020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } 26120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen 26220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen private void addHeader(int type, int length) { 26320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen if (mTypeSize == 1) { 26420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen mArray[mPosition] = (byte) type; 26520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } else if (mTypeSize == 2) { 26620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen Memory.pokeShort(mArray, mPosition, (short) type, ByteOrder.BIG_ENDIAN); 26720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } 26820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen mPosition += mTypeSize; 26920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen 27020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen if (mLengthSize == 1) { 27120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen mArray[mPosition] = (byte) length; 27220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } else if (mLengthSize == 2) { 27320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen Memory.pokeShort(mArray, mPosition, (short) length, ByteOrder.BIG_ENDIAN); 27420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } 27520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen mPosition += mLengthSize; 27620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } 27720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } 27820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen 27920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen /** 28020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * Utility class used when iterating over a TLV formatted byte-array. Use 28120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * {@link TlvIterable} to iterate over array. A {@link TlvElement} 28220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * represents each entry in a TLV formatted byte-array. 28320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen */ 28420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen public static class TlvElement { 28520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen /** 28620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * The Type (T) field of the current TLV element. Note that for LV 28720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * formatted byte-arrays (i.e. TLV whose Type/T size is 0) the value of 28820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * this field is undefined. 28920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen */ 29020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen public int mType; 29120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen 29220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen /** 29320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * The Length (L) field of the current TLV element. 29420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen */ 29520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen public int mLength; 29620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen 29720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen /** 29820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * The Value (V) field - a raw byte array representing the current TLV 29920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * element where the entry starts at {@link TlvElement#mOffset}. 30020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen */ 30120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen public byte[] mRefArray; 30220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen 30320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen /** 30420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * The offset to be used into {@link TlvElement#mRefArray} to access the 30520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * raw data representing the current TLV element. 30620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen */ 30720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen public int mOffset; 30820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen 30920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen private TlvElement(int type, int length, byte[] refArray, int offset) { 31020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen mType = type; 31120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen mLength = length; 31220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen mRefArray = refArray; 31320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen mOffset = offset; 31420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } 31520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen 31620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen /** 31720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * Utility function to return a byte representation of a TLV element of 31820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * length 1. Note: an attempt to call this function on a TLV item whose 31920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * {@link TlvElement#mLength} is != 1 will result in an exception. 32020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * 32120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * @return byte representation of current TLV element. 32220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen */ 32320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen public byte getByte() { 32420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen if (mLength != 1) { 32520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen throw new IllegalArgumentException( 32620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen "Accesing a byte from a TLV element of length " + mLength); 32720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } 32820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen return mRefArray[mOffset]; 32920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } 33020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen 33120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen /** 33220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * Utility function to return a short representation of a TLV element of 33320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * length 2. Note: an attempt to call this function on a TLV item whose 33420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * {@link TlvElement#mLength} is != 2 will result in an exception. 33520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * 33620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * @return short representation of current TLV element. 33720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen */ 33820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen public short getShort() { 33920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen if (mLength != 2) { 34020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen throw new IllegalArgumentException( 34120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen "Accesing a short from a TLV element of length " + mLength); 34220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } 34320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen return Memory.peekShort(mRefArray, mOffset, ByteOrder.BIG_ENDIAN); 34420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } 34520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen 34620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen /** 34720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * Utility function to return an integer representation of a TLV element 34820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * of length 4. Note: an attempt to call this function on a TLV item 34920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * whose {@link TlvElement#mLength} is != 4 will result in an exception. 35020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * 35120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * @return integer representation of current TLV element. 35220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen */ 35320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen public int getInt() { 35420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen if (mLength != 4) { 35520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen throw new IllegalArgumentException( 35620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen "Accesing an int from a TLV element of length " + mLength); 35720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } 35820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen return Memory.peekInt(mRefArray, mOffset, ByteOrder.BIG_ENDIAN); 35920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } 36020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen 36120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen /** 36220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * Utility function to return a String representation of a TLV element. 36320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * 36420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * @return String repersentation of the current TLV element. 36520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen */ 36620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen public String getString() { 36720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen return new String(mRefArray, mOffset, mLength); 36820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } 36920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } 37020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen 37120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen /** 37220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * Utility class to iterate over a TLV formatted byte-array. 37320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen */ 37420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen public static class TlvIterable implements Iterable<TlvElement> { 37520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen private int mTypeSize; 37620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen private int mLengthSize; 37720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen private byte[] mArray; 37820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen private int mArrayLength; 37920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen 38020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen /** 38120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * Constructs a TlvIterable object - specifying the format of the TLV 38220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * (the sizes of the Type and Length fields), and the byte array whose 38320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * data is to be parsed. 38420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * 38520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * @param typeSize Number of bytes used for the Type (T) field. Valid 38620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * values are 0 (i.e. indicating the format is LV rather than 38720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * TLV), 1, and 2 bytes. 38820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * @param lengthSize Number of bytes sued for the Length (L) field. 38920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * Values values are 1 or 2 bytes. 39020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * @param array The TLV formatted byte-array to parse. 39120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * @param length The number of bytes of the array to be used in the 39220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * parsing. 39320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen */ 39420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen public TlvIterable(int typeSize, int lengthSize, byte[] array, int length) { 39520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen if (typeSize < 0 || typeSize > 2 || lengthSize <= 0 || lengthSize > 2) { 39620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen throw new IllegalArgumentException( 39720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen "Invalid sizes - typeSize=" + typeSize + ", lengthSize=" + lengthSize); 39820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } 39920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen mTypeSize = typeSize; 40020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen mLengthSize = lengthSize; 40120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen mArray = array; 40220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen mArrayLength = length; 40320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } 40420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen 40520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen /** 40620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * Prints out a parsed representation of the TLV-formatted byte array. 40720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * Whenever possible bytes, shorts, and integer are printed out (for 40820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * fields whose length is 1, 2, or 4 respectively). 40920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen */ 41020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen @Override 41120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen public String toString() { 41220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen StringBuilder builder = new StringBuilder(); 41320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen 41420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen builder.append("["); 41520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen boolean first = true; 41620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen for (TlvElement tlv : this) { 41720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen if (!first) { 41820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen builder.append(","); 41920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } 42020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen first = false; 42120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen builder.append(" ("); 42220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen if (mTypeSize != 0) { 42320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen builder.append("T=" + tlv.mType + ","); 42420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } 42520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen builder.append("L=" + tlv.mLength + ") "); 42620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen if (tlv.mLength == 0) { 42720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen builder.append("<null>"); 42820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } else if (tlv.mLength == 1) { 42920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen builder.append(tlv.getByte()); 43020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } else if (tlv.mLength == 2) { 43120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen builder.append(tlv.getShort()); 43220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } else if (tlv.mLength == 4) { 43320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen builder.append(tlv.getInt()); 43420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } else { 43520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen builder.append("<bytes>"); 43620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } 43720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen if (tlv.mLength != 0) { 43820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen builder.append(" (S='" + tlv.getString() + "')"); 43920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } 44020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } 44120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen builder.append("]"); 44220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen 44320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen return builder.toString(); 44420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } 44520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen 44620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen /** 44720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * Returns an iterator to step through a TLV formatted byte-array. The 44820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen * individual elements returned by the iterator are {@link TlvElement}. 44920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen */ 45020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen @Override 45120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen public Iterator<TlvElement> iterator() { 45220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen return new Iterator<TlvElement>() { 45320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen private int mOffset = 0; 45420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen 45520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen @Override 45620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen public boolean hasNext() { 45720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen return mOffset < mArrayLength; 45820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } 45920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen 46020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen @Override 46120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen public TlvElement next() { 46220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen int type = 0; 46320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen if (mTypeSize == 1) { 46420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen type = mArray[mOffset]; 46520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } else if (mTypeSize == 2) { 46620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen type = Memory.peekShort(mArray, mOffset, ByteOrder.BIG_ENDIAN); 46720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } 46820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen mOffset += mTypeSize; 46920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen 47020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen int length = 0; 47120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen if (mLengthSize == 1) { 47220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen length = mArray[mOffset]; 47320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } else if (mLengthSize == 2) { 47420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen length = Memory.peekShort(mArray, mOffset, ByteOrder.BIG_ENDIAN); 47520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } 47620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen mOffset += mLengthSize; 47720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen 47820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen TlvElement tlv = new TlvElement(type, length, mArray, mOffset); 47920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen mOffset += length; 48020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen return tlv; 48120d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } 48220d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen 48320d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen @Override 48420d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen public void remove() { 48520d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen throw new UnsupportedOperationException(); 48620d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } 48720d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen }; 48820d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } 48920d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen } 49020d329b08df7d1a94e6caee781f09e812a79c913Etan Cohen} 491