summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatitiahu Allouche2011-08-18 09:49:17 (EDT)
committer Oleg Besedin2011-08-18 09:49:17 (EDT)
commit443d39df762926eff2c600a9cfd0f1e620dd7cb8 (patch)
tree7787aa5ba7a076fb4a9cf86a0c383e482ab816ae
parent08145c3ce3c347e8e90f47329ac7db9775ff164f (diff)
downloadrt.equinox.bundles-443d39df762926eff2c600a9cfd0f1e620dd7cb8.zip
rt.equinox.bundles-443d39df762926eff2c600a9cfd0f1e620dd7cb8.tar.gz
rt.equinox.bundles-443d39df762926eff2c600a9cfd0f1e620dd7cb8.tar.bz2
Bug 183164 - [Implementation for] Display of Complex Expressions
Containing Bidirectional Text
-rw-r--r--bundles/org.eclipse.equinox.bidi.tests/STextTestSuite.launch42
-rw-r--r--bundles/org.eclipse.equinox.bidi.tests/src/org/eclipse/equinox/bidi/internal/tests/STextFullToLeanTest.java4
-rw-r--r--bundles/org.eclipse.equinox.bidi.tests/src/org/eclipse/equinox/bidi/internal/tests/STextMethodsTest.java14
-rw-r--r--bundles/org.eclipse.equinox.bidi.tests/src/org/eclipse/equinox/bidi/internal/tests/STextProcessorTest.java10
-rw-r--r--bundles/org.eclipse.equinox.bidi.tests/src/org/eclipse/equinox/bidi/internal/tests/TestHandler1.java7
-rw-r--r--bundles/org.eclipse.equinox.bidi.tests/src/org/eclipse/equinox/bidi/internal/tests/TestHandler2.java4
-rw-r--r--bundles/org.eclipse.equinox.bidi.tests/src/org/eclipse/equinox/bidi/internal/tests/TestHandler3.java6
-rw-r--r--bundles/org.eclipse.equinox.bidi.tests/src/org/eclipse/equinox/bidi/internal/tests/TestHandlerMyComma.java12
-rw-r--r--bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/STextProcessor.java13
-rw-r--r--bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/advanced/ISTextExpert.java10
-rw-r--r--bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/advanced/STextEnvironment.java16
-rw-r--r--bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/advanced/STextExpertFactory.java6
-rw-r--r--bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/custom/STextCharTypes.java17
-rw-r--r--bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/custom/STextOffsets.java21
-rw-r--r--bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/custom/STextTypeHandler.java20
-rw-r--r--bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/STextDelims.java5
-rw-r--r--bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/STextDelimsEsc.java3
-rw-r--r--bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/STextImpl.java214
-rw-r--r--bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/STextSingle.java9
-rw-r--r--bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/consumable/STextEmail.java12
-rw-r--r--bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/consumable/STextJava.java9
-rw-r--r--bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/consumable/STextMath.java10
-rw-r--r--bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/consumable/STextRegex.java15
-rw-r--r--bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/consumable/STextSql.java9
-rw-r--r--bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/consumable/STextXPath.java4
25 files changed, 265 insertions, 227 deletions
diff --git a/bundles/org.eclipse.equinox.bidi.tests/STextTestSuite.launch b/bundles/org.eclipse.equinox.bidi.tests/STextTestSuite.launch
new file mode 100644
index 0000000..49e45fe
--- /dev/null
+++ b/bundles/org.eclipse.equinox.bidi.tests/STextTestSuite.launch
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="org.eclipse.pde.ui.JunitLaunchConfig">
+<booleanAttribute key="append.args" value="true"/>
+<stringAttribute key="application" value="org.eclipse.pde.junit.runtime.coretestapplication"/>
+<booleanAttribute key="askclear" value="false"/>
+<booleanAttribute key="automaticAdd" value="true"/>
+<booleanAttribute key="automaticValidate" value="false"/>
+<stringAttribute key="bootstrap" value=""/>
+<stringAttribute key="checked" value="[NONE]"/>
+<booleanAttribute key="clearConfig" value="true"/>
+<booleanAttribute key="clearws" value="true"/>
+<booleanAttribute key="clearwslog" value="false"/>
+<stringAttribute key="configLocation" value="${workspace_loc}/.metadata/.plugins/org.eclipse.pde.core/pde-junit"/>
+<booleanAttribute key="default" value="true"/>
+<booleanAttribute key="includeOptional" value="true"/>
+<stringAttribute key="location" value="${workspace_loc}/../junit-workspace"/>
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
+<listEntry value="/org.eclipse.equinox.bidi.tests/src/org/eclipse/equinox/bidi/tests/STextTestSuite.java"/>
+</listAttribute>
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
+<listEntry value="1"/>
+</listAttribute>
+<stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value=""/>
+<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/>
+<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/>
+<stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit3"/>
+<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.4"/>
+<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.eclipse.equinox.bidi.tests.STextTestSuite"/>
+<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl} -consoleLog"/>
+<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="org.eclipse.equinox.bidi.tests"/>
+<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/>
+<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xms40m -Xmx384m"/>
+<stringAttribute key="pde.version" value="3.3"/>
+<stringAttribute key="product" value="org.eclipse.equinox.p2.director.app.product"/>
+<booleanAttribute key="run_in_ui_thread" value="true"/>
+<booleanAttribute key="show_selected_only" value="false"/>
+<booleanAttribute key="tracing" value="false"/>
+<booleanAttribute key="useCustomFeatures" value="false"/>
+<booleanAttribute key="useDefaultConfig" value="true"/>
+<booleanAttribute key="useDefaultConfigArea" value="false"/>
+<booleanAttribute key="useProduct" value="false"/>
+</launchConfiguration>
diff --git a/bundles/org.eclipse.equinox.bidi.tests/src/org/eclipse/equinox/bidi/internal/tests/STextFullToLeanTest.java b/bundles/org.eclipse.equinox.bidi.tests/src/org/eclipse/equinox/bidi/internal/tests/STextFullToLeanTest.java
index ee6edc8..bed6e1f 100644
--- a/bundles/org.eclipse.equinox.bidi.tests/src/org/eclipse/equinox/bidi/internal/tests/STextFullToLeanTest.java
+++ b/bundles/org.eclipse.equinox.bidi.tests/src/org/eclipse/equinox/bidi/internal/tests/STextFullToLeanTest.java
@@ -68,14 +68,14 @@ public class STextFullToLeanTest extends STextTestBase {
data = "update \"AB_CDE\" set \"COL1\"@='01', \"COL2\"@='02' /* GH IJK";
text = toUT16(data);
ISTextExpert expertLTR = STextExpertFactory.getPrivateExpert(type, envLTR);
- expertLTR.resetState();
+ expertLTR.clearState();
lean = expertLTR.fullToLeanText(text);
state1 = expertLTR.getState();
model = "update \"AB_CDE\" set \"COL1\"='01', \"COL2\"='02' /* GH IJK";
assertEquals(msg + "LTR lean", model, toPseudo(lean));
ISTextExpert expertLTR2 = STextExpertFactory.getPrivateExpert(type, envLTR);
- expertLTR2.resetState();
+ expertLTR2.clearState();
full = expertLTR2.leanToFullText(lean);
assertEquals(msg + "LTR full", data, toPseudo(full));
diff --git a/bundles/org.eclipse.equinox.bidi.tests/src/org/eclipse/equinox/bidi/internal/tests/STextMethodsTest.java b/bundles/org.eclipse.equinox.bidi.tests/src/org/eclipse/equinox/bidi/internal/tests/STextMethodsTest.java
index 3429077..9172024 100644
--- a/bundles/org.eclipse.equinox.bidi.tests/src/org/eclipse/equinox/bidi/internal/tests/STextMethodsTest.java
+++ b/bundles/org.eclipse.equinox.bidi.tests/src/org/eclipse/equinox/bidi/internal/tests/STextMethodsTest.java
@@ -165,13 +165,13 @@ public class STextMethodsTest extends STextTestBase {
String data, lean, full, model;
int dirA, dirH;
ISTextExpert expertRL = STextExpertFactory.getExpert("test.MyCommaRL");
- dirA = expertRL.getCurDirection(toUT16("###"));
- dirH = expertRL.getCurDirection(toUT16("ABC"));
+ dirA = expertRL.getTextDirection(toUT16("###"));
+ dirH = expertRL.getTextDirection(toUT16("ABC"));
assertTrue("TestDirection #1", dirA == RTL && dirH == LTR);
ISTextExpert expertRR = STextExpertFactory.getExpert("test.MyCommaRR");
- dirA = expertRR.getCurDirection(toUT16("###"));
- dirH = expertRR.getCurDirection(toUT16("ABC"));
+ dirA = expertRR.getTextDirection(toUT16("###"));
+ dirH = expertRR.getTextDirection(toUT16("ABC"));
assertTrue("TestDirection #2", dirA == RTL && dirH == RTL);
ISTextExpert expertLL = STextExpertFactory.getExpert("test.MyCommaLL");
@@ -186,8 +186,8 @@ public class STextMethodsTest extends STextTestBase {
STextEnvironment environment = new STextEnvironment(null, true, STextEnvironment.ORIENT_LTR);
ISTextExpert expert = STextExpertFactory.getExpert("test.MyCommaRL", environment);
- dirA = expert.getCurDirection(toUT16("###"));
- dirH = expert.getCurDirection(toUT16("ABC"));
+ dirA = expert.getTextDirection(toUT16("###"));
+ dirH = expert.getTextDirection(toUT16("ABC"));
assertTrue("TestDirection #10.5", dirA == RTL && dirH == LTR);
lean = toUT16("ABC,#DEF,HOST,com");
@@ -231,7 +231,7 @@ public class STextMethodsTest extends STextTestBase {
full = expert.leanToFullText(lean);
model = "ABc,|#DEF,HOST,com";
assertEquals("TestDirection #17 full", model, toPseudo(full));
- int dir = expert.getCurDirection(lean);
+ int dir = expert.getTextDirection(lean);
assertEquals("Test curDirection", RTL, dir);
}
diff --git a/bundles/org.eclipse.equinox.bidi.tests/src/org/eclipse/equinox/bidi/internal/tests/STextProcessorTest.java b/bundles/org.eclipse.equinox.bidi.tests/src/org/eclipse/equinox/bidi/internal/tests/STextProcessorTest.java
index abdae5c..3bbec2d 100644
--- a/bundles/org.eclipse.equinox.bidi.tests/src/org/eclipse/equinox/bidi/internal/tests/STextProcessorTest.java
+++ b/bundles/org.eclipse.equinox.bidi.tests/src/org/eclipse/equinox/bidi/internal/tests/STextProcessorTest.java
@@ -12,9 +12,8 @@
package org.eclipse.equinox.bidi.internal.tests;
import java.util.Locale;
-import org.eclipse.equinox.bidi.STextTypeHandlerFactory;
import org.eclipse.equinox.bidi.STextProcessor;
-import org.eclipse.equinox.bidi.custom.STextTypeHandler;
+import org.eclipse.equinox.bidi.STextTypeHandlerFactory;
/**
* Tests methods in BidiComplexUtil
@@ -84,10 +83,9 @@ public class STextProcessorTest extends STextTestBase {
}
private void doTest3(String msg, String data, String result, String resLean) {
- STextTypeHandler handler = STextTypeHandlerFactory.getHandler(STextTypeHandlerFactory.COMMA_DELIMITED);
- String full = STextProcessor.process(toUT16(data), handler);
+ String full = STextProcessor.processTyped(toUT16(data), STextTypeHandlerFactory.COMMA_DELIMITED);
assertEquals(msg + "full", result, toPseudo(full));
- String lean = STextProcessor.deprocess(full, handler);
+ String lean = STextProcessor.deprocessTyped(full, STextTypeHandlerFactory.COMMA_DELIMITED);
assertEquals(msg + "lean", resLean, toPseudo(lean));
}
@@ -98,7 +96,7 @@ public class STextProcessorTest extends STextTestBase {
assertEquals(txt, result, toPseudo(full));
}
- public void testBidiComplexUtil() {
+ public void testSTextProcessor() {
// Test process() and deprocess() with default delimiters
doTest1("ABC/DEF/G", ">@ABC@/DEF@/G@^");
diff --git a/bundles/org.eclipse.equinox.bidi.tests/src/org/eclipse/equinox/bidi/internal/tests/TestHandler1.java b/bundles/org.eclipse.equinox.bidi.tests/src/org/eclipse/equinox/bidi/internal/tests/TestHandler1.java
index 0e2fff2..d89881a 100644
--- a/bundles/org.eclipse.equinox.bidi.tests/src/org/eclipse/equinox/bidi/internal/tests/TestHandler1.java
+++ b/bundles/org.eclipse.equinox.bidi.tests/src/org/eclipse/equinox/bidi/internal/tests/TestHandler1.java
@@ -11,20 +11,19 @@
package org.eclipse.equinox.bidi.internal.tests;
import org.eclipse.equinox.bidi.advanced.ISTextExpert;
-import org.eclipse.equinox.bidi.advanced.STextEnvironment;
import org.eclipse.equinox.bidi.custom.*;
public class TestHandler1 extends STextTypeHandler {
- public int getSpecialsCount(STextEnvironment env) {
+ public int getSpecialsCount(ISTextExpert expert) {
return 1;
}
- public int indexOfSpecial(STextEnvironment env, String text, STextCharTypes charTypes, STextOffsets offsets, int caseNumber, int fromIndex) {
+ public int indexOfSpecial(ISTextExpert expert, String text, STextCharTypes charTypes, STextOffsets offsets, int caseNumber, int fromIndex) {
return fromIndex;
}
- public int processSpecial(ISTextExpert expert, STextEnvironment env, String text, STextCharTypes charTypes, STextOffsets offsets, int caseNumber, int separLocation) {
+ public int processSpecial(ISTextExpert expert, String text, STextCharTypes charTypes, STextOffsets offsets, int caseNumber, int separLocation) {
int len = text.length();
for (int i = len - 1; i >= 0; i--) {
STextTypeHandler.insertMark(text, charTypes, offsets, i);
diff --git a/bundles/org.eclipse.equinox.bidi.tests/src/org/eclipse/equinox/bidi/internal/tests/TestHandler2.java b/bundles/org.eclipse.equinox.bidi.tests/src/org/eclipse/equinox/bidi/internal/tests/TestHandler2.java
index acf1f8a..a115631 100644
--- a/bundles/org.eclipse.equinox.bidi.tests/src/org/eclipse/equinox/bidi/internal/tests/TestHandler2.java
+++ b/bundles/org.eclipse.equinox.bidi.tests/src/org/eclipse/equinox/bidi/internal/tests/TestHandler2.java
@@ -10,12 +10,12 @@
******************************************************************************/
package org.eclipse.equinox.bidi.internal.tests;
-import org.eclipse.equinox.bidi.advanced.STextEnvironment;
+import org.eclipse.equinox.bidi.advanced.ISTextExpert;
import org.eclipse.equinox.bidi.custom.STextTypeHandler;
public class TestHandler2 extends STextTypeHandler {
- public int getSpecialsCount(STextEnvironment env) {
+ public int getSpecialsCount(ISTextExpert expert) {
return 1;
}
diff --git a/bundles/org.eclipse.equinox.bidi.tests/src/org/eclipse/equinox/bidi/internal/tests/TestHandler3.java b/bundles/org.eclipse.equinox.bidi.tests/src/org/eclipse/equinox/bidi/internal/tests/TestHandler3.java
index 354a8c9..06729b5 100644
--- a/bundles/org.eclipse.equinox.bidi.tests/src/org/eclipse/equinox/bidi/internal/tests/TestHandler3.java
+++ b/bundles/org.eclipse.equinox.bidi.tests/src/org/eclipse/equinox/bidi/internal/tests/TestHandler3.java
@@ -10,16 +10,16 @@
******************************************************************************/
package org.eclipse.equinox.bidi.internal.tests;
-import org.eclipse.equinox.bidi.advanced.STextEnvironment;
+import org.eclipse.equinox.bidi.advanced.ISTextExpert;
import org.eclipse.equinox.bidi.custom.*;
public class TestHandler3 extends STextTypeHandler {
- public int getSpecialsCount(STextEnvironment env) {
+ public int getSpecialsCount(ISTextExpert expert) {
return 1;
}
- public int indexOfSpecial(STextEnvironment env, String text, STextCharTypes charTypes, STextOffsets offsets, int caseNumber, int fromIndex) {
+ public int indexOfSpecial(ISTextExpert expert, String text, STextCharTypes charTypes, STextOffsets offsets, int caseNumber, int fromIndex) {
return fromIndex;
}
}
diff --git a/bundles/org.eclipse.equinox.bidi.tests/src/org/eclipse/equinox/bidi/internal/tests/TestHandlerMyComma.java b/bundles/org.eclipse.equinox.bidi.tests/src/org/eclipse/equinox/bidi/internal/tests/TestHandlerMyComma.java
index 89688a0..5e06038 100644
--- a/bundles/org.eclipse.equinox.bidi.tests/src/org/eclipse/equinox/bidi/internal/tests/TestHandlerMyComma.java
+++ b/bundles/org.eclipse.equinox.bidi.tests/src/org/eclipse/equinox/bidi/internal/tests/TestHandlerMyComma.java
@@ -11,7 +11,7 @@
package org.eclipse.equinox.bidi.internal.tests;
import org.eclipse.equinox.bidi.STextDirection;
-import org.eclipse.equinox.bidi.advanced.STextEnvironment;
+import org.eclipse.equinox.bidi.advanced.ISTextExpert;
import org.eclipse.equinox.bidi.custom.STextCharTypes;
import org.eclipse.equinox.bidi.custom.STextTypeHandler;
@@ -29,22 +29,22 @@ public class TestHandlerMyComma extends STextTypeHandler {
this.dirHebrew = dirHebrew;
}
- public String getSeparators(STextEnvironment environment) {
+ public String getSeparators(ISTextExpert expert) {
return ","; //$NON-NLS-1$
}
- public boolean skipProcessing(STextEnvironment environment, String text, STextCharTypes charTypes) {
+ public boolean skipProcessing(ISTextExpert expert, String text, STextCharTypes charTypes) {
byte charType = charTypes.getBidiTypeAt(0);
if (charType == AL)
return true;
return false;
}
- public int getDirection(STextEnvironment environment, String text) {
- return getDirection(environment, text, new STextCharTypes(this, environment, text));
+ public int getDirection(ISTextExpert expert, String text) {
+ return getDirection(expert, text, new STextCharTypes(expert, text));
}
- public int getDirection(STextEnvironment environment, String text, STextCharTypes charTypes) {
+ public int getDirection(ISTextExpert expert, String text, STextCharTypes charTypes) {
for (int i = 0; i < text.length(); i++) {
byte charType = charTypes.getBidiTypeAt(i);
if (charType == AL)
diff --git a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/STextProcessor.java b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/STextProcessor.java
index 6f90bfe..6fe723e 100644
--- a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/STextProcessor.java
+++ b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/STextProcessor.java
@@ -91,11 +91,12 @@ public final class STextProcessor {
curMark = LRM;
curPrefix = "\u202a\u200e"; /* LRE+LRM *///$NON-NLS-1$
curSuffix = "\u200e\u202c"; /* LRM+PDF *///$NON-NLS-1$
- } else {
+ } else if (direction == STextDirection.DIR_RTL) {
curMark = RLM;
curPrefix = "\u202b\u200f"; /* RLE+RLM *///$NON-NLS-1$
curSuffix = "\u200f\u202c"; /* RLM+PDF *///$NON-NLS-1$
- }
+ } else
+ throw new IllegalArgumentException();
// add marks at offsets
if ((offsets != null) && (offsets.length > 0)) {
int offLen = offsets.length;
@@ -201,7 +202,7 @@ public final class STextProcessor {
* @param handler a handler instance appropriate for the type of the structured text
* @return the processed string
*/
- public static String process(String str, STextTypeHandler handler) {
+ public static String processTyped(String str, String textType) {
if ((str == null) || (str.length() <= 1))
return str;
@@ -214,7 +215,7 @@ public final class STextProcessor {
STextEnvironment env = new STextEnvironment(null, false, STextEnvironment.ORIENT_UNKNOWN);
if (!env.isProcessingNeeded())
return str;
- ISTextExpert expert = STextExpertFactory.getExpert(handler, env);
+ ISTextExpert expert = STextExpertFactory.getExpert(textType, env);
return expert.leanToFullText(str);
}
@@ -254,7 +255,7 @@ public final class STextProcessor {
* @param handler appropriate for the structured text
* @return string without directional formatting characters
*/
- public static String deprocess(String str, STextTypeHandler handler) {
+ public static String deprocessTyped(String str, String textType) {
if ((str == null) || (str.length() <= 1))
return str;
@@ -262,7 +263,7 @@ public final class STextProcessor {
STextEnvironment env = new STextEnvironment(null, false, STextEnvironment.ORIENT_UNKNOWN);
if (!env.isProcessingNeeded())
return str;
- ISTextExpert expert = STextExpertFactory.getExpert(handler, env);
+ ISTextExpert expert = STextExpertFactory.getExpert(textType, env);
return expert.fullToLeanText(str);
}
diff --git a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/advanced/ISTextExpert.java b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/advanced/ISTextExpert.java
index 46e221f..7e8b130 100644
--- a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/advanced/ISTextExpert.java
+++ b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/advanced/ISTextExpert.java
@@ -10,6 +10,8 @@
******************************************************************************/
package org.eclipse.equinox.bidi.advanced;
+import org.eclipse.equinox.bidi.custom.STextTypeHandler;
+
/**
* For a general introduction to structured text, see
* {@link <a href="package-summary.html"> the package documentation</a>}.
@@ -95,6 +97,10 @@ public interface ISTextExpert {
*/
public static final int DIR_RTL = 1;
+ public STextTypeHandler getTypeHandler();
+
+ public STextEnvironment getEnvironment();
+
/**
* Add directional formatting characters to a structured text
* to ensure correct presentation.
@@ -256,7 +262,7 @@ public interface ISTextExpert {
*
* @return the base direction of the structured text, {@link #DIR_LTR} or {@link #DIR_RTL}
*/
- public int getCurDirection(String text);
+ public int getTextDirection(String text);
///////////////////////////////////////////////////////////////////////////////////////////////
// Expert's state handling - can be used only for non-shared experts
@@ -271,5 +277,5 @@ public interface ISTextExpert {
/**
* Resets state to initial.
*/
- public void resetState();
+ public void clearState();
}
diff --git a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/advanced/STextEnvironment.java b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/advanced/STextEnvironment.java
index fc0372b..6e21116 100644
--- a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/advanced/STextEnvironment.java
+++ b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/advanced/STextEnvironment.java
@@ -36,26 +36,32 @@ public class STextEnvironment {
/**
* Specifies that a GUI component should display text depending on the context
+ * (value is 2).
+ */
+ public static final int ORIENT_CONTEXTUAL = 1 << 1;
+
+ /**
+ * Specifies that a GUI component should display text depending on the context
* with default orientation being Left-To-Right (value is 2).
*/
- public static final int ORIENT_CONTEXTUAL_LTR = 2;
+ public static final int ORIENT_CONTEXTUAL_LTR = ORIENT_CONTEXTUAL | ORIENT_LTR;
/**
* Specifies that a GUI component should display text depending on the context
* with default orientation being Right-To-Left (value is 3).
*/
- public static final int ORIENT_CONTEXTUAL_RTL = 3;
+ public static final int ORIENT_CONTEXTUAL_RTL = ORIENT_CONTEXTUAL | ORIENT_RTL;
/**
* Used when the orientation of a GUI component is not known (value is 4).
*/
- public static final int ORIENT_UNKNOWN = 4;
+ public static final int ORIENT_UNKNOWN = 1 << 2;
/**
* Used to specify that no directional formatting characters
- * should be added as prefix or suffix (value is 5).
+ * should be added as prefix or suffix (value is 8).
*/
- public static final int ORIENT_IGNORE = 5;
+ public static final int ORIENT_IGNORE = 1 << 3;
/**
* Pre-defined <code>STextEnvironment</code> instance which uses default locale,
diff --git a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/advanced/STextExpertFactory.java b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/advanced/STextExpertFactory.java
index 9329fc3..9c16269 100644
--- a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/advanced/STextExpertFactory.java
+++ b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/advanced/STextExpertFactory.java
@@ -58,6 +58,8 @@ final public class STextExpertFactory {
static public ISTextExpert getExpert(String type, STextEnvironment environment) {
ISTextExpert expert;
+ if (environment == null)
+ environment = STextEnvironment.DEFAULT;
synchronized (sharedExperts) {
Map experts = (Map) sharedExperts.get(type);
if (experts == null) {
@@ -77,6 +79,8 @@ final public class STextExpertFactory {
}
static public ISTextExpert getExpert(STextTypeHandler handler, STextEnvironment environment) {
+ if (environment == null)
+ environment = STextEnvironment.DEFAULT;
return new STextImpl(handler, environment, true);
}
@@ -88,6 +92,8 @@ final public class STextExpertFactory {
STextTypeHandler handler = STextTypeHandlerFactory.getHandler(type);
if (handler == null)
return null;
+ if (environment == null)
+ environment = STextEnvironment.DEFAULT;
return new STextImpl(handler, environment, true);
}
diff --git a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/custom/STextCharTypes.java b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/custom/STextCharTypes.java
index ba1f0b7..6857a59 100644
--- a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/custom/STextCharTypes.java
+++ b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/custom/STextCharTypes.java
@@ -10,6 +10,7 @@
******************************************************************************/
package org.eclipse.equinox.bidi.custom;
+import org.eclipse.equinox.bidi.advanced.ISTextExpert;
import org.eclipse.equinox.bidi.advanced.STextEnvironment;
/**
@@ -35,6 +36,7 @@ public class STextCharTypes {
private static final int CHARTYPES_ADD = 2;
+ final protected ISTextExpert expert;
final protected STextTypeHandler handler;
final protected STextEnvironment environment;
final protected String text;
@@ -59,16 +61,17 @@ public class STextCharTypes {
*
* @param text is the text whose characters are analyzed.
*/
- public STextCharTypes(STextTypeHandler handler, STextEnvironment environment, String text) {
- this.handler = handler;
- this.environment = environment;
+ public STextCharTypes(ISTextExpert expert, String text) {
+ this.expert = expert;
+ this.handler = expert.getTypeHandler();
+ this.environment = expert.getEnvironment();
this.text = text;
types = new byte[text.length()];
}
public int getDirection() {
if (direction < 0)
- direction = handler.getDirection(environment, text, this);
+ direction = handler.getDirection(expert, text, this);
return direction;
}
@@ -99,7 +102,7 @@ public class STextCharTypes {
if (direction < -1) // called by handler.getDirection
return charType; // avoid infinite recursion
direction = -2; // signal we go within handler.getDirection
- direction = handler.getDirection(environment, text, this);
+ direction = handler.getDirection(expert, text, this);
}
charType = (direction == STextEnvironment.ORIENT_RTL) ? R : L;
}
@@ -136,11 +139,11 @@ public class STextCharTypes {
*/
public int resolveOrientation(STextEnvironment envir) {
int orient = envir.getOrientation();
- if ((orient & STextEnvironment.ORIENT_CONTEXTUAL_LTR) == 0) { // absolute orientation
+ if ((orient & STextEnvironment.ORIENT_CONTEXTUAL) == 0) { // absolute orientation
return orient;
}
// contextual orientation:
- orient &= 1; // initiate to the default orientation minus contextual bit
+ orient &= ~STextEnvironment.ORIENT_CONTEXTUAL; // initiate to the default orientation minus contextual bit
int len = text.length();
byte charType;
for (int i = 0; i < len; i++) {
diff --git a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/custom/STextOffsets.java b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/custom/STextOffsets.java
index 4ac9270..dd1075d 100644
--- a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/custom/STextOffsets.java
+++ b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/custom/STextOffsets.java
@@ -51,7 +51,7 @@ public class STextOffsets {
/**
* Mark that all entries in the offsets array are unused.
*/
- public void resetCount() {
+ public void clear() {
count = 0;
}
@@ -71,6 +71,11 @@ public class STextOffsets {
* @param offset is the value to insert.
*/
public void insertOffset(STextCharTypes charTypes, int offset) {
+ if (count >= offsets.length) {
+ int[] newOffsets = new int[offsets.length * 2];
+ System.arraycopy(offsets, 0, newOffsets, 0, count);
+ offsets = newOffsets;
+ }
int index = count - 1; // index of greatest member <= offset
// look up after which member the new offset should be inserted
while (index >= 0) {
@@ -109,22 +114,10 @@ public class STextOffsets {
}
/**
- * Make sure that there is at least 3 free entries in the offsets array.
- */
- public void ensureRoom() {
- // make sure there are at least 3 empty slots in offsets
- if ((offsets.length - count) < 3) {
- int[] newOffsets = new int[offsets.length * 2];
- System.arraycopy(offsets, 0, newOffsets, 0, count);
- offsets = newOffsets;
- }
- }
-
- /**
* Get all and only the used offset entries.
* @return the current used entries of the offsets array.
*/
- public int[] getArray() {
+ public int[] getOffsets() {
if (count == offsets.length)
return offsets;
int[] array = new int[count];
diff --git a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/custom/STextTypeHandler.java b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/custom/STextTypeHandler.java
index f79906a..af197b5 100644
--- a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/custom/STextTypeHandler.java
+++ b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/custom/STextTypeHandler.java
@@ -36,7 +36,7 @@ import org.eclipse.equinox.bidi.internal.STextImpl;
* See {@link #getSpecialsCount getSpecialsCount}.</li>
* </ul></li>
* <li>Before starting deeper analysis of the submitted text, the common
- * logic gives to the handler a chance to shorten the processus by
+ * logic gives to the handler a chance to shorten the process by
* invoking its {@link #skipProcessing skipProcessing} method.</li>
* <li>The common logic then analyzes the text to segment it into tokens
* according to the appearance of separators (as retrieved using
@@ -46,11 +46,11 @@ import org.eclipse.equinox.bidi.internal.STextImpl;
* method, the common logic will repeatedly invoke the handler's
* {@link #indexOfSpecial indexOfSpecial} method to let it signal the
* presence of special strings which may further delimit the source text.</li>
- * <li>When such a special case is signalled by the handler, the common
+ * <li>When such a special case is signaled by the handler, the common
* logic will call the handler's {@link #processSpecial processSpecial}
* method to give it the opportunity to handle it as needed. Typical
* actions that the handler may perform are to add directional marks
- * inconditionally (by calling {@link #insertMark insertMark} or
+ * unconditionally (by calling {@link #insertMark insertMark} or
* conditionally (by calling {@link #processSeparator processSeparator}).</li>
* </ul>
*
@@ -127,7 +127,7 @@ public class STextTypeHandler {
* number of special cases is zero, which means that
* <code>indexOfSpecial</code> should never be called for them.
*/
- public int indexOfSpecial(STextEnvironment environment, String text, STextCharTypes charTypes, STextOffsets offsets, int caseNumber, int fromIndex) {
+ public int indexOfSpecial(ISTextExpert expert, String text, STextCharTypes charTypes, STextOffsets offsets, int caseNumber, int fromIndex) {
// This method must be overridden by all subclasses with special cases.
throw new IllegalStateException("A handler with specialsCount > 0 must have an indexOfSpecial() method."); //$NON-NLS-1$
}
@@ -210,7 +210,7 @@ public class STextTypeHandler {
* number of special cases is zero, which means that
* <code>processSpecial</code> should never be called for them.
*/
- public int processSpecial(ISTextExpert expert, STextEnvironment environment, String text, STextCharTypes charTypes, STextOffsets offsets, int caseNumber, int separLocation) {
+ public int processSpecial(ISTextExpert expert, String text, STextCharTypes charTypes, STextOffsets offsets, int caseNumber, int separLocation) {
// This method must be overridden by all subclasses with any special case.
throw new IllegalStateException("A handler with specialsCount > 0 must have a processSpecial() method."); //$NON-NLS-1$
}
@@ -300,7 +300,7 @@ public class STextTypeHandler {
* @return a string grouping one-character separators which separate
* the structured text into tokens.
*/
- public String getSeparators(STextEnvironment environment) {
+ public String getSeparators(ISTextExpert expert) {
return separators;
}
@@ -325,7 +325,7 @@ public class STextTypeHandler {
* The value returned is either
* {@link STextDirection#DIR_LTR DIR_LTR} or {@link STextDirection#DIR_RTL DIR_RTL}.
*/
- public int getDirection(STextEnvironment environment, String text) {
+ public int getDirection(ISTextExpert expert, String text) {
return STextDirection.DIR_LTR;
}
@@ -354,7 +354,7 @@ public class STextTypeHandler {
* The value returned is either
* {@link STextDirection#DIR_LTR DIR_LTR} or {@link STextDirection#DIR_RTL DIR_RTL}.
*/
- public int getDirection(STextEnvironment environment, String text, STextCharTypes charTypes) {
+ public int getDirection(ISTextExpert expert, String text, STextCharTypes charTypes) {
return STextDirection.DIR_LTR;
}
@@ -380,7 +380,7 @@ public class STextTypeHandler {
* anything which is not identified by a one-character separator.
*
*/
- public int getSpecialsCount(STextEnvironment environment) {
+ public int getSpecialsCount(ISTextExpert expert) {
return 0;
}
@@ -409,7 +409,7 @@ public class STextTypeHandler {
* text to add directional formatting characters.
*
*/
- public boolean skipProcessing(STextEnvironment environment, String text, STextCharTypes charTypes) {
+ public boolean skipProcessing(ISTextExpert expert, String text, STextCharTypes charTypes) {
return false;
}
diff --git a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/STextDelims.java b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/STextDelims.java
index 81e3767..d9562bf 100644
--- a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/STextDelims.java
+++ b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/STextDelims.java
@@ -11,7 +11,6 @@
package org.eclipse.equinox.bidi.internal;
import org.eclipse.equinox.bidi.advanced.ISTextExpert;
-import org.eclipse.equinox.bidi.advanced.STextEnvironment;
import org.eclipse.equinox.bidi.custom.*;
/**
@@ -44,7 +43,7 @@ public abstract class STextDelims extends STextTypeHandler {
*
* @see #getDelimiters
*/
- public int indexOfSpecial(STextEnvironment environment, String text, STextCharTypes charTypes, STextOffsets offsets, int caseNumber, int fromIndex) {
+ public int indexOfSpecial(ISTextExpert expert, String text, STextCharTypes charTypes, STextOffsets offsets, int caseNumber, int fromIndex) {
char delim = getDelimiters().charAt((caseNumber - 1) * 2);
return text.indexOf(delim, fromIndex);
}
@@ -59,7 +58,7 @@ public abstract class STextDelims extends STextTypeHandler {
* @return the position after the matching end delimiter, or the length
* of <code>text</code> if no end delimiter is found.
*/
- public int processSpecial(ISTextExpert expert, STextEnvironment environment, String text, STextCharTypes charTypes, STextOffsets offsets, int caseNumber, int separLocation) {
+ public int processSpecial(ISTextExpert expert, String text, STextCharTypes charTypes, STextOffsets offsets, int caseNumber, int separLocation) {
STextTypeHandler.processSeparator(text, charTypes, offsets, separLocation);
int loc = separLocation + 1;
char delim = getDelimiters().charAt((caseNumber * 2) - 1);
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 73e8571..67b5baf 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
@@ -11,7 +11,6 @@
package org.eclipse.equinox.bidi.internal;
import org.eclipse.equinox.bidi.advanced.ISTextExpert;
-import org.eclipse.equinox.bidi.advanced.STextEnvironment;
import org.eclipse.equinox.bidi.custom.*;
/**
@@ -50,7 +49,7 @@ public abstract class STextDelimsEsc extends STextDelims {
* and skips until after the matching end delimiter,
* ignoring possibly escaped end delimiters.
*/
- public int processSpecial(ISTextExpert expert, STextEnvironment environment, String text, STextCharTypes charTypes, STextOffsets offsets, int caseNumber, int separLocation) {
+ public int processSpecial(ISTextExpert expert, String text, STextCharTypes charTypes, STextOffsets offsets, int caseNumber, int separLocation) {
STextTypeHandler.processSeparator(text, charTypes, offsets, separLocation);
int location = separLocation + 1;
char delim = getDelimiters().charAt((caseNumber * 2) - 1);
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 001322b..412a7b4 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
@@ -46,50 +46,31 @@ public class STextImpl implements ISTextExpert {
static final int SUFFIX_LENGTH = 2;
static final int FIXES_LENGTH = PREFIX_LENGTH + SUFFIX_LENGTH;
static final int[] EMPTY_INT_ARRAY = new int[0];
- static final STextEnvironment IGNORE_ENVIRONMENT = new STextEnvironment(null, false, STextEnvironment.ORIENT_IGNORE);
-
- protected STextTypeHandler structuredTextHandler;
- protected STextEnvironment environment;
+ protected final STextTypeHandler handler;
+ protected final STextEnvironment environment;
+ protected final boolean sharedExpert;
protected Object state;
- protected boolean sharedExpert;
-
public STextImpl(STextTypeHandler structuredTextHandler, STextEnvironment environment, boolean shared) {
- this.structuredTextHandler = structuredTextHandler;
+ this.handler = structuredTextHandler;
this.environment = environment;
sharedExpert = shared;
}
- public String leanToFullText(String text) {
- return leanToFullText(structuredTextHandler, environment, text, state);
- }
-
- public int[] leanToFullMap(String text) {
- return leanToFullMap(structuredTextHandler, environment, text, state);
- }
-
- public int[] leanBidiCharOffsets(String text) {
- return leanBidiCharOffsets(structuredTextHandler, environment, text, state);
- }
-
- public String fullToLeanText(String text) {
- return fullToLeanText(structuredTextHandler, environment, text, state);
- }
-
- public int[] fullToLeanMap(String text) {
- return fullToLeanMap(structuredTextHandler, environment, text, state);
+ public STextTypeHandler getTypeHandler() {
+ return handler;
}
- public int[] fullBidiCharOffsets(String text) {
- return fullBidiCharOffsets(structuredTextHandler, environment, text, state);
+ public STextEnvironment getEnvironment() {
+ return environment;
}
- public int getCurDirection(String text) {
- return structuredTextHandler.getDirection(environment, text);
+ public int getTextDirection(String text) {
+ return handler.getDirection(this, text);
}
- public void resetState() {
+ public void clearState() {
if (sharedExpert)
state = null;
}
@@ -103,10 +84,10 @@ public class STextImpl implements ISTextExpert {
return state;
}
- long computeNextLocation(STextTypeHandler handler, STextEnvironment environment, String text, STextCharTypes charTypes, STextOffsets offsets, int[] locations, int curPos) {
- String separators = handler.getSeparators(environment);
+ long computeNextLocation(String text, STextCharTypes charTypes, STextOffsets offsets, int[] locations, int curPos) {
+ String separators = handler.getSeparators(this);
int separCount = separators.length();
- int specialsCount = handler.getSpecialsCount(environment);
+ int specialsCount = handler.getSpecialsCount(this);
int len = text.length();
int nextLocation = len;
int idxLocation = 0;
@@ -115,8 +96,7 @@ public class STextImpl implements ISTextExpert {
for (int i = 0; i < specialsCount; i++) {
int location = locations[separCount + i];
if (location < curPos) {
- offsets.ensureRoom();
- location = handler.indexOfSpecial(environment, text, charTypes, offsets, i + 1, curPos);
+ location = handler.indexOfSpecial(this, text, charTypes, offsets, i + 1, curPos);
if (location < 0)
location = len;
locations[separCount + i] = location;
@@ -243,12 +223,12 @@ public class STextImpl implements ISTextExpert {
* <p>
* @see ISTextExpert#leanToFullText STextEngine.leanToFullText
*/
- public String leanToFullText(STextTypeHandler handler, STextEnvironment environment, String text, Object state) {
+ public String leanToFullText(String text) {
int len = text.length();
if (len == 0)
return text;
- STextCharTypes charTypes = new STextCharTypes(handler, environment, text);
- STextOffsets offsets = leanToFullCommon(handler, environment, text, state, charTypes);
+ STextCharTypes charTypes = new STextCharTypes(this, text);
+ STextOffsets offsets = leanToFullCommon(text, charTypes);
int prefixLength = offsets.getPrefixLength();
int count = offsets.getCount();
if (count == 0 && prefixLength == 0)
@@ -290,12 +270,12 @@ public class STextImpl implements ISTextExpert {
return new String(fullChars);
}
- public int[] leanToFullMap(STextTypeHandler handler, STextEnvironment environment, String text, Object state) {
+ public int[] leanToFullMap(String text) {
int len = text.length();
if (len == 0)
return EMPTY_INT_ARRAY;
- STextCharTypes charTypes = new STextCharTypes(handler, environment, text);
- STextOffsets offsets = leanToFullCommon(handler, environment, text, state, charTypes);
+ STextCharTypes charTypes = new STextCharTypes(this, text);
+ STextOffsets offsets = leanToFullCommon(text, charTypes);
int prefixLength = offsets.getPrefixLength();
int[] map = new int[len];
int count = offsets.getCount(); // number of used entries
@@ -310,51 +290,47 @@ public class STextImpl implements ISTextExpert {
return map;
}
- public int[] leanBidiCharOffsets(STextTypeHandler handler, STextEnvironment environment, String text, Object state) {
+ public int[] leanBidiCharOffsets(String text) {
int len = text.length();
if (len == 0)
return EMPTY_INT_ARRAY;
- STextCharTypes charTypes = new STextCharTypes(handler, environment, text);
- STextOffsets offsets = leanToFullCommon(handler, environment, text, state, charTypes);
- return offsets.getArray();
+ STextCharTypes charTypes = new STextCharTypes(this, text);
+ STextOffsets offsets = leanToFullCommon(text, charTypes);
+ return offsets.getOffsets();
}
- public STextOffsets leanToFullCommon(STextTypeHandler handler, STextEnvironment environment, String text, Object state, STextCharTypes charTypes) {
- if (environment == null)
- environment = STextEnvironment.DEFAULT;
+ private STextOffsets leanToFullCommon(String text, STextCharTypes charTypes) {
int len = text.length();
- int direction = handler.getDirection(environment, text, charTypes);
+ int direction = handler.getDirection(this, text, charTypes);
STextOffsets offsets = new STextOffsets();
- if (!handler.skipProcessing(environment, text, charTypes)) {
+ if (!handler.skipProcessing(this, text, charTypes)) {
// initialize locations
- int separCount = handler.getSeparators(environment).length();
- int[] locations = new int[separCount + handler.getSpecialsCount(environment)];
+ int separCount = handler.getSeparators(this).length();
+ int[] locations = new int[separCount + handler.getSpecialsCount(this)];
for (int i = 0, k = locations.length; i < k; i++) {
locations[i] = -1;
}
// current position
int curPos = 0;
if (state != null) {
- offsets.ensureRoom();
- curPos = handler.processSpecial(this, environment, text, charTypes, offsets, 0, -1);
+ curPos = handler.processSpecial(this, text, charTypes, offsets, 0, -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(handler, environment, text, charTypes, offsets, locations, curPos);
+ long res = computeNextLocation(text, charTypes, offsets, locations, curPos);
nextLocation = (int) (res & 0x00000000FFFFFFFF); /* low word */
if (nextLocation >= len)
break;
- offsets.ensureRoom();
idxLocation = (int) (res >> 32); /* high word */
if (idxLocation < separCount) {
processSeparator(text, charTypes, offsets, nextLocation);
curPos = nextLocation + 1;
} else {
idxLocation -= (separCount - 1); // because caseNumber starts from 1
- curPos = handler.processSpecial(this, environment, text, charTypes, offsets, idxLocation, nextLocation);
+ curPos = handler.processSpecial(this, text, charTypes, offsets, idxLocation, nextLocation);
}
if (curPos >= len)
break;
@@ -368,7 +344,7 @@ public class STextImpl implements ISTextExpert {
int resolvedOrientation = charTypes.resolveOrientation(environment);
if (orientation != STextEnvironment.ORIENT_UNKNOWN && resolvedOrientation == direction)
prefixLength = 0;
- else if ((orientation & STextEnvironment.ORIENT_CONTEXTUAL_LTR) != 0)
+ else if ((orientation & STextEnvironment.ORIENT_CONTEXTUAL) != 0)
prefixLength = 1;
else
prefixLength = 2;
@@ -377,101 +353,117 @@ public class STextImpl implements ISTextExpert {
return offsets;
}
- public String fullToLeanText(STextTypeHandler handler, STextEnvironment environment, String text, Object state) {
- if (text.length() == 0)
- return text;
- if (environment == null)
- environment = STextEnvironment.DEFAULT;
- int dir = handler.getDirection(environment, text);
+ public String fullToLeanText(String full) {
+ if (full.length() == 0)
+ return full;
+ int dir = handler.getDirection(this, full);
char curMark = MARKS[dir];
char curEmbed = EMBEDS[dir];
int i; // used as loop index
// remove any prefix and leading mark
- int lenText = text.length();
- for (i = 0; i < lenText; i++) {
- char c = text.charAt(i);
+ int lenFull = full.length();
+ for (i = 0; i < lenFull; i++) {
+ char c = full.charAt(i);
if (c != curEmbed && c != curMark)
break;
}
if (i > 0) { // found at least one prefix or leading mark
- text = text.substring(i);
- lenText = text.length();
+ full = full.substring(i);
+ lenFull = full.length();
}
// remove any suffix and trailing mark
- for (i = lenText - 1; i >= 0; i--) {
- char c = text.charAt(i);
+ for (i = lenFull - 1; i >= 0; i--) {
+ char c = full.charAt(i);
if (c != PDF && c != curMark)
break;
}
if (i < 0) // only suffix and trailing marks, no real data
return EMPTY_STRING;
- if (i < (lenText - 1)) { // found at least one suffix or trailing mark
- text = text.substring(0, i + 1);
- lenText = text.length();
+ if (i < (lenFull - 1)) { // found at least one suffix or trailing mark
+ full = full.substring(0, i + 1);
+ lenFull = full.length();
}
- char[] chars = text.toCharArray();
+ char[] chars = full.toCharArray();
// remove marks from chars
int cnt = 0;
- for (i = 0; i < lenText; i++) {
+ for (i = 0; i < lenFull; i++) {
char c = chars[i];
if (c == curMark)
cnt++;
else if (cnt > 0)
chars[i - cnt] = c;
}
- String lean = new String(chars, 0, lenText - cnt);
- String full = leanToFullText(handler, IGNORE_ENVIRONMENT, lean, state);
- if (full.equals(text))
+ String lean = new String(chars, 0, lenFull - cnt);
+ String full2 = leanToFullText(lean);
+ // strip prefix and suffix
+ int beginIndex = 0, endIndex = full2.length();
+ if (full2.charAt(0) == curMark)
+ beginIndex = 1;
+ else {
+ if (full2.charAt(0) == curEmbed) {
+ beginIndex = 1;
+ if (full2.charAt(0) == curMark)
+ beginIndex = 2;
+ }
+ if (full2.charAt(endIndex - 1) == PDF) {
+ endIndex--;
+ if (full2.charAt(endIndex - 1) == curMark)
+ endIndex--;
+ }
+ }
+ if (beginIndex > 0 || endIndex < full2.length())
+ full2 = full2.substring(beginIndex, endIndex);
+ if (full2.equals(full))
return lean;
- // There are some marks in full which are not in text and/or vice versa.
- // We need to add to lean any mark appearing in text and not in full.
- // The completed lean can never be longer than text itself.
- char[] newChars = new char[lenText];
- char cFull, cText;
- int idxFull, idxText, idxLean, newCharsPos;
- int lenFull = full.length();
- idxFull = idxText = idxLean = newCharsPos = 0;
- while (idxText < lenText && idxFull < lenFull) {
+ // There are some marks in full which are not in full2 and/or vice versa.
+ // We need to add to lean any mark appearing in full and not in full2.
+ // The completed lean can never be longer than full itself.
+ char[] newChars = new char[lenFull];
+ char cFull, cFull2;
+ int idxFull, idxFull2, idxLean, newCharsPos;
+ int lenFull2 = full2.length();
+ idxFull = idxFull2 = idxLean = newCharsPos = 0;
+ while (idxFull < lenFull && idxFull2 < lenFull2) {
+ cFull2 = full2.charAt(idxFull2);
cFull = full.charAt(idxFull);
- cText = text.charAt(idxText);
- if (cFull == cText) { /* chars are equal, proceed */
- if (cFull != curMark)
+ if (cFull2 == cFull) { /* chars are equal, proceed */
+ if (cFull2 != curMark)
newChars[newCharsPos++] = chars[idxLean++];
- idxText++;
idxFull++;
+ idxFull2++;
continue;
}
- if (cFull == curMark) { /* extra Mark in full text */
- idxFull++;
+ if (cFull2 == curMark) { /* extra Mark in full2 text */
+ idxFull2++;
continue;
}
- if (cText == curMark) { /* extra Mark in source full text */
- idxText++;
- // idxText-2 always >= 0 since leading Marks were removed from text
- if (text.charAt(idxText - 2) == curMark)
- continue; // ignore successive Marks in text after the first one
+ if (cFull == curMark) { /* extra Mark in source full text */
+ idxFull++;
+ // idxFull-2 always >= 0 since leading Marks were removed from full
+ if (full.charAt(idxFull - 2) == curMark)
+ continue; // ignore successive Marks in full after the first one
newChars[newCharsPos++] = curMark;
continue;
}
// we should never get here (extra char which is not a Mark)
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 */
+ if (idxFull < lenFull) /* full2 ended before full - this should never happen since
+ we removed all marks and PDFs at the end of full */
throw new IllegalStateException("Internal error: unexpected EOL."); //$NON-NLS-1$
lean = new String(newChars, 0, newCharsPos);
return lean;
}
- public int[] fullToLeanMap(STextTypeHandler handler, STextEnvironment environment, String full, Object state) {
+ public int[] fullToLeanMap(String full) {
int lenFull = full.length();
if (lenFull == 0)
return EMPTY_INT_ARRAY;
- String lean = fullToLeanText(handler, environment, full, state);
+ String lean = fullToLeanText(full);
int lenLean = lean.length();
- int dir = handler.getDirection(environment, lean);
+ int dir = handler.getDirection(this, lean);
char curMark = MARKS[dir];
char curEmbed = EMBEDS[dir];
int[] map = new int[lenFull];
@@ -496,11 +488,11 @@ public class STextImpl implements ISTextExpert {
return map;
}
- public int[] fullBidiCharOffsets(STextTypeHandler handler, STextEnvironment environment, String full, Object state) {
+ public int[] fullBidiCharOffsets(String full) {
int lenFull = full.length();
if (lenFull == 0)
return EMPTY_INT_ARRAY;
- String lean = fullToLeanText(handler, environment, full, state);
+ String lean = fullToLeanText(full);
STextOffsets offsets = new STextOffsets();
int lenLean = lean.length();
int idxLean, idxFull;
@@ -508,15 +500,11 @@ public class STextImpl implements ISTextExpert {
for (idxLean = idxFull = 0; idxLean < lenLean; idxFull++) {
if (full.charAt(idxFull) == lean.charAt(idxLean))
idxLean++;
- else {
- offsets.ensureRoom();
+ else
offsets.insertOffset(null, idxFull);
- }
}
- for (; idxFull < lenFull; idxFull++) {
- offsets.ensureRoom();
+ for (; idxFull < lenFull; idxFull++)
offsets.insertOffset(null, idxFull);
- }
- return offsets.getArray();
+ return offsets.getOffsets();
}
}
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 6822bd8..accaf57 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
@@ -11,7 +11,6 @@
package org.eclipse.equinox.bidi.internal;
import org.eclipse.equinox.bidi.advanced.ISTextExpert;
-import org.eclipse.equinox.bidi.advanced.STextEnvironment;
import org.eclipse.equinox.bidi.custom.*;
/**
@@ -41,8 +40,8 @@ public class STextSingle extends STextTypeHandler {
*
* @see #getSeparators getSeparators
*/
- public int indexOfSpecial(STextEnvironment environment, String text, STextCharTypes charTypes, STextOffsets offsets, int caseNumber, int fromIndex) {
- return text.indexOf(this.getSeparators(environment).charAt(0), fromIndex);
+ public int indexOfSpecial(ISTextExpert expert, String text, STextCharTypes charTypes, STextOffsets offsets, int caseNumber, int fromIndex) {
+ return text.indexOf(this.getSeparators(expert).charAt(0), fromIndex);
}
/**
@@ -51,7 +50,7 @@ public class STextSingle extends STextTypeHandler {
*
* @return the length of <code>text</code>.
*/
- public int processSpecial(ISTextExpert expert, STextEnvironment environment, String text, STextCharTypes charTypes, STextOffsets offsets, int caseNumber, int separLocation) {
+ public int processSpecial(ISTextExpert expert, String text, STextCharTypes charTypes, STextOffsets offsets, int caseNumber, int separLocation) {
STextTypeHandler.processSeparator(text, charTypes, offsets, separLocation);
return text.length();
}
@@ -61,7 +60,7 @@ public class STextSingle extends STextTypeHandler {
*
* @return 1.
*/
- public int getSpecialsCount(STextEnvironment environment) {
+ public int getSpecialsCount(ISTextExpert expert) {
return 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 2be4a2b..3f47965 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
@@ -11,7 +11,7 @@
package org.eclipse.equinox.bidi.internal.consumable;
import org.eclipse.equinox.bidi.STextDirection;
-import org.eclipse.equinox.bidi.advanced.STextEnvironment;
+import org.eclipse.equinox.bidi.advanced.ISTextExpert;
import org.eclipse.equinox.bidi.custom.STextCharTypes;
import org.eclipse.equinox.bidi.internal.STextDelimsEsc;
@@ -27,8 +27,8 @@ public class STextEmail extends STextDelimsEsc {
super("<>.:,;@"); //$NON-NLS-1$
}
- public int getDirection(STextEnvironment environment, String text) {
- return getDirection(environment, text, new STextCharTypes(this, environment, text));
+ public int getDirection(ISTextExpert expert, String text) {
+ return getDirection(expert, text, new STextCharTypes(expert, text));
}
/**
@@ -42,8 +42,8 @@ public class STextEmail extends STextDelimsEsc {
* </ul>
* Otherwise, returns {@link STextDirection#DIR_LTR DIR_LTR}.
*/
- public int getDirection(STextEnvironment environment, String text, STextCharTypes charTypes) {
- String language = environment.getLanguage();
+ public int getDirection(ISTextExpert expert, String text, STextCharTypes charTypes) {
+ String language = expert.getEnvironment().getLanguage();
if (!language.equals("ar")) //$NON-NLS-1$
return STextDirection.DIR_LTR;
int domainStart;
@@ -61,7 +61,7 @@ public class STextEmail extends STextDelimsEsc {
/**
* @return 2 as number of special cases handled by this handler.
*/
- public int getSpecialsCount(STextEnvironment environment) {
+ public int getSpecialsCount(ISTextExpert expert) {
return 2;
}
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 4b42661..7efdfd1 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
@@ -11,7 +11,6 @@
package org.eclipse.equinox.bidi.internal.consumable;
import org.eclipse.equinox.bidi.advanced.ISTextExpert;
-import org.eclipse.equinox.bidi.advanced.STextEnvironment;
import org.eclipse.equinox.bidi.custom.*;
import org.eclipse.equinox.bidi.internal.STextActivator;
@@ -46,7 +45,7 @@ public class STextJava extends STextTypeHandler {
/**
* @return 4 as the number of special cases handled by this handler.
*/
- public int getSpecialsCount(STextEnvironment environment) {
+ public int getSpecialsCount(ISTextExpert expert) {
return 4;
}
@@ -59,7 +58,7 @@ public class STextJava extends STextTypeHandler {
* <li>comments starting with slash-slash</li>
* </ol>
*/
- public int indexOfSpecial(STextEnvironment environment, String text, STextCharTypes charTypes, STextOffsets offsets, int caseNumber, int fromIndex) {
+ public int indexOfSpecial(ISTextExpert expert, String text, STextCharTypes charTypes, STextOffsets offsets, int caseNumber, int fromIndex) {
switch (caseNumber) {
case 1 : /* space */
return text.indexOf(' ', fromIndex);
@@ -83,13 +82,13 @@ public class STextJava extends STextTypeHandler {
* <li>skip until after a line separator</li>
* </ol>
*/
- public int processSpecial(ISTextExpert expert, STextEnvironment environment, String text, STextCharTypes charTypes, STextOffsets offsets, int caseNumber, int separLocation) {
+ public int processSpecial(ISTextExpert expert, String text, STextCharTypes charTypes, STextOffsets offsets, int caseNumber, int separLocation) {
int location, counter, i;
STextTypeHandler.processSeparator(text, charTypes, offsets, separLocation);
if (separLocation < 0) {
caseNumber = ((Integer) expert.getState()).intValue(); // TBD guard against "undefined"
- expert.resetState();
+ expert.clearState();
}
switch (caseNumber) {
case 1 : /* space */
diff --git a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/consumable/STextMath.java b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/consumable/STextMath.java
index d15af0b..7336c30 100644
--- a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/consumable/STextMath.java
+++ b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/consumable/STextMath.java
@@ -11,7 +11,7 @@
package org.eclipse.equinox.bidi.internal.consumable;
import org.eclipse.equinox.bidi.STextDirection;
-import org.eclipse.equinox.bidi.advanced.STextEnvironment;
+import org.eclipse.equinox.bidi.advanced.ISTextExpert;
import org.eclipse.equinox.bidi.custom.STextCharTypes;
import org.eclipse.equinox.bidi.custom.STextTypeHandler;
@@ -29,8 +29,8 @@ public class STextMath extends STextTypeHandler {
super("+-/*()="); //$NON-NLS-1$
}
- public int getDirection(STextEnvironment environment, String text) {
- return getDirection(environment, text, new STextCharTypes(this, environment, text));
+ public int getDirection(ISTextExpert expert, String text) {
+ return getDirection(expert, text, new STextCharTypes(expert, text));
}
/**
@@ -45,8 +45,8 @@ public class STextMath extends STextTypeHandler {
* </ul>
* Otherwise, returns {@link STextDirection#DIR_LTR DIR_LTR}.
*/
- public int getDirection(STextEnvironment environment, String text, STextCharTypes charTypes) {
- String language = environment.getLanguage();
+ public int getDirection(ISTextExpert expert, String text, STextCharTypes charTypes) {
+ String language = expert.getEnvironment().getLanguage();
if (!language.equals("ar")) //$NON-NLS-1$
return STextDirection.DIR_LTR;
boolean flagAN = false;
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 08c4a70..b08db51 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
@@ -71,7 +71,7 @@ public class STextRegex extends STextTypeHandler {
*
* @return the number of special cases for this handler.
*/
- public int getSpecialsCount(STextEnvironment environment) {
+ public int getSpecialsCount(ISTextExpert expert) {
return maxSpecial;
}
@@ -79,7 +79,7 @@ public class STextRegex extends STextTypeHandler {
* This method locates occurrences of the syntactic strings and of
* R, AL, EN, AN characters.
*/
- public int indexOfSpecial(STextEnvironment environment, String text, STextCharTypes charTypes, STextOffsets offsets, int caseNumber, int fromIndex) {
+ public int indexOfSpecial(ISTextExpert expert, String text, STextCharTypes charTypes, STextOffsets 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/ ).
@@ -147,12 +147,12 @@ public class STextRegex extends STextTypeHandler {
/**
* This method process the special cases.
*/
- public int processSpecial(ISTextExpert expert, STextEnvironment environment, String text, STextCharTypes charTypes, STextOffsets offsets, int caseNumber, int separLocation) {
+ public int processSpecial(ISTextExpert expert, String text, STextCharTypes charTypes, STextOffsets offsets, int caseNumber, int separLocation) {
int location;
if (separLocation < 0) {
caseNumber = ((Integer) expert.getState()).intValue(); // TBD guard against "undefined"
- expert.resetState();
+ expert.clearState();
}
switch (caseNumber) {
case 1 : /* comment (?#...) */
@@ -221,8 +221,8 @@ public class STextRegex extends STextTypeHandler {
return text.length();
}
- public int getDirection(STextEnvironment environment, String text) {
- return getDirection(environment, text, new STextCharTypes(this, environment, text));
+ public int getDirection(ISTextExpert expert, String text) {
+ return getDirection(expert, text, new STextCharTypes(expert, text));
}
/**
@@ -237,7 +237,8 @@ public class STextRegex extends STextTypeHandler {
* </ul>
* Otherwise, returns {@link STextDirection#DIR_LTR DIR_LTR}.
*/
- public int getDirection(STextEnvironment environment, String text, STextCharTypes charTypes) {
+ public int getDirection(ISTextExpert expert, String text, STextCharTypes charTypes) {
+ STextEnvironment environment = expert.getEnvironment();
String language = environment.getLanguage();
if (!language.equals("ar")) //$NON-NLS-1$
return STextDirection.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 c1219bc..0ea92a7 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
@@ -11,7 +11,6 @@
package org.eclipse.equinox.bidi.internal.consumable;
import org.eclipse.equinox.bidi.advanced.ISTextExpert;
-import org.eclipse.equinox.bidi.advanced.STextEnvironment;
import org.eclipse.equinox.bidi.custom.*;
import org.eclipse.equinox.bidi.internal.STextActivator;
@@ -47,7 +46,7 @@ public class STextSql extends STextTypeHandler {
/**
* @return 5 as the number of special cases handled by this handler.
*/
- public int getSpecialsCount(STextEnvironment environment) {
+ public int getSpecialsCount(ISTextExpert expert) {
return 5;
}
@@ -61,7 +60,7 @@ public class STextSql extends STextTypeHandler {
* <li>comments starting with hyphen-hyphen</li>
* </ol>
*/
- public int indexOfSpecial(STextEnvironment environment, String text, STextCharTypes charTypes, STextOffsets offsets, int caseNumber, int fromIndex) {
+ public int indexOfSpecial(ISTextExpert expert, String text, STextCharTypes charTypes, STextOffsets offsets, int caseNumber, int fromIndex) {
switch (caseNumber) {
case 1 : /* space */
return text.indexOf(" ", fromIndex); //$NON-NLS-1$
@@ -88,13 +87,13 @@ public class STextSql extends STextTypeHandler {
* <li>skip until after a line separator</li>
* </ol>
*/
- public int processSpecial(ISTextExpert expert, STextEnvironment environment, String text, STextCharTypes charTypes, STextOffsets offsets, int caseNumber, int separLocation) {
+ public int processSpecial(ISTextExpert expert, String text, STextCharTypes charTypes, STextOffsets offsets, int caseNumber, int separLocation) {
int location;
STextTypeHandler.processSeparator(text, charTypes, offsets, separLocation);
if (separLocation < 0) {
caseNumber = ((Integer) expert.getState()).intValue(); // TBD guard against "undefined"
- expert.resetState();
+ expert.clearState();
}
switch (caseNumber) {
case 1 : /* space */
diff --git a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/consumable/STextXPath.java b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/consumable/STextXPath.java
index 637b229..a0f7bf3 100644
--- a/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/consumable/STextXPath.java
+++ b/bundles/org.eclipse.equinox.bidi/src/org/eclipse/equinox/bidi/internal/consumable/STextXPath.java
@@ -10,7 +10,7 @@
******************************************************************************/
package org.eclipse.equinox.bidi.internal.consumable;
-import org.eclipse.equinox.bidi.advanced.STextEnvironment;
+import org.eclipse.equinox.bidi.advanced.ISTextExpert;
import org.eclipse.equinox.bidi.internal.STextDelims;
/**
@@ -25,7 +25,7 @@ public class STextXPath extends STextDelims {
/**
* @return 2 as the number of special cases handled by this handler.
*/
- public int getSpecialsCount(STextEnvironment environment) {
+ public int getSpecialsCount(ISTextExpert expert) {
return 2;
}