EMMA Coverage Report (generated Wed Aug 16 18:51:55 GMT 2006)
[all classes][javax.swing.text.rtf]

COVERAGE SUMMARY FOR SOURCE FILE [RTFScanner.java]

nameclass, %method, %block, %line, %
RTFScanner.java100% (1/1)63%  (5/8)37%  (101/270)41%  (30/74)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class RTFScanner100% (1/1)63%  (5/8)37%  (101/270)41%  (30/74)
RTFScanner (): void 100% (1/1)100% (8/8)100% (3/3)
RTFScanner (InputStream): void 0%   (0/1)0%   (0/14)0%   (0/4)
RTFScanner (Reader): void 100% (1/1)75%  (12/16)80%  (4/5)
peekToken (): Token 0%   (0/1)0%   (0/7)0%   (0/2)
readControlWord (): Token 0%   (0/1)0%   (0/101)0%   (0/25)
readText (): Token 100% (1/1)100% (46/46)100% (13/13)
readToken (): Token 100% (1/1)53%  (8/15)60%  (3/5)
readTokenImpl (): Token 100% (1/1)43%  (27/63)41%  (7/17)

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

[all classes][javax.swing.text.rtf]
EMMA 2.0.6427 (unsupported private build) (C) Vladimir Roubtsov