1 /* 2 * Copyright (c) 2005, 2009, 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 * (C) Copyright IBM Corp. and others, 1996-2009 - All Rights Reserved * 28 * * 29 * The original version of this source code and documentation is copyrighted * 30 * and owned by IBM, These materials are provided under terms of a License * 31 * Agreement between IBM and Sun. This technology is protected by multiple * 32 * US and International patents. This notice and attribution to IBM may not * 33 * to removed. * 34 ******************************************************************************* 35 * file name: UBiDiProps.java 36 * encoding: US-ASCII 37 * tab size: 8 (not used) 38 * indentation:4 39 * 40 * created on: 2005jan16 41 * created by: Markus W. Scherer 42 * 43 * Low-level Unicode bidi/shaping properties access. 44 * Java port of ubidi_props.h/.c. 45 */ 46 47 package sun.text.normalizer; 48 49 import java.io.BufferedInputStream; 50 import java.io.DataInputStream; 51 import java.io.InputStream; 52 import java.io.IOException; 53 54 public final class UBiDiProps { 55 // constructors etc. --------------------------------------------------- *** 56 57 // port of ubidi_openProps() 58 public UBiDiProps() throws IOException{ 59 InputStream is=ICUData.getStream(DATA_FILE_NAME); 60 BufferedInputStream b=new BufferedInputStream(is, 4096 /* data buffer size */); 61 readData(b); 62 b.close(); 63 is.close(); 64 65 } 66 67 private void readData(InputStream is) throws IOException { 68 DataInputStream inputStream=new DataInputStream(is); 69 70 // read the header 71 ICUBinary.readHeader(inputStream, FMT, new IsAcceptable()); 72 73 // read indexes[] 74 int i, count; 75 count=inputStream.readInt(); 76 if(count<IX_INDEX_TOP) { 77 throw new IOException("indexes[0] too small in "+DATA_FILE_NAME); 78 } 79 indexes=new int[count]; 80 81 indexes[0]=count; 82 for(i=1; i<count; ++i) { 83 indexes[i]=inputStream.readInt(); 84 } 85 86 // read the trie 87 trie=new CharTrie(inputStream, null); 88 89 // read mirrors[] 90 count=indexes[IX_MIRROR_LENGTH]; 91 if(count>0) { 92 mirrors=new int[count]; 93 for(i=0; i<count; ++i) { 94 mirrors[i]=inputStream.readInt(); 95 } 96 } 97 98 // read jgArray[] 99 count=indexes[IX_JG_LIMIT]-indexes[IX_JG_START]; 100 jgArray=new byte[count]; 101 for(i=0; i<count; ++i) { 102 jgArray[i]=inputStream.readByte(); 103 } 104 } 105 106 // implement ICUBinary.Authenticate 107 private final class IsAcceptable implements ICUBinary.Authenticate { 108 public boolean isDataVersionAcceptable(byte version[]) { 109 return version[0]==1 && 110 version[2]==Trie.INDEX_STAGE_1_SHIFT_ && version[3]==Trie.INDEX_STAGE_2_SHIFT_; 111 } 112 } 113 114 // UBiDiProps singleton 115 private static UBiDiProps gBdp=null; 116 117 // port of ubidi_getSingleton() 118 public static final synchronized UBiDiProps getSingleton() throws IOException { 119 if(gBdp==null) { 120 gBdp=new UBiDiProps(); 121 } 122 return gBdp; 123 } 124 125 // UBiDiProps dummy singleton 126 private static UBiDiProps gBdpDummy=null; 127 128 private UBiDiProps(boolean makeDummy) { // ignore makeDummy, only creates a unique signature 129 indexes=new int[IX_TOP]; 130 indexes[0]=IX_TOP; 131 trie=new CharTrie(0, 0, null); // dummy trie, always returns 0 132 } 133 134 /** 135 * Get a singleton dummy object, one that works with no real data. 136 * This can be used when the real data is not available. 137 * Using the dummy can reduce checks for available data after an initial failure. 138 * Port of ucase_getDummy(). 139 */ 140 public static final synchronized UBiDiProps getDummy() { 141 if(gBdpDummy==null) { 142 gBdpDummy=new UBiDiProps(true); 143 } 144 return gBdpDummy; 145 } 146 147 public final int getClass(int c) { 148 return getClassFromProps(trie.getCodePointValue(c)); 149 } 150 151 // data members -------------------------------------------------------- *** 152 private int indexes[]; 153 private int mirrors[]; 154 private byte jgArray[]; 155 156 private CharTrie trie; 157 158 // data format constants ----------------------------------------------- *** 159 private static final String DATA_FILE_NAME = "/sun/text/resources/ubidi.icu"; 160 161 /* format "BiDi" */ 162 private static final byte FMT[]={ 0x42, 0x69, 0x44, 0x69 }; 163 164 /* indexes into indexes[] */ 165 private static final int IX_INDEX_TOP=0; 166 private static final int IX_MIRROR_LENGTH=3; 167 168 private static final int IX_JG_START=4; 169 private static final int IX_JG_LIMIT=5; 170 171 private static final int IX_TOP=16; 172 173 private static final int CLASS_MASK= 0x0000001f; 174 175 private static final int getClassFromProps(int props) { 176 return props&CLASS_MASK; 177 } 178 179 } | 1 /* 2 * Copyright (c) 2005, 2015, 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 sun.text.normalizer; 45 46 import java.io.IOException; 47 import java.nio.ByteBuffer; 48 import java.util.MissingResourceException; 49 50 public final class UBiDiProps { 51 // constructors etc. --------------------------------------------------- *** 52 53 // port of ubidi_openProps() 54 private UBiDiProps() throws IOException{ 55 ByteBuffer bytes=ICUBinary.getRequiredData(DATA_FILE_NAME); 56 readData(bytes); 57 } 58 59 private void readData(ByteBuffer bytes) throws IOException { 60 // read the header 61 ICUBinary.readHeader(bytes, FMT, new IsAcceptable()); 62 63 // read indexes[] 64 int i, count; 65 count=bytes.getInt(); 66 if(count<IX_TOP) { 67 throw new IOException("indexes[0] too small in "+DATA_FILE_NAME); 68 } 69 indexes=new int[count]; 70 71 indexes[0]=count; 72 for(i=1; i<count; ++i) { 73 indexes[i]=bytes.getInt(); 74 } 75 76 // read the trie 77 trie=Trie2_16.createFromSerialized(bytes); 78 int expectedTrieLength=indexes[IX_TRIE_SIZE]; 79 int trieLength=trie.getSerializedLength(); 80 if(trieLength>expectedTrieLength) { 81 throw new IOException(DATA_FILE_NAME+": not enough bytes for the trie"); 82 } 83 // skip padding after trie bytes 84 ICUBinary.skipBytes(bytes, expectedTrieLength-trieLength); 85 86 // read mirrors[] 87 count=indexes[IX_MIRROR_LENGTH]; 88 if(count>0) { 89 mirrors=new int[count]; 90 for(i=0; i<count; ++i) { 91 mirrors[i]=bytes.getInt(); 92 } 93 } 94 95 // read jgArray[] 96 count=indexes[IX_JG_LIMIT]-indexes[IX_JG_START]; 97 jgArray=new byte[count]; 98 for(i=0; i<count; ++i) { 99 jgArray[i]=bytes.get(); 100 } 101 102 // read jgArray2[] 103 count=indexes[IX_JG_LIMIT2]-indexes[IX_JG_START2]; 104 jgArray2=new byte[count]; 105 for(i=0; i<count; ++i) { 106 jgArray2[i]=bytes.get(); 107 } 108 } 109 110 // implement ICUBinary.Authenticate 111 private final static class IsAcceptable implements ICUBinary.Authenticate { 112 public boolean isDataVersionAcceptable(byte version[]) { 113 return version[0]==2; 114 } 115 } 116 117 // property access functions ------------------------------------------- *** 118 119 public final int getClass(int c) { 120 return getClassFromProps(trie.get(c)); 121 } 122 123 private final int getMirror(int c, int props) { 124 int delta=getMirrorDeltaFromProps(props); 125 if(delta!=ESC_MIRROR_DELTA) { 126 return c+delta; 127 } else { 128 /* look for mirror code point in the mirrors[] table */ 129 int m; 130 int i, length; 131 int c2; 132 133 length=indexes[IX_MIRROR_LENGTH]; 134 135 /* linear search */ 136 for(i=0; i<length; ++i) { 137 m=mirrors[i]; 138 c2=getMirrorCodePoint(m); 139 if(c==c2) { 140 /* found c, return its mirror code point using the index in m */ 141 return getMirrorCodePoint(mirrors[getMirrorIndex(m)]); 142 } else if(c<c2) { 143 break; 144 } 145 } 146 147 /* c not found, return it itself */ 148 return c; 149 } 150 } 151 152 public final int getMirror(int c) { 153 int props=trie.get(c); 154 return getMirror(c, props); 155 } 156 157 public final int getJoiningType(int c) { 158 return (trie.get(c)&JT_MASK)>>JT_SHIFT; 159 } 160 161 public final int getJoiningGroup(int c) { 162 int start, limit; 163 164 start=indexes[IX_JG_START]; 165 limit=indexes[IX_JG_LIMIT]; 166 if(start<=c && c<limit) { 167 return (int)jgArray[c-start]&0xff; 168 } 169 start=indexes[IX_JG_START2]; 170 limit=indexes[IX_JG_LIMIT2]; 171 if(start<=c && c<limit) { 172 return (int)jgArray2[c-start]&0xff; 173 } 174 return UCharacter.JoiningGroup.NO_JOINING_GROUP; 175 } 176 177 public final int getPairedBracketType(int c) { 178 return (trie.get(c)&BPT_MASK)>>BPT_SHIFT; 179 } 180 181 public final int getPairedBracket(int c) { 182 int props=trie.get(c); 183 if((props&BPT_MASK)==0) { 184 return c; 185 } else { 186 return getMirror(c, props); 187 } 188 } 189 190 // data members -------------------------------------------------------- *** 191 private int indexes[]; 192 private int mirrors[]; 193 private byte jgArray[]; 194 private byte jgArray2[]; 195 196 private Trie2_16 trie; 197 198 // data format constants ----------------------------------------------- *** 199 private static final String DATA_FILE_NAME = "/sun/text/resources/ubidi.icu"; 200 201 /* format "BiDi" */ 202 private static final int FMT=0x42694469; 203 204 /* indexes into indexes[] */ 205 private static final int IX_TRIE_SIZE=2; 206 private static final int IX_MIRROR_LENGTH=3; 207 208 private static final int IX_JG_START=4; 209 private static final int IX_JG_LIMIT=5; 210 private static final int IX_JG_START2=6; /* new in format version 2.2, ICU 54 */ 211 private static final int IX_JG_LIMIT2=7; 212 213 private static final int IX_TOP=16; 214 215 // definitions for 16-bit bidi/shaping properties word ----------------- *** 216 217 /* CLASS_SHIFT=0, */ /* bidi class: 5 bits (4..0) */ 218 private static final int JT_SHIFT=5; /* joining type: 3 bits (7..5) */ 219 220 private static final int BPT_SHIFT=8; /* Bidi_Paired_Bracket_Type(bpt): 2 bits (9..8) */ 221 222 private static final int MIRROR_DELTA_SHIFT=13; /* bidi mirroring delta: 3 bits (15..13) */ 223 224 private static final int CLASS_MASK= 0x0000001f; 225 private static final int JT_MASK= 0x000000e0; 226 private static final int BPT_MASK= 0x00000300; 227 228 private static final int getClassFromProps(int props) { 229 return props&CLASS_MASK; 230 } 231 private static final boolean getFlagFromProps(int props, int shift) { 232 return ((props>>shift)&1)!=0; 233 } 234 private static final int getMirrorDeltaFromProps(int props) { 235 return (short)props>>MIRROR_DELTA_SHIFT; 236 } 237 238 private static final int ESC_MIRROR_DELTA=-4; 239 240 // definitions for 32-bit mirror table entry --------------------------- *** 241 242 /* the source Unicode code point takes 21 bits (20..0) */ 243 private static final int MIRROR_INDEX_SHIFT=21; 244 245 private static final int getMirrorCodePoint(int m) { 246 return m&0x1fffff; 247 } 248 private static final int getMirrorIndex(int m) { 249 return m>>>MIRROR_INDEX_SHIFT; 250 } 251 252 253 /* 254 * public singleton instance 255 */ 256 public static final UBiDiProps INSTANCE; 257 258 // This static initializer block must be placed after 259 // other static member initialization 260 static { 261 try { 262 INSTANCE = new UBiDiProps(); 263 } catch (IOException e) { 264 throw new MissingResourceException(e.getMessage(),DATA_FILE_NAME,""); 265 } 266 } 267 } |