1 /* 2 * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 /* 26 ******************************************************************************* 27 * 28 * Copyright (C) 2004-2014, International Business Machines 29 * Corporation and others. All Rights Reserved. 30 * 31 ******************************************************************************* 32 * file name: UBiDiProps.java 33 * encoding: US-ASCII 34 * tab size: 8 (not used) 35 * indentation:4 36 * 37 * created on: 2005jan16 38 * created by: Markus W. Scherer 39 * 40 * Low-level Unicode bidi/shaping properties access. 41 * Java port of ubidi_props.h/.c. 42 */ 43 44 package jdk.internal.icu.impl; 45 46 import jdk.internal.icu.lang.UCharacter; 47 48 import java.io.IOException; 49 import java.nio.ByteBuffer; 50 import java.util.MissingResourceException; 51 52 public final class UBiDiProps { 53 // constructors etc. --------------------------------------------------- *** 54 55 // port of ubidi_openProps() 56 private UBiDiProps() throws IOException{ 57 ByteBuffer bytes=ICUBinary.getRequiredData(DATA_FILE_NAME); 58 readData(bytes); 59 } 60 61 private void readData(ByteBuffer bytes) throws IOException { 62 // read the header 63 ICUBinary.readHeader(bytes, FMT, new IsAcceptable()); 64 65 // read indexes[] 66 int i, count; 67 count=bytes.getInt(); 68 if(count<IX_TOP) { 69 throw new IOException("indexes[0] too small in "+DATA_FILE_NAME); 70 } 71 indexes=new int[count]; 72 73 indexes[0]=count; 74 for(i=1; i<count; ++i) { 75 indexes[i]=bytes.getInt(); 76 } 77 78 // read the trie 79 trie=Trie2_16.createFromSerialized(bytes); 80 int expectedTrieLength=indexes[IX_TRIE_SIZE]; 81 int trieLength=trie.getSerializedLength(); 82 if(trieLength>expectedTrieLength) { 83 throw new IOException(DATA_FILE_NAME+": not enough bytes for the trie"); 84 } 85 // skip padding after trie bytes 86 ICUBinary.skipBytes(bytes, expectedTrieLength-trieLength); 87 88 // read mirrors[] 89 count=indexes[IX_MIRROR_LENGTH]; 90 if(count>0) { 91 mirrors=new int[count]; 92 for(i=0; i<count; ++i) { 93 mirrors[i]=bytes.getInt(); 94 } 95 } 96 97 // read jgArray[] 98 count=indexes[IX_JG_LIMIT]-indexes[IX_JG_START]; 99 jgArray=new byte[count]; 100 for(i=0; i<count; ++i) { 101 jgArray[i]=bytes.get(); 102 } 103 104 // read jgArray2[] 105 count=indexes[IX_JG_LIMIT2]-indexes[IX_JG_START2]; 106 jgArray2=new byte[count]; 107 for(i=0; i<count; ++i) { 108 jgArray2[i]=bytes.get(); 109 } 110 } 111 112 // implement ICUBinary.Authenticate 113 private static final class IsAcceptable implements ICUBinary.Authenticate { 114 public boolean isDataVersionAcceptable(byte version[]) { 115 return version[0]==2; 116 } 117 } 118 119 // property access functions ------------------------------------------- *** 120 121 public final int getClass(int c) { 122 return getClassFromProps(trie.get(c)); 123 } 124 125 private final int getMirror(int c, int props) { 126 int delta=getMirrorDeltaFromProps(props); 127 if(delta!=ESC_MIRROR_DELTA) { 128 return c+delta; 129 } else { 130 /* look for mirror code point in the mirrors[] table */ 131 int m; 132 int i, length; 133 int c2; 134 135 length=indexes[IX_MIRROR_LENGTH]; 136 137 /* linear search */ 138 for(i=0; i<length; ++i) { 139 m=mirrors[i]; 140 c2=getMirrorCodePoint(m); 141 if(c==c2) { 142 /* found c, return its mirror code point using the index in m */ 143 return getMirrorCodePoint(mirrors[getMirrorIndex(m)]); 144 } else if(c<c2) { 145 break; 146 } 147 } 148 149 /* c not found, return it itself */ 150 return c; 151 } 152 } 153 154 public final int getMirror(int c) { 155 int props=trie.get(c); 156 return getMirror(c, props); 157 } 158 159 public final int getJoiningType(int c) { 160 return (trie.get(c)&JT_MASK)>>JT_SHIFT; 161 } 162 163 public final int getJoiningGroup(int c) { 164 int start, limit; 165 166 start=indexes[IX_JG_START]; 167 limit=indexes[IX_JG_LIMIT]; 168 if(start<=c && c<limit) { 169 return (int)jgArray[c-start]&0xff; 170 } 171 start=indexes[IX_JG_START2]; 172 limit=indexes[IX_JG_LIMIT2]; 173 if(start<=c && c<limit) { 174 return (int)jgArray2[c-start]&0xff; 175 } 176 return UCharacter.JoiningGroup.NO_JOINING_GROUP; 177 } 178 179 public final int getPairedBracketType(int c) { 180 return (trie.get(c)&BPT_MASK)>>BPT_SHIFT; 181 } 182 183 public final int getPairedBracket(int c) { 184 int props=trie.get(c); 185 if((props&BPT_MASK)==0) { 186 return c; 187 } else { 188 return getMirror(c, props); 189 } 190 } 191 192 // data members -------------------------------------------------------- *** 193 private int indexes[]; 194 private int mirrors[]; 195 private byte jgArray[]; 196 private byte jgArray2[]; 197 198 private Trie2_16 trie; 199 200 // data format constants ----------------------------------------------- *** 201 private static final String DATA_FILE_NAME = "/jdk/internal/icu/impl/data/icudt64b/ubidi.icu"; 202 203 /* format "BiDi" */ 204 private static final int FMT=0x42694469; 205 206 /* indexes into indexes[] */ 207 private static final int IX_TRIE_SIZE=2; 208 private static final int IX_MIRROR_LENGTH=3; 209 210 private static final int IX_JG_START=4; 211 private static final int IX_JG_LIMIT=5; 212 private static final int IX_JG_START2=6; /* new in format version 2.2, ICU 54 */ 213 private static final int IX_JG_LIMIT2=7; 214 215 private static final int IX_TOP=16; 216 217 // definitions for 16-bit bidi/shaping properties word ----------------- *** 218 219 /* CLASS_SHIFT=0, */ /* bidi class: 5 bits (4..0) */ 220 private static final int JT_SHIFT=5; /* joining type: 3 bits (7..5) */ 221 222 private static final int BPT_SHIFT=8; /* Bidi_Paired_Bracket_Type(bpt): 2 bits (9..8) */ 223 224 private static final int MIRROR_DELTA_SHIFT=13; /* bidi mirroring delta: 3 bits (15..13) */ 225 226 private static final int CLASS_MASK= 0x0000001f; 227 private static final int JT_MASK= 0x000000e0; 228 private static final int BPT_MASK= 0x00000300; 229 230 private static final int getClassFromProps(int props) { 231 return props&CLASS_MASK; 232 } 233 private static final boolean getFlagFromProps(int props, int shift) { 234 return ((props>>shift)&1)!=0; 235 } 236 private static final int getMirrorDeltaFromProps(int props) { 237 return (short)props>>MIRROR_DELTA_SHIFT; 238 } 239 240 private static final int ESC_MIRROR_DELTA=-4; 241 242 // definitions for 32-bit mirror table entry --------------------------- *** 243 244 /* the source Unicode code point takes 21 bits (20..0) */ 245 private static final int MIRROR_INDEX_SHIFT=21; 246 247 private static final int getMirrorCodePoint(int m) { 248 return m&0x1fffff; 249 } 250 private static final int getMirrorIndex(int m) { 251 return m>>>MIRROR_INDEX_SHIFT; 252 } 253 254 255 /* 256 * public singleton instance 257 */ 258 public static final UBiDiProps INSTANCE; 259 260 // This static initializer block must be placed after 261 // other static member initialization 262 static { 263 try { 264 INSTANCE = new UBiDiProps(); 265 } catch (IOException e) { 266 throw new MissingResourceException(e.getMessage(),DATA_FILE_NAME,""); 267 } 268 } 269 }