4 * License : The MIT License
5 * Copyright(c) 2009 olyutorskii
8 package jp.sourceforge.jovsonz;
10 import java.io.Closeable;
11 import java.io.IOException;
12 import java.io.Reader;
13 import java.io.StringReader;
17 * 先読みした文字のプッシュバック機能と行番号のカウント機能を有する。
19 * 行と行はLF('\n')で区切られるものとする。(※CRは無視)
20 * @see java.io.PushbackReader
21 * @see java.io.LineNumberReader
23 class JsonSource implements Closeable {
26 private static final int PUSHBACK_TOKENS = 10;
28 private static final char LINEFEED = '\n'; // LF(0x0a)
30 private static final String ERRMSG_OVERFLOW =
31 "Pushback buffer overflow";
32 private static final String ERRMSG_CLOSED =
36 assert "\\uXXXX".length() < PUSHBACK_TOKENS;
39 private final Reader reader;
42 private final char[] charStack = new char[PUSHBACK_TOKENS];
43 private int stackPt = 0;
45 private int lineNumber = 1;
47 private boolean closed = false;
51 * @param reader 文字入力リーダー
52 * @throws NullPointerException 引数がnull
54 public JsonSource(Reader reader) throws NullPointerException{
56 if(reader == null) throw new NullPointerException();
65 * @see java.io.StringReader
67 public JsonSource(CharSequence text){
68 this(new StringReader(text.toString()));
73 * JSON規格のwhitespace文字を判定する。
75 * @return whitespaceならtrue
77 public static boolean isWhitespace(char ch){
91 * JSON規格のwhitespace文字を判定する。
93 * 上位16bitがゼロでなければwhitespaceと判定されない。
94 * @return whitespaceならtrue。引数が負の場合はfalse。
96 public static boolean isWhitespace(int ch){
97 if((int)Character.MIN_VALUE > ch) return false;
98 if((int)Character.MAX_VALUE < ch) return false;
99 return isWhitespace((char)ch);
103 * プッシュバック可能な残り文字数を返す。
104 * @return プッシュバック可能な残り文字数
106 public int getPushBackSpared(){
107 return PUSHBACK_TOKENS - this.stackPt;
114 public int getLineNumber(){
115 return this.lineNumber;
120 * @return 読み込んだ文字。入力が終わっている場合は負の値。
121 * @throws IOException 入力エラー
122 * @see java.io.Reader#read()
124 public int read() throws IOException{
125 if(this.closed) throw new IOException(ERRMSG_CLOSED);
128 if(this.stackPt > 0){
129 chData = (int) this.charStack[--this.stackPt];
131 chData = this.reader.read();
134 if(chData == (int)LINEFEED) this.lineNumber++;
140 * 入力末端ではないと仮定して1文字読み込む。
142 * @throws IOException 入力エラー
143 * @throws JsParseException 入力が終わっている
145 public char readOrDie() throws IOException, JsParseException{
148 throw new JsParseException(JsParseException.ERRMSG_NODATA,
157 * 長さ0の文字列は必ずマッチに成功する。
158 * @param seq マッチ対象文字列
160 * @throws IOException 入力エラー
161 * @throws JsParseException 入力が終わっている。
163 public boolean matchOrDie(CharSequence seq)
164 throws IOException, JsParseException{
165 int length = seq.length();
166 for(int pt = 0; pt < length; pt++){
167 if(readOrDie() != seq.charAt(pt)) return false;
176 * @throws IOException バッファあふれもしくはクローズ済み
178 public void unread(char ch) throws IOException{
179 if(this.closed) throw new IOException(ERRMSG_CLOSED);
181 if(this.stackPt >= PUSHBACK_TOKENS){
182 throw new IOException(ERRMSG_OVERFLOW);
185 this.charStack[this.stackPt++] = ch;
187 if(ch == LINEFEED) this.lineNumber--;
194 * char型にキャストした引数が次回読み込まれる。
196 * @param ch 読み戻す文字。負の符号を含む上位16bitは無視される。
197 * @throws IOException バッファあふれもしくはクローズ済み
199 public void unread(int ch) throws IOException{
205 * whitespace文字を読み飛ばす。
206 * @throws IOException 入力エラー
208 public void skipWhiteSpace() throws IOException{
211 if(chData < 0) break;
212 if( ! isWhitespace(chData) ){
222 * まだ読み込めるデータがあるか判定する。
223 * @return まだ読めるデータがあればtrue
224 * @throws IOException IO入力エラー
226 public boolean hasMore() throws IOException{
228 if(chData < 0) return false;
234 * コンストラクタで指定されたReaderを閉じる。
235 * クローズ後の読み込みおよび読み戻し動作は全て例外を投げる。
236 * @throws IOException 入出力エラー
237 * @see java.io.Closeable
239 public void close() throws IOException{