You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by ay...@apache.org on 2008/07/19 12:53:51 UTC
svn commit: r678130 [1/2] - in
/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common:
javax/swing/text/rtf/ org/apache/harmony/x/swing/text/rtf/
Author: ayza
Date: Sat Jul 19 03:53:50 2008
New Revision: 678130
URL: http://svn.apache.org/viewvc?rev=678130&view=rev
Log:
Applying patch for RTF parser from HARMONY-5911 ([classlib][rtf] RTF parser improvements and fixes)
Added:
harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/org/apache/harmony/x/swing/text/rtf/DocumentRTFHandler.java (with props)
harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/org/apache/harmony/x/swing/text/rtf/RTFEncodings.java (with props)
harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/org/apache/harmony/x/swing/text/rtf/RTFHandler.java (with props)
Removed:
harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/org/apache/harmony/x/swing/text/rtf/RTFParserHandler.java
Modified:
harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/rtf/RTFEditorKit.java
harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/org/apache/harmony/x/swing/text/rtf/RTFParser.java
harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/org/apache/harmony/x/swing/text/rtf/RTFParser.jj
harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/org/apache/harmony/x/swing/text/rtf/RTFParserConstants.java
harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/org/apache/harmony/x/swing/text/rtf/RTFParserTokenManager.java
harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/org/apache/harmony/x/swing/text/rtf/SimpleCharStream.java
Modified: harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/rtf/RTFEditorKit.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/rtf/RTFEditorKit.java?rev=678130&r1=678129&r2=678130&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/rtf/RTFEditorKit.java (original)
+++ harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/javax/swing/text/rtf/RTFEditorKit.java Sat Jul 19 03:53:50 2008
@@ -14,10 +14,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package javax.swing.text.rtf;
import org.apache.harmony.x.swing.text.rtf.RTFParser;
import org.apache.harmony.x.swing.text.rtf.ParseException;
+import org.apache.harmony.x.swing.text.rtf.RTFHandler;
+import org.apache.harmony.x.swing.text.rtf.DocumentRTFHandler;
import javax.swing.text.StyledEditorKit;
import javax.swing.text.Document;
@@ -25,7 +28,7 @@
import java.io.*;
/**
- * @author ayzen
+ * @author Aleksey Lagoshin
*/
public class RTFEditorKit extends StyledEditorKit {
@@ -40,7 +43,8 @@
public void read(InputStream in, Document doc, int pos) throws IOException, BadLocationException {
RTFParser parser = new RTFParser(in);
try {
- parser.parse(doc, pos);
+ RTFHandler handler = new DocumentRTFHandler(doc, pos);
+ parser.parse(handler);
}
catch (ParseException e) {
IOException ioex = new IOException(e.toString());
@@ -50,16 +54,26 @@
}
}
- public void read(Reader in, Document doc, int pos) {
+ public void read(Reader in, Document doc, int pos) throws IOException, BadLocationException {
+ RTFParser parser = new RTFParser(in);
+ try {
+ RTFHandler handler = new DocumentRTFHandler(doc, pos);
+ parser.parse(handler);
+ }
+ catch (ParseException e) {
+ IOException ioex = new IOException(e.toString());
+ ioex.initCause(e);
+ throw ioex;
+ }
}
public void write(OutputStream out, Document doc, int pos, int len) {
-
+
}
public void write(Writer out, Document doc, int pos, int len) {
}
-}
+}
\ No newline at end of file
Added: harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/org/apache/harmony/x/swing/text/rtf/DocumentRTFHandler.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/org/apache/harmony/x/swing/text/rtf/DocumentRTFHandler.java?rev=678130&view=auto
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/org/apache/harmony/x/swing/text/rtf/DocumentRTFHandler.java (added)
+++ harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/org/apache/harmony/x/swing/text/rtf/DocumentRTFHandler.java Sat Jul 19 03:53:50 2008
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.x.swing.text.rtf;
+
+import javax.swing.text.*;
+import java.util.Stack;
+
+/**
+ * @author Aleksey Lagoshin
+ */
+public class DocumentRTFHandler implements RTFHandler {
+
+ private StyledDocument sdoc;
+ private Document doc;
+
+ private int offset;
+
+ private Stack<MutableAttributeSet> stylesStack;
+ private MutableAttributeSet currentStyle;
+
+ public DocumentRTFHandler(Document doc, int position) {
+ stylesStack = new Stack<MutableAttributeSet>();
+ currentStyle = new SimpleAttributeSet();
+
+ if (doc instanceof StyledDocument)
+ sdoc = (StyledDocument) doc;
+ else
+ this.doc = doc;
+
+ offset = position;
+ }
+
+ public void startGroup() {
+ stylesStack.push(currentStyle);
+ currentStyle = new SimpleAttributeSet(currentStyle);
+ }
+
+ public void endGroup() {
+ currentStyle = stylesStack.pop();
+ }
+
+ public void addText(String text) {
+ try {
+ if (sdoc != null)
+ sdoc.insertString(offset, text, currentStyle);
+ else
+ doc.insertString(offset, text, null);
+
+ offset += text.length();
+ }
+ catch (BadLocationException e) {
+ //todo: throw it to RTFEditorKit?
+ }
+ }
+
+ public void newParagraph() {
+ addText("\n");
+ }
+
+ public void setBold(boolean enable) {
+ StyleConstants.setBold(currentStyle, enable);
+ }
+
+ public void setItalic(boolean enable) {
+ StyleConstants.setItalic(currentStyle, enable);
+ }
+
+ public void setUnderline(boolean enable) {
+ StyleConstants.setUnderline(currentStyle, enable);
+ }
+
+}
+
+
Propchange: harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/org/apache/harmony/x/swing/text/rtf/DocumentRTFHandler.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/org/apache/harmony/x/swing/text/rtf/RTFEncodings.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/org/apache/harmony/x/swing/text/rtf/RTFEncodings.java?rev=678130&view=auto
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/org/apache/harmony/x/swing/text/rtf/RTFEncodings.java (added)
+++ harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/org/apache/harmony/x/swing/text/rtf/RTFEncodings.java Sat Jul 19 03:53:50 2008
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.x.swing.text.rtf;
+
+/**
+ * This class contains methods for converting RTF code pages to Java encodings and vice versa.
+ *
+ * @author Aleksey Lagoshin
+ */
+public class RTFEncodings {
+
+ /**
+ * The default encoding for RTF files, it is also used for unsupported code pages.
+ */
+ public static final String DEFAULT_ENCODING = "Cp1252";
+
+ /**
+ * Returns an encoding name for Java corresponding to parsed code page.
+ * For all unsupported code pages this method returns the default encoding
+ * (see <a href="http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html">this</a> page)
+ *
+ * @param rtfCodePage code page parsed from RTF file
+ * @return an encoding name for Java
+ */
+ public static String getEncoding(int rtfCodePage) {
+ switch (rtfCodePage) {
+ case 437: return "Cp437"; // United States IBM
+ case 708: return "ISO8859_6"; // Arabic (ASMO 708)
+ case 709: // Arabic (ASMO 449+, BCON V4)
+ case 710: // Arabic (transparent Arabic)
+ case 711: // Arabic (Nafitha Enhanced)
+ case 720: return DEFAULT_ENCODING; // Arabic (transparent ASMO)
+ case 819: return "ISO8859_1"; // Windows 3.1 (United States and Western Europe)
+ case 850: return "Cp850"; // IBM multilingual
+ case 852: return "Cp852"; // Eastern European
+ case 860: return "Cp860"; // Portuguese
+ case 862: return "Cp862"; // Hebrew
+ case 863: return "Cp863"; // French Canadian
+ case 864: return "Cp864"; // Arabic
+ case 865: return "Cp865"; // Norwegian
+ case 866: return "Cp866"; // Soviet Union
+ case 874: return "MS874"; // Thai
+ case 932: return "MS932"; // Japanese
+ case 936: return "MS936"; // Simplified Chinese
+ case 949: return "MS949"; // Korean
+ case 950: return "MS950"; // Traditional Chinese
+ case 1250: return "Cp1250"; // Eastern European
+ case 1251: return "Cp1251"; // Cyrillic
+ case 1252: return "Cp1252"; // Western European
+ case 1253: return "Cp1253"; // Greek
+ case 1254: return "Cp1255"; // Turkish
+ case 1255: return "Cp1255"; // Hebrew
+ case 1256: return "Cp1256"; // Arabic
+ case 1257: return "Cp1257"; // Baltic
+ case 1258: return "Cp1258"; // Vietnamese
+ case 1361: return "x-Johab"; // Johab
+ case 10000: return "MacRoman"; // MAC Roman
+ case 10001: return "SJIS"; // MAC Japan
+ case 10004: return "MacArabic"; // MAC Arabic
+ case 10005: return "MacHebrew"; // MAC Hebrew
+ case 10006: return "MacGreek"; // MAC Greek
+ case 10007: return "MacCyrillic"; // MAC Cyrillic
+ case 10029: return "MacCentralEurope"; // MAC Latin2
+ case 10081: return "MacTurkish"; // MAC Turkish
+ case 57002: return "ISCII91"; // Devanagari
+ case 57003: // Bengali
+ case 57004: // Tamil
+ case 57005: // Telugu
+ case 57006: // Assamese
+ case 57007: // Oriya
+ case 57008: // Kannada
+ case 57009: // Malayalam
+ case 57010: // Gujarati
+ case 57011: // Punjabi
+ default: return DEFAULT_ENCODING;
+ }
+ }
+
+}
Propchange: harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/org/apache/harmony/x/swing/text/rtf/RTFEncodings.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/org/apache/harmony/x/swing/text/rtf/RTFHandler.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/org/apache/harmony/x/swing/text/rtf/RTFHandler.java?rev=678130&view=auto
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/org/apache/harmony/x/swing/text/rtf/RTFHandler.java (added)
+++ harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/org/apache/harmony/x/swing/text/rtf/RTFHandler.java Sat Jul 19 03:53:50 2008
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.x.swing.text.rtf;
+
+/**
+ * @author Aleksey Lagoshin
+ */
+public interface RTFHandler {
+
+ public void startGroup();
+
+ public void endGroup();
+
+ public void addText(String text);
+
+ public void newParagraph();
+
+ public void setBold(boolean enable);
+
+ public void setItalic(boolean enable);
+
+ public void setUnderline(boolean enable);
+
+}
Propchange: harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/org/apache/harmony/x/swing/text/rtf/RTFHandler.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/org/apache/harmony/x/swing/text/rtf/RTFParser.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/org/apache/harmony/x/swing/text/rtf/RTFParser.java?rev=678130&r1=678129&r2=678130&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/org/apache/harmony/x/swing/text/rtf/RTFParser.java (original)
+++ harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/org/apache/harmony/x/swing/text/rtf/RTFParser.java Sat Jul 19 03:53:50 2008
@@ -2,12 +2,21 @@
package org.apache.harmony.x.swing.text.rtf;
import java.io.*;
-import javax.swing.text.Document;
+import java.util.Stack;
import javax.swing.text.DefaultStyledDocument;
public class RTFParser implements RTFParserConstants {
- private static RTFParserHandler handler;
+ private RTFHandler handler;
+
+ private String encoding = RTFEncodings.DEFAULT_ENCODING;
+
+ private int ucValue = 1;
+ /**
+ * This stack contains only UC values as a scope parameter.
+ * It could be modified to contain additional parameters.
+ */
+ private Stack scopeStack = new Stack();
public static void main(String args[]) throws Exception {
InputStream in;
@@ -18,16 +27,27 @@
in = System.in;
RTFParser parser = new RTFParser(in);
- parser.parse(new DefaultStyledDocument(), 0);
+ RTFHandler handler = new DocumentRTFHandler(new DefaultStyledDocument(), 0);
+ parser.parse(handler);
}
- static final public void parse(Document doc, int position) throws ParseException {
- handler = new RTFParserHandler(doc, position);
+ private byte[] getBytes(String str) {
+ char[] chars = str.toCharArray();
+ byte[] bytes = new byte[chars.length];
+ for (int i = 0; i < chars.length; i++)
+ bytes[i] = (byte) chars[i];
+ return bytes;
+ }
+
+ final public void parse(RTFHandler handler) throws ParseException {
+ if (handler == null)
+ {if (true) throw new NullPointerException("Parameter handler cannot be null");}
+ this.handler = handler;
file();
jj_consume_token(0);
}
- static final private int parameter() throws ParseException {
+ final private int parameter() throws ParseException {
Token param = null;
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case PARAM:
@@ -37,11 +57,11 @@
jj_la1[0] = jj_gen;
;
}
- {if (true) return param == null ? -1 : Integer.parseInt(param.image);}
+ {if (true) return param == null ? -1 : Integer.parseInt(param.image.trim());}
throw new Error("Missing return statement in function");
}
- static final private void unknownControlWord() throws ParseException {
+ final private void unknownControlWord() throws ParseException {
jj_consume_token(CONTROL_WORD);
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case PARAM:
@@ -54,173 +74,323 @@
}
/**
- * Catches all unhandled control symbols.
+ * Catches all unhandled control symbols.
*/
- static final public void unknownControlSymbol() throws ParseException {
+ final public void unknownControlSymbol() throws ParseException {
jj_consume_token(CONTROL_SYMBOL);
}
- static final public void text() throws ParseException {
- Token text;
- text = jj_consume_token(TEXT);
- handler.addText(text.image);
- }
-
- static final public void file() throws ParseException {
+/**
+ * Group which starts with "{\*" and describes destination, currently this part
+ * is ignored.
+ */
+ final public void ignoredDestination() throws ParseException {
jj_consume_token(OPEN_BRACE);
- header();
- document();
+ jj_consume_token(IGNORED_DESTINATION);
+ ignoredBlock();
jj_consume_token(CLOSE_BRACE);
}
- static final public void header() throws ParseException {
- jj_consume_token(RTF);
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case PARAM:
- jj_consume_token(PARAM);
- break;
- default:
- jj_la1[2] = jj_gen;
- ;
- }
- }
-
- static final public void document() throws ParseException {
+ final public String parseText() throws ParseException {
+ byte[] bytes;
+ String text;
+ ByteArrayOutputStream textBytes = new ByteArrayOutputStream();
+ StringBuffer parsedText = new StringBuffer();
label_1:
while (true) {
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case B:
- case I:
- case UL:
- paragraph();
- break;
- default:
- jj_la1[3] = jj_gen;
- if (jj_2_1(2147483647)) {
- fonttbl();
- } else if (jj_2_2(2147483647)) {
- stylesheet();
- } else if (jj_2_3(2147483647)) {
- info();
- } else if (jj_2_4(2147483647)) {
- ignoredDestination();
- } else {
+ case HEX_CHAR:
+ case TEXT:
+ label_2:
+ while (true) {
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case OPEN_BRACE:
- documentBlock();
- break;
- case CONTROL_WORD:
- unknownControlWord();
- break;
- case CONTROL_SYMBOL:
- unknownControlSymbol();
+ case HEX_CHAR:
+ bytes = parseHexBytes();
break;
case TEXT:
- text();
+ bytes = parseTextBytes();
break;
default:
- jj_la1[4] = jj_gen;
+ jj_la1[2] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
+ try {
+ textBytes.write(bytes);
+ } catch (IOException e) {}
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case HEX_CHAR:
+ case TEXT:
+ ;
+ break;
+ default:
+ jj_la1[3] = jj_gen;
+ break label_2;
+ }
}
+ // Decoding collected characters using specified encoding
+ try {
+ parsedText.append(textBytes.toString(encoding));
+ textBytes.reset();
+ }
+ catch (UnsupportedEncodingException e) {
+ {if (true) throw new ParseException("Unsupported encoding");}
+ }
+ break;
+ case ESCAPED_OPEN_BRACE:
+ case ESCAPED_CLOSE_BRACE:
+ case ESCAPED_BACKSLASH:
+ case U:
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case ESCAPED_OPEN_BRACE:
+ case ESCAPED_CLOSE_BRACE:
+ case ESCAPED_BACKSLASH:
+ text = parseSpecialCharacter();
+ break;
+ case U:
+ text = parseUnicodeText();
+ break;
+ default:
+ jj_la1[4] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ parsedText.append(text);
+ break;
+ default:
+ jj_la1[5] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
}
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case OPEN_BRACE:
+ case ESCAPED_OPEN_BRACE:
+ case ESCAPED_CLOSE_BRACE:
+ case ESCAPED_BACKSLASH:
+ case HEX_CHAR:
case TEXT:
- case B:
- case I:
- case UL:
- case CONTROL_WORD:
- case CONTROL_SYMBOL:
+ case U:
;
break;
default:
- jj_la1[5] = jj_gen;
+ jj_la1[6] = jj_gen;
break label_1;
}
}
+ {if (true) return parsedText.toString();}
+ throw new Error("Missing return statement in function");
}
-/**
- * A group.
- */
- static final public void documentBlock() throws ParseException {
+ final public byte[] parseHexBytes() throws ParseException {
+ Token token;
+ byte[] result = new byte[1];
+ token = jj_consume_token(HEX_CHAR);
+ result[0] = (byte) Integer.parseInt(token.image.substring(2), 16);
+ {if (true) return result;}
+ throw new Error("Missing return statement in function");
+ }
+
+ final public byte[] parseTextBytes() throws ParseException {
+ Token token;
+ token = jj_consume_token(TEXT);
+ {if (true) return getBytes(token.image);}
+ throw new Error("Missing return statement in function");
+ }
+
+ final public String parseSpecialCharacter() throws ParseException {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case ESCAPED_OPEN_BRACE:
+ jj_consume_token(ESCAPED_OPEN_BRACE);
+ {if (true) return "{";}
+ break;
+ case ESCAPED_CLOSE_BRACE:
+ jj_consume_token(ESCAPED_CLOSE_BRACE);
+ {if (true) return "}";}
+ break;
+ case ESCAPED_BACKSLASH:
+ jj_consume_token(ESCAPED_BACKSLASH);
+ {if (true) return "\\";}
+ break;
+ default:
+ jj_la1[7] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ throw new Error("Missing return statement in function");
+ }
+
+ final public String parseUnicodeText() throws ParseException {
+ int param;
+ StringBuffer unicodeBuffer = new StringBuffer();
+ label_3:
+ while (true) {
+ jj_consume_token(U);
+ param = parameter();
+ if (param < 0)
+ param += 65536;
+
+ unicodeBuffer.append((char) param);
+ skipAfterUnicode(ucValue);
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case U:
+ ;
+ break;
+ default:
+ jj_la1[8] = jj_gen;
+ break label_3;
+ }
+ }
+ {if (true) return unicodeBuffer.toString();}
+ throw new Error("Missing return statement in function");
+ }
+
+ final public void file() throws ParseException {
jj_consume_token(OPEN_BRACE);
- handler.startGroup();
+ jj_consume_token(RTF);
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case PARAM:
+ jj_consume_token(PARAM);
+ break;
+ default:
+ jj_la1[9] = jj_gen;
+ ;
+ }
document();
jj_consume_token(CLOSE_BRACE);
- handler.endGroup();
}
-/**
- * Ignored block of RTF file, currently is using to ignore unknown parts
- * of file.
- */
- static final public void ignoredBlock() throws ParseException {
- label_2:
+ final public void document() throws ParseException {
+ boolean skipped;
+ String text;
+ label_4:
while (true) {
- if (jj_2_5(2147483647)) {
- ignoredDestination();
+ if (jj_2_1(2)) {
+ header();
} else {
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case B:
case I:
case UL:
- characterFormat();
- break;
- case CONTROL_WORD:
- unknownControlWord();
- break;
- case CONTROL_SYMBOL:
- unknownControlSymbol();
- break;
- case TEXT:
- jj_consume_token(TEXT);
- break;
- case OPEN_BRACE:
- jj_consume_token(OPEN_BRACE);
- ignoredBlock();
- jj_consume_token(CLOSE_BRACE);
+ case PAR:
+ paragraph();
break;
default:
- jj_la1[6] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
+ jj_la1[10] = jj_gen;
+ if (jj_2_2(2147483647)) {
+ info();
+ } else if (jj_2_3(2147483647)) {
+ ignoredDestination();
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case OPEN_BRACE:
+ documentGroup();
+ break;
+ case CONTROL_WORD:
+ unknownControlWord();
+ break;
+ case CONTROL_SYMBOL:
+ unknownControlSymbol();
+ break;
+ case ESCAPED_OPEN_BRACE:
+ case ESCAPED_CLOSE_BRACE:
+ case ESCAPED_BACKSLASH:
+ case HEX_CHAR:
+ case TEXT:
+ case U:
+ text = parseText();
+ handler.addText(text);
+ break;
+ default:
+ jj_la1[11] = jj_gen;
+ skipped = handleUnexpectedControlWord();
+ if (!skipped) {if (true) return;}
+ }
+ }
}
}
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case OPEN_BRACE:
- case TEXT:
- case B:
- case I:
- case UL:
- case CONTROL_WORD:
- case CONTROL_SYMBOL:
- ;
- break;
- default:
- jj_la1[7] = jj_gen;
- break label_2;
- }
+ ;
}
}
/**
- * Group which starts with "{\*" and describes destination, currently this part
- * is ignored.
+ * A group.
*/
- static final public void ignoredDestination() throws ParseException {
+ final public void documentGroup() throws ParseException {
+ startGroup();
+ document();
+ endGroup();
+ }
+
+ final public void startGroup() throws ParseException {
jj_consume_token(OPEN_BRACE);
- jj_consume_token(IGNORED_DESTINATION);
- ignoredBlock();
+ scopeStack.push(ucValue);
+ handler.startGroup();
+ }
+
+ final public void endGroup() throws ParseException {
jj_consume_token(CLOSE_BRACE);
+ ucValue = (Integer) scopeStack.pop();
+ handler.endGroup();
+ }
+
+ final public void header() throws ParseException {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case ANSI:
+ case MAC:
+ case PC:
+ case PCA:
+ case ANSICPG:
+ characterSet();
+ break;
+ default:
+ jj_la1[12] = jj_gen;
+ if (jj_2_4(2147483647)) {
+ fonttbl();
+ } else if (jj_2_5(2147483647)) {
+ colortbl();
+ } else if (jj_2_6(2147483647)) {
+ stylesheet();
+ } else {
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ }
+ }
+
+ final public void characterSet() throws ParseException {
+ int param;
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case ANSI:
+ jj_consume_token(ANSI);
+ encoding = "Cp1252";
+ break;
+ case MAC:
+ jj_consume_token(MAC);
+ encoding = "MacRoman";
+ break;
+ case PC:
+ jj_consume_token(PC);
+ encoding = "Cp437";
+ break;
+ case PCA:
+ jj_consume_token(PCA);
+ encoding = "Cp850";
+ break;
+ case ANSICPG:
+ jj_consume_token(ANSICPG);
+ param = parameter();
+ encoding = RTFEncodings.getEncoding(param);
+ break;
+ default:
+ jj_la1[13] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
}
/**
* Part which describes font table group.
*/
- static final public void fonttbl() throws ParseException {
+ final public void fonttbl() throws ParseException {
jj_consume_token(OPEN_BRACE);
jj_consume_token(FONTTBL);
ignoredBlock();
@@ -228,9 +398,19 @@
}
/**
+ * Part which describes color table group.
+ */
+ final public void colortbl() throws ParseException {
+ jj_consume_token(OPEN_BRACE);
+ jj_consume_token(COLORTBL);
+ ignoredBlock();
+ jj_consume_token(CLOSE_BRACE);
+ }
+
+/**
* Part which describes the style sheet group.
*/
- static final public void stylesheet() throws ParseException {
+ final public void stylesheet() throws ParseException {
jj_consume_token(OPEN_BRACE);
jj_consume_token(STYLESHEET);
ignoredBlock();
@@ -240,18 +420,32 @@
/**
* Part which describes the information group inside document area.
*/
- static final public void info() throws ParseException {
+ final public void info() throws ParseException {
jj_consume_token(OPEN_BRACE);
jj_consume_token(INFO);
ignoredBlock();
jj_consume_token(CLOSE_BRACE);
}
- static final public void paragraph() throws ParseException {
- characterFormat();
+ final public void paragraph() throws ParseException {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case B:
+ case I:
+ case UL:
+ characterFormat();
+ break;
+ case PAR:
+ jj_consume_token(PAR);
+ handler.newParagraph();
+ break;
+ default:
+ jj_la1[14] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
}
- static final public void characterFormat() throws ParseException {
+ final public void characterFormat() throws ParseException {
int param;
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case B:
@@ -270,172 +464,343 @@
handler.setUnderline(param != 0);
break;
default:
- jj_la1[8] = jj_gen;
+ jj_la1[15] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
}
- static final private boolean jj_2_1(int xla) {
+ private void ignoredBlock() throws ParseException {
+ Token token;
+ int nesting = 1;
+ while (true) {
+ token = getToken(1);
+ if (token.kind == OPEN_BRACE)
+ nesting++;
+ else if (token.kind == CLOSE_BRACE) {
+ nesting--;
+ if (nesting == 0)
+ return;
+ }
+ getNextToken();
+ }
+ }
+
+ private boolean handleUnexpectedControlWord() throws ParseException {
+ Token token = getToken(1);
+
+ if (token.kind == UC) {
+ getNextToken();
+ token = getToken(1);
+ if (token.kind == PARAM) {
+ ucValue = Integer.parseInt(token.image);
+ getNextToken();
+ }
+ return true;
+ }
+
+ String text = token.image;
+ if (text.matches("\\\\[a-zA-Z]+")) {
+ getNextToken();
+ token = getToken(1);
+ if (token.kind == PARAM)
+ getNextToken();
+ return true;
+ }
+
+ return false;
+ }
+
+ private void skipAfterUnicode(int n) throws ParseException {
+ while (n-- > 0) {
+ Token token = getToken(1);
+ // If token is a control word or a control symbol
+ if (token.image.startsWith("\\")) {
+ getNextToken();
+ token = getToken(1);
+ // If control word has parameter
+ if (token.kind == PARAM)
+ getNextToken();
+ //TODO: Need to skip \bin data
+ }
+ else if (token.kind == HEX_CHAR)
+ getNextToken();
+ else if (token.kind == TEXT) {
+ String text = token.image;
+ if (text.length() <= n + 1) {
+ n -= text.length() - 1;
+ getNextToken();
+ }
+ else {
+ token.image = text.substring(n + 1);
+ return;
+ }
+ }
+ else throw new ParseException("Wrong token " + token + " while skipping data after Unicode character");
+ }
+ }
+
+ final private boolean jj_2_1(int xla) {
jj_la = xla; jj_lastpos = jj_scanpos = token;
try { return !jj_3_1(); }
catch(LookaheadSuccess ls) { return true; }
finally { jj_save(0, xla); }
}
- static final private boolean jj_2_2(int xla) {
+ final private boolean jj_2_2(int xla) {
jj_la = xla; jj_lastpos = jj_scanpos = token;
try { return !jj_3_2(); }
catch(LookaheadSuccess ls) { return true; }
finally { jj_save(1, xla); }
}
- static final private boolean jj_2_3(int xla) {
+ final private boolean jj_2_3(int xla) {
jj_la = xla; jj_lastpos = jj_scanpos = token;
try { return !jj_3_3(); }
catch(LookaheadSuccess ls) { return true; }
finally { jj_save(2, xla); }
}
- static final private boolean jj_2_4(int xla) {
+ final private boolean jj_2_4(int xla) {
jj_la = xla; jj_lastpos = jj_scanpos = token;
try { return !jj_3_4(); }
catch(LookaheadSuccess ls) { return true; }
finally { jj_save(3, xla); }
}
- static final private boolean jj_2_5(int xla) {
+ final private boolean jj_2_5(int xla) {
jj_la = xla; jj_lastpos = jj_scanpos = token;
try { return !jj_3_5(); }
catch(LookaheadSuccess ls) { return true; }
finally { jj_save(4, xla); }
}
- static final private boolean jj_3_3() {
+ final private boolean jj_2_6(int xla) {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ try { return !jj_3_6(); }
+ catch(LookaheadSuccess ls) { return true; }
+ finally { jj_save(5, xla); }
+ }
+
+ final private boolean jj_3R_18() {
+ if (jj_scan_token(ANSICPG)) return true;
+ if (jj_3R_19()) return true;
+ return false;
+ }
+
+ final private boolean jj_3R_17() {
+ if (jj_scan_token(PCA)) return true;
+ return false;
+ }
+
+ final private boolean jj_3_3() {
+ if (jj_scan_token(OPEN_BRACE)) return true;
+ if (jj_scan_token(IGNORED_DESTINATION)) return true;
+ return false;
+ }
+
+ final private boolean jj_3R_16() {
+ if (jj_scan_token(PC)) return true;
+ return false;
+ }
+
+ final private boolean jj_3_2() {
if (jj_scan_token(OPEN_BRACE)) return true;
if (jj_scan_token(INFO)) return true;
return false;
}
- static final private boolean jj_3_2() {
+ final private boolean jj_3_6() {
if (jj_scan_token(OPEN_BRACE)) return true;
if (jj_scan_token(STYLESHEET)) return true;
return false;
}
- static final private boolean jj_3_5() {
+ final private boolean jj_3R_15() {
+ if (jj_scan_token(MAC)) return true;
+ return false;
+ }
+
+ final private boolean jj_3R_10() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_14()) {
+ jj_scanpos = xsp;
+ if (jj_3R_15()) {
+ jj_scanpos = xsp;
+ if (jj_3R_16()) {
+ jj_scanpos = xsp;
+ if (jj_3R_17()) {
+ jj_scanpos = xsp;
+ if (jj_3R_18()) return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ final private boolean jj_3R_14() {
+ if (jj_scan_token(ANSI)) return true;
+ return false;
+ }
+
+ final private boolean jj_3_5() {
if (jj_scan_token(OPEN_BRACE)) return true;
- if (jj_scan_token(IGNORED_DESTINATION)) return true;
+ if (jj_scan_token(COLORTBL)) return true;
return false;
}
- static final private boolean jj_3_1() {
+ final private boolean jj_3_4() {
if (jj_scan_token(OPEN_BRACE)) return true;
if (jj_scan_token(FONTTBL)) return true;
return false;
}
- static final private boolean jj_3_4() {
+ final private boolean jj_3R_9() {
+ if (jj_3R_13()) return true;
+ return false;
+ }
+
+ final private boolean jj_3R_19() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_scan_token(38)) jj_scanpos = xsp;
+ return false;
+ }
+
+ final private boolean jj_3R_8() {
+ if (jj_3R_12()) return true;
+ return false;
+ }
+
+ final private boolean jj_3_1() {
+ if (jj_3R_5()) return true;
+ return false;
+ }
+
+ final private boolean jj_3R_7() {
+ if (jj_3R_11()) return true;
+ return false;
+ }
+
+ final private boolean jj_3R_13() {
if (jj_scan_token(OPEN_BRACE)) return true;
- if (jj_scan_token(IGNORED_DESTINATION)) return true;
+ if (jj_scan_token(STYLESHEET)) return true;
+ return false;
+ }
+
+ final private boolean jj_3R_6() {
+ if (jj_3R_10()) return true;
+ return false;
+ }
+
+ final private boolean jj_3R_5() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_6()) {
+ jj_scanpos = xsp;
+ if (jj_3R_7()) {
+ jj_scanpos = xsp;
+ if (jj_3R_8()) {
+ jj_scanpos = xsp;
+ if (jj_3R_9()) return true;
+ }
+ }
+ }
return false;
}
- static private boolean jj_initialized_once = false;
- static public RTFParserTokenManager token_source;
- static SimpleCharStream jj_input_stream;
- static public Token token, jj_nt;
- static private int jj_ntk;
- static private Token jj_scanpos, jj_lastpos;
- static private int jj_la;
- static public boolean lookingAhead = false;
- static private boolean jj_semLA;
- static private int jj_gen;
- static final private int[] jj_la1 = new int[9];
+ final private boolean jj_3R_12() {
+ if (jj_scan_token(OPEN_BRACE)) return true;
+ if (jj_scan_token(COLORTBL)) return true;
+ return false;
+ }
+
+ final private boolean jj_3R_11() {
+ if (jj_scan_token(OPEN_BRACE)) return true;
+ if (jj_scan_token(FONTTBL)) return true;
+ return false;
+ }
+
+ public RTFParserTokenManager token_source;
+ SimpleCharStream jj_input_stream;
+ public Token token, jj_nt;
+ private int jj_ntk;
+ private Token jj_scanpos, jj_lastpos;
+ private int jj_la;
+ public boolean lookingAhead = false;
+ private boolean jj_semLA;
+ private int jj_gen;
+ final private int[] jj_la1 = new int[16];
static private int[] jj_la1_0;
+ static private int[] jj_la1_1;
static {
jj_la1_0();
+ jj_la1_1();
}
private static void jj_la1_0() {
- jj_la1_0 = new int[] {0x400000,0x400000,0x400000,0x70000,0x3000a0,0x3700a0,0x3700a0,0x3700a0,0x70000,};
+ jj_la1_0 = new int[] {0x0,0x0,0x4400,0x4400,0x40000e0,0x40044e0,0x40044e0,0xe0,0x4000000,0x0,0x0,0x40055e0,0x1f00000,0x1f00000,0x0,0x0,};
}
- static final private JJCalls[] jj_2_rtns = new JJCalls[5];
- static private boolean jj_rescan = false;
- static private int jj_gc = 0;
+ private static void jj_la1_1() {
+ jj_la1_1 = new int[] {0x40,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40,0x1e,0x20,0x0,0x0,0x1e,0xe,};
+ }
+ final private JJCalls[] jj_2_rtns = new JJCalls[6];
+ private boolean jj_rescan = false;
+ private int jj_gc = 0;
public RTFParser(java.io.InputStream stream) {
this(stream, null);
}
public RTFParser(java.io.InputStream stream, String encoding) {
- if (jj_initialized_once) {
- System.out.println("ERROR: Second call to constructor of static parser. You must");
- System.out.println(" either use ReInit() or set the JavaCC option STATIC to false");
- System.out.println(" during parser generation.");
- throw new Error();
- }
- jj_initialized_once = true;
try { jj_input_stream = new SimpleCharStream(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
token_source = new RTFParserTokenManager(jj_input_stream);
token = new Token();
jj_ntk = -1;
jj_gen = 0;
- for (int i = 0; i < 9; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 16; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
- static public void ReInit(java.io.InputStream stream) {
+ public void ReInit(java.io.InputStream stream) {
ReInit(stream, null);
}
- static public void ReInit(java.io.InputStream stream, String encoding) {
+ public void ReInit(java.io.InputStream stream, String encoding) {
try { jj_input_stream.ReInit(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
token_source.ReInit(jj_input_stream);
token = new Token();
jj_ntk = -1;
jj_gen = 0;
- for (int i = 0; i < 9; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 16; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
public RTFParser(java.io.Reader stream) {
- if (jj_initialized_once) {
- System.out.println("ERROR: Second call to constructor of static parser. You must");
- System.out.println(" either use ReInit() or set the JavaCC option STATIC to false");
- System.out.println(" during parser generation.");
- throw new Error();
- }
- jj_initialized_once = true;
jj_input_stream = new SimpleCharStream(stream, 1, 1);
token_source = new RTFParserTokenManager(jj_input_stream);
token = new Token();
jj_ntk = -1;
jj_gen = 0;
- for (int i = 0; i < 9; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 16; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
- static public void ReInit(java.io.Reader stream) {
+ public void ReInit(java.io.Reader stream) {
jj_input_stream.ReInit(stream, 1, 1);
token_source.ReInit(jj_input_stream);
token = new Token();
jj_ntk = -1;
jj_gen = 0;
- for (int i = 0; i < 9; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 16; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
public RTFParser(RTFParserTokenManager tm) {
- if (jj_initialized_once) {
- System.out.println("ERROR: Second call to constructor of static parser. You must");
- System.out.println(" either use ReInit() or set the JavaCC option STATIC to false");
- System.out.println(" during parser generation.");
- throw new Error();
- }
- jj_initialized_once = true;
token_source = tm;
token = new Token();
jj_ntk = -1;
jj_gen = 0;
- for (int i = 0; i < 9; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 16; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
@@ -444,11 +809,11 @@
token = new Token();
jj_ntk = -1;
jj_gen = 0;
- for (int i = 0; i < 9; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 16; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
- static final private Token jj_consume_token(int kind) throws ParseException {
+ final private Token jj_consume_token(int kind) throws ParseException {
Token oldToken;
if ((oldToken = token).next != null) token = token.next;
else token = token.next = token_source.getNextToken();
@@ -473,8 +838,8 @@
}
static private final class LookaheadSuccess extends java.lang.Error { }
- static final private LookaheadSuccess jj_ls = new LookaheadSuccess();
- static final private boolean jj_scan_token(int kind) {
+ final private LookaheadSuccess jj_ls = new LookaheadSuccess();
+ final private boolean jj_scan_token(int kind) {
if (jj_scanpos == jj_lastpos) {
jj_la--;
if (jj_scanpos.next == null) {
@@ -495,7 +860,7 @@
return false;
}
- static final public Token getNextToken() {
+ final public Token getNextToken() {
if (token.next != null) token = token.next;
else token = token.next = token_source.getNextToken();
jj_ntk = -1;
@@ -503,7 +868,7 @@
return token;
}
- static final public Token getToken(int index) {
+ final public Token getToken(int index) {
Token t = lookingAhead ? jj_scanpos : token;
for (int i = 0; i < index; i++) {
if (t.next != null) t = t.next;
@@ -512,20 +877,20 @@
return t;
}
- static final private int jj_ntk() {
+ final private int jj_ntk() {
if ((jj_nt=token.next) == null)
return (jj_ntk = (token.next=token_source.getNextToken()).kind);
else
return (jj_ntk = jj_nt.kind);
}
- static private java.util.Vector jj_expentries = new java.util.Vector();
- static private int[] jj_expentry;
- static private int jj_kind = -1;
- static private int[] jj_lasttokens = new int[100];
- static private int jj_endpos;
+ private java.util.Vector jj_expentries = new java.util.Vector();
+ private int[] jj_expentry;
+ private int jj_kind = -1;
+ private int[] jj_lasttokens = new int[100];
+ private int jj_endpos;
- static private void jj_add_error_token(int kind, int pos) {
+ private void jj_add_error_token(int kind, int pos) {
if (pos >= 100) return;
if (pos == jj_endpos + 1) {
jj_lasttokens[jj_endpos++] = kind;
@@ -553,26 +918,29 @@
}
}
- static public ParseException generateParseException() {
+ public ParseException generateParseException() {
jj_expentries.removeAllElements();
- boolean[] la1tokens = new boolean[24];
- for (int i = 0; i < 24; i++) {
+ boolean[] la1tokens = new boolean[40];
+ for (int i = 0; i < 40; i++) {
la1tokens[i] = false;
}
if (jj_kind >= 0) {
la1tokens[jj_kind] = true;
jj_kind = -1;
}
- for (int i = 0; i < 9; i++) {
+ for (int i = 0; i < 16; i++) {
if (jj_la1[i] == jj_gen) {
for (int j = 0; j < 32; j++) {
if ((jj_la1_0[i] & (1<<j)) != 0) {
la1tokens[j] = true;
}
+ if ((jj_la1_1[i] & (1<<j)) != 0) {
+ la1tokens[32+j] = true;
+ }
}
}
}
- for (int i = 0; i < 24; i++) {
+ for (int i = 0; i < 40; i++) {
if (la1tokens[i]) {
jj_expentry = new int[1];
jj_expentry[0] = i;
@@ -589,15 +957,15 @@
return new ParseException(token, exptokseq, tokenImage);
}
- static final public void enable_tracing() {
+ final public void enable_tracing() {
}
- static final public void disable_tracing() {
+ final public void disable_tracing() {
}
- static final private void jj_rescan_token() {
+ final private void jj_rescan_token() {
jj_rescan = true;
- for (int i = 0; i < 5; i++) {
+ for (int i = 0; i < 6; i++) {
try {
JJCalls p = jj_2_rtns[i];
do {
@@ -609,6 +977,7 @@
case 2: jj_3_3(); break;
case 3: jj_3_4(); break;
case 4: jj_3_5(); break;
+ case 5: jj_3_6(); break;
}
}
p = p.next;
@@ -618,7 +987,7 @@
jj_rescan = false;
}
- static final private void jj_save(int index, int xla) {
+ final private void jj_save(int index, int xla) {
JJCalls p = jj_2_rtns[index];
while (p.gen > jj_gen) {
if (p.next == null) { p = p.next = new JJCalls(); break; }
Modified: harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/org/apache/harmony/x/swing/text/rtf/RTFParser.jj
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/org/apache/harmony/x/swing/text/rtf/RTFParser.jj?rev=678130&r1=678129&r2=678130&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/org/apache/harmony/x/swing/text/rtf/RTFParser.jj (original)
+++ harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/org/apache/harmony/x/swing/text/rtf/RTFParser.jj Sat Jul 19 03:53:50 2008
@@ -1,35 +1,45 @@
/*
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
-//options {
+options {
// DEBUG_PARSER = true;
-// DEBUG_TOKEN_MANAGER=true;
-//}
+// DEBUG_TOKEN_MANAGER = true;
+ STATIC = false;
+}
PARSER_BEGIN(RTFParser)
package org.apache.harmony.x.swing.text.rtf;
import java.io.*;
-import javax.swing.text.Document;
+import java.util.Stack;
import javax.swing.text.DefaultStyledDocument;
public class RTFParser {
- private static RTFParserHandler handler;
+ private RTFHandler handler;
+
+ private String encoding = RTFEncodings.DEFAULT_ENCODING;
+
+ private int ucValue = 1;
+ /**
+ * This stack contains only UC values as a scope parameter.
+ * It could be modified to contain additional parameters.
+ */
+ private Stack scopeStack = new Stack();
public static void main(String args[]) throws Exception {
InputStream in;
@@ -38,48 +48,49 @@
in = new FileInputStream(args[0]);
else
in = System.in;
-
+
RTFParser parser = new RTFParser(in);
- parser.parse(new DefaultStyledDocument(), 0);
+ RTFHandler handler = new DocumentRTFHandler(new DefaultStyledDocument(), 0);
+ parser.parse(handler);
}
-
+
+ private byte[] getBytes(String str) {
+ char[] chars = str.toCharArray();
+ byte[] bytes = new byte[chars.length];
+ for (int i = 0; i < chars.length; i++)
+ bytes[i] = (byte) chars[i];
+ return bytes;
+ }
+
}
PARSER_END(RTFParser)
-/*<*> MORE :
+<DEFAULT>
+SKIP :
{
- "\\" : InControlWord
+ "\n"
+| "\r"
+| "\t"
}
-<InControlWord> TOKEN :
-{
- <RTF: "rtf"<PARAM>> {System.out.println("rtf");} : DEFAULT
-}
- (
- documentBlock()
-<InControlWord> TOKEN :
+<*>
+TOKEN:
{
- {System.out.println("param");} <PARAM: "123">
+ <IGNORED_DESTINATION: "\\*"> : DEFAULT
+| <ESCAPED_OPEN_BRACE: "\\{"> : DEFAULT
+| <ESCAPED_CLOSE_BRACE: "\\}"> : DEFAULT
+| <ESCAPED_BACKSLASH: "\\\\"> : DEFAULT
+| <CONTROL_SYMBOL: "\\" ~["a"-"z", "A"-"Z", "0"-"9", " ", "\t",
+ "{", "}", "\n", "\r"]> : DEFAULT
+| <#HEX_DIGIT: ["0"-"9","a"-"f","A"-"F"]>
+| <HEX_CHAR: "\\'" <HEX_DIGIT> <HEX_DIGIT>> : DEFAULT
}
-<InControlWord> MORE:
-{
- <~[]> : DEFAULT
-}*/
-
<*>
MORE:
{
- <BACKSLASH: "\\"> : IN_CONTROL
-}
-
-<DEFAULT>
-SKIP :
-{
- "\n"
-| "\r"
-| "\t"
+ <BACKSLASH: "\\"> : IN_CONTROL_WORD
}
<*>
@@ -92,10 +103,10 @@
<DEFAULT>
TOKEN:
{
- <TEXT: (~["\\","{","}","\n","\r", "\t"])+>
+ <TEXT: (~["\\", "{", "}", "\n", "\r", "\t"])+>
}
-<IN_CONTROL>
+<IN_CONTROL_WORD>
SKIP:
{
" " : DEFAULT
@@ -104,54 +115,47 @@
| "\t" : DEFAULT
}
-<IN_CONTROL>
+<IN_CONTROL_WORD>
TOKEN:
{
<RTF: "rtf">
+| <ANSI: "ansi">
+| <MAC: "mac">
+| <PC: "pc">
+| <PCA: "pca">
+| <ANSICPG: "ansicpg">
+| <UC: "uc">
+| <U: "u">
+| <UPR: "upr">
+| <UD: "ud">
| <FONTTBL: "fonttbl">
+| <COLORTBL: "colortbl">
| <STYLESHEET: "stylesheet">
-| <INFO: "info">
+| <INFO: "info">
| <B: "b">
| <I: "i">
| <UL: "ul">
//| <SECT: "sect">
//| <SUBDOCUMENT: "subdocument">
-//| <PAR: "par">
-}
+| <PAR: "par">
-<IN_CONTROL>
-TOKEN:
-{
- <IGNORED_DESTINATION: "*">
+| <CONTROL_WORD: (["a"-"z", "A"-"Z"])+>
+| <PARAM: (["-"])? (["0"-"9"])+ (" ")?> : DEFAULT
}
-<IN_CONTROL>
-TOKEN:
-{
- <CONTROL_WORD: (["a"-"z", "A"-"Z"])+>
-| <CONTROL_SYMBOL: ~["a"-"z", "A"-"Z", "0"-"9", " ", "\t",
- "{", "}", "\n", "\r", "\\"]>
-}
-
-<IN_CONTROL>
-TOKEN:
-{
- <PARAM: (["-"])? (["0"-"9"])+>
-}
-
-<IN_CONTROL>
+<IN_CONTROL_WORD>
SKIP:
{
<~[]> : DEFAULT
}
-
-
-public void parse(Document doc, int position) :
+public void parse(RTFHandler handler) :
{}
{
{
- handler = new RTFParserHandler(doc, position);
+ if (handler == null)
+ throw new NullPointerException("Parameter handler cannot be null");
+ this.handler = handler;
}
file() <EOF>
}
@@ -161,14 +165,14 @@
Token param = null;
}
{
- [param=<PARAM>]
+ [param=<PARAM>]
{
- return param == null ? -1 : Integer.parseInt(param.image);
+ return param == null ? -1 : Integer.parseInt(param.image.trim());
}
}
/**
- * Catches all unhandled control words.
+ * Catches all unhandled control words.
*/
private void unknownControlWord() :
{}
@@ -177,94 +181,197 @@
}
/**
- * Catches all unhandled control symbols.
+ * Catches all unhandled control symbols.
*/
-void unknownControlSymbol() :
+void unknownControlSymbol() :
{}
{
<CONTROL_SYMBOL>
}
-void text() :
+/**
+ * Group which starts with "{\*" and describes destination, currently this part
+ * is ignored.
+ */
+void ignoredDestination() :
+{}
+{
+ <OPEN_BRACE> <IGNORED_DESTINATION> ignoredBlock() <CLOSE_BRACE>
+}
+
+String parseText() :
{
- Token text;
+ byte[] bytes;
+ String text;
+ ByteArrayOutputStream textBytes = new ByteArrayOutputStream();
+ StringBuffer parsedText = new StringBuffer();
}
{
- text=<TEXT>
- {
- handler.addText(text.image);
+ (
+ (
+ // Here we collecting all the characters which should be decoded
+ // using specified encoding
+ (
+ bytes = parseHexBytes()
+ | bytes = parseTextBytes()
+ ) {
+ try {
+ textBytes.write(bytes);
+ } catch (IOException e) {}
+ }
+ )+
+ {
+ // Decoding collected characters using specified encoding
+ try {
+ parsedText.append(textBytes.toString(encoding));
+ textBytes.reset();
+ }
+ catch (UnsupportedEncodingException e) {
+ throw new ParseException("Unsupported encoding");
+ }
+ }
+ // Appending characters which don't require decoding to parsed text
+ | (
+ text = parseSpecialCharacter()
+ | text = parseUnicodeText()
+ ) { parsedText.append(text); }
+ )+
+ { return parsedText.toString(); }
+}
+
+byte[] parseHexBytes() :
+{
+ Token token;
+ byte[] result = new byte[1];
+}
+{
+ token = <HEX_CHAR>
+ {
+ result[0] = (byte) Integer.parseInt(token.image.substring(2), 16);
+ return result;
}
}
-void file() :
+byte[] parseTextBytes() :
+{
+ Token token;
+}
+{
+ token = <TEXT>
+ {
+ return getBytes(token.image);
+ }
+}
+
+String parseSpecialCharacter() :
{}
{
- <OPEN_BRACE> header() document() <CLOSE_BRACE>
+ <ESCAPED_OPEN_BRACE> { return "{"; }
+| <ESCAPED_CLOSE_BRACE> { return "}"; }
+| <ESCAPED_BACKSLASH> { return "\\"; }
}
-void header() :
+String parseUnicodeText() :
+{
+ int param;
+ StringBuffer unicodeBuffer = new StringBuffer();
+}
+{
+ (
+ <U> param = parameter()
+ {
+ if (param < 0)
+ param += 65536;
+
+ unicodeBuffer.append((char) param);
+ }
+ skipAfterUnicode(ucValue)
+ )+
+ { return unicodeBuffer.toString(); }
+}
+
+void file() :
{}
{
- <RTF>[<PARAM>]
+ <OPEN_BRACE> <RTF>[<PARAM>] document() <CLOSE_BRACE>
}
void document() :
-{}
+{
+ boolean skipped;
+ String text;
+}
{
(
- paragraph()
- | LOOKAHEAD(<OPEN_BRACE> <FONTTBL>)
- fonttbl()
- | LOOKAHEAD(<OPEN_BRACE> <STYLESHEET>)
- stylesheet()
+ LOOKAHEAD(2)
+ header()
+ | paragraph()
| LOOKAHEAD(<OPEN_BRACE> <INFO>)
info()
| LOOKAHEAD(<OPEN_BRACE> <IGNORED_DESTINATION>)
- ignoredDestination()
- | documentBlock()
- | unknownControlWord()
- | unknownControlSymbol()
- | text()
+ ignoredDestination()
+ | documentGroup()
+ | unknownControlWord()
+ | unknownControlSymbol()
+ | text = parseText() { handler.addText(text); }
+ | skipped = handleUnexpectedControlWord() { if (!skipped) return; }
)+
}
/**
- * A group.
+ * A group.
*/
-void documentBlock() :
+void documentGroup() :
{}
{
- <OPEN_BRACE> { handler.startGroup(); }
- document()
- <CLOSE_BRACE> { handler.endGroup(); }
+ startGroup() document() endGroup()
}
-/**
- * Ignored block of RTF file, currently is using to ignore unknown parts
- * of file.
- */
-void ignoredBlock() :
+void startGroup() :
{}
{
- (
- LOOKAHEAD(<OPEN_BRACE> <IGNORED_DESTINATION>)
- ignoredDestination()
- | characterFormat() //TODO: Need to find a way to ignore control words declared as TOKENS
- | unknownControlWord()
- | unknownControlSymbol()
- | <TEXT>
- | <OPEN_BRACE> ignoredBlock() <CLOSE_BRACE>
- )+
+ <OPEN_BRACE>
+ {
+ scopeStack.push(ucValue);
+ handler.startGroup();
+ }
}
-/**
- * Group which starts with "{\*" and describes destination, currently this part
- * is ignored.
- */
-void ignoredDestination() :
+void endGroup() :
{}
{
- <OPEN_BRACE> <IGNORED_DESTINATION> ignoredBlock() <CLOSE_BRACE>
+ <CLOSE_BRACE>
+ {
+ ucValue = (Integer) scopeStack.pop();
+ handler.endGroup();
+ }
+}
+
+void header() :
+{}
+{
+ characterSet()
+| LOOKAHEAD(<OPEN_BRACE> <FONTTBL>)
+ fonttbl()
+| LOOKAHEAD(<OPEN_BRACE> <COLORTBL>)
+ colortbl()
+| LOOKAHEAD(<OPEN_BRACE> <STYLESHEET>)
+ stylesheet()
+}
+
+void characterSet() :
+{
+ int param;
+}
+{
+ <ANSI> { encoding = "Cp1252"; }
+| <MAC> { encoding = "MacRoman"; }
+| <PC> { encoding = "Cp437"; }
+| <PCA> { encoding = "Cp850"; }
+| <ANSICPG> param = parameter()
+ {
+ encoding = RTFEncodings.getEncoding(param);
+ }
}
/**
@@ -277,6 +384,15 @@
}
/**
+ * Part which describes color table group.
+ */
+void colortbl() :
+{}
+{
+ <OPEN_BRACE> <COLORTBL> ignoredBlock() <CLOSE_BRACE>
+}
+
+/**
* Part which describes the style sheet group.
*/
void stylesheet() :
@@ -298,10 +414,11 @@
{}
{
characterFormat()
+| <PAR> { handler.newParagraph(); }
}
void characterFormat() :
-{
+{
int param;
}
{
@@ -309,3 +426,90 @@
| <I> param = parameter() { handler.setItalic(param != 0); }
| <UL> param = parameter() { handler.setUnderline(param != 0); }
}
+
+JAVACODE
+/**
+ * Ignoring a block of RTF file enclosed in braces, it is using
+ * to ignore unknown or unnecessary parts of file.
+ */
+private void ignoredBlock() {
+ Token token;
+ int nesting = 1;
+ while (true) {
+ token = getToken(1);
+ if (token.kind == OPEN_BRACE)
+ nesting++;
+ else if (token.kind == CLOSE_BRACE) {
+ nesting--;
+ if (nesting == 0)
+ return;
+ }
+ getNextToken();
+ }
+}
+
+JAVACODE
+/**
+ * This function skips an unexpected control word defined as token
+ * and handle control words which could appear anywhere in a file.
+ *
+ * @return true if control was skipped or handled
+ */
+private boolean handleUnexpectedControlWord() {
+ Token token = getToken(1);
+
+ if (token.kind == UC) {
+ getNextToken();
+ token = getToken(1);
+ if (token.kind == PARAM) {
+ ucValue = Integer.parseInt(token.image);
+ getNextToken();
+ }
+ return true;
+ }
+
+ String text = token.image;
+ if (text.matches("\\\\[a-zA-Z]+")) {
+ getNextToken();
+ token = getToken(1);
+ if (token.kind == PARAM)
+ getNextToken();
+ return true;
+ }
+
+ return false;
+}
+
+JAVACODE
+/**
+ * This function skips n characters and/or control words and/or
+ * control symbols after Unicode character.
+ */
+private void skipAfterUnicode(int n) {
+ while (n-- > 0) {
+ Token token = getToken(1);
+ // If token is a control word or a control symbol
+ if (token.image.startsWith("\\")) {
+ getNextToken();
+ token = getToken(1);
+ // If control word has parameter
+ if (token.kind == PARAM)
+ getNextToken();
+ //TODO: Need to skip \bin data
+ }
+ else if (token.kind == HEX_CHAR)
+ getNextToken();
+ else if (token.kind == TEXT) {
+ String text = token.image;
+ if (text.length() <= n + 1) {
+ n -= text.length() - 1;
+ getNextToken();
+ }
+ else {
+ token.image = text.substring(n + 1);
+ return;
+ }
+ }
+ else throw new ParseException("Wrong token " + token + " while skipping data after Unicode character");
+ }
+}
\ No newline at end of file
Modified: harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/org/apache/harmony/x/swing/text/rtf/RTFParserConstants.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/org/apache/harmony/x/swing/text/rtf/RTFParserConstants.java?rev=678130&r1=678129&r2=678130&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/org/apache/harmony/x/swing/text/rtf/RTFParserConstants.java (original)
+++ harmony/enhanced/classlib/trunk/modules/swing/src/main/java/common/org/apache/harmony/x/swing/text/rtf/RTFParserConstants.java Sat Jul 19 03:53:50 2008
@@ -4,31 +4,54 @@
public interface RTFParserConstants {
int EOF = 0;
- int BACKSLASH = 1;
- int OPEN_BRACE = 5;
- int CLOSE_BRACE = 6;
- int TEXT = 7;
- int RTF = 12;
- int FONTTBL = 13;
- int STYLESHEET = 14;
- int INFO = 15;
- int B = 16;
- int I = 17;
- int UL = 18;
- int IGNORED_DESTINATION = 19;
- int CONTROL_WORD = 20;
- int CONTROL_SYMBOL = 21;
- int PARAM = 22;
+ int IGNORED_DESTINATION = 4;
+ int ESCAPED_OPEN_BRACE = 5;
+ int ESCAPED_CLOSE_BRACE = 6;
+ int ESCAPED_BACKSLASH = 7;
+ int CONTROL_SYMBOL = 8;
+ int HEX_DIGIT = 9;
+ int HEX_CHAR = 10;
+ int BACKSLASH = 11;
+ int OPEN_BRACE = 12;
+ int CLOSE_BRACE = 13;
+ int TEXT = 14;
+ int RTF = 19;
+ int ANSI = 20;
+ int MAC = 21;
+ int PC = 22;
+ int PCA = 23;
+ int ANSICPG = 24;
+ int UC = 25;
+ int U = 26;
+ int UPR = 27;
+ int UD = 28;
+ int FONTTBL = 29;
+ int COLORTBL = 30;
+ int STYLESHEET = 31;
+ int INFO = 32;
+ int B = 33;
+ int I = 34;
+ int UL = 35;
+ int PAR = 36;
+ int CONTROL_WORD = 37;
+ int PARAM = 38;
- int IN_CONTROL = 0;
- int DEFAULT = 1;
+ int DEFAULT = 0;
+ int IN_CONTROL_WORD = 1;
String[] tokenImage = {
"<EOF>",
- "\"\\\\\"",
"\"\\n\"",
"\"\\r\"",
"\"\\t\"",
+ "\"\\\\*\"",
+ "\"\\\\{\"",
+ "\"\\\\}\"",
+ "\"\\\\\\\\\"",
+ "<CONTROL_SYMBOL>",
+ "<HEX_DIGIT>",
+ "<HEX_CHAR>",
+ "\"\\\\\"",
"\"{\"",
"\"}\"",
"<TEXT>",
@@ -37,17 +60,26 @@
"\"\\r\"",
"\"\\t\"",
"\"rtf\"",
+ "\"ansi\"",
+ "\"mac\"",
+ "\"pc\"",
+ "\"pca\"",
+ "\"ansicpg\"",
+ "\"uc\"",
+ "\"u\"",
+ "\"upr\"",
+ "\"ud\"",
"\"fonttbl\"",
+ "\"colortbl\"",
"\"stylesheet\"",
"\"info\"",
"\"b\"",
"\"i\"",
"\"ul\"",
- "\"*\"",
+ "\"par\"",
"<CONTROL_WORD>",
- "<CONTROL_SYMBOL>",
"<PARAM>",
- "<token of kind 23>",
+ "<token of kind 39>",
};
}