12d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert// © 2016 and later: Unicode, Inc. and others. 22d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert// License & terms of use: http://www.unicode.org/copyright.html#License 37935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 47935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert******************************************************************************* 5f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert* Copyright (C) 2013-2015, International Business Machines 67935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert* Corporation and others. All Rights Reserved. 77935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert******************************************************************************* 87935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert* CollationTailoring.java, ported from collationtailoring.h/.cpp 97935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert* 107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert* C++ version created on: 2013mar12 117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert* created by: Markus W. Scherer 127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert*/ 137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpackage com.ibm.icu.impl.coll; 157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Map; 177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.impl.Norm2AllModes; 197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.impl.Normalizer2Impl; 207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.impl.Trie2_32; 217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.text.UnicodeSet; 227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.ULocale; 23bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport com.ibm.icu.util.UResourceBundle; 247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.VersionInfo; 257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/** 277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Collation tailoring data & settings. 287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * This is a container of values for a collation tailoring 297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * built from rules or deserialized from binary data. 307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * It is logically immutable: Do not modify its values. 327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * The fields are public for convenience. 337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpublic final class CollationTailoring { 357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert CollationTailoring(SharedObject.Reference<CollationSettings> baseSettings) { 367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if(baseSettings != null) { 377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assert(baseSettings.readOnly().reorderCodes.length == 0); 387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assert(baseSettings.readOnly().reorderTable == null); 39f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert assert(baseSettings.readOnly().minHighNoReorder == 0); 407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert settings = baseSettings.clone(); 417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert settings = new SharedObject.Reference<CollationSettings>(new CollationSettings()); 437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert void ensureOwnedData() { 477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if(ownedData == null) { 487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Normalizer2Impl nfcImpl = Norm2AllModes.getNFCInstance().impl; 497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ownedData = new CollationData(nfcImpl); 507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert data = ownedData; 527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 54bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert /** Not thread-safe, call only before sharing. */ 55bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert void setRules(String r) { 56bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert assert rules == null && rulesResource == null; 57bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert rules = r; 58bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 59bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert /** Not thread-safe, call only before sharing. */ 60bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert void setRulesResource(UResourceBundle res) { 61bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert assert rules == null && rulesResource == null; 62bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert rulesResource = res; 63bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 64bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public String getRules() { 65bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (rules != null) { 66bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert return rules; 67bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 68bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (rulesResource != null) { 69bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert return rulesResource.getString(); 70bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 71bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert return ""; 72bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 73bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert static VersionInfo makeBaseVersion(VersionInfo ucaVersion) { 757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return VersionInfo.getInstance( 767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert VersionInfo.UCOL_BUILDER_VERSION.getMajor(), 777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert (ucaVersion.getMajor() << 3) + ucaVersion.getMinor(), 787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ucaVersion.getMilli() << 6, 797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 0); 807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert void setVersion(int baseVersion, int rulesVersion) { 827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // See comments for version field. 837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int r = (rulesVersion >> 16) & 0xff00; 847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int s = (rulesVersion >> 16) & 0xff; 857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int t = (rulesVersion >> 8) & 0xff; 867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int q = rulesVersion & 0xff; 877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert version = (VersionInfo.UCOL_BUILDER_VERSION.getMajor() << 24) | 887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert (baseVersion & 0xffc000) | // UCA version u.v.w 897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ((r + (r >> 6)) & 0x3f00) | 907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert (((s << 3) + (s >> 5) + t + (q << 4) + (q >> 4)) & 0xff); 917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int getUCAVersion() { 937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Version second byte/bits 23..16 to bits 11..4, 947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // third byte/bits 15..14 to bits 1..0. 957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return ((version >> 12) & 0xff0) | ((version >> 14) & 3); 967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // data for sorting etc. 997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public CollationData data; // == base data or ownedData 1007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public SharedObject.Reference<CollationSettings> settings; // reference-counted 101bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // In Java, deserialize the rules string from the resource bundle 102bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // only when it is used. (It can be large and is rarely used.) 103bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private String rules; 104bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private UResourceBundle rulesResource; 1057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // The locale is null (C++: bogus) when built from rules or constructed from a binary blob. 1067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // It can then be set by the service registration code which is thread-safe. 1077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public ULocale actualLocale = ULocale.ROOT; 1087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // UCA version u.v.w & rules version r.s.t.q: 1097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // version[0]: builder version (runtime version is mixed in at runtime) 1107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // version[1]: bits 7..3=u, bits 2..0=v 1117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // version[2]: bits 7..6=w, bits 5..0=r 1127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // version[3]= (s<<5)+(s>>3)+t+(q<<4)+(q>>4) 1137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public int version = 0; 1147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // owned objects 1167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert CollationData ownedData; 1177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Trie2_32 trie; 1187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert UnicodeSet unsafeBackwardSet; 1197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public Map<Integer, Integer> maxExpansions; 1207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /* 1227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Not Cloneable: A CollationTailoring cannot be copied. 1237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * It is immutable, and the data trie cannot be copied either. 1247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 1257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert} 126