View Javadoc

1   /*******************************************************************************
2    * SAT4J: a SATisfiability library for Java Copyright (C) 2004-2008 Daniel Le Berre
3    *
4    * All rights reserved. This program and the accompanying materials
5    * are made available under the terms of the Eclipse Public License v1.0
6    * which accompanies this distribution, and is available at
7    * http://www.eclipse.org/legal/epl-v10.html
8    *
9    * Alternatively, the contents of this file may be used under the terms of
10   * either the GNU Lesser General Public License Version 2.1 or later (the
11   * "LGPL"), in which case the provisions of the LGPL are applicable instead
12   * of those above. If you wish to allow use of your version of this file only
13   * under the terms of the LGPL, and not to allow others to use your version of
14   * this file under the terms of the EPL, indicate your decision by deleting
15   * the provisions above and replace them with the notice and other provisions
16   * required by the LGPL. If you do not delete the provisions above, a recipient
17   * may use your version of this file under the terms of the EPL or the LGPL.
18   * 
19   * Based on the original MiniSat specification from:
20   * 
21   * An extensible SAT solver. Niklas Een and Niklas Sorensson. Proceedings of the
22   * Sixth International Conference on Theory and Applications of Satisfiability
23   * Testing, LNCS 2919, pp 502-518, 2003.
24   *
25   * See www.minisat.se for the original solver in C++.
26   * 
27   *******************************************************************************/
28  package org.sat4j.reader;
29  
30  import java.io.BufferedInputStream;
31  import java.io.IOException;
32  import java.io.InputStream;
33  import java.io.Serializable;
34  import java.math.BigInteger;
35  
36  /**
37   * Efficient scanner based on the LecteurDimacs class written by Frederic
38   * Laihem. It is much faster than Java Scanner class because it does not split
39   * the input file into strings but reads and interpret the input char by char.
40   * Furthermore, it is based on stream (char in ASCII) and not reader (word in
41   * UTF).
42   * 
43   * @author laihem
44   * @author leberre
45   * @since 2.1
46   */
47  public class EfficientScanner implements Serializable {
48  
49  	private static final long serialVersionUID = 1L;
50  
51  	/* taille du buffer */
52  	private final static int TAILLE_BUF = 16384;
53  
54  	private transient final BufferedInputStream in;
55  
56  	private static final char EOF = (char) -1;
57  
58  	private final char commentChar;
59  
60  	/*
61  	 * nomFichier repr?sente le nom du fichier ? lire
62  	 */
63  	public EfficientScanner(final InputStream input, char commentChar) {
64  		this.in = new BufferedInputStream(input, EfficientScanner.TAILLE_BUF);
65  		this.commentChar = commentChar;
66  	}
67  
68  	public EfficientScanner(final InputStream input) {
69  		this(input, 'c');
70  	}
71  
72  	public void close() throws IOException {
73  		in.close();
74  	}
75  
76  	/** Skip commented lines. */
77  	public void skipComments() throws IOException {
78  		char currentChar;
79  		for (;;) {
80  			currentChar = currentChar();
81  			if (currentChar != commentChar) {
82  				break;
83  			}
84  			skipRestOfLine();
85  			if (currentChar == EOF)
86  				break;
87  		}
88  	}
89  
90  	/**
91  	 * To get the next available integer.
92  	 * 
93  	 * @return
94  	 * @throws IOException
95  	 * @throws ParseFormatException
96  	 */
97  	public int nextInt() throws IOException, ParseFormatException {
98  		int val = 0;
99  		boolean neg = false;
100 		char currentChar = skipSpaces();
101 		if (currentChar == '-') {
102 			neg = true;
103 			currentChar = (char) in.read();
104 		} else if (currentChar == '+') {
105 			currentChar = (char) in.read();
106 		} else if (currentChar >= '0' && currentChar <= '9') {
107 			val = currentChar - '0';
108 			currentChar = (char) in.read();
109 		} else {
110 			throw new ParseFormatException("Unknown character " + currentChar);
111 		}
112 		/* on lit la suite du literal */
113 		while (currentChar >= '0' && currentChar <= '9') {
114 			val = (val * 10) + currentChar - '0';
115 			currentChar = (char) in.read();
116 		}
117 		if (currentChar == '\r') {
118 			in.read(); // skip \r\n on windows.
119 		}
120 		return neg ? -val : val;
121 	}
122 
123 	public BigInteger nextBigInteger() throws IOException, ParseFormatException {
124 		StringBuffer stb = new StringBuffer();
125 		char currentChar = skipSpaces();
126 		if (currentChar == '-') {
127 			stb.append(currentChar);
128 			currentChar = (char) in.read();
129 		} else if (currentChar == '+') {
130 			currentChar = (char) in.read();
131 		} else if (currentChar >= '0' && currentChar <= '9') {
132 			stb.append(currentChar);
133 			currentChar = (char) in.read();
134 		} else {
135 			throw new ParseFormatException("Unknown character " + currentChar);
136 		}
137 		while (currentChar >= '0' && currentChar <= '9') {
138 			stb.append(currentChar);
139 			currentChar = (char) in.read();
140 		}
141 		return new BigInteger(stb.toString());
142 	}
143 
144 	/**
145 	 * @throws ParseFormatException
146 	 *             never used in that method.
147 	 */
148 	public String next() throws IOException, ParseFormatException {
149 		StringBuffer stb = new StringBuffer();
150 		char currentChar = skipSpaces();
151 		while (currentChar != ' ' && currentChar != '\n') {
152 			stb.append(currentChar);
153 			currentChar = (char) in.read();
154 		}
155 		return stb.toString();
156 	}
157 
158 	public char skipSpaces() throws IOException {
159 		char car;
160 
161 		do {
162 			car = (char) in.read();
163 		} while (car == ' ' || car == '\n');
164 
165 		return car;
166 	}
167 
168 	public String nextLine() throws IOException {
169 		StringBuffer stb = new StringBuffer();
170 		char car;
171 		do {
172 			car = (char) in.read();
173 			stb.append(car);
174 		} while ((car != '\n') && (car != EOF));
175 		return stb.toString();
176 	}
177 
178 	public void skipRestOfLine() throws IOException {
179 		char car;
180 		do {
181 			car = (char) in.read();
182 		} while ((car != '\n') && (car != EOF));
183 	}
184 
185 	public boolean eof() throws IOException {
186 		return currentChar() == EOF;
187 	}
188 
189 	public char currentChar() throws IOException {
190 		in.mark(10);
191 		char car = (char) in.read();
192 		in.reset();
193 		return car;
194 	}
195 }