diff options
author | Carsten Weisse <[email protected]> | 2007-05-13 00:07:34 +0000 |
---|---|---|
committer | Carsten Weisse <[email protected]> | 2007-05-13 00:07:34 +0000 |
commit | 2604e81ac41dc1c13e7ddba81bc2823b6b9b3bb2 (patch) | |
tree | bfc890bb7f3a748de58dabe00d1b4db3bf7e1ad6 /src/jake2/client/LayoutParser.java | |
parent | fc9117c8cb946fed7fc99490c27499db0900d8b4 (diff) |
add a new layout string parser to minimize the String garbage
Diffstat (limited to 'src/jake2/client/LayoutParser.java')
-rw-r--r-- | src/jake2/client/LayoutParser.java | 236 |
1 files changed, 236 insertions, 0 deletions
diff --git a/src/jake2/client/LayoutParser.java b/src/jake2/client/LayoutParser.java new file mode 100644 index 0000000..61e2def --- /dev/null +++ b/src/jake2/client/LayoutParser.java @@ -0,0 +1,236 @@ +/* + * LayoutParser.java + * Copyright (C) 2003 + */ +/* + Copyright (C) 1997-2001 Id Software, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ +package jake2.client; + +import jake2.Defines; +import jake2.qcommon.Com; + +final class LayoutParser { + int tokenPos; + + int tokenLength; + + int index; + + int length; + + String data; + + LayoutParser() { + init(null); + } + + public void init(String layout) { + tokenPos = 0; + tokenLength = 0; + index = 0; + data = (layout != null) ? layout : ""; + length = (layout != null) ? layout.length() : 0; + } + + public boolean hasNext() { + return !isEof(); + } + + public void next() { + if (data == null) { + tokenLength = 0; + return; + } + + while (true) { + // skip whitespace + skipwhites(); + if (isEof()) { + tokenLength = 0; + return; + } + + // skip // comments + if (getchar() == '/') { + if (nextchar() == '/') { + skiptoeol(); + // goto skip whitespace + continue; + } else { + prevchar(); + break; + } + } else + break; + } + + int c; + int len = 0; + // handle quoted strings specially + if (getchar() == '\"') { + nextchar(); + tokenPos = index; + while (true) { + c = getchar(); + nextchar(); + if (c == '\"' || c == 0) { + tokenLength = len; + return; + } + if (len < Defines.MAX_TOKEN_CHARS) { + ++len; + } + } + } + + // parse a regular word + c = getchar(); + tokenPos = index; + do { + if (len < Defines.MAX_TOKEN_CHARS) { + ++len; + } + c = nextchar(); + } while (c > 32); + + if (len == Defines.MAX_TOKEN_CHARS) { + Com.Printf("Token exceeded " + Defines.MAX_TOKEN_CHARS + + " chars, discarded.\n"); + len = 0; + } + + tokenLength = len; + return; + } + + public boolean tokenEquals(String other) { + if (tokenLength != other.length()) + return false; + return data.regionMatches(tokenPos, other, 0, tokenLength); + } + + public int tokenAsInt() { + if (tokenLength == 0) + return 0; + return atoi(); + } + + public String token() { + if (tokenLength == 0) + return ""; + return data.substring(tokenPos, tokenPos + tokenLength); + } + + private int atoi() { + int result = 0; + boolean negative = false; + int i = 0, max = tokenLength; + String s = data; + int limit; + int multmin; + int digit; + + if (max > 0) { + if (s.charAt(tokenPos) == '-') { + negative = true; + limit = Integer.MIN_VALUE; + i++; + } else { + limit = -Integer.MAX_VALUE; + } + multmin = limit / 10; + if (i < max) { + digit = Character.digit(s.charAt(tokenPos + i++), 10); + if (digit < 0) { + return 0; // wrong format + } else { + result = -digit; + } + } + while (i < max) { + // Accumulating negatively avoids surprises near MAX_VALUE + digit = Character.digit(s.charAt(tokenPos + i++), 10); + if (digit < 0) { + return 0; // wrong format + } + if (result < multmin) { + return 0; // wrong format + } + result *= 10; + if (result < limit + digit) { + return 0; // wrong format + } + result -= digit; + } + } else { + return 0; // wrong format + } + if (negative) { + if (i > 1) { + return result; + } else { /* Only got "-" */ + return 0; // wrong format + } + } else { + return -result; + } + } + + private char getchar() { + if (index < length) { + return data.charAt(index); + } + return 0; + } + + private char nextchar() { + ++index; + if (index < length) { + return data.charAt(index); + } + return 0; + } + + private char prevchar() { + if (index > 0) { + --index; + return data.charAt(index); + } + return 0; + } + + private boolean isEof() { + return index >= length; + } + + private char skipwhites() { + char c = 0; + while (index < length && ((c = data.charAt(index)) <= ' ') && c != 0) + ++index; + return c; + } + + private char skiptoeol() { + char c = 0; + while (index < length && (c = data.charAt(index)) != '\n' && c != 0) + ++index; + return c; + } +} |