/** * read encoding len. see Stringpool.cpp ENCODE_LENGTH * * @param in * @return * @throws IOException */ private static int readLen16(TellableInputStream in) throws IOException { int len = 0; int i = in.readUShort(); if ((i & 0x8000) != 0) { len |= (i & 0x7fff) << 15; len += in.readUShort(); } else { len = i; } return len; }
/** * read res value, convert from different types to string. * * @param in * @param stringPool * @return * @throws IOException */ public static ResValue readResValue( TellableInputStream in, StringPool stringPool, ResourceTable resourceTable, boolean isStyle, Locale locale) throws IOException { ResValue resValue = new ResValue(); resValue.size = in.readUShort(); resValue.res0 = in.readUByte(); resValue.dataType = in.readUByte(); switch (resValue.dataType) { case ResValue.ResType.INT_DEC: case ResValue.ResType.INT_HEX: resValue.data = String.valueOf(in.readInt()); break; case ResValue.ResType.STRING: int strRef = in.readInt(); if (strRef > 0) { resValue.data = stringPool.get(strRef); } break; case ResValue.ResType.REFERENCE: long resourceId = in.readUInt(); resValue.data = getResourceByid(resourceId, isStyle, resourceTable, locale); break; case ResValue.ResType.INT_BOOLEAN: resValue.data = String.valueOf(in.readInt() != 0); break; case ResValue.ResType.NULL: resValue.data = ""; break; case ResValue.ResType.INT_COLOR_RGB8: case ResValue.ResType.INT_COLOR_RGB4: resValue.data = readRGBs(in, 6); break; case ResValue.ResType.INT_COLOR_ARGB8: case ResValue.ResType.INT_COLOR_ARGB4: resValue.data = readRGBs(in, 8); break; case ResValue.ResType.DIMENSION: resValue.data = getDemension(in); break; case ResValue.ResType.FRACTION: resValue.data = getFraction(in); break; default: resValue.data = "{" + resValue.dataType + ":" + in.readUInt() + "}"; } return resValue; }
/** read string from input stream. if get EOF before read enough data, throw IOException. */ public static String readString(TellableInputStream in, StringEncoding encoding) throws IOException { if (encoding == StringEncoding.UTF8) { // The lengths are encoded in the same way as for the 16-bit format // but using 8-bit rather than 16-bit integers. int strLen = readLen(in); int bytesLen = readLen(in); byte[] bytes = in.readBytes(bytesLen); String str = new String(bytes, "UTF-8"); // zero int trailling = in.readUByte(); return str; } else { // The length is encoded as either one or two 16-bit integers as per the commentRef... int strLen = readLen16(in); String str = in.readStringUTF16(strLen); // zero int trailling = in.readUShort(); return str; } }