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  	/*
59  	 * nomFichier repr?sente le nom du fichier ? lire
60  	 */
61  	public EfficientScanner(final InputStream input) {
62  		this.in = new BufferedInputStream(input, EfficientScanner.TAILLE_BUF);
63  	}
64  
65  	public void close() throws IOException {
66  		in.close();
67  	}
68  
69  	/** on passe les commentaires et on lit le nombre de literaux */
70  	public void skipComments() throws IOException {
71  		char currentChar;
72  		for (;;) {
73  			currentChar = currentChar();
74  			if (currentChar != 'c') {
75  				break;
76  			}
77  			skipRestOfLine();
78  			if (currentChar == EOF)
79  				break;
80  		}
81  	}
82  
83  	public int nextInt() throws IOException, ParseFormatException {
84  		int val = 0;
85  		boolean neg = false;
86  		char currentChar = skipSpaces();
87  		if (currentChar == '-') {
88  			neg = true;
89  			currentChar = (char) in.read();
90  		} else if (currentChar == '+') {
91  			currentChar = (char) in.read();
92  		} else if (currentChar >= '0' && currentChar <= '9') {
93  			val = currentChar - '0';
94  			currentChar = (char) in.read();
95  		} else {
96  			throw new ParseFormatException("Unknown character " + currentChar);
97  		}
98  		/* on lit la suite du literal */
99  		while (currentChar >= '0' && currentChar <= '9') {
100 			val = (val * 10) + currentChar - '0';
101 			currentChar = (char) in.read();
102 		}
103 		if (currentChar == '\r') {
104 			in.read(); // skip \r\n on windows.
105 		}
106 		return neg ? -val : val;
107 	}
108 
109 	public BigInteger nextBigInteger() throws IOException, ParseFormatException {
110 		StringBuffer stb = new StringBuffer();
111 		char currentChar = skipSpaces();
112 		if (currentChar == '-') {
113 			stb.append(currentChar);
114 			currentChar = (char) in.read();
115 		} else if (currentChar == '+') {
116 			currentChar = (char) in.read();
117 		} else if (currentChar >= '0' && currentChar <= '9') {
118 			stb.append(currentChar);
119 			currentChar = (char) in.read();
120 		} else {
121 			throw new ParseFormatException("Unknown character " + currentChar);
122 		}
123 		while (currentChar >= '0' && currentChar <= '9') {
124 			stb.append(currentChar);
125 			currentChar = (char) in.read();
126 		}
127 		return new BigInteger(stb.toString());
128 	}
129 
130 	public String next() throws IOException, ParseFormatException {
131 		StringBuffer stb = new StringBuffer();
132 		char currentChar = skipSpaces();
133 		while (currentChar != ' ' && currentChar != '\n') {
134 			stb.append(currentChar);
135 			currentChar = (char) in.read();
136 		}
137 		return stb.toString();
138 	}
139 
140 	public char skipSpaces() throws IOException {
141 		char car;
142 
143 		while ((car = (char) in.read()) == ' ' || car == '\n')
144 			;
145 		return car;
146 	}
147 
148 	public String nextLine() throws IOException {
149 		StringBuffer stb = new StringBuffer();
150 		char car;
151 		do {
152 			car = (char) in.read();
153 			stb.append(car);
154 		} while ((car != '\n') && (car != EOF));
155 		return stb.toString();
156 	}
157 
158 	public void skipRestOfLine() throws IOException {
159 		char car;
160 		do {
161 			car = (char) in.read();
162 		} while ((car != '\n') && (car != EOF));
163 	}
164 
165 	public boolean eof() throws IOException {
166 		return currentChar() == EOF;
167 	}
168 
169 	public char currentChar() throws IOException {
170 		in.mark(10);
171 		char car = (char) in.read();
172 		in.reset();
173 		return car;
174 	}
175 }