comparison src/main/java/org/monetdb/mcl/parser/StartOfHeaderParser.java @ 391:f523727db392

Moved Java classes from packages starting with nl.cwi.monetdb.* to package org.monetdb.* This naming complies to the Java Package Naming convention as MonetDB's main website is www.monetdb.org.
author Martin van Dinther <martin.van.dinther@monetdbsolutions.com>
date Thu, 12 Nov 2020 22:02:01 +0100 (2020-11-12)
parents src/main/java/nl/cwi/monetdb/mcl/parser/StartOfHeaderParser.java@8a813f5cef1b
children bf9f6b6ecf40
comparison
equal deleted inserted replaced
390:6199e0be3c6e 391:f523727db392
1 /*
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5 *
6 * Copyright 1997 - July 2008 CWI, August 2008 - 2020 MonetDB B.V.
7 */
8
9 package org.monetdb.mcl.parser;
10
11 import java.nio.CharBuffer;
12
13 /**
14 * The StartOfHeaderParser allows easy examination of a start of header
15 * line. It does not fit into the general MCLParser framework because
16 * it uses a different interface. While the parser is very shallow, it
17 * requires the caller to know about the header lines that are parsed.
18 * All this parser does is detect the (valid) type of a soheader, and
19 * allow to return the fields in it as integer or string. An extra
20 * bonus is that it can return if another field should be present in the
21 * soheader.
22 *
23 * @author Fabian Groffen
24 */
25 public final class StartOfHeaderParser {
26 private CharBuffer soh = null;
27 private int len;
28 private int pos;
29
30 /* Query types (copied from sql/include/sql_querytype.h) */
31 /** A parse response (not handled) */
32 public final static int Q_PARSE = '0';
33 /** A tabular response (typical ResultSet) */
34 public final static int Q_TABLE = '1';
35 /** A response to an update statement, contains number of affected
36 * rows and generated key-id */
37 public final static int Q_UPDATE = '2';
38 /** A response to a schema update */
39 public final static int Q_SCHEMA = '3';
40 /** A response to a transation statement (start, rollback, abort,
41 * commit) */
42 public final static int Q_TRANS = '4';
43 /** A tabular response in response to a PREPARE statement containing
44 * information about the wildcard values that need to be supplied */
45 public final static int Q_PREPARE = '5';
46 /** A tabular continuation response (for a ResultSet) */
47 public final static int Q_BLOCK = '6';
48
49
50 public final int parse(final String in) throws MCLParseException {
51 soh = CharBuffer.wrap(in);
52 soh.get(); // skip the &
53 final int type = soh.get();
54 switch (type) {
55 case Q_PARSE:
56 case Q_SCHEMA:
57 len = 0;
58 break;
59 case Q_TABLE:
60 case Q_PREPARE:
61 len = 4;
62 soh.get();
63 break;
64 case Q_UPDATE:
65 len = 2;
66 soh.get();
67 break;
68 case Q_TRANS:
69 len = 1;
70 soh.get();
71 break;
72 case Q_BLOCK:
73 len = 3;
74 soh.get();
75 break;
76 default:
77 throw new MCLParseException("invalid or unknown header", 1);
78 }
79 pos = 0;
80 return type;
81 }
82
83 /* MvD: disabled hasNext() method as it is never called.
84 public final boolean hasNext() {
85 return pos < len;
86 }
87 */
88
89 /**
90 * Returns the next token in the CharBuffer as integer. The value is
91 * considered to end at the end of the CharBuffer or at a space. If
92 * a non-numeric character is encountered an MCLParseException is thrown.
93 *
94 * @return The next token in the CharBuffer as integer
95 * @throws MCLParseException if no numeric value could be read
96 */
97 public final int getNextAsInt() throws MCLParseException {
98 return (int) getNextAsLong();
99 }
100
101 /**
102 * Returns the next token in the CharBuffer as long integer. The value
103 * is considered to end at the end of the CharBuffer or at a space.
104 * If a non-numeric character is encountered an MCLParseException is thrown.
105 *
106 * @return The next token in the CharBuffer as long integer
107 * @throws MCLParseException if no numeric value could be read
108 */
109 public final long getNextAsLong() throws MCLParseException {
110 pos++;
111 if (!soh.hasRemaining())
112 throw new MCLParseException("unexpected end of string", soh.position() - 1);
113
114 boolean positive = true;
115 char chr = soh.get();
116 // note: don't use Character.isDigit() here, because
117 // we only want ISO-LATIN-1 digits
118 if (chr == '-') {
119 positive = false;
120 if (!soh.hasRemaining())
121 throw new MCLParseException("unexpected end of string", soh.position() - 1);
122 chr = soh.get();
123 }
124
125 long tmp = 0;
126 if (chr >= '0' && chr <= '9') {
127 tmp = (int)chr - (int)'0';
128 } else {
129 throw new MCLParseException("expected a digit", soh.position() - 1);
130 }
131
132 while (soh.hasRemaining() && (chr = soh.get()) != ' ') {
133 if (chr >= '0' && chr <= '9') {
134 tmp *= 10;
135 tmp += (int)chr - (int)'0';
136 } else {
137 throw new MCLParseException("expected a digit", soh.position() - 1);
138 }
139 }
140
141 return positive ? tmp : -tmp;
142 }
143
144 public final String getNextAsString() throws MCLParseException {
145 pos++;
146 if (!soh.hasRemaining())
147 throw new MCLParseException("unexpected end of string", soh.position() - 1);
148
149 int cnt = 0;
150 soh.mark();
151 while (soh.hasRemaining() && soh.get() != ' ') {
152 cnt++;
153 }
154 soh.reset();
155
156 return soh.subSequence(0, cnt).toString();
157 }
158 }