17935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 27935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ******************************************************************************* 37935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Copyright (C) 1996-2014, International Business Machines Corporation and 47935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * others. All Rights Reserved. 57935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ******************************************************************************* 67935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 77935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 87935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpackage com.ibm.icu.impl; 97935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.io.IOException; 117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.nio.ByteBuffer; 127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Arrays; 137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/** 157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert* <p>Internal reader class for ICU data file uname.dat containing 167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert* Unicode codepoint name data.</p> 177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert* <p>This class simply reads unames.icu, authenticates that it is a valid 187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert* ICU data file and split its contents up into blocks of data for use in 197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert* <a href=UCharacterName.html>com.ibm.icu.impl.UCharacterName</a>. 207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert* </p> 217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert* <p>unames.icu which is in big-endian format is jared together with this 227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert* package.</p> 237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert* @author Syn Wee Quek 247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert* @since release 2.1, February 1st 2002 257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert*/ 267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertfinal class UCharacterNameReader implements ICUBinary.Authenticate 287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert{ 297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // public methods ---------------------------------------------------- 307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public boolean isDataVersionAcceptable(byte version[]) 327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return version[0] == 1; 347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // protected constructor --------------------------------------------- 377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>Protected constructor.</p> 407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param bytes ICU uprop.dat file buffer 417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @exception IOException throw if data file fails authentication 427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected UCharacterNameReader(ByteBuffer bytes) throws IOException 447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ICUBinary.readHeader(bytes, DATA_FORMAT_ID_, this); 467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert m_byteBuffer_ = bytes; 477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // protected methods ------------------------------------------------- 507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Read and break up the stream of data passed in as arguments 537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * and fills up UCharacterName. 547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * If unsuccessful false will be returned. 557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param data instance of datablock 567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @exception IOException thrown when there's a data error. 577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected void read(UCharacterName data) throws IOException 597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // reading index 617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert m_tokenstringindex_ = m_byteBuffer_.getInt(); 627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert m_groupindex_ = m_byteBuffer_.getInt(); 637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert m_groupstringindex_ = m_byteBuffer_.getInt(); 647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert m_algnamesindex_ = m_byteBuffer_.getInt(); 657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // reading tokens 677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int count = m_byteBuffer_.getChar(); 687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert char token[] = new char[count]; 697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (char i = 0; i < count; i ++) { 707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert token[i] = m_byteBuffer_.getChar(); 717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int size = m_groupindex_ - m_tokenstringindex_; 737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert byte tokenstr[] = new byte[size]; 747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert m_byteBuffer_.get(tokenstr); 757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert data.setToken(token, tokenstr); 767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // reading the group information records 787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert count = m_byteBuffer_.getChar(); 797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert data.setGroupCountSize(count, GROUP_INFO_SIZE_); 807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert count *= GROUP_INFO_SIZE_; 817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert char group[] = new char[count]; 827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = 0; i < count; i ++) { 837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert group[i] = m_byteBuffer_.getChar(); 847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert size = m_algnamesindex_ - m_groupstringindex_; 877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert byte groupstring[] = new byte[size]; 887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert m_byteBuffer_.get(groupstring); 897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert data.setGroup(group, groupstring); 917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert count = m_byteBuffer_.getInt(); 937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert UCharacterName.AlgorithmName alg[] = 947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert new UCharacterName.AlgorithmName[count]; 957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = 0; i < count; i ++) 977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert UCharacterName.AlgorithmName an = readAlg(); 997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (an == null) { 1007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert throw new IOException("unames.icu read error: Algorithmic names creation error"); 1017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert alg[i] = an; 1037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert data.setAlgorithm(alg); 1057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 1087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>Checking the file for the correct format.</p> 1097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param dataformatid 1107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param dataformatversion 1117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return true if the file format version is correct 1127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 1137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ///CLOVER:OFF 1147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected boolean authenticate(byte dataformatid[], 1157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert byte dataformatversion[]) 1167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 1177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return Arrays.equals( 1187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ICUBinary.getVersionByteArrayFromCompactInt(DATA_FORMAT_ID_), 1197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert dataformatid) && 1207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert isDataVersionAcceptable(dataformatversion); 1217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ///CLOVER:ON 1237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // private variables ------------------------------------------------- 1257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 1277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Byte buffer for names 1287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 1297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private ByteBuffer m_byteBuffer_; 1307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 1317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Size of the group information block in number of char 1327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 1337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static final int GROUP_INFO_SIZE_ = 3; 1347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 1367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Index of the offset information 1377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 1387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private int m_tokenstringindex_; 1397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private int m_groupindex_; 1407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private int m_groupstringindex_; 1417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private int m_algnamesindex_; 1427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 1447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Size of an algorithmic name information group 1457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * start code point size + end code point size + type size + variant size + 1467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * size of data size 1477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 1487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static final int ALG_INFO_SIZE_ = 12; 1497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 1517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * File format id that this class understands. 1527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 1537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static final int DATA_FORMAT_ID_ = 0x756E616D; 1547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // private methods --------------------------------------------------- 1567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 1587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Reads an individual record of AlgorithmNames 1597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return an instance of AlgorithNames if read is successful otherwise null 1607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @exception IOException thrown when file read error occurs or data is corrupted 1617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 1627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private UCharacterName.AlgorithmName readAlg() throws IOException 1637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 1647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert UCharacterName.AlgorithmName result = 1657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert new UCharacterName.AlgorithmName(); 1667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int rangestart = m_byteBuffer_.getInt(); 1677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int rangeend = m_byteBuffer_.getInt(); 1687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert byte type = m_byteBuffer_.get(); 1697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert byte variant = m_byteBuffer_.get(); 1707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!result.setInfo(rangestart, rangeend, type, variant)) { 1717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return null; 1727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int size = m_byteBuffer_.getChar(); 1757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (type == UCharacterName.AlgorithmName.TYPE_1_) 1767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 1777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert char factor[] = new char[variant]; 1787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int j = 0; j < variant; j ++) { 1797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert factor[j] = m_byteBuffer_.getChar(); 1807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result.setFactor(factor); 1837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert size -= (variant << 1); 1847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert StringBuilder prefix = new StringBuilder(); 1877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert char c = (char)(m_byteBuffer_.get() & 0x00FF); 1887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert while (c != 0) 1897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 1907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert prefix.append(c); 1917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert c = (char)(m_byteBuffer_.get() & 0x00FF); 1927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result.setPrefix(prefix.toString()); 1957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert size -= (ALG_INFO_SIZE_ + prefix.length() + 1); 1977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (size > 0) 1997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 2007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert byte string[] = new byte[size]; 2017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert m_byteBuffer_.get(string); 2027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result.setFactorString(string); 2037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return result; 2057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert} 207