1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project******************************************************************************* 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project* Copyright (C) 1996-2006, International Business Machines Corporation and * 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project* others. All Rights Reserved. * 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project******************************************************************************* 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project* 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project******************************************************************************* 8f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes*/ 9f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes /** 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * A JNI interface for ICU converters. 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 12f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @author Ram Viswanadha, IBM 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 153664d8839f0ba794f428119ee7f7304a66861da5Elliott Hughespackage java.nio.charset; 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 177365de1056414750d0a7d1fdd26025fd247f0d04Jesse Wilsonimport java.nio.ByteBuffer; 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.CharBuffer; 195ec69b20ab9b3e2dcbe225d548168b09afbbbac2Elliott Hughesimport libcore.icu.ICU; 203664d8839f0ba794f428119ee7f7304a66861da5Elliott Hughesimport libcore.icu.NativeConverter; 2126ce8fbd8fe488cc969b08f64c56525662763dc4Jesse Wilsonimport libcore.util.EmptyArray; 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 234fd8ac297725190c6d81e9538b1faf7cfb0f5bb8Elliott Hughesfinal class CharsetDecoderICU extends CharsetDecoder { 24cf6c3a752da274cc5025191d3bcd62e6222f4a4cElliott Hughes private static final int MAX_CHARS_PER_BYTE = 2; 25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 26c60bc1815dca549f3fb4e572f6aac749d7fa9fc6Elliott Hughes private static final int INPUT_OFFSET = 0; 27c60bc1815dca549f3fb4e572f6aac749d7fa9fc6Elliott Hughes private static final int OUTPUT_OFFSET = 1; 28c60bc1815dca549f3fb4e572f6aac749d7fa9fc6Elliott Hughes private static final int INVALID_BYTES = 2; 29c60bc1815dca549f3fb4e572f6aac749d7fa9fc6Elliott Hughes /* 30c60bc1815dca549f3fb4e572f6aac749d7fa9fc6Elliott Hughes * data[INPUT_OFFSET] = on input contains the start of input and on output the number of input bytes consumed 31c60bc1815dca549f3fb4e572f6aac749d7fa9fc6Elliott Hughes * data[OUTPUT_OFFSET] = on input contains the start of output and on output the number of output chars written 32c60bc1815dca549f3fb4e572f6aac749d7fa9fc6Elliott Hughes * data[INVALID_BYTES] = number of invalid bytes 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 342981b5e8cf7c19dfd85b2088b18b7a6146825317Elliott Hughes private int[] data = new int[3]; 35f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* handle to the ICU converter that is opened */ 37c60bc1815dca549f3fb4e572f6aac749d7fa9fc6Elliott Hughes private long converterHandle = 0; 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 39c60bc1815dca549f3fb4e572f6aac749d7fa9fc6Elliott Hughes private byte[] input = null; 40c60bc1815dca549f3fb4e572f6aac749d7fa9fc6Elliott Hughes private char[] output= null; 419932735d0306721523082f77b0a9ba4aa4db8cdbMihai Preda 429932735d0306721523082f77b0a9ba4aa4db8cdbMihai Preda private byte[] allocatedInput = null; 439932735d0306721523082f77b0a9ba4aa4db8cdbMihai Preda private char[] allocatedOutput = null; 44f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 45866e7ae17a3da81a02b0b144e0c9c2b3196d293aElliott Hughes // These instance variables are always assigned in the methods before being used. This class 46866e7ae17a3da81a02b0b144e0c9c2b3196d293aElliott Hughes // is inherently thread-unsafe so we don't have to worry about synchronization. 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private int inEnd; 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private int outEnd; 49f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 507d52d787302b862019da41aa753646d88d43fd61Elliott Hughes public static CharsetDecoderICU newInstance(Charset cs, String icuCanonicalName) { 517d52d787302b862019da41aa753646d88d43fd61Elliott Hughes // This complexity is necessary to ensure that even if the constructor, superclass 527d52d787302b862019da41aa753646d88d43fd61Elliott Hughes // constructor, or call to updateCallback throw, we still free the native peer. 537d52d787302b862019da41aa753646d88d43fd61Elliott Hughes long address = 0; 547d52d787302b862019da41aa753646d88d43fd61Elliott Hughes try { 557d52d787302b862019da41aa753646d88d43fd61Elliott Hughes address = NativeConverter.openConverter(icuCanonicalName); 567d52d787302b862019da41aa753646d88d43fd61Elliott Hughes float averageCharsPerByte = NativeConverter.getAveCharsPerByte(address); 577d52d787302b862019da41aa753646d88d43fd61Elliott Hughes CharsetDecoderICU result = new CharsetDecoderICU(cs, averageCharsPerByte, address); 587d52d787302b862019da41aa753646d88d43fd61Elliott Hughes address = 0; // CharsetDecoderICU has taken ownership; its finalizer will do the free. 597d52d787302b862019da41aa753646d88d43fd61Elliott Hughes result.updateCallback(); 607d52d787302b862019da41aa753646d88d43fd61Elliott Hughes return result; 617d52d787302b862019da41aa753646d88d43fd61Elliott Hughes } finally { 627d52d787302b862019da41aa753646d88d43fd61Elliott Hughes if (address != 0) { 637d52d787302b862019da41aa753646d88d43fd61Elliott Hughes NativeConverter.closeConverter(address); 647d52d787302b862019da41aa753646d88d43fd61Elliott Hughes } 657d52d787302b862019da41aa753646d88d43fd61Elliott Hughes } 667d52d787302b862019da41aa753646d88d43fd61Elliott Hughes } 677d52d787302b862019da41aa753646d88d43fd61Elliott Hughes 687d52d787302b862019da41aa753646d88d43fd61Elliott Hughes private CharsetDecoderICU(Charset cs, float averageCharsPerByte, long address) { 697d52d787302b862019da41aa753646d88d43fd61Elliott Hughes super(cs, averageCharsPerByte, MAX_CHARS_PER_BYTE); 707d52d787302b862019da41aa753646d88d43fd61Elliott Hughes this.converterHandle = address; 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 72f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 732981b5e8cf7c19dfd85b2088b18b7a6146825317Elliott Hughes @Override protected void implReplaceWith(String newReplacement) { 7437871fb106b08055ad56d7f04d4faccdd163e1afElliott Hughes updateCallback(); 75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 76f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 772981b5e8cf7c19dfd85b2088b18b7a6146825317Elliott Hughes @Override protected final void implOnMalformedInput(CodingErrorAction newAction) { 78cf6c3a752da274cc5025191d3bcd62e6222f4a4cElliott Hughes updateCallback(); 79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 80f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 812981b5e8cf7c19dfd85b2088b18b7a6146825317Elliott Hughes @Override protected final void implOnUnmappableCharacter(CodingErrorAction newAction) { 82cf6c3a752da274cc5025191d3bcd62e6222f4a4cElliott Hughes updateCallback(); 83cf6c3a752da274cc5025191d3bcd62e6222f4a4cElliott Hughes } 84cf6c3a752da274cc5025191d3bcd62e6222f4a4cElliott Hughes 85cf6c3a752da274cc5025191d3bcd62e6222f4a4cElliott Hughes private void updateCallback() { 865ec69b20ab9b3e2dcbe225d548168b09afbbbac2Elliott Hughes NativeConverter.setCallbackDecode(converterHandle, this); 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 88f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 892981b5e8cf7c19dfd85b2088b18b7a6146825317Elliott Hughes @Override protected void implReset() { 902981b5e8cf7c19dfd85b2088b18b7a6146825317Elliott Hughes NativeConverter.resetByteToChar(converterHandle); 912981b5e8cf7c19dfd85b2088b18b7a6146825317Elliott Hughes data[INPUT_OFFSET] = 0; 922981b5e8cf7c19dfd85b2088b18b7a6146825317Elliott Hughes data[OUTPUT_OFFSET] = 0; 932981b5e8cf7c19dfd85b2088b18b7a6146825317Elliott Hughes data[INVALID_BYTES] = 0; 942981b5e8cf7c19dfd85b2088b18b7a6146825317Elliott Hughes output = null; 952981b5e8cf7c19dfd85b2088b18b7a6146825317Elliott Hughes input = null; 962981b5e8cf7c19dfd85b2088b18b7a6146825317Elliott Hughes allocatedInput = null; 972981b5e8cf7c19dfd85b2088b18b7a6146825317Elliott Hughes allocatedOutput = null; 982981b5e8cf7c19dfd85b2088b18b7a6146825317Elliott Hughes inEnd = 0; 992981b5e8cf7c19dfd85b2088b18b7a6146825317Elliott Hughes outEnd = 0; 1002981b5e8cf7c19dfd85b2088b18b7a6146825317Elliott Hughes } 1012981b5e8cf7c19dfd85b2088b18b7a6146825317Elliott Hughes 102dbf863488607fbb16a3d28c09f772d9581bd64adElliott Hughes @Override protected final CoderResult implFlush(CharBuffer out) { 103c60bc1815dca549f3fb4e572f6aac749d7fa9fc6Elliott Hughes try { 104dbf863488607fbb16a3d28c09f772d9581bd64adElliott Hughes // ICU needs to see an empty input. 105dbf863488607fbb16a3d28c09f772d9581bd64adElliott Hughes input = EmptyArray.BYTE; 106dbf863488607fbb16a3d28c09f772d9581bd64adElliott Hughes inEnd = 0; 107dbf863488607fbb16a3d28c09f772d9581bd64adElliott Hughes data[INPUT_OFFSET] = 0; 108dbf863488607fbb16a3d28c09f772d9581bd64adElliott Hughes 109c60bc1815dca549f3fb4e572f6aac749d7fa9fc6Elliott Hughes data[OUTPUT_OFFSET] = getArray(out); 110dbf863488607fbb16a3d28c09f772d9581bd64adElliott Hughes data[INVALID_BYTES] = 0; // Make sure we don't see earlier errors. 111dbf863488607fbb16a3d28c09f772d9581bd64adElliott Hughes 1125ec69b20ab9b3e2dcbe225d548168b09afbbbac2Elliott Hughes int error = NativeConverter.decode(converterHandle, input, inEnd, output, outEnd, data, true); 1135ec69b20ab9b3e2dcbe225d548168b09afbbbac2Elliott Hughes if (ICU.U_FAILURE(error)) { 1145ec69b20ab9b3e2dcbe225d548168b09afbbbac2Elliott Hughes if (error == ICU.U_BUFFER_OVERFLOW_ERROR) { 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return CoderResult.OVERFLOW; 1165ec69b20ab9b3e2dcbe225d548168b09afbbbac2Elliott Hughes } else if (error == ICU.U_TRUNCATED_CHAR_FOUND) { 117c60bc1815dca549f3fb4e572f6aac749d7fa9fc6Elliott Hughes if (data[INPUT_OFFSET] > 0) { 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return CoderResult.malformedForLength(data[INPUT_OFFSET]); 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return CoderResult.UNDERFLOW; 123c60bc1815dca549f3fb4e572f6aac749d7fa9fc6Elliott Hughes } finally { 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project setPosition(out); 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project implReset(); 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 128f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 129dbf863488607fbb16a3d28c09f772d9581bd64adElliott Hughes @Override protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) { 130dbf863488607fbb16a3d28c09f772d9581bd64adElliott Hughes if (!in.hasRemaining()) { 131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return CoderResult.UNDERFLOW; 132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project data[INPUT_OFFSET] = getArray(in); 135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project data[OUTPUT_OFFSET]= getArray(out); 136f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 1372981b5e8cf7c19dfd85b2088b18b7a6146825317Elliott Hughes try { 1385ec69b20ab9b3e2dcbe225d548168b09afbbbac2Elliott Hughes int error = NativeConverter.decode(converterHandle, input, inEnd, output, outEnd, data, false); 1395ec69b20ab9b3e2dcbe225d548168b09afbbbac2Elliott Hughes if (ICU.U_FAILURE(error)) { 1405ec69b20ab9b3e2dcbe225d548168b09afbbbac2Elliott Hughes if (error == ICU.U_BUFFER_OVERFLOW_ERROR) { 1415ec69b20ab9b3e2dcbe225d548168b09afbbbac2Elliott Hughes return CoderResult.OVERFLOW; 1425ec69b20ab9b3e2dcbe225d548168b09afbbbac2Elliott Hughes } else if (error == ICU.U_INVALID_CHAR_FOUND) { 1435ec69b20ab9b3e2dcbe225d548168b09afbbbac2Elliott Hughes return CoderResult.unmappableForLength(data[INVALID_BYTES]); 1445ec69b20ab9b3e2dcbe225d548168b09afbbbac2Elliott Hughes } else if (error == ICU.U_ILLEGAL_CHAR_FOUND) { 1455ec69b20ab9b3e2dcbe225d548168b09afbbbac2Elliott Hughes return CoderResult.malformedForLength(data[INVALID_BYTES]); 1465ec69b20ab9b3e2dcbe225d548168b09afbbbac2Elliott Hughes } else { 1475ec69b20ab9b3e2dcbe225d548168b09afbbbac2Elliott Hughes throw new AssertionError(error); 1485ec69b20ab9b3e2dcbe225d548168b09afbbbac2Elliott Hughes } 149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 150c60bc1815dca549f3fb4e572f6aac749d7fa9fc6Elliott Hughes // Decoding succeeded: give us more data. 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return CoderResult.UNDERFLOW; 152c60bc1815dca549f3fb4e572f6aac749d7fa9fc6Elliott Hughes } finally { 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project setPosition(in); 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project setPosition(out); 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 157f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 158e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom @Override protected void finalize() throws Throwable { 159e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom try { 160e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom NativeConverter.closeConverter(converterHandle); 161e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom converterHandle = 0; 162e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom } finally { 163e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom super.finalize(); 164e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom } 165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 166f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 167866e7ae17a3da81a02b0b144e0c9c2b3196d293aElliott Hughes private int getArray(CharBuffer out) { 168c60bc1815dca549f3fb4e572f6aac749d7fa9fc6Elliott Hughes if (out.hasArray()) { 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project output = out.array(); 170b7bfb47e9720ecc6e10f43878f27e40542a9c800Elliott Hughes outEnd = out.arrayOffset() + out.limit(); 171b7bfb47e9720ecc6e10f43878f27e40542a9c800Elliott Hughes return out.arrayOffset() + out.position(); 172c60bc1815dca549f3fb4e572f6aac749d7fa9fc6Elliott Hughes } else { 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project outEnd = out.remaining(); 1742981b5e8cf7c19dfd85b2088b18b7a6146825317Elliott Hughes if (allocatedOutput == null || outEnd > allocatedOutput.length) { 1759932735d0306721523082f77b0a9ba4aa4db8cdbMihai Preda allocatedOutput = new char[outEnd]; 176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1772981b5e8cf7c19dfd85b2088b18b7a6146825317Elliott Hughes // The array's start position is 0. 1789932735d0306721523082f77b0a9ba4aa4db8cdbMihai Preda output = allocatedOutput; 179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return 0; 180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 182c60bc1815dca549f3fb4e572f6aac749d7fa9fc6Elliott Hughes 183866e7ae17a3da81a02b0b144e0c9c2b3196d293aElliott Hughes private int getArray(ByteBuffer in) { 184c60bc1815dca549f3fb4e572f6aac749d7fa9fc6Elliott Hughes if (in.hasArray()) { 185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project input = in.array(); 186b7bfb47e9720ecc6e10f43878f27e40542a9c800Elliott Hughes inEnd = in.arrayOffset() + in.limit(); 1872981b5e8cf7c19dfd85b2088b18b7a6146825317Elliott Hughes return in.arrayOffset() + in.position(); 188c60bc1815dca549f3fb4e572f6aac749d7fa9fc6Elliott Hughes } else { 189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project inEnd = in.remaining(); 1902981b5e8cf7c19dfd85b2088b18b7a6146825317Elliott Hughes if (allocatedInput == null || inEnd > allocatedInput.length) { 1919932735d0306721523082f77b0a9ba4aa4db8cdbMihai Preda allocatedInput = new byte[inEnd]; 192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1932981b5e8cf7c19dfd85b2088b18b7a6146825317Elliott Hughes // Copy the input buffer into the allocated array. 194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int pos = in.position(); 1952981b5e8cf7c19dfd85b2088b18b7a6146825317Elliott Hughes in.get(allocatedInput, 0, inEnd); 196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project in.position(pos); 1972981b5e8cf7c19dfd85b2088b18b7a6146825317Elliott Hughes // The array's start position is 0. 1982981b5e8cf7c19dfd85b2088b18b7a6146825317Elliott Hughes input = allocatedInput; 1992981b5e8cf7c19dfd85b2088b18b7a6146825317Elliott Hughes return 0; 200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 202c60bc1815dca549f3fb4e572f6aac749d7fa9fc6Elliott Hughes 203866e7ae17a3da81a02b0b144e0c9c2b3196d293aElliott Hughes private void setPosition(CharBuffer out) { 204c60bc1815dca549f3fb4e572f6aac749d7fa9fc6Elliott Hughes if (out.hasArray()) { 205b7bfb47e9720ecc6e10f43878f27e40542a9c800Elliott Hughes out.position(out.position() + data[OUTPUT_OFFSET] - out.arrayOffset()); 206c60bc1815dca549f3fb4e572f6aac749d7fa9fc6Elliott Hughes } else { 207c60bc1815dca549f3fb4e572f6aac749d7fa9fc6Elliott Hughes out.put(output, 0, data[OUTPUT_OFFSET]); 208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2099932735d0306721523082f77b0a9ba4aa4db8cdbMihai Preda // release reference to output array, which may not be ours 2109932735d0306721523082f77b0a9ba4aa4db8cdbMihai Preda output = null; 211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 213866e7ae17a3da81a02b0b144e0c9c2b3196d293aElliott Hughes private void setPosition(ByteBuffer in) { 2142981b5e8cf7c19dfd85b2088b18b7a6146825317Elliott Hughes in.position(in.position() + data[INPUT_OFFSET]); 2159932735d0306721523082f77b0a9ba4aa4db8cdbMihai Preda // release reference to input array, which may not be ours 2169932735d0306721523082f77b0a9ba4aa4db8cdbMihai Preda input = null; 217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 219