Save This Page
Home » openjdk-7 » javax » swing » text » rtf » [javadoc | source]
    1   /* RTFScanner.java --
    2      Copyright (C) 2005  Free Software Foundation, Inc.
    3   
    4   This file is part of GNU Classpath.
    5   
    6   GNU Classpath is free software; you can redistribute it and/or modify
    7   it under the terms of the GNU General Public License as published by
    8   the Free Software Foundation; either version 2, or (at your option)
    9   any later version.
   10   
   11   GNU Classpath is distributed in the hope that it will be useful, but
   12   WITHOUT ANY WARRANTY; without even the implied warranty of
   13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   14   General Public License for more details.
   15   
   16   You should have received a copy of the GNU General Public License
   17   along with GNU Classpath; see the file COPYING.  If not, write to the
   18   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
   19   02110-1301 USA.
   20   
   21   Linking this library statically or dynamically with other modules is
   22   making a combined work based on this library.  Thus, the terms and
   23   conditions of the GNU General Public License cover the whole
   24   combination.
   25   
   26   As a special exception, the copyright holders of this library give you
   27   permission to link this library with independent modules to produce an
   28   executable, regardless of the license terms of these independent
   29   modules, and to copy and distribute the resulting executable under
   30   terms of your choice, provided that you also meet, for each linked
   31   independent module, the terms and conditions of the license of that
   32   module.  An independent module is a module which is not derived from
   33   or based on this library.  If you modify this library, you may extend
   34   this exception to your version of the library, but you are not
   35   obligated to do so.  If you do not wish to do so, delete this
   36   exception statement from your version. */
   37   
   38   
   39   package javax.swing.text.rtf;
   40   
   41   import java.io.BufferedReader;
   42   import java.io.IOException;
   43   import java.io.InputStream;
   44   import java.io.InputStreamReader;
   45   import java.io.Reader;
   46   
   47   /**
   48    * Provides a scanner that scans an {@link InputStream} for tokens of the
   49    * RTF syntax.
   50    *
   51    * This scanner is based upon the RTF specification 1.6
   52    * available at:
   53    * 
   54    * <a
   55    * href="http://msdn.microsoft.com/library/en-us/dnrtfspec/html/rtfspec.asp">
   56    * RTF specification at MSDN</a>
   57    *
   58    * @author Roman Kennke (roman@ontographics.com)
   59    */
   60   class RTFScanner
   61   {
   62   
   63     /**
   64      * The reader from which we read the RTF data.
   65      */
   66     private Reader in;
   67   
   68     /**
   69      * This is used to constuct strings from the read in chars.
   70      */
   71     private StringBuffer buffer;
   72   
   73     /**
   74      * Constructs a new RTFScanner without initializing the {@link Reader}.
   75      */
   76     private RTFScanner()
   77     {
   78       buffer = new StringBuffer();
   79     }
   80   
   81     /**
   82      * Constructs a new RTFScanner for the given {@link InputStream}.
   83      * The stream is wrapped into an {@link InputStreamReader} and if it's
   84      * not yet buffered then the Reader is wrapped in a {@link BufferedReader}
   85      *
   86      * @param stream the {@link InputStream} to read RTF data from
   87      */
   88     public RTFScanner(InputStream stream)
   89     {
   90       this();
   91       InputStreamReader reader = new InputStreamReader(stream);
   92       in = new BufferedReader(reader);
   93     }
   94   
   95     /**
   96      * Constructs a new RTFScanner for the given {@link Reader}.
   97      *
   98      * If the reader is not an instance of {@link BufferedReader} then it
   99      * is wrapped into a BufferedReader.
  100      *
  101      * @param reader the {@link BufferedReader} to read RTF data from
  102      */
  103     public RTFScanner(Reader reader)
  104     {
  105       this();
  106       if (reader instanceof BufferedReader)
  107         {
  108           in = reader;
  109         }
  110       else
  111         {
  112           in = new BufferedReader(reader);
  113         }
  114     }
  115   
  116     /**
  117      * Reads in the next {@link Token} from the stream.
  118      *
  119      * @return the read {@link Token}
  120      *
  121      * @throws IOException if the underlying stream has problems
  122      */
  123     public Token readToken()
  124       throws IOException
  125     {
  126       Token token = null;
  127   
  128       int c = in.read();
  129       switch(c)
  130         {
  131         case -1:
  132           token = new Token(Token.EOF);
  133           break;
  134   
  135         case '{':
  136           token = new Token(Token.LCURLY);
  137           break;
  138   
  139         case '}':
  140           token = new Token(Token.RCURLY);
  141           break;
  142   
  143         case '\\':
  144           buffer.delete(0, buffer.length());
  145           buffer.append((char) c);
  146           token = readControlWord();
  147           break;
  148   
  149         default:
  150           buffer.delete(0, buffer.length());
  151           buffer.append((char) c);
  152           token = readText();
  153           break;
  154         }
  155   
  156       return token;
  157     }
  158   
  159     /**
  160      * Reads in a control word and optional parameter.
  161      *
  162      * @return the read in control word as {@link ControlWordToken}
  163      *
  164      * @throws IOException if the underlying stream has problems
  165      */
  166     private Token readControlWord()
  167       throws IOException
  168     {
  169       // this flag indicates if we are still reading the name or are already
  170       // in the parameter
  171       boolean readingName = true;
  172       String name = null;
  173       String param = null;
  174   
  175       while (true)
  176         {
  177           in.mark(1);
  178           int c = in.read();
  179   
  180           // check for 'a'..'z'
  181           if (readingName && (c >= 'a') && (c <= 'z'))
  182             {
  183               buffer.append((char) c);
  184             }
  185           else if ((c >= '0') && (c <= '9'))
  186             {
  187               // if the last char was in the name, then finish reading the name
  188               if (readingName)
  189                 {
  190                   name = buffer.toString();
  191                   buffer.delete(0, buffer.length());
  192                   readingName = false;
  193                 }
  194               buffer.append((char) c);
  195             }
  196           else
  197             {
  198               // if we were in the name, then finish this
  199               if (readingName)
  200                 {
  201                   name = buffer.toString();
  202                 }
  203               // otherwise finish the parameter
  204               else
  205                 {
  206                   param = buffer.toString();
  207                 }
  208   
  209               // clear up
  210               buffer.delete(0, buffer.length());
  211               // reset input buffer to last char
  212               in.reset();
  213               // break while loop
  214               break;
  215             }
  216         }
  217   
  218       ControlWordToken token = null;
  219   
  220       if (param == null)
  221         token = new ControlWordToken(name);
  222       else
  223         token =new ControlWordToken(name, Integer.parseInt(param));
  224   
  225       return token;
  226   
  227     }
  228   
  229     /**
  230      * Reads in a block of text.
  231      *
  232      * @return the token for the text
  233      */
  234     private Token readText()
  235       throws IOException
  236     {
  237   
  238       boolean readingText = true;
  239       while (readingText)
  240         {
  241           in.mark(1);
  242           int c = in.read();
  243           switch(c)
  244             {
  245             case '\\':
  246             case '{':
  247             case '}':
  248             case -1:
  249               readingText = false;
  250               in.reset();
  251               break;
  252   
  253             default:
  254               buffer.append((char) c);
  255               break;
  256             }
  257   
  258         }
  259   
  260       String text = buffer.toString();
  261       Token token = new TextToken(text);
  262   
  263       buffer.delete(0, buffer.length());
  264   
  265       return token;
  266   
  267     }
  268   }

Save This Page
Home » openjdk-7 » javax » swing » text » rtf » [javadoc | source]