001: /*
002:
003: Licensed to the Apache Software Foundation (ASF) under one or more
004: contributor license agreements. See the NOTICE file distributed with
005: this work for additional information regarding copyright ownership.
006: The ASF licenses this file to You under the Apache License, Version 2.0
007: (the "License"); you may not use this file except in compliance with
008: the License. You may obtain a copy of the License at
009:
010: http://www.apache.org/licenses/LICENSE-2.0
011:
012: Unless required by applicable law or agreed to in writing, software
013: distributed under the License is distributed on an "AS IS" BASIS,
014: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: See the License for the specific language governing permissions and
016: limitations under the License.
017:
018: */
019: package org.apache.batik.parser;
020:
021: import java.io.IOException;
022:
023: /**
024: * This class implements an event-based parser for the SVG length
025: * values.
026: *
027: * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
028: * @version $Id: LengthParser.java 502167 2007-02-01 09:26:51Z dvholten $
029: */
030: public class LengthParser extends AbstractParser {
031:
032: /**
033: * The length handler used to report parse events.
034: */
035: protected LengthHandler lengthHandler;
036:
037: /**
038: * Creates a new LengthParser.
039: */
040: public LengthParser() {
041: lengthHandler = DefaultLengthHandler.INSTANCE;
042: }
043:
044: /**
045: * Allows an application to register a length handler.
046: *
047: * <p>If the application does not register a handler, all
048: * events reported by the parser will be silently ignored.
049: *
050: * <p>Applications may register a new or different handler in the
051: * middle of a parse, and the parser must begin using the new
052: * handler immediately.</p>
053: * @param handler The transform list handler.
054: */
055: public void setLengthHandler(LengthHandler handler) {
056: lengthHandler = handler;
057: }
058:
059: /**
060: * Returns the length handler in use.
061: */
062: public LengthHandler getLengthHandler() {
063: return lengthHandler;
064: }
065:
066: protected void doParse() throws ParseException, IOException {
067: lengthHandler.startLength();
068:
069: current = reader.read();
070: skipSpaces();
071:
072: parseLength();
073:
074: skipSpaces();
075: if (current != -1) {
076: reportError("end.of.stream.expected",
077: new Object[] { new Integer(current) });
078: }
079: lengthHandler.endLength();
080: }
081:
082: /**
083: * Parses a length value.
084: */
085: protected void parseLength() throws ParseException, IOException {
086: int mant = 0;
087: int mantDig = 0;
088: boolean mantPos = true;
089: boolean mantRead = false;
090:
091: int exp = 0;
092: int expDig = 0;
093: int expAdj = 0;
094: boolean expPos = true;
095:
096: int unitState = 0;
097:
098: switch (current) {
099: case '-':
100: mantPos = false;
101: case '+':
102: current = reader.read();
103: }
104:
105: m1: switch (current) {
106: default:
107: reportUnexpectedCharacterError(current);
108: return;
109:
110: case '.':
111: break;
112:
113: case '0':
114: mantRead = true;
115: l: for (;;) {
116: current = reader.read();
117: switch (current) {
118: case '1':
119: case '2':
120: case '3':
121: case '4':
122: case '5':
123: case '6':
124: case '7':
125: case '8':
126: case '9':
127: break l;
128: default:
129: break m1;
130: case '0':
131: }
132: }
133:
134: case '1':
135: case '2':
136: case '3':
137: case '4':
138: case '5':
139: case '6':
140: case '7':
141: case '8':
142: case '9':
143: mantRead = true;
144: l: for (;;) {
145: if (mantDig < 9) {
146: mantDig++;
147: mant = mant * 10 + (current - '0');
148: } else {
149: expAdj++;
150: }
151: current = reader.read();
152: switch (current) {
153: default:
154: break l;
155: case '0':
156: case '1':
157: case '2':
158: case '3':
159: case '4':
160: case '5':
161: case '6':
162: case '7':
163: case '8':
164: case '9':
165: }
166: }
167: }
168:
169: if (current == '.') {
170: current = reader.read();
171: m2: switch (current) {
172: default:
173: case 'e':
174: case 'E':
175: if (!mantRead) {
176: reportUnexpectedCharacterError(current);
177: return;
178: }
179: break;
180:
181: case '0':
182: if (mantDig == 0) {
183: l: for (;;) {
184: current = reader.read();
185: expAdj--;
186: switch (current) {
187: case '1':
188: case '2':
189: case '3':
190: case '4':
191: case '5':
192: case '6':
193: case '7':
194: case '8':
195: case '9':
196: break l;
197: default:
198: break m2;
199: case '0':
200: }
201: }
202: }
203: case '1':
204: case '2':
205: case '3':
206: case '4':
207: case '5':
208: case '6':
209: case '7':
210: case '8':
211: case '9':
212: l: for (;;) {
213: if (mantDig < 9) {
214: mantDig++;
215: mant = mant * 10 + (current - '0');
216: expAdj--;
217: }
218: current = reader.read();
219: switch (current) {
220: default:
221: break l;
222: case '0':
223: case '1':
224: case '2':
225: case '3':
226: case '4':
227: case '5':
228: case '6':
229: case '7':
230: case '8':
231: case '9':
232: }
233: }
234: }
235: }
236:
237: boolean le = false;
238: es: switch (current) {
239: case 'e':
240: le = true;
241: case 'E':
242: current = reader.read();
243: switch (current) {
244: default:
245: reportUnexpectedCharacterError(current);
246: return;
247: case 'm':
248: if (!le) {
249: reportUnexpectedCharacterError(current);
250: return;
251: }
252: unitState = 1;
253: break es;
254: case 'x':
255: if (!le) {
256: reportUnexpectedCharacterError(current);
257: return;
258: }
259: unitState = 2;
260: break es;
261: case '-':
262: expPos = false;
263: case '+':
264: current = reader.read();
265: switch (current) {
266: default:
267: reportUnexpectedCharacterError(current);
268: return;
269: case '0':
270: case '1':
271: case '2':
272: case '3':
273: case '4':
274: case '5':
275: case '6':
276: case '7':
277: case '8':
278: case '9':
279: }
280: case '0':
281: case '1':
282: case '2':
283: case '3':
284: case '4':
285: case '5':
286: case '6':
287: case '7':
288: case '8':
289: case '9':
290: }
291:
292: en: switch (current) {
293: case '0':
294: l: for (;;) {
295: current = reader.read();
296: switch (current) {
297: case '1':
298: case '2':
299: case '3':
300: case '4':
301: case '5':
302: case '6':
303: case '7':
304: case '8':
305: case '9':
306: break l;
307: default:
308: break en;
309: case '0':
310: }
311: }
312:
313: case '1':
314: case '2':
315: case '3':
316: case '4':
317: case '5':
318: case '6':
319: case '7':
320: case '8':
321: case '9':
322: l: for (;;) {
323: if (expDig < 3) {
324: expDig++;
325: exp = exp * 10 + (current - '0');
326: }
327: current = reader.read();
328: switch (current) {
329: default:
330: break l;
331: case '0':
332: case '1':
333: case '2':
334: case '3':
335: case '4':
336: case '5':
337: case '6':
338: case '7':
339: case '8':
340: case '9':
341: }
342: }
343: }
344: default:
345: }
346:
347: if (!expPos) {
348: exp = -exp;
349: }
350: exp += expAdj;
351: if (!mantPos) {
352: mant = -mant;
353: }
354:
355: lengthHandler.lengthValue(NumberParser.buildFloat(mant, exp));
356:
357: switch (unitState) {
358: case 1:
359: lengthHandler.em();
360: current = reader.read();
361: return;
362: case 2:
363: lengthHandler.ex();
364: current = reader.read();
365: return;
366: }
367:
368: switch (current) {
369: case 'e':
370: current = reader.read();
371: switch (current) {
372: case 'm':
373: lengthHandler.em();
374: current = reader.read();
375: break;
376: case 'x':
377: lengthHandler.ex();
378: current = reader.read();
379: break;
380: default:
381: reportUnexpectedCharacterError(current);
382: }
383: break;
384:
385: case 'p':
386: current = reader.read();
387: switch (current) {
388: case 'c':
389: lengthHandler.pc();
390: current = reader.read();
391: break;
392: case 't':
393: lengthHandler.pt();
394: current = reader.read();
395: break;
396: case 'x':
397: lengthHandler.px();
398: current = reader.read();
399: break;
400: default:
401: reportUnexpectedCharacterError(current);
402: }
403: break;
404:
405: case 'i':
406: current = reader.read();
407: if (current != 'n') {
408: reportCharacterExpectedError('n', current);
409: break;
410: }
411: lengthHandler.in();
412: current = reader.read();
413: break;
414: case 'c':
415: current = reader.read();
416: if (current != 'm') {
417: reportCharacterExpectedError('m', current);
418: break;
419: }
420: lengthHandler.cm();
421: current = reader.read();
422: break;
423: case 'm':
424: current = reader.read();
425: if (current != 'm') {
426: reportCharacterExpectedError('m', current);
427: break;
428: }
429: lengthHandler.mm();
430: current = reader.read();
431: break;
432: case '%':
433: lengthHandler.percentage();
434: current = reader.read();
435: break;
436: }
437: }
438: }
|