AbstractUnicodeDataScanner.java
/*
* Copyright (C) 2009 Steve Rowe <sarowe@gmail.com>
* Copyright (C) 2020 Google, LLC.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package de.jflex.ucd_generator.scanner;
import com.google.common.base.Preconditions;
import de.jflex.ucd.UcdVersion;
import de.jflex.ucd.Versions;
import de.jflex.ucd_generator.ucd.UnicodeData;
import de.jflex.version.Version;
/** Scanner of the {@code UnicodeData.txt}. */
abstract class AbstractUnicodeDataScanner {
private static final String GENERAL_CATEGORY = "General_Category";
private final UcdVersion ucdVersion;
private final UnicodeData unicodeData;
int codePoint = -1;
int startCodePoint = -1;
int prevCodePoint = 0;
int assignedStartCodePoint = -1;
int assignedEndCodePoint = -1;
String genCatPropValue;
String prevGenCatPropValue;
String uppercaseMapping = null;
String lowercaseMapping = null;
String titlecaseMapping = null;
boolean isLastInRange = false;
protected AbstractUnicodeDataScanner(UcdVersion ucdVersion, UnicodeData unicodeData) {
this.ucdVersion = ucdVersion;
this.unicodeData = unicodeData;
}
public void handleEntry() {
Preconditions.checkArgument(codePoint >= 0, "Negative codepoint: " + codePoint);
unicodeData.addCaselessMatches(codePoint, uppercaseMapping, lowercaseMapping, titlecaseMapping);
// UnicodeData-1.1.5.txt does not list the end point for the Unified Han
// range (starting point is listed as U+4E00). This is U+9FFF according
// to <http://unicode.org/Public/TEXT/OLDAPIX/CHANGES.TXT>:
//
// U+4E00 ^ U+9FFF 20,992 I-ZONE Ideographs
//
// U+4E00 is listed in UnicodeData-1.1.5.txt as having the "Lo" property
// value, as are the previous code points, so to include
// [ U+4E00 - U+9FFF ], this interval should be extended to U+9FFF.
if (assignedEndCodePoint == 0x4E00
&& Version.MAJOR_MINOR_COMPARATOR.compare(ucdVersion.version(), Versions.VERSION_1_1)
== 0) {
assignedEndCodePoint = 0x9FFF;
}
if (assignedStartCodePoint == -1) {
assignedStartCodePoint = startCodePoint;
} else if (codePoint > assignedEndCodePoint + 1 && !isLastInRange) {
unicodeData.addBinaryPropertyInterval(
"Assigned", assignedStartCodePoint, assignedEndCodePoint);
unicodeData.addEnumPropertyInterval(
GENERAL_CATEGORY, "Cn", assignedEndCodePoint + 1, codePoint - 1);
assignedStartCodePoint = codePoint;
}
assignedEndCodePoint = codePoint;
if (startCodePoint != -1
&& prevGenCatPropValue.length() > 0
&& (((codePoint > prevCodePoint + 1) && !isLastInRange)
|| !genCatPropValue.equals(prevGenCatPropValue))) {
// UnicodeData-1.1.5.txt does not list the end point for the Unified Han
// range (starting point is listed as U+4E00). This is U+9FFF according
// to <http://unicode.org/Public/TEXT/OLDAPIX/CHANGES.TXT>:
//
// U+4E00 ^ U+9FFF 20,992 I-ZONE Ideographs
//
// U+4E00 is listed in UnicodeData-1.1.5.txt as having the "Lo" property
// value, as are the previous code points, so to include
// [ U+4E00 - U+9FFF ], this interval should be extended to U+9FFF.
if (prevCodePoint == 0x4E00
&& Version.MAJOR_MINOR_COMPARATOR.compare(ucdVersion.version(), Versions.VERSION_1_1)
== 0) {
prevCodePoint = 0x9FFF;
}
unicodeData.addEnumPropertyInterval(
GENERAL_CATEGORY, prevGenCatPropValue, startCodePoint, prevCodePoint);
startCodePoint = -1;
}
if (genCatPropValue.length() > 0 && startCodePoint == -1) {
startCodePoint = codePoint;
}
prevCodePoint = codePoint;
prevGenCatPropValue = genCatPropValue;
reset();
}
public void reset() {
isLastInRange = false;
uppercaseMapping = null;
lowercaseMapping = null;
titlecaseMapping = null;
codePoint = -1;
}
public void handleFinalInterval() {
if (startCodePoint != -1 && prevGenCatPropValue.length() > 0) {
unicodeData.addEnumPropertyInterval(
GENERAL_CATEGORY, prevGenCatPropValue, startCodePoint, prevCodePoint);
}
// Handle the final Assigned interval
unicodeData.addBinaryPropertyInterval("Assigned", assignedStartCodePoint, assignedEndCodePoint);
// Round max code point up to end-of-plane.
unicodeData.maximumCodePoint(((prevCodePoint + 0x800) & 0xFFF000) - 1);
// Handle the final Unassigned (Cn) interval, if any
if (assignedEndCodePoint < unicodeData.maximumCodePoint()) {
unicodeData.addEnumPropertyInterval(
GENERAL_CATEGORY, "Cn", assignedEndCodePoint + 1, unicodeData.maximumCodePoint());
}
}
}