001: /*
002: *
003: *
004: * Portions Copyright 2000-2007 Sun Microsystems, Inc. All Rights
005: * Reserved. Use is subject to license terms.
006: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
007: *
008: * This program is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU General Public License version
010: * 2 only, as published by the Free Software Foundation.
011: *
012: * This program is distributed in the hope that it will be useful, but
013: * WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * General Public License version 2 for more details (a copy is
016: * included at /legal/license.txt).
017: *
018: * You should have received a copy of the GNU General Public License
019: * version 2 along with this work; if not, write to the Free Software
020: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
021: * 02110-1301 USA
022: *
023: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
024: * Clara, CA 95054 or visit www.sun.com if you need additional
025: * information or have any questions.
026: */
027:
028: /*****************************************************************************
029: * Copyright (C) The Apache Software Foundation. All rights reserved. *
030: * ------------------------------------------------------------------------- *
031: * This software is published under the terms of the Apache Software License *
032: * version 1.1, a copy of which has been included with this distribution in *
033: * the LICENSE file. *
034: *****************************************************************************/package com.sun.perseus.parser;
035:
036: /**
037: * Parser for SVG Length values
038: *
039: * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
040: * @version $Id: LengthParser.java,v 1.2 2006/04/21 06:40:30 st125089 Exp $
041: */
042: public class LengthParser extends NumberParser {
043: /**
044: * Parses a length value. This method throws an
045: * <code>IllegalArgumentException</code> if the input argument's
046: * syntax does not conform to that of a length value, as defined
047: * by the CSS 2 specification.
048: *
049: * @param s the value to convert to a <code>Length</code> object.
050: * @return <code>Length</code> corresponding to the input argument.
051: */
052: public Length parseLength(final String s) {
053: setString(s);
054:
055: int mant = 0;
056: int mantDig = 0;
057: boolean mantPos = true;
058: boolean mantRead = false;
059:
060: int exp = 0;
061: int expDig = 0;
062: int expAdj = 0;
063: boolean expPos = true;
064:
065: int unitState = 0;
066:
067: current = read();
068: Length val = new Length();
069:
070: switch (current) {
071: case '-':
072: mantPos = false;
073: case '+':
074: current = read();
075: default:
076: // nothing, see next switch
077: }
078:
079: m1: switch (current) {
080: default:
081: throw new IllegalArgumentException();
082:
083: case '.':
084: break;
085:
086: case '0':
087: mantRead = true;
088: l: for (;;) {
089: current = read();
090: switch (current) {
091: case '1':
092: case '2':
093: case '3':
094: case '4':
095: case '5':
096: case '6':
097: case '7':
098: case '8':
099: case '9':
100: break l;
101: default:
102: break m1;
103: case '0':
104: }
105: }
106:
107: case '1':
108: case '2':
109: case '3':
110: case '4':
111: case '5':
112: case '6':
113: case '7':
114: case '8':
115: case '9':
116: mantRead = true;
117: l: for (;;) {
118: if (mantDig < 9) {
119: mantDig++;
120: mant = mant * 10 + (current - '0');
121: } else {
122: expAdj++;
123: }
124: current = read();
125: switch (current) {
126: default:
127: break l;
128: case '0':
129: case '1':
130: case '2':
131: case '3':
132: case '4':
133: case '5':
134: case '6':
135: case '7':
136: case '8':
137: case '9':
138: }
139: }
140: }
141:
142: if (current == '.') {
143: current = read();
144: m2: switch (current) {
145: default:
146: case 'e':
147: case 'E':
148: if (!mantRead) {
149: throw new IllegalArgumentException();
150: }
151: break;
152:
153: case '0':
154: if (mantDig == 0) {
155: l: for (;;) {
156: current = read();
157: expAdj--;
158: switch (current) {
159: case '1':
160: case '2':
161: case '3':
162: case '4':
163: case '5':
164: case '6':
165: case '7':
166: case '8':
167: case '9':
168: break l;
169: default:
170: break m2;
171: case '0':
172: }
173: }
174: }
175: case '1':
176: case '2':
177: case '3':
178: case '4':
179: case '5':
180: case '6':
181: case '7':
182: case '8':
183: case '9':
184: l: for (;;) {
185: if (mantDig < 9) {
186: mantDig++;
187: mant = mant * 10 + (current - '0');
188: expAdj--;
189: }
190: current = read();
191: switch (current) {
192: default:
193: break l;
194: case '0':
195: case '1':
196: case '2':
197: case '3':
198: case '4':
199: case '5':
200: case '6':
201: case '7':
202: case '8':
203: case '9':
204: }
205: }
206: }
207: }
208:
209: boolean le = false;
210: es: switch (current) {
211: case 'e':
212: le = true;
213: case 'E':
214: current = read();
215: switch (current) {
216: default:
217: throw new IllegalArgumentException();
218: case '-':
219: expPos = false;
220: case '+':
221: current = read();
222: switch (current) {
223: default:
224: throw new IllegalArgumentException();
225: case '0':
226: case '1':
227: case '2':
228: case '3':
229: case '4':
230: case '5':
231: case '6':
232: case '7':
233: case '8':
234: case '9':
235: }
236: case '0':
237: case '1':
238: case '2':
239: case '3':
240: case '4':
241: case '5':
242: case '6':
243: case '7':
244: case '8':
245: case '9':
246: }
247:
248: en: switch (current) {
249: case '0':
250: l: for (;;) {
251: current = read();
252: switch (current) {
253: case '1':
254: case '2':
255: case '3':
256: case '4':
257: case '5':
258: case '6':
259: case '7':
260: case '8':
261: case '9':
262: break l;
263: default:
264: break en;
265: case '0':
266: }
267: }
268:
269: case '1':
270: case '2':
271: case '3':
272: case '4':
273: case '5':
274: case '6':
275: case '7':
276: case '8':
277: case '9':
278: l: for (;;) {
279: if (expDig < 3) {
280: expDig++;
281: exp = exp * 10 + (current - '0');
282: }
283: current = read();
284: switch (current) {
285: default:
286: break l;
287: case '0':
288: case '1':
289: case '2':
290: case '3':
291: case '4':
292: case '5':
293: case '6':
294: case '7':
295: case '8':
296: case '9':
297: }
298: }
299: }
300: default:
301: }
302:
303: if (!expPos) {
304: exp = -exp;
305: }
306: exp += expAdj;
307: if (!mantPos) {
308: mant = -mant;
309: }
310:
311: val.value = NumberParser.buildFloat(mant, exp);
312:
313: switch (current) {
314: case 'p':
315: current = read();
316: switch (current) {
317: case 'c':
318: val.unit = val.SVG_LENGTHTYPE_PC;
319: current = read();
320: break;
321: case 't':
322: val.unit = val.SVG_LENGTHTYPE_PT;
323: current = read();
324: break;
325: default:
326: throw new IllegalArgumentException();
327: }
328: break;
329:
330: case 'i':
331: current = read();
332: if (current != 'n') {
333: throw new IllegalArgumentException();
334: }
335: val.unit = val.SVG_LENGTHTYPE_IN;
336: current = read();
337: break;
338: case 'c':
339: current = read();
340: if (current != 'm') {
341: throw new IllegalArgumentException();
342: }
343: val.unit = val.SVG_LENGTHTYPE_CM;
344: current = read();
345: break;
346: case 'm':
347: current = read();
348: if (current != 'm') {
349: throw new IllegalArgumentException();
350: }
351: val.unit = val.SVG_LENGTHTYPE_MM;
352: current = read();
353: break;
354: case '%':
355: val.unit = val.SVG_LENGTHTYPE_PERCENTAGE;
356: current = read();
357: break;
358: case -1:
359: val.unit = val.SVG_LENGTHTYPE_NUMBER;
360: current = read();
361: break;
362: default:
363: throw new IllegalArgumentException();
364: }
365:
366: if (current != -1) {
367: throw new IllegalArgumentException();
368: }
369:
370: return val;
371: }
372: }
|