View Javadoc

1   /*******************************************************************************
2    * SAT4J: a SATisfiability library for Java Copyright (C) 2004, 2012 Artois University and CNRS
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   * Contributors:
28   *   CRIL - initial API and implementation
29   *******************************************************************************/
30  package org.sat4j.reader;
31  
32  import java.io.BufferedInputStream;
33  import java.io.IOException;
34  import java.io.InputStream;
35  import java.io.Serializable;
36  import java.math.BigInteger;
37  
38  /**
39   * Efficient scanner based on the LecteurDimacs class written by Frederic
40   * Laihem. It is much faster than Java Scanner class because it does not split
41   * the input file into strings but reads and interpret the input char by char.
42   * Furthermore, it is based on stream (char in ASCII) and not reader (word in
43   * UTF).
44   * 
45   * @author laihem
46   * @author leberre
47   * @since 2.1
48   */
49  public class EfficientScanner implements Serializable {
50  
51      private static final long serialVersionUID = 1L;
52  
53      /* taille du buffer */
54      private static final int TAILLE_BUF = 16384;
55  
56      private final transient BufferedInputStream in;
57  
58      private static final char EOF = (char) -1;
59  
60      private final char commentChar;
61  
62      /*
63       * nomFichier repr?sente le nom du fichier ? lire
64       */
65      public EfficientScanner(final InputStream input, char commentChar) {
66          this.in = new BufferedInputStream(input, EfficientScanner.TAILLE_BUF);
67          this.commentChar = commentChar;
68      }
69  
70      public EfficientScanner(final InputStream input) {
71          this(input, 'c');
72      }
73  
74      public void close() throws IOException {
75          this.in.close();
76      }
77  
78      /** Skip commented lines. */
79      public void skipComments() throws IOException {
80          char currentChar;
81          for (;;) {
82              currentChar = currentChar();
83              if (currentChar != this.commentChar) {
84                  break;
85              }
86              skipRestOfLine();
87              if (currentChar == EOF) {
88                  break;
89              }
90          }
91      }
92  
93      /**
94       * To get the next available integer.
95       * 
96       * @return
97       * @throws IOException
98       * @throws ParseFormatException
99       */
100     public int nextInt() throws IOException, ParseFormatException {
101         int val = 0;
102         boolean neg = false;
103         char currentChar = skipSpaces();
104         if (currentChar == '-') {
105             neg = true;
106             currentChar = (char) this.in.read();
107         } else if (currentChar == '+') {
108             currentChar = (char) this.in.read();
109         } else if (currentChar >= '0' && currentChar <= '9') {
110             val = currentChar - '0';
111             currentChar = (char) this.in.read();
112         } else {
113             throw new ParseFormatException("Unknown character " + currentChar);
114         }
115         /* on lit la suite du literal */
116         while (currentChar >= '0' && currentChar <= '9') {
117             val = val * 10 + currentChar - '0';
118             currentChar = (char) this.in.read();
119         }
120         if (currentChar == '\r') {
121             this.in.read(); // skip \r\n on windows.
122         }
123         return neg ? -val : val;
124     }
125 
126     public BigInteger nextBigInteger() throws IOException, ParseFormatException {
127         StringBuffer stb = new StringBuffer();
128         char currentChar = skipSpaces();
129         if (currentChar == '-') {
130             stb.append(currentChar);
131             currentChar = (char) this.in.read();
132         } else if (currentChar == '+') {
133             currentChar = (char) this.in.read();
134         } else if (currentChar >= '0' && currentChar <= '9') {
135             stb.append(currentChar);
136             currentChar = (char) this.in.read();
137         } else {
138             throw new ParseFormatException("Unknown character " + currentChar);
139         }
140         while (currentChar >= '0' && currentChar <= '9') {
141             stb.append(currentChar);
142             currentChar = (char) this.in.read();
143         }
144         return new BigInteger(stb.toString());
145     }
146 
147     /**
148      * @throws ParseFormatException
149      *             never used in that method.
150      */
151     public String next() throws IOException, ParseFormatException {
152         StringBuffer stb = new StringBuffer();
153         char currentChar = skipSpaces();
154         while (currentChar != ' ' && currentChar != '\n') {
155             stb.append(currentChar);
156             currentChar = (char) this.in.read();
157         }
158         return stb.toString();
159     }
160 
161     public char skipSpaces() throws IOException {
162         char car;
163 
164         do {
165             car = (char) this.in.read();
166         } while (car == ' ' || car == '\n');
167 
168         return car;
169     }
170 
171     public String nextLine() throws IOException {
172         StringBuffer stb = new StringBuffer();
173         char car;
174         do {
175             car = (char) this.in.read();
176             stb.append(car);
177         } while (car != '\n' && car != EOF);
178         return stb.toString();
179     }
180 
181     public void skipRestOfLine() throws IOException {
182         char car;
183         do {
184             car = (char) this.in.read();
185         } while (car != '\n' && car != EOF);
186     }
187 
188     public boolean eof() throws IOException {
189         return currentChar() == EOF;
190     }
191 
192     public char currentChar() throws IOException {
193         this.in.mark(10);
194         char car = (char) this.in.read();
195         this.in.reset();
196         return car;
197     }
198 }