Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/make/src/classes/build/tools/generatebreakiteratordata/SupplementaryCharacterData.java
32287 views
/*1* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package build.tools.generatebreakiteratordata;2627import java.util.Arrays;2829final class SupplementaryCharacterData {3031/**32* Default value33*/34private static final byte DEFAULT_VALUE = 0;35private byte defaultValue;3637/**38* A array which has a unicode code point(0x010000-0x10FFFF) as the upper39* 3 bytes and a value as the remaining one byte in each data.40*/41private int[] dataTable;4243/*44* Counter to keep the number of data in tempTable45*/46private int dataCount;4748/*49* Temporary data table used until dataTable is generated.50*/51private long[] tempTable;5253/*54* Initila tempTable size55*/56private static final int INITIAL_TABLE_SIZE = 150;5758/*59* The number of entries to be appended when tempTable becomes full60*/61private static final int ADDITIONAL_TABLE_SIZE = 10;6263/*64* Upper limit, used as a sentinel65*/66private static final int UPPER_LIMIT = Character.MAX_CODE_POINT + 1;6768/*69* Mask for supplementary code points(0x010000-0x10FFFF)70*/71private static final int CODEPOINT_MASK = 0x1FFFFF;727374public SupplementaryCharacterData(byte value) {75defaultValue = value;76dataCount = 0;77}7879/**80* Appends the given data to tempTable81*/82public void appendElement(int start, int end, byte value) {83if (tempTable == null) {84tempTable = new long[INITIAL_TABLE_SIZE];85}8687if (dataCount == tempTable.length) {88long[] tempTempTable = new long[dataCount + ADDITIONAL_TABLE_SIZE];89System.arraycopy(tempTable, 0, tempTempTable, 0, dataCount);90tempTable = tempTempTable;91}92tempTable[dataCount++] = ((((long)start<<24) + end)<<8) + value;93}9495/**96* Returns the data table97*/98public int[] getArray() {99return dataTable;100}101102/**103* Creates dataTable104*/105public void complete() {106dataTable = generateTable();107}108109/**110* Generates a table from the given data111*/112private int[] generateTable() {113/* If tempTable is empty, put two data */114if (dataCount == 0) {115int[] tmpArray = new int[2];116tmpArray[0] = composeEntry(0, DEFAULT_VALUE);117tmpArray[1] = composeEntry(UPPER_LIMIT, DEFAULT_VALUE);118tempTable = null;119return tmpArray;120}121122Arrays.sort(tempTable, 0, dataCount);123124int[] newTempTable = new int[dataCount*2 + 3];125126int old_index = 0;127int new_index = 0;128int loop_count = dataCount - 1;129long data = tempTable[old_index];130int start = (int)(data>>32) & CODEPOINT_MASK;131int end = (int)(data>>8) & CODEPOINT_MASK;132133/*134* Add an entry if the first start code point in tempTable is not135* the minimum supplementary code point.136*/137if (start != Character.MIN_SUPPLEMENTARY_CODE_POINT) {138newTempTable[new_index++] = composeEntry(Character.MIN_SUPPLEMENTARY_CODE_POINT, defaultValue);139}140141newTempTable[new_index++] = composeEntry(start, (int)data);142for (int i = 0; i < loop_count; i++) {143data = tempTable[++old_index];144int nextStart = (int)(data>>32) & CODEPOINT_MASK;145146/*147* If the previous end code point is not equal to the previous start148* code point and is not consecutive with the next start code point,149* insert a filler entry before an entry for the next start code150* point.151*/152if (end != start && end != nextStart-1) {153newTempTable[new_index++] = composeEntry(end + 1, defaultValue);154}155newTempTable[new_index++] = composeEntry(nextStart, (int)data);156start = nextStart;157end = (int)(data>>8) & CODEPOINT_MASK;158}159newTempTable[new_index++] = composeEntry(++end, defaultValue);160161/* Add an entry for a sentinel if necessary. */162if (end < UPPER_LIMIT) {163newTempTable[new_index++] = composeEntry(UPPER_LIMIT, defaultValue);164}165166/* Copy data to dataTable. */167dataTable = new int[new_index];168System.arraycopy(newTempTable, 0, dataTable, 0, new_index);169170tempTable = null;171172return dataTable;173}174175/**176* Composes an entry with the given supplementary code point177* (0x010000-0x10FFFF) for the upper 3 bytes and the given value for the178* remaining one byte.179*/180private int composeEntry(int codePoint, int value) {181return (codePoint<<8) | (value&0xFF);182}183}184185186