diff src/main/java/nl/cwi/monetdb/mcl/parser/StartOfHeaderParser.java @ 0:a5a898f6886c

Copy of MonetDB java directory changeset e6e32756ad31.
author Sjoerd Mullender <sjoerd@acm.org>
date Wed, 21 Sep 2016 09:34:48 +0200 (2016-09-21)
parents
children b66003555560 b9b35ca2eec2
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/src/main/java/nl/cwi/monetdb/mcl/parser/StartOfHeaderParser.java
@@ -0,0 +1,138 @@
+/*
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0.  If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * Copyright 1997 - July 2008 CWI, August 2008 - 2016 MonetDB B.V.
+ */
+
+package nl.cwi.monetdb.mcl.parser;
+
+import java.nio.CharBuffer;
+
+/**
+ * The StartOfHeaderParser allows easy examination of a start of header
+ * line.  It does not fit into the general MCLParser framework because
+ * it uses a different interface.  While the parser is very shallow, it
+ * requires the caller to know about the header lines that are parsed.
+ * All this parser does is detect the (valid) type of a soheader, and
+ * allow to return the fields in it as integer or string.  An extra
+ * bonus is that it can return if another field should be present in the
+ * soheader.
+ *
+ * @author Fabian Groffen <Fabian.Groffen>
+ */
+public class StartOfHeaderParser {
+	private CharBuffer soh = null;
+	private int len;
+	private int pos;
+
+	/* Query types (copied from sql_query.mx) */
+
+	/** A parse response (not handled) */
+	public final static int Q_PARSE    = '0';
+	/** A tabular response (typical ResultSet) */
+	public final static int Q_TABLE    = '1';
+	/** A response to an update statement, contains number of affected
+	 * rows and generated key-id */
+	public final static int Q_UPDATE   = '2';
+	/** A response to a schema update */
+	public final static int Q_SCHEMA   = '3';
+	/** A response to a transation statement (start, rollback, abort,
+	 * commit) */
+	public final static int Q_TRANS    = '4';
+	/** A tabular response in response to a PREPARE statement containing
+	 * information about the wildcard values that need to be supplied */
+	public final static int Q_PREPARE  = '5';
+	/** A tabular continuation response (for a ResultSet) */
+	public final static int Q_BLOCK    = '6';
+	/** An unknown and unsupported response */
+	public final static int Q_UNKNOWN  =  0 ;
+
+	public final int parse(String in) throws MCLParseException {
+		soh = CharBuffer.wrap(in);
+		soh.get();	// skip the &
+		int type = soh.get();
+		switch (type) {
+			default:
+				throw new MCLParseException("invalid or unknown header", 1);
+			case Q_PARSE:
+			case Q_SCHEMA:
+				len = 0;
+			break;
+			case Q_TABLE:
+			case Q_PREPARE:
+				len = 4;
+				soh.get();
+			break;
+			case Q_UPDATE:
+				len = 2;
+				soh.get();
+			break;
+			case Q_TRANS:
+				len = 1;
+				soh.get();
+			break;
+			case Q_BLOCK:
+				len = 3;
+				soh.get();
+			break;
+		}
+		pos = 0;
+		return type;
+	}
+
+	public final boolean hasNext() {
+		return pos < len;
+	}
+
+	/**
+	 * Returns the next token in the CharBuffer as integer. The value is
+	 * considered to end at the end of the CharBuffer or at a space.  If
+	 * a non-numeric character is encountered an MCLParseException is
+	 * thrown.
+	 *
+	 * @return The next token in the CharBuffer as integer
+	 * @throws MCLParseException if no numeric value could be read
+	 */
+	public final int getNextAsInt() throws MCLParseException {
+		pos++;
+		if (!soh.hasRemaining()) throw
+			new MCLParseException("unexpected end of string", soh.position() - 1);
+		int tmp;
+		char chr = soh.get();
+		// note: don't use Character.isDigit() here, because
+		// we only want ISO-LATIN-1 digits
+		if (chr >= '0' && chr <= '9') {
+			tmp = (int)chr - (int)'0';
+		} else {
+			throw new MCLParseException("expected a digit", soh.position() - 1);
+		}
+
+		while (soh.hasRemaining() && (chr = soh.get()) != ' ') {
+			tmp *= 10;
+			if (chr >= '0' && chr <= '9') {
+				tmp += (int)chr - (int)'0';
+			} else {
+				throw new MCLParseException("expected a digit", soh.position() - 1);
+			}
+		}
+
+		return tmp;
+	}
+
+	public final String getNextAsString() throws MCLParseException {
+		pos++;
+		if (!soh.hasRemaining()) throw
+			new MCLParseException("unexpected end of string", soh.position() - 1);
+		int cnt = 0;
+		soh.mark();
+		while (soh.hasRemaining() && soh.get() != ' ') {
+			cnt++;
+		}
+
+		soh.reset();
+
+		return soh.subSequence(0, cnt).toString();
+	}
+}