From 55f1018c417315a372c59846f378b53c51ababdf Mon Sep 17 00:00:00 2001
From: Matitiahu Allouche
Date: Wed, 13 Jul 2011 10:48:09 -0400
Subject: Bug 183164 - [Implementation for] Display of Complex Expressions
Containing Bidirectional Text
---
.../internal/tests/STextExtensibilityTest.java | 9 +-
.../bidi/internal/tests/STextExtensionsTest.java | 108 ++++--
.../bidi/internal/tests/STextFullToLeanTest.java | 38 +-
.../equinox/bidi/internal/tests/STextMathTest.java | 32 +-
.../bidi/internal/tests/STextMethodsTest.java | 241 ++++++-------
.../internal/tests/STextNullProcessorTest.java | 21 +-
.../bidi/internal/tests/STextSomeMoreTest.java | 32 +-
.../bidi/internal/tests/STextStringRecordTest.java | 118 ++++---
.../equinox/bidi/internal/tests/STextTest.java | 19 +-
.../equinox/bidi/internal/tests/STextUtilTest.java | 20 +-
.../src/org/eclipse/equinox/bidi/ISTextTypes.java | 106 ------
.../src/org/eclipse/equinox/bidi/STextEngine.java | 258 ++++++++------
.../org/eclipse/equinox/bidi/STextEnvironment.java | 39 +-
.../eclipse/equinox/bidi/STextStringRecord.java | 349 ++++++++++++------
.../src/org/eclipse/equinox/bidi/STextUtil.java | 44 ++-
.../equinox/bidi/custom/ISTextProcessor.java | 170 ---------
.../eclipse/equinox/bidi/custom/STextFeatures.java | 250 -------------
.../equinox/bidi/custom/STextProcessor.java | 392 +++++++++++++++++----
.../equinox/bidi/custom/STextStringProcessor.java | 2 +-
.../org/eclipse/equinox/bidi/custom/package.html | 9 +-
.../eclipse/equinox/bidi/internal/STextDelims.java | 27 +-
.../equinox/bidi/internal/STextDelimsEsc.java | 12 +-
.../eclipse/equinox/bidi/internal/STextImpl.java | 221 ++++--------
.../eclipse/equinox/bidi/internal/STextSingle.java | 28 +-
.../equinox/bidi/internal/STextTypesCollector.java | 8 +-
.../bidi/internal/consumable/STextComma.java | 11 +-
.../bidi/internal/consumable/STextEmail.java | 58 ++-
.../bidi/internal/consumable/STextFile.java | 12 +-
.../bidi/internal/consumable/STextJava.java | 27 +-
.../bidi/internal/consumable/STextMath.java | 52 ++-
.../bidi/internal/consumable/STextProperty.java | 12 +-
.../bidi/internal/consumable/STextRegex.java | 58 ++-
.../equinox/bidi/internal/consumable/STextSql.java | 27 +-
.../bidi/internal/consumable/STextSystem.java | 14 +-
.../equinox/bidi/internal/consumable/STextURL.java | 13 +-
.../bidi/internal/consumable/STextUnderscore.java | 13 +-
.../bidi/internal/consumable/STextXPath.java | 18 +-
.../src/org/eclipse/equinox/bidi/package.html | 38 +-
38 files changed, 1413 insertions(+), 1493 deletions(-)
delete mode 100644 bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/ISTextTypes.java
delete mode 100644 bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/custom/ISTextProcessor.java
delete mode 100644 bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/custom/STextFeatures.java
diff --git a/bundles/org.eclipse.equinox.bidi.tests/src/org/eclipse/equinox/bidi/internal/tests/STextExtensibilityTest.java b/bundles/org.eclipse.equinox.bidi.tests/src/org/eclipse/equinox/bidi/internal/tests/STextExtensibilityTest.java
index 033c167bc..e1b291052 100644
--- a/bundles/org.eclipse.equinox.bidi.tests/src/org/eclipse/equinox/bidi/internal/tests/STextExtensibilityTest.java
+++ b/bundles/org.eclipse.equinox.bidi.tests/src/org/eclipse/equinox/bidi/internal/tests/STextExtensibilityTest.java
@@ -12,8 +12,8 @@
package org.eclipse.equinox.bidi.internal.tests;
import org.eclipse.equinox.bidi.STextEngine;
+import org.eclipse.equinox.bidi.custom.STextProcessor;
import org.eclipse.equinox.bidi.custom.STextStringProcessor;
-import org.eclipse.equinox.bidi.custom.ISTextProcessor;
/**
* Tests contribution of BiDi processors.
@@ -28,7 +28,7 @@ public class STextExtensibilityTest extends STextTestBase {
// check one of the types that we know should be there
assertTrue(isTypePresent(types, "regex"));
- ISTextProcessor processor = STextStringProcessor.getProcessor("regex");
+ STextProcessor processor = STextStringProcessor.getProcessor("regex");
assertNotNull(processor);
}
@@ -40,7 +40,7 @@ public class STextExtensibilityTest extends STextTestBase {
// check the type added by the test bundle
assertTrue(isTypePresent(types, "test"));
- ISTextProcessor processor = STextStringProcessor.getProcessor("test");
+ STextProcessor processor = STextStringProcessor.getProcessor("test");
assertNotNull(processor);
processor = STextStringProcessor.getProcessor("badtest");
@@ -49,7 +49,8 @@ public class STextExtensibilityTest extends STextTestBase {
String data, lean, full, model;
data = "ABC.DEF:HOST-COM=HELLO";
lean = toUT16(data);
- full = STextEngine.leanToFullText("test", null, null, lean, null);
+ processor = STextStringProcessor.getProcessor("test");
+ full = STextEngine.leanToFullText(processor, null, lean, null);
model = "ABC@.DEF@:HOST@-COM@=HELLO";
assertEquals("Test 'test' plugin", model, toPseudo(full));
}
diff --git a/bundles/org.eclipse.equinox.bidi.tests/src/org/eclipse/equinox/bidi/internal/tests/STextExtensionsTest.java b/bundles/org.eclipse.equinox.bidi.tests/src/org/eclipse/equinox/bidi/internal/tests/STextExtensionsTest.java
index 75166beb3..753361e81 100644
--- a/bundles/org.eclipse.equinox.bidi.tests/src/org/eclipse/equinox/bidi/internal/tests/STextExtensionsTest.java
+++ b/bundles/org.eclipse.equinox.bidi.tests/src/org/eclipse/equinox/bidi/internal/tests/STextExtensionsTest.java
@@ -11,9 +11,9 @@
package org.eclipse.equinox.bidi.internal.tests;
+import java.util.Locale;
import org.eclipse.equinox.bidi.STextEngine;
-import org.eclipse.equinox.bidi.ISTextTypes;
-import org.eclipse.equinox.bidi.custom.*;
+import org.eclipse.equinox.bidi.custom.STextProcessor;
/**
* Tests all plug-in extensions
@@ -21,47 +21,55 @@ import org.eclipse.equinox.bidi.custom.*;
public class STextExtensionsTest extends STextTestBase {
- ISTextProcessor processor;
- STextFeatures f1, f2;
+ STextProcessor processor;
int[] state = new int[1];
- String type;
private void doTest1(String label, String data, String result) {
String full;
- full = STextEngine.leanToFullText(type, null, null, toUT16(data), state);
+ full = STextEngine.leanToFullText(processor, null, toUT16(data), state);
assertEquals(label + " data = " + data, result, toPseudo(full));
}
private void doTest2(String label, String data, String result) {
String full;
- full = STextEngine.leanToFullText(type, null, null, data, state);
+ full = STextEngine.leanToFullText(processor, null, data, state);
assertEquals(label + " data = " + data, result, toPseudo(full));
}
private void doTest3(String label, String data, String result) {
String full;
- full = STextEngine.leanToFullText(processor, f2, null, toUT16(data), state);
+ full = STextEngine.leanToFullText(processor, null, toUT16(data), state);
assertEquals(label + " data = " + data, result, toPseudo(full));
}
public void testExtensions() {
- type = ISTextTypes.COMMA_DELIMITED;
+ String data;
+ processor = STextEngine.PROC_COMMA_DELIMITED;
state[0] = STextEngine.STATE_INITIAL;
doTest1("Comma #1", "ab,cd, AB, CD, EFG", "ab,cd, AB@, CD@, EFG");
- type = ISTextTypes.EMAIL;
+ processor = STextEngine.PROC_EMAIL;
state[0] = STextEngine.STATE_INITIAL;
doTest1("Email #1", "abc.DEF:GHI", "abc.DEF@:GHI");
doTest1("Email #2", "DEF.GHI \"A.B\":JK ", "DEF@.GHI @\"A.B\"@:JK ");
doTest1("Email #3", "DEF,GHI (A,B);JK ", "DEF@,GHI @(A,B)@;JK ");
doTest1("Email #4", "DEF.GHI (A.B :JK ", "DEF@.GHI @(A.B :JK ");
-
- type = ISTextTypes.FILE;
+ Locale.setDefault(new Locale("ar"));
+ doTest1("Email #5", "#EF.GHI \"A.B\":JK ", "<EF.GHI \"A.B\":JK &^");
+ doTest1("Email #6", "#EF,GHI (A,B);JK ", "<EF,GHI (A,B);JK &^");
+ doTest1("Email #7", "#EF.GHI (A.B :JK ", "<EF.GHI (A.B :JK &^");
+ data = toUT16("peter.pan") + "@" + toUT16("#EF.GHI");
+ doTest2("Email #8", data, "<&peter&.pan@#EF.GHI&^");
+ Locale.setDefault(new Locale("he"));
+ data = toUT16("peter.pan") + "@" + toUT16("DEF.GHI");
+ doTest2("Email #9", data, "peter.pan@DEF@.GHI");
+
+ processor = STextEngine.PROC_FILE;
state[0] = STextEngine.STATE_INITIAL;
doTest1("File #1", "c:\\A\\B\\FILE.EXT", "c:\\A@\\B@\\FILE@.EXT");
- type = ISTextTypes.JAVA;
+ processor = STextEngine.PROC_JAVA;
state[0] = STextEngine.STATE_INITIAL;
doTest1("Java #1", "A = B + C;", "A@ = B@ + C;");
doTest1("Java #2", "A = B + C;", "A@ = B@ + C;");
@@ -74,14 +82,13 @@ public class STextExtensionsTest extends STextTestBase {
doTest1("Java #9", "A = //B+C* D;", "A@ = //B+C* D;");
doTest1("Java #10", "A = //B+C`|D+E;", "A@ = //B+C`|D@+E;");
- type = ISTextTypes.PROPERTY;
+ processor = STextEngine.PROC_PROPERTY;
state[0] = STextEngine.STATE_INITIAL;
doTest1("Property #0", "NAME,VAL1,VAL2", "NAME,VAL1,VAL2");
doTest1("Property #1", "NAME=VAL1,VAL2", "NAME@=VAL1,VAL2");
doTest1("Property #2", "NAME=VAL1,VAL2=VAL3", "NAME@=VAL1,VAL2=VAL3");
- String data;
- type = ISTextTypes.REGEXP;
+ processor = STextEngine.PROC_REGEXP;
state[0] = STextEngine.STATE_INITIAL;
data = toUT16("ABC(?") + "#" + toUT16("DEF)GHI");
doTest2("Regex #0.0", data, "A@B@C@(?#DEF)@G@H@I");
@@ -127,7 +134,45 @@ public class STextExtensionsTest extends STextTestBase {
doTest1("Regex #17.6", "aB*123", "aB*@123");
doTest1("Regex #17.7", "aB*567", "aB*@567");
- type = ISTextTypes.SQL;
+ Locale.setDefault(new Locale("ar"));
+ data = toUT16("#BC(?") + "#" + toUT16("DEF)GHI");
+ doTest2("Regex #0.0", data, "<BC(?#DEF)GHI&^");
+ data = toUT16("#BC(?") + "#" + toUT16("DEF");
+ doTest2("Regex #0.1", data, "<BC(?#DEF&^");
+ doTest1("Regex #0.2", "#HI)JKL", "<HI)JKL&^");
+ data = toUT16("#BC(?") + "<" + toUT16("DEF") + ">" + toUT16("GHI");
+ doTest2("Regex #1", data, "<BC(? All the methods in this class have a first argument which
- * designates a type of processor.
+ * designates a processor.
*
- * It can be specified as a string (usually one of the
- * literals to be found in {@link ISTextTypes}
- * or as an instance of {@link ISTextProcessor}.
+ * It must be specified as an instance of {@link STextProcessor}.
+ * Pre-defined instances are included in STextEngine for all
+ * the types of structured text supported by this package.
*
- * Such an instance can be obtained using the
+ * For processors supplied by other packages, a processor instance
+ * can be obtained using the
* {@link org.eclipse.equinox.bidi.custom.STextStringProcessor#getProcessor getProcessor}
* method for the registered processors, or by instantiating a private processor.
*
- * When the same processor is used in multiple calls, it may be
- * beneficial to obtain a reference to the processor and to use it
- * in following calls, rather than to specify the processor by its
- * type expressed as a string, which necessitates a registry search
- * for each call.
- *
- * A processor reference is also the only way to examine the
- * features of a processor by calling its
- * {@link ISTextProcessor#getFeatures getFeatures} method.
- *
* Specifying If this argument is This argument may be specified as This argument may be specified as If this argument is This argument may be specified as This argument may be specified as If this argument is This argument may be specified as This argument may be specified as If this argument is This argument may be specified as This argument may be specified as If this argument is This argument may be specified as This argument may be specified as If this argument is This argument may be specified as This argument may be specified as If this argument is This argument may be specified as
* This class also provides a number of convenience methods related to the environment.
*
@@ -22,6 +22,11 @@ import org.eclipse.equinox.bidi.custom.STextStringProcessor;
*
* The pool is managed as a cyclic list. When the pool is full,
* each new element overrides the oldest element in the list.
+ *
+ * A string may be itself entirely a structured text, or it may contain
+ * segments each of which is a structured text of a given type. Each such
+ * segment is identified by its starting and ending offsets within the
+ * string, and by the processor which is appropriate to handle it.
*/
public class STextStringRecord {
/**
@@ -33,144 +38,274 @@ public class STextStringRecord {
private static final int MAXINDEX = POOLSIZE - 1;
// index of the last entered record
- private static int last = MAXINDEX;
+ private static int last = -1;
+
+ // flag indicating that the pool has wrapped around
+ private static boolean wrapAround;
// the pool
- private static STextStringRecord[] records = new STextStringRecord[POOLSIZE];
+ private static SoftReference[] recordRefs = new SoftReference[POOLSIZE];
- // structured text types
- private static final String[] types = STextStringProcessor.getKnownTypes();
+ // hash code of the recorded strings
+ private static int[] hashArray = new int[POOLSIZE];
- // maximum type index allowed
- private static int MAXTYPE = types.length - 1;
+ // total number of segments in the record
+ private int totalSegmentCount;
+
+ // number of used segments in the record
+ private int usedSegmentCount;
// reference to the recorded string
- private SoftReference strRef;
+ private String string;
- // hash code of the recorded string
- private int hash;
+ // reference to the processors of the STT segments in the recorded string
+ private STextProcessor[] processors;
- // reference to the triplets of the recorded string
- private SoftReference triRef;
+ // reference to the boundaries of the STT segments in the recorded string
+ // (entries 0, 2, 4, ... are start offsets; entries 1, 3, 5, ... are
+ // ending offsets)
+ private short[] boundaries;
/**
- * Constructor.
- *
- * @param string the string to record
- *
- * @param triplets
- * array of short integers, the number of elements in the array
- * must be a multiple of 3, so that the array is made of one or
- * more triplets of short integers.
- *
- * The first element in each triplet is the beginning offset of a
- * susbstring of
- * The second element in each triplet is the ending offset of a
- * susbstring of
- * The third element in each triplet is the numeric type of the
- * structured text.
- * This method is called repeatedly from the code implementing
- * {@link STextEngine#leanToFullText leanToFullText} if the
- * number of special cases appearing in the associated
- * The code implementing this method may use the following methods
- * in {@link STextProcessor}:
- *
- * The code implementing this method may use the following methods
- * in {@link STextProcessor}:
- *
- * If a special processing cannot be completed within a current call to
- *
- * All public fields in this class are Example 1 (set all features)
- * Example 2 (change only the separators)
- *
* Here are some guidelines about how to write structured text
@@ -23,89 +23,220 @@ import org.eclipse.equinox.bidi.internal.STextImpl;
*
+ * This method is called repeatedly from the code implementing
+ * {@link STextEngine#leanToFullText leanToFullText} if the
+ * number of special cases returned by {@link #getSpecialsCount getSpecialsCount}
+ * is greater than zero.
+ *
+ * The code implementing this method may use the following methods:
+ * A processor which extends this class must override this method
- * and return a STextFeatures instance representing its specific
- * features.
+ * @param environment the current environment, which may affect the behavior of
+ * the processor. This parameter may be specified as
+ * If not overridden, this method throws an
* A processor handling special cases must override this method.
- *
- * @see ISTextProcessor#indexOfSpecial the corresponding interface method
*/
- public int indexOfSpecial(STextFeatures features, String text, byte[] dirProps, int[] offsets, int caseNumber, int fromIndex) {
+ public int indexOfSpecial(STextEnvironment environment, String text, byte[] dirProps, int[] offsets, int caseNumber, int fromIndex) {
// This method must be overridden by all subclasses with special cases.
- throw new IllegalStateException("A processor must have an indexOfSpecial() method."); //$NON-NLS-1$
+ throw new IllegalStateException("A processor with specialsCount > 0 must have an indexOfSpecial() method."); //$NON-NLS-1$
}
/**
- * In
+ * The code implementing this method may use the following methods:
+ *
+ * If a special processing cannot be completed within a current call to
+ * If not overridden, this method throws an
* A processor handling special cases must override this method.
- *
- * @see ISTextProcessor#processSpecial the corresponding interface method
+ * A processor handling special cases (with a number of
+ * special cases greater than zero) must override this method.
*/
- public int processSpecial(STextFeatures features, String text, byte[] dirProps, int[] offsets, int[] state, int caseNumber, int separLocation) {
+ public int processSpecial(STextEnvironment environment, String text, byte[] dirProps, int[] offsets, int[] state, int caseNumber, int separLocation) {
// This method must be overridden by all subclasses with any special case.
- throw new IllegalStateException("A processor must have a processSpecial() method."); //$NON-NLS-1$
+ throw new IllegalStateException("A processor with specialsCount > 0 must have a processSpecial() method."); //$NON-NLS-1$
}
/**
* This method can be called from within
- * {@link ISTextProcessor#indexOfSpecial indexOfSpecial} or
- * {@link ISTextProcessor#processSpecial processSpecial} in
- * implementations of {@link ISTextProcessor} to retrieve the
+ * {@link #indexOfSpecial indexOfSpecial} or
+ * {@link #processSpecial processSpecial} in extensions of
+ * The logic implemented in this method considers the text before
+ * If not overridden, this method returns an empty string;
+ */
+ public String getSeparators(STextEnvironment environment, String text, byte[] dirProps) {
+ return ""; //$NON-NLS-1$
+ }
+
+ /**
+ * Indicate the base text direction appropriate for an instance
+ * of structured text.
+ * This methode is invoked before starting the processing.
+ *
+ * @param environment the current environment, which may affect the behavior of
+ * the processor. This parameter may be specified as
+ * If not overridden, this method returns If not overridden, this method returns If not overridden, this method returns A delimited part is bounded by a start delimiter and an end delimiter.
+ *
* @author Matitiahu Allouche
*/
public abstract class STextDelims extends STextProcessor {
/**
* This method locates occurrences of start delimiters.
+ *
+ * @return the position starting from offset
+There are various types of structured text. Each type should
+be handled by a specific processor. A number of standard
+processors are supplied in the associated package
+{@link
+org.eclipse.equinox.bidi.internal.consumable}.
@@ -44,7 +49,7 @@ The class {@link
is the main tool for processing structured text. It facilitates
handling several types of structured text, each type being handled
by a specific
-{@link processor} :
- * name=value
- *
- */
- public String PROPERTY = "property"; //$NON-NLS-1$
-
- /**
- * Constant indicating a type of structured text processor adapted
- * to processing compound names.
- * This type covers names made of one or more parts separated by underscores:
- *
- * part1_part2_part3
- *
- */
- public String UNDERSCORE = "underscore"; //$NON-NLS-1$
-
- /**
- * Constant indicating a type of structured text processor adapted
- * to processing comma-delimited lists, such as:
- *
- * part1,part2,part3
- *
- */
- public String COMMA_DELIMITED = "comma"; //$NON-NLS-1$
-
- /**
- * Constant indicating a type of structured text processor adapted
- * to processing strings with the following format:
- *
- * system(user)
- *
- */
- public String SYSTEM_USER = "system"; //$NON-NLS-1$
-
- /**
- * Constant indicating a type of structured text processor adapted
- * to processing directory and file paths.
- */
- public String FILE = "file"; //$NON-NLS-1$
-
- /**
- * Constant indicating a type of structured text processor adapted
- * to processing e-mail addresses.
- */
- public String EMAIL = "email"; //$NON-NLS-1$
-
- /**
- * Constant indicating a type of structured text processor adapted
- * to processing URLs.
- */
- public String URL = "url"; //$NON-NLS-1$
-
- /**
- * Constant indicating a type of structured text processor adapted
- * to processing regular expressions, possibly spanning more than one
- * line.
- */
- public String REGEXP = "regex"; //$NON-NLS-1$
-
- /**
- * Constant indicating a type of structured text processor adapted
- * to processing XPath expressions.
- */
- public String XPATH = "xpath"; //$NON-NLS-1$
-
- /**
- * Constant indicating a type of structured text processor adapted
- * to processing Java code, possibly spanning more than one line.
- */
- public String JAVA = "java"; //$NON-NLS-1$
-
- /**
- * Constant indicating a type of structured text processor adapted
- * to processing SQL statements, possibly spanning more than one line.
- */
- public String SQL = "sql"; //$NON-NLS-1$
-
- /**
- * Constant indicating a type of structured text processor adapted
- * to processing arithmetic expressions with a RTL base direction.
- */
- public String RTL_ARITHMETIC = "math"; //$NON-NLS-1$
-}
diff --git a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/STextEngine.java b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/STextEngine.java
index da8649f67..3d05bf8a6 100644
--- a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/STextEngine.java
+++ b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/STextEngine.java
@@ -10,8 +10,8 @@
******************************************************************************/
package org.eclipse.equinox.bidi;
-import org.eclipse.equinox.bidi.custom.ISTextProcessor;
-import org.eclipse.equinox.bidi.custom.STextFeatures;
+import org.eclipse.equinox.bidi.custom.STextProcessor;
+import org.eclipse.equinox.bidi.custom.STextStringProcessor;
import org.eclipse.equinox.bidi.internal.STextImpl;
/**
@@ -29,26 +29,17 @@ import org.eclipse.equinox.bidi.internal.STextImpl;
* How to Specify a Processor
*
* null
for the processor as first argument
* of a method causes this method to behave as a no-op.
*
@@ -90,7 +81,7 @@ import org.eclipse.equinox.bidi.internal.STextImpl;
*
*
* String leanText = "D:\\\u05d0\u05d1\\\u05d2\\\u05d3.ext";
- * String fullText = STextEngine.leanToFullText(ISTextTypes.FILE, null, null, leanText, null);
+ * String fullText = STextEngine.leanToFullText(STextEngine.PROC_FILE, null, leanText, null);
* System.out.println("full text = " + fullText);
*
*
@@ -104,10 +95,10 @@ import org.eclipse.equinox.bidi.internal.STextImpl;
* int[] state = new int[1];
* state[0] = STextEngine.STATE_INITIAL;
* String leanText = "int i = 3; // first Java statement";
- * String fullText = STextEngine.leanToFullText(ISTextTypes.JAVA, null, null, leanText, state);
+ * String fullText = STextEngine.leanToFullText(STextEngine.PROC_JAVA, null, leanText, state);
* System.out.println("full text = " + fullText);
* leanText = "i += 4; // next Java statement";
- * fullText = STextEngine.leanToFullText(ISTextTypes.JAVA, null, null, leanText, state);
+ * fullText = STextEngine.leanToFullText(STextEngine.PROC_JAVA, null, leanText, state);
* System.out.println("full text = " + fullText);
*
*
@@ -122,6 +113,113 @@ import org.eclipse.equinox.bidi.internal.STextImpl;
*
*/
public class STextEngine {
+ /**
+ * Constant indicating a type of structured text processor adapted
+ * to processing property file statements. It expects the following
+ * format:
+ *
+ * name=value
+ *
+ */
+ public static final STextProcessor PROC_PROPERTY = STextStringProcessor.getProcessor("property"); //$NON-NLS-1$
+
+ /**
+ * Constant indicating a type of structured text processor adapted
+ * to processing compound names.
+ * This type covers names made of one or more parts separated by underscores:
+ *
+ * part1_part2_part3
+ *
+ */
+ public static final STextProcessor PROC_UNDERSCORE = STextStringProcessor.getProcessor("underscore"); //$NON-NLS-1$
+
+ /**
+ * Constant indicating a type of structured text processor adapted
+ * to processing comma-delimited lists, such as:
+ *
+ * part1,part2,part3
+ *
+ */
+ public static final STextProcessor PROC_COMMA_DELIMITED = STextStringProcessor.getProcessor("comma"); //$NON-NLS-1$
+
+ /**
+ * Constant indicating a type of structured text processor adapted
+ * to processing strings with the following format:
+ *
+ * system(user)
+ *
+ */
+ public static final STextProcessor PROC_SYSTEM_USER = STextStringProcessor.getProcessor("system"); //$NON-NLS-1$
+
+ /**
+ * Constant indicating a type of structured text processor adapted
+ * to processing directory and file paths.
+ */
+ public static final STextProcessor PROC_FILE = STextStringProcessor.getProcessor("file"); //$NON-NLS-1$
+
+ /**
+ * Constant indicating a type of structured text processor adapted
+ * to processing e-mail addresses.
+ */
+ public static final STextProcessor PROC_EMAIL = STextStringProcessor.getProcessor("email"); //$NON-NLS-1$
+
+ /**
+ * Constant indicating a type of structured text processor adapted
+ * to processing URLs.
+ */
+ public static final STextProcessor PROC_URL = STextStringProcessor.getProcessor("url"); //$NON-NLS-1$
+
+ /**
+ * Constant indicating a type of structured text processor adapted
+ * to processing regular expressions, possibly spanning more than one
+ * line.
+ */
+ public static final STextProcessor PROC_REGEXP = STextStringProcessor.getProcessor("regex"); //$NON-NLS-1$
+
+ /**
+ * Constant indicating a type of structured text processor adapted
+ * to processing XPath expressions.
+ */
+ public static final STextProcessor PROC_XPATH = STextStringProcessor.getProcessor("xpath"); //$NON-NLS-1$
+
+ /**
+ * Constant indicating a type of structured text processor adapted
+ * to processing Java code, possibly spanning more than one line.
+ */
+ public static final STextProcessor PROC_JAVA = STextStringProcessor.getProcessor("java"); //$NON-NLS-1$
+
+ /**
+ * Constant indicating a type of structured text processor adapted
+ * to processing SQL statements, possibly spanning more than one line.
+ */
+ public static final STextProcessor PROC_SQL = STextStringProcessor.getProcessor("sql"); //$NON-NLS-1$
+
+ /**
+ * Constant indicating a type of structured text processor adapted
+ * to processing arithmetic expressions, possibly with a RTL base direction.
+ */
+ public static final STextProcessor PROC_RTL_ARITHMETIC = STextStringProcessor.getProcessor("math"); //$NON-NLS-1$
+
+ /**
+ * Constant specifying that the base direction of a structured text is LTR.
+ * The base direction may depend on whether the GUI is
+ * {@link STextEnvironment#getMirrored mirrored} and may
+ * may be different for Arabic and for Hebrew.
+ * This constant can appear as value returned by the
+ * {@link #getCurDirection getCurDirection} method.
+ */
+ public static final int DIR_LTR = 0;
+
+ /**
+ * Constant specifying that the base direction of a structured text is RTL.
+ * The base direction may depend on whether the GUI is
+ * {@link STextEnvironment#getMirrored mirrored} and may
+ * may be different for Arabic and for Hebrew.
+ * This constant can appear as value returned by the
+ * {@link #getCurDirection getCurDirection} method.
+ */
+ public static final int DIR_RTL = 1;
+
/**
* Constant to use in the first element of the state
* argument when calling most methods of this class
@@ -142,22 +240,12 @@ public class STextEngine {
/** Add directional formatting characters to a structured text
* to ensure correct presentation.
*
- * @param processor designates one of the registered processors.
- * It can be a string containing a keyword according to
- * the processor type, or a processor reference.
+ * @param processor designates a processor instance.
* For more details, see above
* How to Specify a Processor.
* null
, this method
* returns the text
string.
*
- * @param features specifies features that affect the processor's
- * behavior.
- * null
,
- * in which case the processor will use its standard features
- * (as returned by the processor
- * {@link ISTextProcessor#getFeatures getFeatures}
- * method).
- *
* @param environment specifies an environment whose characteristics
* may affect the processor's behavior.
* null
,
@@ -179,32 +267,22 @@ public class STextEngine {
* characters added at proper locations to ensure correct
* presentation.
*/
- public static String leanToFullText(Object processor, STextFeatures features, STextEnvironment environment, String text, int[] state) {
+ public static String leanToFullText(STextProcessor processor, STextEnvironment environment, String text, int[] state) {
if (processor == null)
return text;
- return STextImpl.leanToFullText(processor, features, environment, text, state);
+ return STextImpl.leanToFullText(processor, environment, text, state);
}
/**
* Given a lean string, compute the positions of each of its
* characters within the corresponding full string.
*
- * @param processor designates one of the registered processors.
- * It can be a string containing a keyword according to
- * the processor type, or a processor reference.
+ * @param processor designates a processor instance.
* For more details, see above
* How to Specify a Processor.
* null
, this method
* returns an identity map.
*
- * @param features specifies features that affect the processor's
- * behavior.
- * null
,
- * in which case the processor will use its standard features
- * (as returned by the processor
- * {@link ISTextProcessor#getFeatures getFeatures}
- * method).
- *
* @param environment specifies an environment whose characteristics
* may affect the processor's behavior.
* null
,
@@ -226,14 +304,14 @@ public class STextEngine {
* in the text
argument, equal to the offset of the
* corresponding character in the full string.
*/
- public static int[] leanToFullMap(Object processor, STextFeatures features, STextEnvironment environment, String text, int[] state) {
+ public static int[] leanToFullMap(STextProcessor processor, STextEnvironment environment, String text, int[] state) {
if (processor == null) {
int[] map = new int[text.length()];
for (int i = 0; i < map.length; i++)
map[i] = i;
return map;
}
- return STextImpl.leanToFullMap(processor, features, environment, text, state);
+ return STextImpl.leanToFullMap(processor, environment, text, state);
}
/**
@@ -247,22 +325,12 @@ public class STextEngine {
* depending on the {@link STextEnvironment#getOrientation orientation} of the
* GUI component used for display are not reflected in this method.
*
- * @param processor designates one of the registered processors.
- * It can be a string containing a keyword according to
- * the processor type, or a processor reference.
+ * @param processor designates a processor instance.
* For more details, see above
* How to Specify a Processor.
* null
, this method
* returns an empty array.
*
- * @param features specifies features that affect the processor's
- * behavior.
- * null
,
- * in which case the processor will use its standard features
- * (as returned by the processor
- * {@link ISTextProcessor#getFeatures getFeatures}
- * method).
- *
* @param environment specifies an environment whose characteristics
* may affect the processor's behavior.
* null
,
@@ -285,32 +353,22 @@ public class STextEngine {
* added to ensure correct presentation.
* The offsets are sorted in ascending order.
*/
- public static int[] leanBidiCharOffsets(Object processor, STextFeatures features, STextEnvironment environment, String text, int[] state) {
+ public static int[] leanBidiCharOffsets(STextProcessor processor, STextEnvironment environment, String text, int[] state) {
if (processor == null)
return EMPTY_INT_ARRAY;
- return STextImpl.leanBidiCharOffsets(processor, features, environment, text, state);
+ return STextImpl.leanBidiCharOffsets(processor, environment, text, state);
}
/**
* Remove directional formatting characters which were added to a
* structured text string to ensure correct presentation.
*
- * @param processor designates one of the registered processors.
- * It can be a string containing a keyword according to
- * the processor type, or a processor reference.
+ * @param processor designates a processor instance.
* For more details, see above
* How to Specify a Processor.
* null
, this method
* returns the text
string.
*
- * @param features specifies features that affect the processor's
- * behavior.
- * null
,
- * in which case the processor will use its standard features
- * (as returned by the processor
- * {@link ISTextProcessor#getFeatures getFeatures}
- * method).
- *
* @param environment specifies an environment whose characteristics
* may affect the processor's behavior.
* null
,
@@ -334,32 +392,22 @@ public class STextEngine {
* with {@link #leanToFullText leanToFullText}.
*
*/
- public static String fullToLeanText(Object processor, STextFeatures features, STextEnvironment environment, String text, int[] state) {
+ public static String fullToLeanText(STextProcessor processor, STextEnvironment environment, String text, int[] state) {
if (processor == null)
return text;
- return STextImpl.fullToLeanText(processor, features, environment, text, state);
+ return STextImpl.fullToLeanText(processor, environment, text, state);
}
/**
* Given a full string, compute the positions of each of its
* characters within the corresponding lean string.
*
- * @param processor designates one of the registered processors.
- * It can be a string containing a keyword according to
- * the processor type, or a processor reference.
+ * @param processor designates a processor instance.
* For more details, see above
* How to Specify a Processor.
* null
, this method
* returns an identity map.
*
- * @param features specifies features that affect the processor's
- * behavior.
- * null
,
- * in which case the processor will use its standard features
- * (as returned by the processor
- * {@link ISTextProcessor#getFeatures getFeatures}
- * method).
- *
* @param environment specifies an environment whose characteristics
* may affect the processor's behavior.
* null
,
@@ -387,14 +435,14 @@ public class STextEngine {
* added when invoking {@link #leanToFullText leanToFullText}),
* the value returned for this character is -1.
*/
- public static int[] fullToLeanMap(Object processor, STextFeatures features, STextEnvironment environment, String text, int[] state) {
+ public static int[] fullToLeanMap(STextProcessor processor, STextEnvironment environment, String text, int[] state) {
if (processor == null) {
int[] map = new int[text.length()];
for (int i = 0; i < map.length; i++)
map[i] = i;
return map;
}
- return STextImpl.fullToLeanMap(processor, features, environment, text, state);
+ return STextImpl.fullToLeanMap(processor, environment, text, state);
}
/**
@@ -408,22 +456,12 @@ public class STextEngine {
* depending on the {@link STextEnvironment#getOrientation orientation}
* of the GUI component used for display.
*
- * @param processor designates one of the registered processors.
- * It can be a string containing a keyword according to
- * the processor type, or a processor reference.
+ * @param processor designates a processor instance.
* For more details, see above
* How to Specify a Processor.
* null
, this method
* returns an empty array.
*
- * @param features specifies features that affect the processor's
- * behavior.
- * null
,
- * in which case the processor will use its standard features
- * (as returned by the processor
- * {@link ISTextProcessor#getFeatures getFeatures}
- * method).
- *
* @param environment specifies an environment whose characteristics
* may affect the processor's behavior.
* null
,
@@ -447,10 +485,10 @@ public class STextEngine {
* added to ensure correct presentation.
* The offsets are sorted in ascending order.
*/
- public static int[] fullBidiCharOffsets(Object processor, STextFeatures features, STextEnvironment environment, String text, int[] state) {
+ public static int[] fullBidiCharOffsets(STextProcessor processor, STextEnvironment environment, String text, int[] state) {
if (processor == null)
return EMPTY_INT_ARRAY;
- return STextImpl.fullBidiCharOffsets(processor, features, environment, text, state);
+ return STextImpl.fullBidiCharOffsets(processor, environment, text, state);
}
/**
@@ -461,21 +499,11 @@ public class STextEngine {
* text determines which is the governing script) and on
* whether the GUI is {@link STextEnvironment#getMirrored mirrored}.
*
- * @param processor designates one of the registered processors.
- * It can be a string containing a keyword according to
- * the processor type, or a processor reference.
+ * @param processor designates a processor instance.
* For more details, see above
* How to Specify a Processor.
* null
, this method
- * returns {@link STextFeatures#DIR_LTR}.
- *
- * @param features specifies features that affect the processor's
- * behavior.
- * null
,
- * in which case the processor will use its standard features
- * (as returned by the processor
- * {@link ISTextProcessor#getFeatures getFeatures}
- * method).
+ * returns {@link #DIR_LTR}.
*
* @param environment specifies an environment whose characteristics
* may affect the processor's behavior.
@@ -487,11 +515,13 @@ public class STextEngine {
* @param text is the structured text string.
*
* @return the base direction of the structured text.
- * It is one of the values {@link STextFeatures#DIR_LTR}
- * or {@link STextFeatures#DIR_RTL}.
+ * It is one of the values {@link #DIR_LTR}
+ * or {@link #DIR_RTL}.
*/
- public static int getCurDirection(Object processor, STextFeatures features, STextEnvironment environment, String text) {
- return STextImpl.getCurDirection(processor, features, environment, text, null);
+ public static int getCurDirection(STextProcessor processor, STextEnvironment environment, String text) {
+ if (processor == null)
+ return DIR_LTR;
+ return STextImpl.getCurDirection(processor, environment, text, null);
}
}
diff --git a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/STextEnvironment.java b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/STextEnvironment.java
index 5108424f1..5a6500c44 100644
--- a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/STextEnvironment.java
+++ b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/STextEnvironment.java
@@ -11,7 +11,6 @@
package org.eclipse.equinox.bidi;
import java.util.Locale;
-import org.eclipse.equinox.bidi.custom.ISTextProcessor;
import org.eclipse.equinox.bidi.internal.STextActivator;
/**
@@ -35,7 +34,6 @@ import org.eclipse.equinox.bidi.internal.STextActivator;
* null
, it defaults to the language
- * of the current default locale.
+ * ISO-639. If specified as null
, it defaults to the
+ * language of the current default locale.
*/
public String getLanguage() {
- return language;
+ if (language != null)
+ return language;
+ return getDefaultLocale().getLanguage();
}
/**
@@ -260,20 +253,12 @@ public class STextEnvironment {
* @see #getLanguage
*/
public boolean isBidi() {
- if (defaultLanguage != null && defaultLocale.equals(getDefaultLocale()))
- return defaultBidi;
-
- if (language == null) {
- defaultLocale = getDefaultLocale();
- defaultLanguage = defaultLocale.getLanguage();
- defaultBidi = isBidiLanguage(defaultLanguage);
- return defaultBidi;
- }
-
- return bidiFlag;
+ if (language != null)
+ return isBidiLanguage(language);
+ return isBidiLanguage(getDefaultLocale().getLanguage());
}
- static boolean isBidiLanguage(String lang) {
+ boolean isBidiLanguage(String lang) {
return "iw".equals(lang) || "he".equals(lang) || "ar".equals(lang) || "fa".equals(lang) || "ur".equals(lang); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
}
diff --git a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/STextStringRecord.java b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/STextStringRecord.java
index fc50de390..76bd6f853 100644
--- a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/STextStringRecord.java
+++ b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/STextStringRecord.java
@@ -11,10 +11,10 @@
package org.eclipse.equinox.bidi;
import java.lang.ref.SoftReference;
-import org.eclipse.equinox.bidi.custom.STextStringProcessor;
+import org.eclipse.equinox.bidi.custom.STextProcessor;
/**
- * This class records strings which are structured text. Several static
+ * This class records strings which contain structured text. Several static
* methods in this class allow to record such strings in a pool, and to find if
* a given string is member of the pool.
* string
which is a structured text.
- * string
which is a structured text.
- * This offset points to one position beyond the last
- * character of the substring.
- *
- * The type of a structured text must be one of the string
- * values listed in {@link ISTextTypes}.
- * The corresponding numeric type must be obtained using the
- * method {@link #typeStringToShort typeStringToShort}.
+ * Constructor
*/
- public STextStringRecord(String string, short[] triplets) {
- if (string == null || triplets == null)
- throw new IllegalArgumentException("The string and triplets argument must not be null!"); //$NON-NLS-1$
- if ((triplets.length % 3) != 0)
- throw new IllegalArgumentException("The number of elements in triplets must be a multiple of 3!"); //$NON-NLS-1$
- for (int i = 2; i < triplets.length; i += 3)
- if (triplets[i] < 0 || triplets[i] > MAXTYPE)
- throw new IllegalArgumentException("Illegal type value in element" + i); //$NON-NLS-1$
- strRef = new SoftReference(string);
- triRef = new SoftReference(triplets);
- hash = string.hashCode();
+ private STextStringRecord() {
+ // inhibit creation of new instances by customers
}
/**
- * Get the numeric type of a structured text given its string type.
+ * Record a string in the pool. The caller must specify the number
+ * of segments in the record (at least 1), and the processor, starting
+ * and ending offsets for the first segment.
*
- * @param type type of structured text as string. It must be one
- * of the strings listed in {@link ISTextTypes}.
+ * @param string the string to record.
*
- * @return a value which is the corresponding numeric type. If
- * type
is invalid, the method returns -1
.
- */
- public static short typeStringToShort(String type) {
- for (int i = 0; i < types.length; i++)
- if (types[i].equals(type))
- return (short) i;
- return -1;
- }
-
- /**
- * Get the string type of a structured text given its numeric type.
+ * @param segmentCount number of segments allowed in this string.
+ * This number must be >= 1.
*
- * @param shType
- * the numeric type of a structured text. It should be a value
- * obtained using {@link #typeStringToShort typeStringToShort}.
+ * @param processor the processor appropriate to handle the type
+ * of structured text present in the first segment.
+ * It may be one of the pre-defined processor instances
+ * appearing in {@link STextEngine}, or it may be an instance
+ * created by a plug-in or by the application.
*
- * @return the corresponding string type. If shType
is invalid,
- * the method returns null
.
+ * @param start offset in the string of the starting character of the first
+ * segment. It must be >= 0 and less than the length of the string.
+ *
+ * @param limit offset of the character following the first segment. It
+ * must be greater than the start
argument and
+ * not greater than the length of the string.
+ *
+ * @return an instance of STextRecordString which represents this record.
+ * This instance may be used to specify additional segment with
+ * {@link #addSegment addSegment}.
+ *
+ * @throws IllegalArgumentException if string
is null or
+ * if segmentCount
is less than 1.
+ * @throws also the same exceptions as {@link #addSegment addSegment}.
*/
- public static String typeShortToString(short shType) {
- if (shType < 0 || shType > MAXTYPE)
- return null;
- return types[shType];
+ public static STextStringRecord addRecord(String string, int segmentCount, STextProcessor processor, int start, int limit) {
+ if (string == null)
+ throw new IllegalArgumentException("The string argument must not be null!"); //$NON-NLS-1$
+ if (segmentCount < 1)
+ throw new IllegalArgumentException("The segment count must be at least 1!"); //$NON-NLS-1$
+ synchronized (recordRefs) {
+ if (last < MAXINDEX)
+ last++;
+ else {
+ wrapAround = true;
+ last = 0;
+ }
+ }
+ STextStringRecord record = null;
+ if (recordRefs[last] != null)
+ record = (STextStringRecord) recordRefs[last].get();
+ if (record == null) {
+ record = new STextStringRecord();
+ recordRefs[last] = new SoftReference(record);
+ }
+ hashArray[last] = string.hashCode();
+ for (int i = 0; i < record.usedSegmentCount; i++)
+ record.processors[i] = null;
+ if (segmentCount > record.totalSegmentCount) {
+ record.processors = new STextProcessor[segmentCount];
+ record.boundaries = new short[segmentCount * 2];
+ record.totalSegmentCount = segmentCount;
+ }
+ record.usedSegmentCount = 0;
+ record.string = string;
+ record.addSegment(processor, start, limit);
+ return record;
}
/**
- * Add a record to the pool.
+ * Add a second or further segment to a record.
+ *
+ * @param processor the processor appropriate to handle the type
+ * of structured text present in this segment.
+ * It may be one of the pre-defined processor instances
+ * appearing in {@link STextEngine}, or it may be an instance
+ * created by a plug-in or by the application.
+ *
+ * @param start offset in the string of the starting character of the
+ * segment. It must be >= 0 and less than the length of the string.
*
- * @param record a STextStringRecord instance
+ * @param limit offset of the character following the segment. It must be
+ * greater than the start
argument and not greater
+ * than the length of the string.
+ *
+ * @throws IllegalArgumentException if processor
is null,
+ * or if start
or limit
have invalid
+ * values.
+ * @throws IllegalStateException if the current segment exceeds the
+ * number of segments specified by segmentCount
+ * in the call to {@link #addRecord addRecord} which created
+ * the STextStringRecord instance.
*/
- public static synchronized void add(STextStringRecord record) {
- if (last < MAXINDEX)
- last++;
- else
- last = 0;
- records[last] = record;
+ public void addSegment(STextProcessor processor, int start, int limit) {
+ if (processor == null)
+ throw new IllegalArgumentException("The processor argument must not be null!"); //$NON-NLS-1$
+ if (start < 0 || start >= string.length())
+ throw new IllegalArgumentException("The start position must be at least 0 and less than the length of the string!"); //$NON-NLS-1$
+ if (limit <= start || limit > string.length())
+ throw new IllegalArgumentException("The limit position must be greater than the start position but no greater than the length of the string!"); //$NON-NLS-1$
+ if (usedSegmentCount >= totalSegmentCount)
+ throw new IllegalStateException("All segments of the record are already used!"); //$NON-NLS-1$
+ processors[usedSegmentCount] = processor;
+ boundaries[usedSegmentCount * 2] = (short) start;
+ boundaries[usedSegmentCount * 2 + 1] = (short) limit;
+ usedSegmentCount++;
}
/**
- * Check if a string is recorded and retrieve its triplets.
+ * Check if a string is recorded and retrieve its record.
*
- * @param string the string to check
+ * @param string the string to check.
*
* @return null
if the string is not recorded in the pool;
- * otherwise, return the triplets associated with this string.
+ * otherwise, return the STextStringRecord instance which
+ * records this string.
+ * Once a record has been found, the number of its segments can
+ * be retrieved using {@link #getSegmentCount getSegmentCount},
+ * its processor can
+ * be retrieved using {@link #getProcessor getProcessor},
+ * its starting offset can
+ * be retrieved using {@link #getStart getStart},
+ * its ending offset can
+ * be retrieved using {@link #getLimit getLimit},
*/
- public static short[] getTriplets(String string) {
- if (records[0] == null) // no records at all
+ public static STextStringRecord getRecord(String string) {
+ if (last < 0) // no records at all
return null;
if (string == null || string.length() < 1)
return null;
- STextStringRecord rec;
- String str;
- short[] tri;
+ STextStringRecord record;
int myLast = last;
int hash = string.hashCode();
for (int i = myLast; i >= 0; i--) {
- rec = records[i];
- if (hash == rec.hash && (tri = (short[]) rec.triRef.get()) != null && (str = (String) rec.strRef.get()) != null && string.equals(str)) {
- return tri;
- }
+ if (hash != hashArray[i])
+ continue;
+ record = (STextStringRecord) recordRefs[i].get();
+ if (record == null)
+ continue;
+ if (string.equals(record.string))
+ return record;
}
- if (records[MAXINDEX] == null) // never recorded past myLast
+ if (!wrapAround) // never recorded past myLast
return null;
for (int i = MAXINDEX; i > myLast; i--) {
- rec = records[i];
- if (hash == rec.hash && (tri = (short[]) rec.triRef.get()) != null && (str = (String) rec.strRef.get()) != null && string.equals(str)) {
- return tri;
- }
+ if (hash != hashArray[i])
+ continue;
+ record = (STextStringRecord) recordRefs[i].get();
+ if (record == null)
+ continue;
+ if (string.equals(record.string))
+ return record;
}
return null;
}
+ /**
+ * Retrieve the number of segments in a record.
+ *
+ * @return the number of segments in the current record. This number
+ * is always >= 1.
+ */
+ public int getSegmentCount() {
+ return usedSegmentCount;
+ }
+
+ private void checkSegmentNumber(int segmentNumber) {
+ if (segmentNumber >= usedSegmentCount)
+ throw new IllegalArgumentException("The segment number " + segmentNumber + " is greater than the total number of segments = " + usedSegmentCount + "!"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+
+ /**
+ * Retrieve the processor of a given segment.
+ *
+ * @param segmentNumber number of the segment about which information
+ * is required. It must be >= 0 and less than the number of
+ * segments specified by segmentCount
+ * in the call to {@link #addRecord addRecord} which created
+ * the STextStringRecord instance.
+ *
+ * @return the processor to handle the structured text in the segment
+ * specified by segmentNumber
.
+ *
+ * @throws IllegalArgumentException if segmentNumber
+ * has an invalid value.
+ *
+ * @see #getSegmentCount getSegmentCount
+ */
+ public STextProcessor getProcessor(int segmentNumber) {
+ checkSegmentNumber(segmentNumber);
+ return processors[segmentNumber];
+ }
+
+ /**
+ * Retrieve the starting offset of a given segment.
+ *
+ * @param segmentNumber number of the segment about which information
+ * is required. It must be >= 0 and less than the number of
+ * segments specified by segmentCount
+ * in the call to {@link #addRecord addRecord} which created
+ * the STextStringRecord instance.
+ *
+ * @return the starting offset within the string of the segment
+ * specified by segmentNumber
.
+ *
+ * @throws IllegalArgumentException if segmentNumber
+ * has an invalid value.
+ *
+ * @see #getSegmentCount getSegmentCount
+ */
+ public int getStart(int segmentNumber) {
+ checkSegmentNumber(segmentNumber);
+ return boundaries[segmentNumber * 2];
+ }
+
+ /**
+ * Retrieve the ending offset of a given segment.
+ *
+ * @param segmentNumber number of the segment about which information
+ * is required. It must be >= 0 and less than the number of
+ * segments specified by segmentCount
+ * in the call to {@link #addRecord addRecord} which created
+ * the STextStringRecord instance.
+ *
+ * @return the offset of the position following the segment
+ * specified by segmentNumber
.
+ *
+ * @throws IllegalArgumentException if segmentNumber
+ * has an invalid value.
+ *
+ * @see #getSegmentCount getSegmentCount
+ */
+ public int getLimit(int segmentNumber) {
+ checkSegmentNumber(segmentNumber);
+ return boundaries[segmentNumber * 2 + 1];
+ }
+
/**
* Clear the pool. All elements of the pool are erased and any associated
* memory is freed.
@@ -178,15 +313,21 @@ public class STextStringRecord {
*/
public static synchronized void clear() {
for (int i = 0; i <= MAXINDEX; i++) {
- STextStringRecord sr = records[i];
- if (sr == null)
- break;
- sr.hash = 0;
- sr.strRef.clear();
- sr.triRef.clear();
- records[i] = null;
+ hashArray[i] = 0;
+ SoftReference softRef = recordRefs[i];
+ if (softRef == null)
+ continue;
+ STextStringRecord record = (STextStringRecord) softRef.get();
+ if (record == null)
+ continue;
+ record.boundaries = null;
+ record.processors = null;
+ record.totalSegmentCount = 0;
+ record.usedSegmentCount = 0;
+ recordRefs[i].clear();
}
- last = MAXINDEX;
+ last = -1;
+ wrapAround = false;
}
}
diff --git a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/STextUtil.java b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/STextUtil.java
index 329d64d3a..f261833bb 100644
--- a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/STextUtil.java
+++ b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/STextUtil.java
@@ -10,7 +10,6 @@
******************************************************************************/
package org.eclipse.equinox.bidi;
-import org.eclipse.equinox.bidi.custom.STextFeatures;
import org.eclipse.equinox.bidi.custom.STextProcessor;
/**
@@ -22,7 +21,19 @@ import org.eclipse.equinox.bidi.custom.STextProcessor;
*
* @author Matitiahu Allouche
*/
-final public class STextUtil {
+public final class STextUtil {
+
+ static class MyProcessor extends STextProcessor {
+ String separ;
+
+ MyProcessor(String separators) {
+ separ = separators;
+ }
+
+ public String getSeparators(STextEnvironment environment, String text, byte[] dirProps) {
+ return separ;
+ }
+ }
/**
* prevent instantiation
@@ -54,8 +65,8 @@ final public class STextUtil {
* This argument may be null if there are no marks to add.
*
* @param direction specifies the base direction of the structured text.
- * It must be one of the values {@link STextFeatures#DIR_LTR} or
- * {@link STextFeatures#DIR_RTL}.
+ * It must be one of the values {@link STextEngine#DIR_LTR} or
+ * {@link STextEngine#DIR_RTL}.
*
* @param affix specifies if a prefix and a suffix should be added to
* the result to make sure that the direction
@@ -75,7 +86,7 @@ final public class STextUtil {
String curPrefix, curSuffix, full;
char curMark, c;
char[] fullChars;
- if (direction == STextFeatures.DIR_LTR) {
+ if (direction == STextEngine.DIR_LTR) {
curMark = LRM;
curPrefix = "\u202a\u200e"; /* LRE+LRM *///$NON-NLS-1$
curSuffix = "\u200e\u202c"; /* LRM+PDF *///$NON-NLS-1$
@@ -212,8 +223,8 @@ final public class STextUtil {
// make sure that LRE/PDF are added around the string
STextEnvironment env = new STextEnvironment(null, false, STextEnvironment.ORIENT_UNKNOWN);
- STextFeatures features = new STextFeatures(separators, 0, -1, -1, false, false);
- return STextEngine.leanToFullText(new STextProcessor(), features, env, str, null);
+ STextProcessor processor = new MyProcessor(separators);
+ return STextEngine.leanToFullText(processor, env, str, null);
}
/**
@@ -237,16 +248,19 @@ final public class STextUtil {
*
* @param str the text to process.
*
- * @param type specifies the type of the structured text. It must
- * be one of the values in {@link ISTextTypes} or a value.
- * added by a plug-in extension.
+ * @param processor specifies a processor instance appropriate for
+ * the type of the structured text. It will usually be
+ * one of the pre-defined processor instances appearing in
+ * {@link STextEngine}, but can be an instance
+ * added by a plug-in extension or an instance of a
+ * processor defined in the application itself.
*
* @return the processed string.
* If str
is null
,
* or of length 0, or if the current locale is not a bidi one,
* return the original string.
*/
- public static String processTyped(String str, String type) {
+ public static String processTyped(String str, STextProcessor processor) {
if ((str == null) || (str.length() <= 1) || !isProcessingNeeded())
return str;
@@ -257,7 +271,7 @@ final public class STextUtil {
// make sure that LRE/PDF are added around the string
STextEnvironment env = new STextEnvironment(null, false, STextEnvironment.ORIENT_UNKNOWN);
- return STextEngine.leanToFullText(type, null, env, str, null);
+ return STextEngine.leanToFullText(processor, env, str, null);
}
/**
@@ -296,18 +310,18 @@ final public class STextUtil {
*
* @param str string with directional characters to remove.
*
- * @param type type of the structured text as specified when
+ * @param processor to handle the structured text as specified when
* calling {@link #processTyped processTyped}.
*
* @return string with no directional formatting characters.
*/
- public static String deprocess(String str, String type) {
+ public static String deprocess(String str, STextProcessor processor) {
if ((str == null) || (str.length() <= 1) || !isProcessingNeeded())
return str;
// make sure that LRE/PDF are added around the string
STextEnvironment env = new STextEnvironment(null, false, STextEnvironment.ORIENT_UNKNOWN);
- return STextEngine.fullToLeanText(type, null, env, str, null);
+ return STextEngine.fullToLeanText(processor, env, str, null);
}
}
diff --git a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/custom/ISTextProcessor.java b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/custom/ISTextProcessor.java
deleted file mode 100644
index 8177c2b74..000000000
--- a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/custom/ISTextProcessor.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010, 2011 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- ******************************************************************************/
-package org.eclipse.equinox.bidi.custom;
-
-import org.eclipse.equinox.bidi.STextEngine;
-import org.eclipse.equinox.bidi.STextEnvironment;
-
-/**
- * Interface for all structured text processors.
- * For guidelines about implementation, see
- * {@link STextProcessor}.
- *
- * @author Matitiahu Allouche
- */
-public interface ISTextProcessor {
-
- /**
- * return the
- * {@link STextFeatures} characterizing the processor.
- *
- * @param env the current environment, which may affect the behavior of
- * the processor. This parameter may be specified as
- * null
, in which case the
- * {@link STextEnvironment#DEFAULT DEFAULT}
- * environment should be assumed.
- *
- * @return the features in use for this processor.
- */
- public abstract STextFeatures getFeatures(STextEnvironment env);
-
- /**
- * Locate occurrences of special strings within a structured text
- * and return their indexes one after the other in successive calls.
- * features
- * parameter is greater than zero.
- *
- *
- *
- * @param features is the {@link STextFeatures} instance
- * currently associated with this processor.
- *
- * @param text is the structured text string before
- * addition of any directional formatting characters.
- *
- * @param dirProps is a parameter received by indexOfSpecial
- * uniquely to be used as argument for calls to methods which
- * need it.
- *
- * @param offsets is a parameter received by indexOfSpecial
- * uniquely to be used as argument for calls to methods which
- * need it.
- *
- * @param caseNumber number of the special case to locate.
- * This number varies from 1 to the number of special cases
- * in the features associated with this processor.
- * The meaning of this number is internal to the class
- * implementing indexOfSpecial
.
- *
- * @param fromIndex the index within text
to start
- * the search from.
- *
- * @return the position where the start of the special case was located.
- * The method must return the first occurrence of whatever
- * identifies the start of the special case starting from
- * fromIndex
. The method does not have to check if
- * this occurrence appears within the scope of another special
- * case (e.g. a comment starting delimiter within the scope of
- * a literal or vice-versa).
- *
If no occurrence is found, the method must return -1.
- */
- public int indexOfSpecial(STextFeatures features, String text, byte[] dirProps, int[] offsets, int caseNumber, int fromIndex);
-
- /**
- * This method handles special cases specific to this processor.
- * It is called by {@link STextEngine#leanToFullText leanToFullText}
- * when a special case occurrence is located by
- * {@link #indexOfSpecial indexOfSpecial}.
- *
- *
- * processSpecial
(for instance, a comment has been started
- * in the current line but its end appears in a following line),
- * processSpecial
should specify a final state by
- * putting its value in the first element of the state
- * parameter.
- * The meaning of this state is internal to the processor.
- * On a later call to
- * {@link STextEngine#leanToFullText leanToFullText}
- * specifying that state value, processSpecial
will be
- * called with that value for parameter caseNumber
and
- * -1
for parameter separLocation
and should
- * perform whatever initializations are required depending on the state.
- *
- * @param features is the {@link STextFeatures} instance
- * currently associated with this processor.
- *
- * @param text is the structured text string before
- * addition of any directional formatting characters.
- *
- * @param dirProps is a parameter received by processSpecial
- * uniquely to be used as argument for calls to methods which
- * need it.
- *
- * @param offsets is a parameter received by processSpecial
- * uniquely to be used as argument for calls to methods which
- * need it.
- *
- * @param state is an integer array with at least one element.
- * If the processor needs to signal the occurrence of a
- * special case which must be passed to the next call to
- * leanToFullText
(for instance, a comment or a
- * literal started but not closed in the current
- * text
), it must put a value in the first element
- * of the state
parameter.
- * This value must be a number between 1 and the number of
- * special cases appearing in the features associated with
- * this processor. This number is passed back to the caller
- * and should be specified as state
argument
- * in the next call to leanToFullText
together
- * with the continuation text.
- * The meaning of this number is internal to the processor.
- *
- * @param caseNumber number of the special case to handle.
- *
- * @param separLocation the position returned by
- * {@link #indexOfSpecial indexOfSpecial}. In calls to
- * {@link STextEngine#leanToFullText leanToFullText} and other
- * methods of {@link STextEngine} specifying a non-null
- * state
parameter, processSpecial
is
- * called when initializing the processing with the value of
- * caseNumber
equal to the value returned in the
- * first element of state
and the value of
- * separLocation
equal to -1
.
- *
- * @return the position after the scope of the special case ends.
- * For instance, the position after the end of a comment,
- * the position after the end of a literal.
- *
A value greater or equal to the length of text
- * means that there is no further occurrence of this case in the
- * current structured text.
- */
- public int processSpecial(STextFeatures features, String text, byte[] dirProps, int[] offsets, int[] state, int caseNumber, int separLocation);
-
-}
diff --git a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/custom/STextFeatures.java b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/custom/STextFeatures.java
deleted file mode 100644
index 9d7c1a13e..000000000
--- a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/custom/STextFeatures.java
+++ /dev/null
@@ -1,250 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010, 2011 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- ******************************************************************************/
-package org.eclipse.equinox.bidi.custom;
-
-import org.eclipse.equinox.bidi.STextEnvironment;
-
-/**
- * This class defines features of a structured text processor.
- * final
, i.e. cannot be
- * changed after creating an instance.
- *
- * Code Sample
- *
- *
- * STextFeatures f1 = new STextFeatures("+-=", 0, -1, -1, false, false);
- *
- *
- *
- *
- * STextFeatures f2 = new STextFeatures("[]|()", f1.getSpecialsCount(),
- * f1.getDirArabic(), f1.getDirHebrew(),
- * f1.getIgnoreArabic(), f1.getIgnoreHebrew());
- *
- *
- *
- * @see ISTextProcessor#getFeatures
- *
- * @author Matitiahu Allouche
- */
-public class STextFeatures {
-
- /**
- * Constant specifying that the base direction of a structured text is LTR.
- * The base direction may depend on whether the GUI is
- * {@link STextEnvironment#getMirrored mirrored} and may
- * may be different for Arabic and for Hebrew.
- * This constant can appear as dirArabic
- * or dirHebrew
argument for the
- * {@link STextFeatures#STextFeatures STextFeatures constructor}
- * and as value returned by {@link #getDirArabic} or {@link #getDirHebrew}
- * methods.
- */
- public static final int DIR_LTR = 0;
-
- /**
- * Constant specifying that the base direction of a structured text is RTL.
- * The base direction may depend on whether the GUI is
- * {@link STextEnvironment#getMirrored mirrored} and may
- * may be different for Arabic and for Hebrew.
- * This constant can appear as dirArabic
- * or dirHebrew
argument for the
- * {@link STextFeatures#STextFeatures STextFeatures constructor}
- * and as value returned by {@link #getDirArabic} or {@link #getDirHebrew}
- * methods.
- */
- public static final int DIR_RTL = 1;
-
- /**
- * Pre-defined STextFeatures
instance with values for no
- * separators, no special processing, all directions LTR
- * and support for neither Arabic nor Hebrew.
- * Since there are no separators and no special processing, a structured text
- * processor with such features would do nothing.
- * It is more efficient to do nothing with a null
processor.
- */
- public static final STextFeatures DEFAULT = new STextFeatures(null, 0, -1, -1, true, true);
-
- /**
- * String grouping one-character separators which
- * separate the structured text into tokens.
- */
- final String separators;
-
- /**
- * Number of special cases for the associated processor.
- * Special cases exist for some types of structured text processors.
- * They are implemented by overriding methods
- * {@link ISTextProcessor#indexOfSpecial indexOfSpecial} and
- * {@link ISTextProcessor#processSpecial processSpecial}.
- * Examples of special cases are comments, literals, or anything which
- * is not identified by a one-character separator.
- */
- final int specialsCount;
-
- /**
- * Base direction of the structured text for Arabic.
- * If a structured text contains both Arabic and
- * Hebrew words, the first Arabic or Hebrew letter in the
- * text determines which is the governing script).
- * The value of this field must be one of
- * {@link #DIR_LTR} or {@link #DIR_RTL}.
- *
- * @see #dirHebrew
- */
- final int dirArabic;
-
- /**
- * Base direction of the structured text for Hebrew.
- * If a structured text contains both Arabic and
- * Hebrew words, the first Arabic or Hebrew letter in the
- * text determines which is the governing script).
- * The value of this field must be one of
- * {@link #DIR_LTR} or {@link #DIR_RTL}.
- *
- * @see #dirArabic
- */
- final int dirHebrew;
-
- /**
- * Flag indicating that Arabic letters will not be considered for
- * processing structured text. If both this flag and
- * ignoreHebrew are set to true
, the
- * processor will do nothing (but some overhead can be expected).
- */
- final boolean ignoreArabic;
-
- /**
- * Flag indicating that Hebrew letters will not be considered for
- * processing structured text. If both this flag and
- * ignoreArabic are set to true
, the
- * processor will do nothing (but some overhead can be expected).
- */
- final boolean ignoreHebrew;
-
- /**
- * Constructor
- *
- * @param separators is a string where each character is a separator
- * which separates the structured text into tokens.
- * @see #getSeparators
- *
- * @param specialsCount specifies the number of special cases handled
- * by the processor. This value must be identical to the
- * number of special cases handled by the processor with which
- * this STextFeatures
instance is associated.
- * @see #getSpecialsCount
- *
- * @param dirArabic specifies the base direction of the structured text
- * for Arabic. It must be {@link #DIR_LTR} or {@link #DIR_RTL}.
- * If it is not (for instance if it is a negative value), it
- * defaults to DIR_LTR
.
- * @see #getDirArabic
- *
- * @param dirHebrew specifies the base direction of the structured text
- * for Hebrew. It must be {@link #DIR_LTR} or {@link #DIR_RTL}.
- * If it is not (for instance if it is a negative value), it
- * defaults to DIR_LTR
.
- * @see #getDirHebrew
- *
- * @param ignoreArabic indicates that Arabic letters will not be
- * considered for processing structured text.
- * If both this flag and ignoreHebrew
- * are set to true
, the processor will do
- * nothing (but some overhead can be expected).
- * @see #getIgnoreArabic
- *
- * @param ignoreHebrew indicates that Hebrew letters will not be
- * considered for processing structured text.
- * If both this flag and ignoreArabic
- * are set to true
, the processor will do
- * nothing (but some overhead can be expected).
- * @see #getIgnoreHebrew
- */
- public STextFeatures(String separators, int specialsCount, int dirArabic, int dirHebrew, boolean ignoreArabic, boolean ignoreHebrew) {
-
- this.separators = separators == null ? "" : separators; //$NON-NLS-1$
- this.specialsCount = specialsCount;
- this.dirArabic = dirArabic == DIR_LTR || dirArabic == DIR_RTL ? dirArabic : DIR_LTR;
- this.dirHebrew = dirHebrew == DIR_LTR || dirHebrew == DIR_RTL ? dirHebrew : DIR_LTR;
- this.ignoreArabic = ignoreArabic;
- this.ignoreHebrew = ignoreHebrew;
- }
-
- /**
- * @return a string grouping one-character separators which separate
- * the structured text into tokens.
- */
- public String getSeparators() {
- return separators;
- }
-
- /**
- * @return the number of special cases for the associated processor.
- * Special cases exist for some types of structured text
- * processors. They are implemented by overriding methods
- * {@link ISTextProcessor#indexOfSpecial indexOfSpecial} and
- * {@link ISTextProcessor#processSpecial processSpecial}.
- * Examples of special cases are comments, literals, or
- * anything which is not identified by a one-character separator.
- */
- public int getSpecialsCount() {
- return specialsCount;
- }
-
- /**
- * @return the base direction of the structured text for Arabic.
- * If a structured text contains both Arabic and
- * Hebrew words, the first Arabic or Hebrew letter in the
- * text determines which is the governing script.
- * The value of this field is one of
- * {@link #DIR_LTR} or {@link #DIR_RTL}.
- *
- * @see #getDirHebrew
- */
- public int getDirArabic() {
- return dirArabic;
- }
-
- /**
- * @return the base direction of the structured text for Hebrew.
- * If a structured text contains both Arabic and
- * Hebrew words, the first Arabic or Hebrew letter in the
- * text determines which is the governing script.
- * The value of this field is one of
- * {@link #DIR_LTR} or {@link #DIR_RTL}.
- *
- * @see #getDirArabic
- */
- public int getDirHebrew() {
- return dirHebrew;
- }
-
- /**
- * @return a flag indicating that Arabic letters will not be considered
- * for processing structured text.
- */
- public boolean getIgnoreArabic() {
- return ignoreArabic;
- }
-
- /**
- * Flag indicating that Hebrew letters will not be considered for
- * processing structured text.
- */
- public boolean getIgnoreHebrew() {
- return ignoreHebrew;
- }
-
-}
diff --git a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/custom/STextProcessor.java b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/custom/STextProcessor.java
index f552dbc22..8401d9c97 100644
--- a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/custom/STextProcessor.java
+++ b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/custom/STextProcessor.java
@@ -15,7 +15,7 @@ import org.eclipse.equinox.bidi.STextEnvironment;
import org.eclipse.equinox.bidi.internal.STextImpl;
/**
- * Generic processor which can be used as superclass (base class)
+ * Generic processor to be used as superclass (base class)
* for specific structured text processors.
*
*
*
- * @see STextFeatures#getSeparators
- * @see STextFeatures#getDirArabic
- * @see STextFeatures#getDirHebrew
- * @see STextFeatures#getSpecialsCount
- *
* @author Matitiahu Allouche
*/
-public class STextProcessor implements ISTextProcessor {
+public abstract class STextProcessor {
/**
- * In features
argument when calling a method.
- * See for instance
- * {@link STextEngine#leanToFullText leanToFullText}.
- *
- *
STextProcessor
this method returns a
- * {@link STextFeatures#DEFAULT DEFAULT} value which
- * directs the processor to do nothing.
+ * Locate occurrences of special strings within a structured text
+ * and return their indexes one after the other in successive calls.
+ *
+ *
*
- * null
, in which case the
+ * {@link STextEnvironment#DEFAULT DEFAULT}
+ * environment should be assumed.
*
- * @see ISTextProcessor#getFeatures the corresponding interface method
- */
- public STextFeatures getFeatures(STextEnvironment environment) {
- throw new IllegalStateException("A processor must have a getFeatures() method."); //$NON-NLS-1$
- }
-
- /**
- * In STextProcessor
this method throws an
+ * @param text is the structured text string before
+ * addition of any directional formatting characters.
+ *
+ * @param dirProps is a parameter received by indexOfSpecial
+ * uniquely to be used as argument for calls to methods which
+ * need it.
+ *
+ * @param offsets is a parameter received by indexOfSpecial
+ * uniquely to be used as argument for calls to methods which
+ * need it.
+ *
+ * @param caseNumber number of the special case to locate.
+ * This number varies from 1 to the number of special cases
+ * returned by {@link #getSpecialsCount getSpecialsCount}
+ * for this processor.
+ * The meaning of this number is internal to the class
+ * implementing indexOfSpecial
.
+ *
+ * @param fromIndex the index within text
to start
+ * the search from.
+ *
+ * @return the position where the start of the special case
+ * corresponding to caseNumber
was located.
+ * The method must return the first occurrence of whatever
+ * identifies the start of the special case starting from
+ * fromIndex
. The method does not have to check if
+ * this occurrence appears within the scope of another special
+ * case (e.g. a comment starting delimiter within the scope of
+ * a literal or vice-versa).
+ *
If no occurrence is found, the method must return -1.
+ *
+ * @throws IllegalStateException
+ *
+ * IllegalStateException
. This is appropriate behavior
* (and does not need to be overridden) for processors whose
* number of special cases is zero, which means that
* indexOfSpecial
should never be called for them.
*
* STextProcessor
this method throws an
+ * This method handles special cases specific to this processor.
+ * It is called by {@link STextEngine#leanToFullText leanToFullText}
+ * when a special case occurrence is located by
+ * {@link #indexOfSpecial indexOfSpecial}.
+ *
+ *
+ * processSpecial
(for instance, a comment has been started
+ * in the current line but its end appears in a following line),
+ * processSpecial
should specify a final state by
+ * putting its value in the first element of the state
+ * parameter.
+ * The meaning of this state is internal to the processor.
+ * On a later call to
+ * {@link STextEngine#leanToFullText leanToFullText}
+ * specifying that state value, processSpecial
will be
+ * called with that value for parameter caseNumber
and
+ * -1
for parameter separLocation
and should
+ * perform whatever initializations are required depending on the state.
+ *
+ * @param environment the current environment, which may affect the behavior of
+ * the processor. This parameter may be specified as
+ * null
, in which case the
+ * {@link STextEnvironment#DEFAULT DEFAULT}
+ * environment should be assumed.
+ *
+ * @param text is the structured text string before
+ * addition of any directional formatting characters.
+ *
+ * @param dirProps is a parameter received by processSpecial
+ * uniquely to be used as argument for calls to methods which
+ * need it.
+ *
+ * @param offsets is a parameter received by processSpecial
+ * uniquely to be used as argument for calls to methods which
+ * need it.
+ *
+ * @param state is an integer array with at least one element.
+ * If the processor needs to signal the occurrence of a
+ * special case which must be passed to the next call to
+ * leanToFullText
(for instance, a comment or a
+ * literal started but not closed in the current
+ * text
), it must put a value in the first element
+ * of the state
parameter.
+ * This number must be >= 1 and less or equal to the number of special
+ * cases returned by {@link #getSpecialsCount getSpecialsCount}
+ * by this processor.
+ * This number is passed back to the caller
+ * and should be specified as state
argument
+ * in the next call to leanToFullText
together
+ * with the continuation text.
+ * The meaning of this number is internal to the processor.
+ *
+ * @param caseNumber number of the special case to handle.
+ *
+ * @param separLocation the position returned by
+ * {@link #indexOfSpecial indexOfSpecial}. In calls to
+ * {@link STextEngine#leanToFullText leanToFullText} and other
+ * methods of {@link STextEngine} specifying a non-null
+ * state
parameter, processSpecial
is
+ * called when initializing the processing with the value of
+ * caseNumber
equal to the value returned in the
+ * first element of state
and the value of
+ * separLocation
equal to -1
.
+ *
+ * @return the position after the scope of the special case ends.
+ * For instance, the position after the end of a comment,
+ * the position after the end of a literal.
+ *
A value greater or equal to the length of text
+ * means that there is no further occurrence of this case in the
+ * current structured text.
+ *
+ * @throws IllegalStateException
+ *
+ * IllegalStateException
. This is appropriate behavior
* (and does not need to be overridden) for processors whose
* number of special cases is zero, which means that
* processSpecial
should never be called for them.
*
- * STextProcessor
to retrieve the
* bidirectional class of characters in the lean text.
*
* @param text is the structured text string received as
@@ -130,15 +261,15 @@ public class STextProcessor implements ISTextProcessor {
* properties and so can be more efficient than calling the
* java.lang.Character method.
*/
- public static byte getDirProp(String text, byte[] dirProps, int index) {
+ public static final byte getDirProp(String text, byte[] dirProps, int index) {
return STextImpl.getDirProp(text, dirProps, index);
}
/**
* This method can be called from within
- * {@link ISTextProcessor#indexOfSpecial indexOfSpecial} or
- * {@link ISTextProcessor#processSpecial processSpecial} in
- * implementations of {@link ISTextProcessor} to set or
+ * {@link #indexOfSpecial indexOfSpecial} or
+ * {@link #processSpecial processSpecial} in extensions of
+ * STextProcessor
to set or
* override the bidirectional class of characters in the lean text.
*
* @param dirProps is a parameter received by indexOfSpecial
@@ -150,19 +281,19 @@ public class STextProcessor implements ISTextProcessor {
* It must be a non-negative number smaller than the length
* of the lean text.
*
- * @param dirProp bidirectional class of the character. It is one of the
- * values which can be returned by
+ * @param dirProp bidirectional class of the character. It must be
+ * one of the values which can be returned by
* java.lang.Character.getDirectionality
.
*/
- public static void setDirProp(byte[] dirProps, int index, byte dirProp) {
+ public static final void setDirProp(byte[] dirProps, int index, byte dirProp) {
STextImpl.setDirProp(dirProps, index, dirProp);
}
/**
* This method can be called from within
- * {@link ISTextProcessor#indexOfSpecial indexOfSpecial} or
- * {@link ISTextProcessor#processSpecial processSpecial} in
- * implementations of {@link ISTextProcessor}
+ * {@link #indexOfSpecial indexOfSpecial} or
+ * {@link #processSpecial processSpecial} in extensions of
+ * STextProcessor
* to specify that a mark character must be added before the character
* at the specified position of the lean text when generating the
* full text. The mark character will be LRM for structured text
@@ -191,24 +322,25 @@ public class STextProcessor implements ISTextProcessor {
* For the benefit of efficiency, it is better to insert
* multiple marks in ascending order of the offsets.
*/
- public static void insertMark(String text, byte[] dirProps, int[] offsets, int offset) {
+ public static final void insertMark(String text, byte[] dirProps, int[] offsets, int offset) {
STextImpl.insertMark(text, dirProps, offsets, offset);
}
/**
* This method can be called from within
- * {@link ISTextProcessor#indexOfSpecial indexOfSpecial} or
- * {@link ISTextProcessor#processSpecial processSpecial} in
- * implementations of {@link ISTextProcessor} to add a
- * directional mark before a
+ * {@link #indexOfSpecial indexOfSpecial} or
+ * {@link #processSpecial processSpecial} in extensions of
+ * STextProcessor
to add a directional mark before a
* separator if needed for correct display, depending on the
* base direction of the text and on the class of the
* characters in the lean text preceding and following
* the separator itself.
*
- * @param features is the {@link STextFeatures} instance
- * received as parameter to indexOfSpecial
or
- * processSpecial
.
+ * separLocation
and the text following it. If, and only if,
+ * a directional mark is needed to insure that the two parts of text
+ * will be laid out according to the base direction, a mark will be
+ * added when generating the full text.
*
* @param text is the structured text string received as
* parameter to indexOfSpecial
or
@@ -228,8 +360,124 @@ public class STextProcessor implements ISTextProcessor {
* It must be a non-negative number smaller than the length
* of the lean text.
*/
- public static void processSeparator(STextFeatures features, String text, byte[] dirProps, int[] offsets, int separLocation) {
- STextImpl.processSeparator(features, text, dirProps, offsets, separLocation);
+ public static final void processSeparator(String text, byte[] dirProps, int[] offsets, int separLocation) {
+ STextImpl.processSeparator(text, dirProps, offsets, separLocation);
+ }
+
+ /**
+ * Indicate the separators to use for the current processor.
+ * This methode is invoked before starting the processing.
+ *
+ * @param environment the current environment, which may affect the behavior of
+ * the processor. This parameter may be specified as
+ * null
, in which case the
+ * {@link STextEnvironment#DEFAULT DEFAULT}
+ * environment should be assumed.
+ *
+ * @param text is the structured text string to process.
+ *
+ * @param dirProps is a parameter received uniquely to be used as argument
+ * for calls to getDirProp
and other methods used
+ * by processors.
+ *
+ * @return a string grouping one-character separators which separate
+ * the structured text into tokens.
+ *
+ * null
, in which case the
+ * {@link STextEnvironment#DEFAULT DEFAULT}
+ * environment should be assumed.
+ *
+ * @param text is the structured text string to process.
+ *
+ * @param dirProps is a parameter received uniquely to be used as argument
+ * for calls to getDirProp
and other methods used
+ * by processors.
+ *
+ * @return the base direction of the structured text. This direction
+ * may not be the same depending on the environment and on
+ * whether the structured text contains Arabic or Hebrew
+ * letters.
+ * The value returned is either
+ * {@link STextEngine#DIR_LTR DIR_LTR} or {@link STextEngine#DIR_RTL DIR_RTL}.
+ *
+ * DIR_LTR
.
+ */
+ public int getDirection(STextEnvironment environment, String text, byte[] dirProps) {
+ return STextEngine.DIR_LTR;
+ }
+
+ /**
+ * Indicate the number of special cases handled by the current processor.
+ * This methode is invoked before starting the processing.
+ * If the number returned is zero,
+ * {@link #indexOfSpecial indexOfSpecial} and
+ * {@link #processSpecial processSpecial} will not be invoked.
+ *
+ * @param environment the current environment, which may affect the behavior of
+ * the processor. This parameter may be specified as
+ * null
, in which case the
+ * {@link STextEnvironment#DEFAULT DEFAULT}
+ * environment should be assumed.
+ *
+ * @param text is the structured text string to process.
+ *
+ * @param dirProps is a parameter received uniquely to be used as argument
+ * for calls to getDirProp
and other methods used
+ * by processors.
+ *
+ * @return the number of special cases for the associated processor.
+ * Special cases exist for some types of structured text
+ * processors. They are implemented by overriding methods
+ * {@link STextProcessor#indexOfSpecial indexOfSpecial} and
+ * {@link STextProcessor#processSpecial processSpecial}.
+ * Examples of special cases are comments, literals, or
+ * anything which is not identified by a one-character separator.
+ *
+ * zero
.
+ */
+ public int getSpecialsCount(STextEnvironment environment, String text, byte[] dirProps) {
+ return 0;
+ }
+
+ /**
+ * Check if there is a need for processing structured text.
+ * This methode is invoked before starting the processing. If the
+ * processor returns true
, no directional formatting
+ * characters are added to the lean text and the processing
+ * is shortened.
+ *
+ * @param environment the current environment, which may affect the behavior of
+ * the processor. This parameter may be specified as
+ * null
, in which case the
+ * {@link STextEnvironment#DEFAULT DEFAULT}
+ * environment should be assumed.
+ *
+ * @param text is the structured text string to process.
+ *
+ * @param dirProps is a parameter received uniquely to be used as argument
+ * for calls to getDirProp
and other methods used
+ * by processors.
+ *
+ * @return a flag indicating if there is no need to process the structured
+ * text to add directional formatting characters.
+ *
+ * false
.
+ */
+ public boolean skipProcessing(STextEnvironment environment, String text, byte[] dirProps) {
+ return false;
}
}
diff --git a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/custom/STextStringProcessor.java b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/custom/STextStringProcessor.java
index dc87dc7f7..04e9479be 100644
--- a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/custom/STextStringProcessor.java
+++ b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/custom/STextStringProcessor.java
@@ -34,7 +34,7 @@ public class STextStringProcessor {
* @return a reference to an instance of a processor of the
* required type. If the type is unknown, return null
.
*/
- static public ISTextProcessor getProcessor(String type) {
+ static public STextProcessor getProcessor(String type) {
return STextTypesCollector.getInstance().getProcessor(type);
}
}
diff --git a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/custom/package.html b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/custom/package.html
index 9bbe97828..382a50212 100644
--- a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/custom/package.html
+++ b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/custom/package.html
@@ -5,18 +5,13 @@
-
fromIndex
+ * in text
of the first occurrence of the
+ * start delimiter corresponding to caseNumber
+ * (first start delimiter if caseNumber
equals 1,
+ * second delimiter if caseNumber
equals 2, etc...).
+ *
+ * @see #getDelimiters
*/
- public int indexOfSpecial(STextFeatures features, String text, byte[] dirProps, int[] offsets, int caseNumber, int fromIndex) {
+ public int indexOfSpecial(STextEnvironment environment, String text, byte[] dirProps, int[] offsets, int caseNumber, int fromIndex) {
char delim = getDelimiters().charAt((caseNumber - 1) * 2);
return text.indexOf(delim, fromIndex);
}
/**
- * This method skips until after the matching end delimiter.
+ * This method handles the text between start and end delimiters
+ * as a token.
+ * It inserts a directional mark if needed at position
+ * separLocation
which corresponds to a start delimiter,
+ * and skips until after the matching end delimiter.
+ *
+ * @return the position after the matching end delimiter, or the length
+ * of text
if no end delimiter is found.
*/
- public int processSpecial(STextFeatures features, String text, byte[] dirProps, int[] offsets, int[] state, int caseNumber, int separLocation) {
- STextProcessor.processSeparator(features, text, dirProps, offsets, separLocation);
+ public int processSpecial(STextEnvironment environment, String text, byte[] dirProps, int[] offsets, int[] state, int caseNumber, int separLocation) {
+ STextProcessor.processSeparator(text, dirProps, offsets, separLocation);
int loc = separLocation + 1;
char delim = getDelimiters().charAt((caseNumber * 2) - 1);
loc = text.indexOf(delim, loc);
diff --git a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/STextDelimsEsc.java b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/STextDelimsEsc.java
index e3b10e4ac..67f944d04 100644
--- a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/STextDelimsEsc.java
+++ b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/STextDelimsEsc.java
@@ -10,7 +10,7 @@
******************************************************************************/
package org.eclipse.equinox.bidi.internal;
-import org.eclipse.equinox.bidi.custom.STextFeatures;
+import org.eclipse.equinox.bidi.STextEnvironment;
import org.eclipse.equinox.bidi.custom.STextProcessor;
/**
@@ -32,11 +32,15 @@ import org.eclipse.equinox.bidi.custom.STextProcessor;
public abstract class STextDelimsEsc extends STextDelims {
/**
- * This method skips until after the matching end delimiter,
+ * This method handles the text between start and end delimiters
+ * as a token.
+ * It inserts a directional mark if needed at position
+ * separLocation
which corresponds to a start delimiter,
+ * and skips until after the matching end delimiter,
* ignoring possibly escaped end delimiters.
*/
- public int processSpecial(STextFeatures features, String text, byte[] dirProps, int[] offsets, int[] state, int caseNumber, int separLocation) {
- STextProcessor.processSeparator(features, text, dirProps, offsets, separLocation);
+ public int processSpecial(STextEnvironment environment, String text, byte[] dirProps, int[] offsets, int[] state, int caseNumber, int separLocation) {
+ STextProcessor.processSeparator(text, dirProps, offsets, separLocation);
int location = separLocation + 1;
char delim = getDelimiters().charAt((caseNumber * 2) - 1);
while (true) {
diff --git a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/STextImpl.java b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/STextImpl.java
index 70c13c2b4..d7ddb750d 100644
--- a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/STextImpl.java
+++ b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/STextImpl.java
@@ -12,7 +12,7 @@ package org.eclipse.equinox.bidi.internal;
import org.eclipse.equinox.bidi.STextEngine;
import org.eclipse.equinox.bidi.STextEnvironment;
-import org.eclipse.equinox.bidi.custom.*;
+import org.eclipse.equinox.bidi.custom.STextProcessor;
/**
* STextImpl
provides the code which implements the API in
@@ -54,16 +54,10 @@ public class STextImpl {
// nothing to do
}
- /*
- // keep private copy of specialsCount to avoid later modification
- specialsCount = features.getSpecialsCount();
- locations = new int[features.getSeparators().length() + specialsCount];
- }
- */
- static long computeNextLocation(ISTextProcessor processor, STextFeatures features, String text, byte[] dirProps, int[] offsets, int[] locations, int[] state, int curPos) {
- String separators = features.getSeparators();
+ static long computeNextLocation(STextProcessor processor, STextEnvironment environment, String text, byte[] dirProps, int[] offsets, int[] locations, int[] state, int curPos) {
+ String separators = processor.getSeparators(environment, text, dirProps);
int separCount = separators.length();
- int specialsCount = features.getSpecialsCount();
+ int specialsCount = processor.getSpecialsCount(environment, text, dirProps);
int len = text.length();
int nextLocation = len;
int idxLocation = 0;
@@ -73,7 +67,7 @@ public class STextImpl {
int location = locations[separCount + i];
if (location < curPos) {
offsets = ensureRoomInOffsets(offsets);
- location = processor.indexOfSpecial(features, text, dirProps, offsets, i + 1, curPos);
+ location = processor.indexOfSpecial(environment, text, dirProps, offsets, i + 1, curPos);
if (location < 0)
location = len;
locations[separCount + i] = location;
@@ -137,57 +131,15 @@ public class STextImpl {
/**
* @see STextEngine#getCurDirection STextEngine.getCurDirection
*/
- public static int getCurDirection(Object _processor, STextFeatures features, STextEnvironment environment, String text, byte[] dirProps) {
- if (environment == null)
- environment = STextEnvironment.DEFAULT;
- if (features == null) {
- if (_processor == null)
- return STextFeatures.DIR_LTR;
- ISTextProcessor processor;
- if (_processor instanceof java.lang.String) {
- processor = STextStringProcessor.getProcessor((String) _processor);
- if (processor == null)
- throw new IllegalArgumentException("Invalid processor type!"); //$NON-NLS-1$
- } else if (_processor instanceof ISTextProcessor)
- processor = (ISTextProcessor) _processor;
- else
- throw new IllegalArgumentException("Invalid processor argument!"); //$NON-NLS-1$
- features = processor.getFeatures(environment);
- }
- int dirArabic = features.getDirArabic();
- int dirHebrew = features.getDirHebrew();
- // same direction for Arabic and Hebrew?
- if (dirArabic == dirHebrew)
- return dirArabic;
- // check if Arabic or Hebrew letter comes first
- int len = text.length();
- if (dirProps == null)
- dirProps = new byte[len + 1];
- byte dirProp;
- for (int i = 0; i < len; i++) {
- // In the following lines, R and AL represent bidi categories
- // as defined in the Unicode Bidirectional Algorithm
- // ( http://www.unicode.org/reports/tr9/ ).
- // R represents the category Right to Left character.
- // AL represents the category Arabic Letter.
- byte saveOrient = dirProps[len];
- dirProps[len] = -1; // make getDirProp return B
- dirProp = getDirProp(text, dirProps, i);
- dirProps[len] = saveOrient;
- if (dirProp == AL)
- return dirArabic;
- if (dirProp == R)
- return dirHebrew;
- }
- // found no Arabic or Hebrew character
- return STextFeatures.DIR_LTR;
+ public static int getCurDirection(STextProcessor processor, STextEnvironment environment, String text, byte[] dirProps) {
+ return processor.getDirection(environment, text, dirProps);
}
/**
* @see STextProcessor#getDirProp STextProcessor.getDirProp
*/
public static byte getDirProp(String text, byte[] dirProps, int index) {
- byte dirProp = dirProps[index];
+ byte dirProp = dirProps == null ? 0 : dirProps[index];
if (dirProp == 0) {
// In the following lines, B, L and R represent bidi categories
// as defined in the Unicode Bidirectional Algorithm
@@ -196,14 +148,15 @@ public class STextImpl {
// L represents the category Left to Right character.
// R represents the category Right to Left character.
dirProp = Character.getDirectionality(text.charAt(index));
- if (dirProp == B) {
+ if (dirProp == B && dirProps != null) {
// the last entry of dirProps contains the current component orientation
byte orient = dirProps[dirProps.length - 1];
if (orient == -1)
return B;
dirProp = orient == STextEnvironment.ORIENT_RTL ? R : L;
}
- dirProps[index] = (byte) (dirProp + DIRPROPS_ADD);
+ if (dirProps != null)
+ dirProps[index] = (byte) (dirProp + DIRPROPS_ADD);
return dirProp;
}
return (byte) (dirProp - DIRPROPS_ADD);
@@ -219,7 +172,7 @@ public class STextImpl {
/**
* @see STextProcessor#processSeparator STextProcessor.processSeparator
*/
- public static void processSeparator(STextFeatures features, String text, byte[] dirProps, int[] offsets, int separLocation) {
+ public static void processSeparator(String text, byte[] dirProps, int[] offsets, int separLocation) {
// In this method, L, R, AL, AN and EN represent bidi categories
// as defined in the Unicode Bidirectional Algorithm
// ( http://www.unicode.org/reports/tr9/ ).
@@ -230,7 +183,7 @@ public class STextImpl {
// EN represents the category European Number.
int len = text.length();
// offsets[2] contains the structured text direction
- if (offsets[2] == STextFeatures.DIR_RTL) {
+ if (offsets[2] == STextEngine.DIR_RTL) {
// the structured text base direction is RTL
for (int i = separLocation - 1; i >= 0; i--) {
byte dirProp = getDirProp(text, dirProps, i);
@@ -254,44 +207,28 @@ public class STextImpl {
// the structured text base direction is LTR
boolean doneAN = false;
- boolean ignoreArabic = features.getIgnoreArabic();
- boolean ignoreHebrew = features.getIgnoreHebrew();
- if (ignoreArabic && ignoreHebrew)
- return;
- byte _R, _AL, _AN;
- if (ignoreArabic) {
- _AL = Byte.MIN_VALUE; // not a real value
- _AN = Byte.MIN_VALUE;
- } else {
- _AL = AL;
- _AN = AN;
- }
- if (ignoreHebrew)
- _R = Byte.MIN_VALUE;
- else
- _R = R;
for (int i = separLocation - 1; i >= 0; i--) {
byte dirProp = getDirProp(text, dirProps, i);
if (dirProp == L)
return;
- if (dirProp == _R || dirProp == _AL) {
+ if (dirProp == R || dirProp == AL) {
for (int j = separLocation; j < len; j++) {
dirProp = getDirProp(text, dirProps, j);
if (dirProp == L)
return;
- if (dirProp == _R || dirProp == EN || dirProp == _AL || dirProp == _AN) {
+ if (dirProp == R || dirProp == EN || dirProp == AL || dirProp == AN) {
insertMark(text, dirProps, offsets, separLocation);
return;
}
}
return;
}
- if (dirProp == _AN && !doneAN) {
+ if (dirProp == AN && !doneAN) {
for (int j = separLocation; j < len; j++) {
dirProp = getDirProp(text, dirProps, j);
if (dirProp == L)
return;
- if (dirProp == _AL || dirProp == _AN || dirProp == _R) {
+ if (dirProp == AL || dirProp == AN || dirProp == R) {
insertMark(text, dirProps, offsets, separLocation);
return;
}
@@ -304,12 +241,12 @@ public class STextImpl {
/**
* @see STextEngine#leanToFullText STextEngine.leanToFullText
*/
- public static String leanToFullText(Object processor, STextFeatures features, STextEnvironment environment, String text, int[] state) {
+ public static String leanToFullText(STextProcessor processor, STextEnvironment environment, String text, int[] state) {
int len = text.length();
if (len == 0)
return text;
byte[] dirProps = new byte[len + 1];
- int[] offsets = leanToFullCommon(processor, features, environment, text, state, dirProps);
+ int[] offsets = leanToFullCommon(processor, environment, text, state, dirProps);
int prefixLength = offsets[1];
int count = offsets[0] - OFFSETS_SHIFT;
if (count == 0 && prefixLength == 0)
@@ -355,12 +292,12 @@ public class STextImpl {
/**
* @see STextEngine#leanToFullMap STextEngine.leanToFullMap
*/
- public static int[] leanToFullMap(Object processor, STextFeatures features, STextEnvironment environment, String text, int[] state) {
+ public static int[] leanToFullMap(STextProcessor processor, STextEnvironment environment, String text, int[] state) {
int len = text.length();
if (len == 0)
return EMPTY_INT_ARRAY;
byte[] dirProps = new byte[len + 1];
- int[] offsets = leanToFullCommon(processor, features, environment, text, state, dirProps);
+ int[] offsets = leanToFullCommon(processor, environment, text, state, dirProps);
int prefixLength = offsets[1];
int[] map = new int[len];
int count = offsets[0]; // number of used entries
@@ -378,12 +315,12 @@ public class STextImpl {
/**
* @see STextEngine#leanBidiCharOffsets STextEngine.leanBidiCharOffsets
*/
- public static int[] leanBidiCharOffsets(Object processor, STextFeatures features, STextEnvironment environment, String text, int[] state) {
+ public static int[] leanBidiCharOffsets(STextProcessor processor, STextEnvironment environment, String text, int[] state) {
int len = text.length();
if (len == 0)
return EMPTY_INT_ARRAY;
byte[] dirProps = new byte[len + 1];
- int[] offsets = leanToFullCommon(processor, features, environment, text, state, dirProps);
+ int[] offsets = leanToFullCommon(processor, environment, text, state, dirProps);
// offsets[0] contains the number of used entries
int count = offsets[0] - OFFSETS_SHIFT;
int[] result = new int[count];
@@ -391,20 +328,9 @@ public class STextImpl {
return result;
}
- static int[] leanToFullCommon(Object _processor, STextFeatures features, STextEnvironment environment, String text, int[] state, byte[] dirProps) {
- ISTextProcessor processor;
- if (_processor instanceof java.lang.String) {
- processor = STextStringProcessor.getProcessor((String) _processor);
- if (processor == null)
- throw new IllegalArgumentException("Invalid processor type!"); //$NON-NLS-1$
- } else if (_processor instanceof ISTextProcessor)
- processor = (ISTextProcessor) _processor;
- else
- throw new IllegalArgumentException("Invalid processor argument!"); //$NON-NLS-1$
+ static int[] leanToFullCommon(STextProcessor processor, STextEnvironment environment, String text, int[] state, byte[] dirProps) {
if (environment == null)
environment = STextEnvironment.DEFAULT;
- if (features == null)
- features = processor.getFeatures(environment);
if (state == null) {
state = new int[1];
state[0] = STextEngine.STATE_INITIAL;
@@ -413,47 +339,51 @@ public class STextImpl {
// dirProps: 1 byte for each char in text, + 1 byte = current orientation
int orient = getCurOrient(environment, text, dirProps);
dirProps[len] = (byte) orient;
- int separCount = features.getSeparators().length();
- int direction = getCurDirection(processor, features, environment, text, dirProps);
- // current position
- int curPos = 0;
+ int direction = processor.getDirection(environment, text, dirProps);
// offsets of marks to add. Entry 0 is the number of used slots;
// entry 1 is reserved to pass prefixLength.
// entry 2 is reserved to pass direction..
int[] offsets = new int[20];
offsets[0] = OFFSETS_SHIFT;
offsets[2] = direction;
- // initialize locations
- int[] locations = new int[separCount + features.getSpecialsCount()];
- for (int i = 0, k = locations.length; i < k; i++) {
- locations[i] = -1;
- }
- if (state[0] > STextEngine.STATE_INITIAL) {
- offsets = ensureRoomInOffsets(offsets);
- int initState = state[0];
- state[0] = STextEngine.STATE_INITIAL;
- curPos = processor.processSpecial(features, text, dirProps, offsets, state, initState, -1);
- }
- while (true) {
- // location of next token to handle
- int nextLocation;
- // index of next token to handle (if < separCount, this is a separator; otherwise a special case
- int idxLocation;
- long res = computeNextLocation(processor, features, text, dirProps, offsets, locations, state, curPos);
- nextLocation = (int) (res & 0x00000000FFFFFFFF); /* low word */
- if (nextLocation >= len)
- break;
- idxLocation = (int) (res >> 32); /* high word */
- if (idxLocation < separCount) {
- offsets = ensureRoomInOffsets(offsets);
- processSeparator(features, text, dirProps, offsets, nextLocation);
- curPos = nextLocation + 1;
- } else {
+ if (!processor.skipProcessing(environment, text, dirProps)) {
+ // initialize locations
+ int separCount = processor.getSeparators(environment, text, dirProps).length();
+ int[] locations = new int[separCount + processor.getSpecialsCount(environment, text, dirProps)];
+ for (int i = 0, k = locations.length; i < k; i++) {
+ locations[i] = -1;
+ }
+ // current position
+ int curPos = 0;
+ if (state[0] > STextEngine.STATE_INITIAL) {
offsets = ensureRoomInOffsets(offsets);
- idxLocation -= (separCount - 1); // because caseNumber starts from 1
- curPos = processor.processSpecial(features, text, dirProps, offsets, state, idxLocation, nextLocation);
+ int initState = state[0];
+ state[0] = STextEngine.STATE_INITIAL;
+ curPos = processor.processSpecial(environment, text, dirProps, offsets, state, initState, -1);
}
- }
+ while (true) {
+ // location of next token to handle
+ int nextLocation;
+ // index of next token to handle (if < separCount, this is a separator; otherwise a special case
+ int idxLocation;
+ long res = computeNextLocation(processor, environment, text, dirProps, offsets, locations, state, curPos);
+ nextLocation = (int) (res & 0x00000000FFFFFFFF); /* low word */
+ if (nextLocation >= len)
+ break;
+ idxLocation = (int) (res >> 32); /* high word */
+ if (idxLocation < separCount) {
+ offsets = ensureRoomInOffsets(offsets);
+ processSeparator(text, dirProps, offsets, nextLocation);
+ curPos = nextLocation + 1;
+ } else {
+ offsets = ensureRoomInOffsets(offsets);
+ idxLocation -= (separCount - 1); // because caseNumber starts from 1
+ curPos = processor.processSpecial(environment, text, dirProps, offsets, state, idxLocation, nextLocation);
+ }
+ if (curPos >= len)
+ break;
+ } // end while
+ } // end if (!processor.skipProcessing())
if (orient == STextEnvironment.ORIENT_IGNORE)
offsets[1] = 0;
else {
@@ -473,27 +403,16 @@ public class STextImpl {
/**
* @see STextEngine#fullToLeanText STextEngine.fullToLeanText
*/
- public static String fullToLeanText(Object _processor, STextFeatures features, STextEnvironment environment, String text, int[] state) {
+ public static String fullToLeanText(STextProcessor processor, STextEnvironment environment, String text, int[] state) {
if (text.length() == 0)
return text;
- ISTextProcessor processor;
- if (_processor instanceof java.lang.String) {
- processor = STextStringProcessor.getProcessor((String) _processor);
- if (processor == null)
- throw new IllegalArgumentException("Invalid processor type!"); //$NON-NLS-1$
- } else if (_processor instanceof ISTextProcessor)
- processor = (ISTextProcessor) _processor;
- else
- throw new IllegalArgumentException("Invalid processor argument!"); //$NON-NLS-1$
if (environment == null)
environment = STextEnvironment.DEFAULT;
- if (features == null)
- features = processor.getFeatures(environment);
if (state == null) {
state = new int[1];
state[0] = STextEngine.STATE_INITIAL;
}
- int dir = getCurDirection(processor, features, environment, text, null);
+ int dir = processor.getDirection(environment, text, null);
char curMark = MARKS[dir];
char curEmbed = EMBEDS[dir];
int i; // used as loop index
@@ -531,7 +450,7 @@ public class STextImpl {
chars[i - cnt] = c;
}
String lean = new String(chars, 0, lenText - cnt);
- String full = leanToFullText(processor, features, IGNORE_ENVIRONMENT, lean, state);
+ String full = leanToFullText(processor, IGNORE_ENVIRONMENT, lean, state);
if (full.equals(text))
return lean;
@@ -569,7 +488,7 @@ public class STextImpl {
throw new IllegalStateException("Internal error: extra character not a Mark."); //$NON-NLS-1$
}
if (idxText < lenText) /* full ended before text - this should never happen since
- we removed all marks and PDFs at the end of text */
+ we removed all marks and PDFs at the end of text */
throw new IllegalStateException("Internal error: unexpected EOL."); //$NON-NLS-1$
lean = new String(newChars, 0, newCharsPos);
@@ -579,13 +498,13 @@ public class STextImpl {
/**
* @see STextEngine#fullToLeanMap STextEngine.fullToLeanMap
*/
- public static int[] fullToLeanMap(Object processor, STextFeatures features, STextEnvironment environment, String full, int[] state) {
+ public static int[] fullToLeanMap(STextProcessor processor, STextEnvironment environment, String full, int[] state) {
int lenFull = full.length();
if (lenFull == 0)
return EMPTY_INT_ARRAY;
- String lean = fullToLeanText(processor, features, environment, full, state);
+ String lean = fullToLeanText(processor, environment, full, state);
int lenLean = lean.length();
- int dir = getCurDirection(processor, features, environment, lean, null);
+ int dir = processor.getDirection(environment, lean, null);
char curMark = MARKS[dir];
char curEmbed = EMBEDS[dir];
int[] map = new int[lenFull];
@@ -613,11 +532,11 @@ public class STextImpl {
/**
* @see STextEngine#fullBidiCharOffsets STextEngine.fullBidiCharOffsets
*/
- public static int[] fullBidiCharOffsets(Object processor, STextFeatures features, STextEnvironment environment, String full, int[] state) {
+ public static int[] fullBidiCharOffsets(STextProcessor processor, STextEnvironment environment, String full, int[] state) {
int lenFull = full.length();
if (lenFull == 0)
return EMPTY_INT_ARRAY;
- String lean = fullToLeanText(processor, features, environment, full, state);
+ String lean = fullToLeanText(processor, environment, full, state);
int[] offsets = new int[20];
offsets[0] = OFFSETS_SHIFT;
int lenLean = lean.length();
diff --git a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/STextSingle.java b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/STextSingle.java
index 7dfcd2bfa..ec8ec0ab0 100644
--- a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/STextSingle.java
+++ b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/STextSingle.java
@@ -10,7 +10,7 @@
******************************************************************************/
package org.eclipse.equinox.bidi.internal;
-import org.eclipse.equinox.bidi.custom.STextFeatures;
+import org.eclipse.equinox.bidi.STextEnvironment;
import org.eclipse.equinox.bidi.custom.STextProcessor;
/**
@@ -24,9 +24,8 @@ import org.eclipse.equinox.bidi.custom.STextProcessor;
*
* part1=part2
*
- * The {@link STextFeatures#getSeparators separators}
- * field in the {@link STextFeatures features}
- * of this processor should contain exactly one character.
+ * The string returned by {@link STextProcessor#getSeparators getSeparators}
+ * for this processor should contain exactly one character.
* Additional characters will be ignored.
*
* @author Matitiahu Allouche
@@ -35,18 +34,31 @@ public abstract class STextSingle extends STextProcessor {
/**
* This method locates occurrences of the separator.
+ *
+ * @see #getSeparators getSeparators
*/
- public int indexOfSpecial(STextFeatures features, String text, byte[] dirProps, int[] offsets, int caseNumber, int fromIndex) {
- return text.indexOf(features.getSeparators().charAt(0), fromIndex);
+ public int indexOfSpecial(STextEnvironment environment, String text, byte[] dirProps, int[] offsets, int caseNumber, int fromIndex) {
+ return text.indexOf(this.getSeparators(environment, text, dirProps).charAt(0), fromIndex);
}
/**
* This method inserts a mark before the separator if needed and
* skips to the end of the source string.
+ *
+ * @return the length of text
.
*/
- public int processSpecial(STextFeatures features, String text, byte[] dirProps, int[] offsets, int[] state, int caseNumber, int separLocation) {
- STextProcessor.processSeparator(features, text, dirProps, offsets, separLocation);
+ public int processSpecial(STextEnvironment environment, String text, byte[] dirProps, int[] offsets, int[] state, int caseNumber, int separLocation) {
+ STextProcessor.processSeparator(text, dirProps, offsets, separLocation);
return text.length();
}
+ /**
+ * This method returns 1 as number of special cases handled by this processor.
+ *
+ * @return 1.
+ */
+ public int getSpecialsCount(STextEnvironment environment, String text, byte[] dirProps) {
+ return 1;
+ }
+
}
diff --git a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/STextTypesCollector.java b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/STextTypesCollector.java
index 0d06e3c31..bbcf564e0 100644
--- a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/STextTypesCollector.java
+++ b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/STextTypesCollector.java
@@ -13,7 +13,7 @@ package org.eclipse.equinox.bidi.internal;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.runtime.*;
-import org.eclipse.equinox.bidi.custom.ISTextProcessor;
+import org.eclipse.equinox.bidi.custom.STextProcessor;
public class STextTypesCollector implements IRegistryEventListener {
@@ -46,12 +46,12 @@ public class STextTypesCollector implements IRegistryEventListener {
return result;
}
- public ISTextProcessor getProcessor(String type) {
+ public STextProcessor getProcessor(String type) {
if (types == null)
read();
Object processor = types.get(type);
- if (processor instanceof ISTextProcessor)
- return (ISTextProcessor) processor;
+ if (processor instanceof STextProcessor)
+ return (STextProcessor) processor;
return null;
}
diff --git a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/consumable/STextComma.java b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/consumable/STextComma.java
index a3493d0e8..dc29ad2b5 100644
--- a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/consumable/STextComma.java
+++ b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/consumable/STextComma.java
@@ -11,7 +11,6 @@
package org.eclipse.equinox.bidi.internal.consumable;
import org.eclipse.equinox.bidi.STextEnvironment;
-import org.eclipse.equinox.bidi.custom.STextFeatures;
import org.eclipse.equinox.bidi.custom.STextProcessor;
/**
@@ -21,16 +20,12 @@ import org.eclipse.equinox.bidi.custom.STextProcessor;
*
*/
public class STextComma extends STextProcessor {
- static final STextFeatures FEATURES = new STextFeatures(",", 0, -1, -1, false, false); //$NON-NLS-1$
/**
- * This method retrieves the features specific to this processor.
- *
- * @return features with one separator (comma), no special cases,
- * LTR direction for Arabic and Hebrew, and support for both.
+ * @return one separator (comma).
*/
- public STextFeatures getFeatures(STextEnvironment env) {
- return FEATURES;
+ public String getSeparators(STextEnvironment environment, String text, byte[] dirProps) {
+ return ","; //$NON-NLS-1$
}
}
diff --git a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/consumable/STextEmail.java b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/consumable/STextEmail.java
index 88ccdc0dc..05bfaba2b 100644
--- a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/consumable/STextEmail.java
+++ b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/consumable/STextEmail.java
@@ -10,32 +10,58 @@
******************************************************************************/
package org.eclipse.equinox.bidi.internal.consumable;
+import org.eclipse.equinox.bidi.STextEngine;
import org.eclipse.equinox.bidi.STextEnvironment;
-import org.eclipse.equinox.bidi.custom.STextFeatures;
+import org.eclipse.equinox.bidi.custom.STextProcessor;
import org.eclipse.equinox.bidi.internal.STextDelimsEsc;
/**
* Processor adapted to processing e-mail addresses.
*/
public class STextEmail extends STextDelimsEsc {
- static final int LTR = STextFeatures.DIR_LTR;
- static final int RTL = STextFeatures.DIR_RTL;
- static final STextFeatures MIRRORED = new STextFeatures("<>.:,;@", 2, RTL, LTR, false, false); //$NON-NLS-1$
- static final STextFeatures NOT_MIRRORED = new STextFeatures("<>.:,;@", 2, LTR, LTR, false, false); //$NON-NLS-1$
+ static final byte L = Character.DIRECTIONALITY_LEFT_TO_RIGHT;
+ static final byte R = Character.DIRECTIONALITY_RIGHT_TO_LEFT;
+ static final byte AL = Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC;
/**
- * This method retrieves the features specific to this processor.
- *
- * @return features with separators "<>.:,;@", 2 special cases,
- * LTR direction for Arabic when the GUI is not mirrored,
- * RTL direction for Arabic when the GUI is mirrored,
- * LTR direction for Hebrew in all cases,
- * and support for both Arabic and Hebrew.
+ * @return separators "<>.:,;@".
*/
- public STextFeatures getFeatures(STextEnvironment env) {
- if (env == null)
- env = STextEnvironment.DEFAULT;
- return env.getMirrored() ? MIRRORED : NOT_MIRRORED;
+ public String getSeparators(STextEnvironment environment, String text, byte[] dirProps) {
+ return "<>.:,;@"; //$NON-NLS-1$
+ }
+
+ /**
+ * @return {@link STextEngine#DIR_RTL DIR_RTL} if the following
+ * conditions are satisfied:
+ *
+ *
+ * Otherwise, returns {@link STextEngine#DIR_LTR DIR_LTR}.
+ */
+ public int getDirection(STextEnvironment environment, String text, byte[] dirProps) {
+ String language = environment.getLanguage();
+ if (!language.equals("ar")) //$NON-NLS-1$
+ return STextEngine.DIR_LTR;
+ int domainStart;
+ domainStart = text.indexOf('@');
+ if (domainStart < 0)
+ domainStart = 0;
+ for (int i = domainStart; i < text.length(); i++) {
+ byte dirProp = STextProcessor.getDirProp(text, dirProps, i);
+ if (dirProp == AL || dirProp == R)
+ return STextEngine.DIR_RTL;
+ }
+ return STextEngine.DIR_LTR;
+ }
+
+ /**
+ * @return 2 as number of special cases handled by this processor.
+ */
+ public int getSpecialsCount(STextEnvironment environment, String text, byte[] dirProps) {
+ return 2;
}
/**
diff --git a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/consumable/STextFile.java b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/consumable/STextFile.java
index 64dfe2801..cc7b2fda4 100644
--- a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/consumable/STextFile.java
+++ b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/consumable/STextFile.java
@@ -11,23 +11,17 @@
package org.eclipse.equinox.bidi.internal.consumable;
import org.eclipse.equinox.bidi.STextEnvironment;
-import org.eclipse.equinox.bidi.custom.STextFeatures;
import org.eclipse.equinox.bidi.custom.STextProcessor;
/**
* Processor adapted to processing directory and file paths.
*/
public class STextFile extends STextProcessor {
- static final STextFeatures FEATURES = new STextFeatures(":/\\.", 0, -1, -1, false, false); //$NON-NLS-1$
-
/**
- * This method retrieves the features specific to this processor.
- *
- * @return features with separators ":/\.", no special cases,
- * LTR direction for Arabic and Hebrew, and support for both.
+ * @return separators ":/\.".
*/
- public STextFeatures getFeatures(STextEnvironment env) {
- return FEATURES;
+ public String getSeparators(STextEnvironment environment, String text, byte[] dirProps) {
+ return ":/\\."; //$NON-NLS-1$
}
}
diff --git a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/consumable/STextJava.java b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/consumable/STextJava.java
index b079748ca..4b717c1d6 100644
--- a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/consumable/STextJava.java
+++ b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/consumable/STextJava.java
@@ -12,7 +12,6 @@ package org.eclipse.equinox.bidi.internal.consumable;
import org.eclipse.equinox.bidi.STextEngine;
import org.eclipse.equinox.bidi.STextEnvironment;
-import org.eclipse.equinox.bidi.custom.STextFeatures;
import org.eclipse.equinox.bidi.custom.STextProcessor;
/**
@@ -36,18 +35,20 @@ import org.eclipse.equinox.bidi.custom.STextProcessor;
*/
public class STextJava extends STextProcessor {
private static final byte WS = Character.DIRECTIONALITY_WHITESPACE;
- static final STextFeatures FEATURES = new STextFeatures("[](){}.+-<>=~!&*/%^|?:,;\t", 4, -1, -1, false, false); //$NON-NLS-1$
static final String lineSep = STextEnvironment.getLineSep();
/**
- * This method retrieves the features specific to this processor.
- *
- * @return features with separators "[](){}.+-<>=~!&/*%^|?:,;\t",
- * 4 special cases, LTR direction for Arabic and Hebrew,
- * and support for both.
+ * @return the separators for Java syntax
*/
- public STextFeatures getFeatures(STextEnvironment env) {
- return FEATURES;
+ public String getSeparators(STextEnvironment environment, String text, byte[] dirProps) {
+ return "[](){}.+-<>=~!&*/%^|?:,;\t"; //$NON-NLS-1$
+ }
+
+ /**
+ * @return 4 as the number of special cases handled by this processor.
+ */
+ public int getSpecialsCount(STextEnvironment environment, String text, byte[] dirProps) {
+ return 4;
}
/**
@@ -59,7 +60,7 @@ public class STextJava extends STextProcessor {
*
+ *
+ * Otherwise, returns {@link STextEngine#DIR_LTR DIR_LTR}.
+ */
+ public int getDirection(STextEnvironment environment, String text, byte[] dirProps) {
+ String language = environment.getLanguage();
+ if (!language.equals("ar")) //$NON-NLS-1$
+ return STextEngine.DIR_LTR;
+ boolean flagAN = false;
+ for (int i = 0; i < text.length(); i++) {
+ byte dirProp = getDirProp(text, dirProps, i);
+ if (dirProp == AL)
+ return STextEngine.DIR_RTL;
+ if (dirProp == L || dirProp == R)
+ return STextEngine.DIR_LTR;
+ if (dirProp == AN)
+ flagAN = true;
+ }
+ if (flagAN)
+ return STextEngine.DIR_RTL;
+ return STextEngine.DIR_LTR;
}
}
diff --git a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/consumable/STextProperty.java b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/consumable/STextProperty.java
index 78d41c195..1cd1b0e39 100644
--- a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/consumable/STextProperty.java
+++ b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/consumable/STextProperty.java
@@ -11,7 +11,6 @@
package org.eclipse.equinox.bidi.internal.consumable;
import org.eclipse.equinox.bidi.STextEnvironment;
-import org.eclipse.equinox.bidi.custom.STextFeatures;
import org.eclipse.equinox.bidi.internal.STextSingle;
/**
@@ -22,16 +21,11 @@ import org.eclipse.equinox.bidi.internal.STextSingle;
*
*/
public class STextProperty extends STextSingle {
- static final STextFeatures FEATURES = new STextFeatures("=", 1, -1, -1, false, false); //$NON-NLS-1$
-
/**
- * This method retrieves the features specific to this processor.
- *
- * @return features with one separator (equal sign), 1 special case,
- * LTR direction for Arabic and Hebrew, and support for both.
+ * @return one separator (equal sign).
*/
- public STextFeatures getFeatures(STextEnvironment env) {
- return FEATURES;
+ public String getSeparators(STextEnvironment environment, String text, byte[] dirProps) {
+ return "="; //$NON-NLS-1$
}
}
diff --git a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/consumable/STextRegex.java b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/consumable/STextRegex.java
index 93c663d02..2dfdf6662 100644
--- a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/consumable/STextRegex.java
+++ b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/consumable/STextRegex.java
@@ -12,7 +12,7 @@ package org.eclipse.equinox.bidi.internal.consumable;
import org.eclipse.equinox.bidi.STextEngine;
import org.eclipse.equinox.bidi.STextEnvironment;
-import org.eclipse.equinox.bidi.custom.*;
+import org.eclipse.equinox.bidi.custom.STextProcessor;
/**
* STextRegex
is a processor for regular expressions.
@@ -57,7 +57,6 @@ public class STextRegex extends STextProcessor {
'.', ')', '>', '\'', ')', ')', ')', ')', '>', '>', '\'', '}', ')', '}', '>', '\'', ')'};
static final int numberOfStrings = startStrings.length; /* 18 */
static final int maxSpecial = numberOfStrings;
- static final STextFeatures FEATURES = new STextFeatures(null, maxSpecial, -1, -1, false, false);
static final byte L = Character.DIRECTIONALITY_LEFT_TO_RIGHT;
static final byte R = Character.DIRECTIONALITY_RIGHT_TO_LEFT;
static final byte AL = Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC;
@@ -65,23 +64,19 @@ public class STextRegex extends STextProcessor {
static final byte EN = Character.DIRECTIONALITY_EUROPEAN_NUMBER;
/**
- * This method retrieves the features specific to this processor.
- *
- * @see ISTextProcessor#getFeatures
- *
- * @return features with no separators , special cases for each kind of
- * regular expression syntactic string,
- * LTR direction for Arabic and Hebrew, and support for both.
+ * This method retrieves the number of special cases handled by this processor.
+ *
+ * @return the number of special cases for this processor.
*/
- public STextFeatures getFeatures(STextEnvironment env) {
- return FEATURES;
+ public int getSpecialsCount(STextEnvironment environment, String text, byte[] dirProps) {
+ return maxSpecial;
}
/**
* This method locates occurrences of the syntactic strings and of
* R, AL, EN, AN characters.
*/
- public int indexOfSpecial(STextFeatures features, String text, byte[] dirProps, int[] offsets, int caseNumber, int fromIndex) {
+ public int indexOfSpecial(STextEnvironment environment, String text, byte[] dirProps, int[] offsets, int caseNumber, int fromIndex) {
// In this method, L, R, AL, AN and EN represent bidi categories
// as defined in the Unicode Bidirectional Algorithm
// ( http://www.unicode.org/reports/tr9/ ).
@@ -149,7 +144,7 @@ public class STextRegex extends STextProcessor {
/**
* This method process the special cases.
*/
- public int processSpecial(STextFeatures features, String text, byte[] dirProps, int[] offsets, int[] state, int caseNumber, int separLocation) {
+ public int processSpecial(STextEnvironment environment, String text, byte[] dirProps, int[] offsets, int[] state, int caseNumber, int separLocation) {
int location;
switch (caseNumber) {
@@ -158,7 +153,7 @@ public class STextRegex extends STextProcessor {
// initial state from previous line
location = 0;
} else {
- STextProcessor.processSeparator(features, text, dirProps, offsets, separLocation);
+ STextProcessor.processSeparator(text, dirProps, offsets, separLocation);
// skip the opening "(?#"
location = separLocation + 3;
}
@@ -174,7 +169,7 @@ public class STextRegex extends STextProcessor {
case 5 : /* conditional named back reference (?(
+ *
+ * Otherwise, returns {@link STextEngine#DIR_LTR DIR_LTR}.
+ */
+ public int getDirection(STextEnvironment environment, String text, byte[] dirProps) {
+ String language = environment.getLanguage();
+ if (!language.equals("ar")) //$NON-NLS-1$
+ return STextEngine.DIR_LTR;
+ for (int i = 0; i < text.length(); i++) {
+ byte dirProp = getDirProp(text, dirProps, i);
+ if (dirProp == AL || dirProp == R)
+ return STextEngine.DIR_RTL;
+ if (dirProp == L)
+ return STextEngine.DIR_LTR;
+ }
+ if (environment.getMirrored())
+ return STextEngine.DIR_RTL;
+ return STextEngine.DIR_LTR;
+ }
+
}
diff --git a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/consumable/STextSql.java b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/consumable/STextSql.java
index baa6aafdf..9c0965cb3 100644
--- a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/consumable/STextSql.java
+++ b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/consumable/STextSql.java
@@ -12,7 +12,6 @@ package org.eclipse.equinox.bidi.internal.consumable;
import org.eclipse.equinox.bidi.STextEngine;
import org.eclipse.equinox.bidi.STextEnvironment;
-import org.eclipse.equinox.bidi.custom.STextFeatures;
import org.eclipse.equinox.bidi.custom.STextProcessor;
/**
@@ -36,18 +35,20 @@ import org.eclipse.equinox.bidi.custom.STextProcessor;
*/
public class STextSql extends STextProcessor {
private static final byte WS = Character.DIRECTIONALITY_WHITESPACE;
- static final String separators = "\t!#%&()*+,-./:;<=>?|[]{}"; //$NON-NLS-1$
- static final STextFeatures FEATURES = new STextFeatures(separators, 5, -1, -1, false, false);
static final String lineSep = STextEnvironment.getLineSep();
/**
- * This method retrieves the features specific to this processor.
- *
- * @return features with separators "\t!#%&()*+,-./:;<=>?|[]{}", 5 special cases,
- * LTR direction for Arabic and Hebrew, and support for both.
+ * @return separators "\t!#%&()*+,-./:;<=>?|[]{}".
*/
- public STextFeatures getFeatures(STextEnvironment env) {
- return FEATURES;
+ public String getSeparators(STextEnvironment environment, String text, byte[] dirProps) {
+ return "\t!#%&()*+,-./:;<=>?|[]{}"; //$NON-NLS-1$
+ }
+
+ /**
+ * @return 5 as the number of special cases handled by this processor.
+ */
+ public int getSpecialsCount(STextEnvironment environment, String text, byte[] dirProps) {
+ return 5;
}
/**
@@ -60,7 +61,7 @@ public class STextSql extends STextProcessor {
* Introduction to Structured Text
-Other classes and one interface in this package may be used to +For each of these types, a static instance is defined in STextEngine. +These pre-defined instances can be used as argument in the methods of +STextEngine. +
+Other classes in this package may be used to complement and facilitate the action of {@link STextEngine}:
{@link STextEngine} and the -other classes and interface mentioned above are intended for users who +other classes mentioned above are intended for users who need to process structured text for which there already exist processors.
@@ -90,14 +97,9 @@ not currently supported can use the following components of the package {@link org.eclipse.equinox.bidi.custom}: