001: // ========================================================================
002: // Copyright 2004-2005 Mort Bay Consulting Pty. Ltd.
003: // ------------------------------------------------------------------------
004: // Licensed under the Apache License, Version 2.0 (the "License");
005: // you may not use this file except in compliance with the License.
006: // You may obtain a copy of the License at
007: // http://www.apache.org/licenses/LICENSE-2.0
008: // Unless required by applicable law or agreed to in writing, software
009: // distributed under the License is distributed on an "AS IS" BASIS,
010: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
011: // See the License for the specific language governing permissions and
012: // limitations under the License.
013: // ========================================================================
014:
015: package org.mortbay.io;
016:
017: /* ------------------------------------------------------------------------------- */
018: /** Buffer utility methods.
019: *
020: * @author gregw
021: */
022: public class BufferUtil {
023: static final byte SPACE = 0x20;
024: static final byte MINUS = '-';
025: static final byte[] DIGIT = { (byte) '0', (byte) '1', (byte) '2',
026: (byte) '3', (byte) '4', (byte) '5', (byte) '6', (byte) '7',
027: (byte) '8', (byte) '9', (byte) 'A', (byte) 'B', (byte) 'C',
028: (byte) 'D', (byte) 'E', (byte) 'F' };
029:
030: /**
031: * Convert buffer to an integer.
032: * Parses up to the first non-numeric character. If no number is found an
033: * IllegalArgumentException is thrown
034: * @param buffer A buffer containing an integer. The position is not changed.
035: * @return an int
036: */
037: public static int toInt(Buffer buffer) {
038: int val = 0;
039: boolean started = false;
040: boolean minus = false;
041: for (int i = buffer.getIndex(); i < buffer.putIndex(); i++) {
042: byte b = buffer.peek(i);
043: if (b <= SPACE) {
044: if (started)
045: break;
046: } else if (b >= '0' && b <= '9') {
047: val = val * 10 + (b - '0');
048: started = true;
049: } else if (b == MINUS && !started) {
050: minus = true;
051: } else
052: break;
053: }
054:
055: if (started)
056: return minus ? (-val) : val;
057: throw new NumberFormatException(buffer.toString());
058: }
059:
060: /**
061: * Convert buffer to an long.
062: * Parses up to the first non-numeric character. If no number is found an
063: * IllegalArgumentException is thrown
064: * @param buffer A buffer containing an integer. The position is not changed.
065: * @return an int
066: */
067: public static long toLong(Buffer buffer) {
068: long val = 0;
069: boolean started = false;
070: boolean minus = false;
071: for (int i = buffer.getIndex(); i < buffer.putIndex(); i++) {
072: byte b = buffer.peek(i);
073: if (b <= SPACE) {
074: if (started)
075: break;
076: } else if (b >= '0' && b <= '9') {
077: val = val * 10L + (b - '0');
078: started = true;
079: } else if (b == MINUS && !started) {
080: minus = true;
081: } else
082: break;
083: }
084:
085: if (started)
086: return minus ? (-val) : val;
087: throw new NumberFormatException(buffer.toString());
088: }
089:
090: public static void putHexInt(Buffer buffer, int n) {
091:
092: if (n < 0) {
093: buffer.put((byte) '-');
094:
095: if (n == Integer.MIN_VALUE) {
096: buffer.put("80000000".getBytes(), 0, 8);
097: return;
098: }
099: n = -n;
100: }
101:
102: if (n < 0x10) {
103: buffer.put(DIGIT[n]);
104: } else {
105: boolean started = false;
106: // This assumes constant time int arithmatic
107: for (int i = 0; i < hexDivisors.length; i++) {
108: if (n < hexDivisors[i]) {
109: if (started)
110: buffer.put((byte) '0');
111: continue;
112: }
113:
114: started = true;
115: int d = n / hexDivisors[i];
116: buffer.put(DIGIT[d]);
117: n = n - d * hexDivisors[i];
118: }
119: }
120: }
121:
122: /* ------------------------------------------------------------ */
123: /**
124: * Add hex integer BEFORE current getIndex.
125: * @param buffer
126: * @param n
127: */
128: public static void prependHexInt(Buffer buffer, int n) {
129: if (n == 0) {
130: int gi = buffer.getIndex();
131: buffer.poke(--gi, (byte) '0');
132: buffer.setGetIndex(gi);
133: } else {
134: boolean minus = false;
135: if (n < 0) {
136: minus = true;
137: n = -n;
138: }
139:
140: int gi = buffer.getIndex();
141: while (n > 0) {
142: int d = 0xf & n;
143: n = n >> 4;
144: buffer.poke(--gi, DIGIT[d]);
145: }
146:
147: if (minus)
148: buffer.poke(--gi, (byte) '-');
149: buffer.setGetIndex(gi);
150: }
151: }
152:
153: /* ------------------------------------------------------------ */
154: public static void putDecInt(Buffer buffer, int n) {
155: if (n < 0) {
156: buffer.put((byte) '-');
157:
158: if (n == Integer.MIN_VALUE) {
159: buffer.put((byte) '2');
160: n = 147483648;
161: } else
162: n = -n;
163: }
164:
165: if (n < 10) {
166: buffer.put(DIGIT[n]);
167: } else {
168: boolean started = false;
169: // This assumes constant time int arithmatic
170: for (int i = 0; i < decDivisors.length; i++) {
171: if (n < decDivisors[i]) {
172: if (started)
173: buffer.put((byte) '0');
174: continue;
175: }
176:
177: started = true;
178: int d = n / decDivisors[i];
179: buffer.put(DIGIT[d]);
180: n = n - d * decDivisors[i];
181: }
182: }
183: }
184:
185: public static void putDecLong(Buffer buffer, long n) {
186: if (n < 0) {
187: buffer.put((byte) '-');
188:
189: if (n == Long.MIN_VALUE) {
190: buffer.put((byte) '9');
191: n = 223372036854775808L;
192: } else
193: n = -n;
194: }
195:
196: if (n < 10) {
197: buffer.put(DIGIT[(int) n]);
198: } else {
199: boolean started = false;
200: // This assumes constant time int arithmatic
201: for (int i = 0; i < decDivisors.length; i++) {
202: if (n < decDivisors[i]) {
203: if (started)
204: buffer.put((byte) '0');
205: continue;
206: }
207:
208: started = true;
209: long d = n / decDivisors[i];
210: buffer.put(DIGIT[(int) d]);
211: n = n - d * decDivisors[i];
212: }
213: }
214: }
215:
216: public static Buffer toBuffer(long value) {
217: ByteArrayBuffer buf = new ByteArrayBuffer(16);
218: putDecLong(buf, value);
219: return buf;
220: }
221:
222: private static int[] decDivisors = { 1000000000, 100000000,
223: 10000000, 1000000, 100000, 10000, 1000, 100, 10, 1 };
224:
225: private static int[] hexDivisors = { 0x10000000, 0x1000000,
226: 0x100000, 0x10000, 0x1000, 0x100, 0x10, 1 };
227:
228: public static void putCRLF(Buffer buffer) {
229: buffer.put((byte) 13);
230: buffer.put((byte) 10);
231: }
232:
233: public static boolean isPrefix(Buffer prefix, Buffer buffer) {
234: if (prefix.length() > buffer.length())
235: return false;
236: int bi = buffer.getIndex();
237: for (int i = prefix.getIndex(); i < prefix.putIndex(); i++)
238: if (prefix.peek(i) != buffer.peek(bi++))
239: return false;
240: return true;
241: }
242:
243: }
|