org.eclipse.jetty.io.BufferUtil Maven / Gradle / Ivy
The newest version!
//
// ========================================================================
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.io;
import org.eclipse.jetty.io.BufferCache.CachedBuffer;
import org.eclipse.jetty.util.StringUtil;
/* ------------------------------------------------------------------------------- */
/** Buffer utility methods.
*
*
*/
public class BufferUtil
{
static final byte SPACE= 0x20;
static final byte MINUS= '-';
static final byte[] DIGIT=
{(byte)'0',(byte)'1',(byte)'2',(byte)'3',(byte)'4',(byte)'5',(byte)'6',(byte)'7',(byte)'8',(byte)'9',(byte)'A',(byte)'B',(byte)'C',(byte)'D',(byte)'E',(byte)'F'};
/**
* Convert buffer to an integer.
* Parses up to the first non-numeric character. If no number is found an
* IllegalArgumentException is thrown
* @param buffer A buffer containing an integer. The position is not changed.
* @return an int
*/
public static int toInt(Buffer buffer)
{
int val= 0;
boolean started= false;
boolean minus= false;
for (int i= buffer.getIndex(); i < buffer.putIndex(); i++)
{
byte b= buffer.peek(i);
if (b <= SPACE)
{
if (started)
break;
}
else if (b >= '0' && b <= '9')
{
val= val * 10 + (b - '0');
started= true;
}
else if (b == MINUS && !started)
{
minus= true;
}
else
break;
}
if (started)
return minus ? (-val) : val;
throw new NumberFormatException(buffer.toString());
}
/**
* Convert buffer to an long.
* Parses up to the first non-numeric character. If no number is found an
* IllegalArgumentException is thrown
* @param buffer A buffer containing an integer. The position is not changed.
* @return an int
*/
public static long toLong(Buffer buffer)
{
long val= 0;
boolean started= false;
boolean minus= false;
for (int i= buffer.getIndex(); i < buffer.putIndex(); i++)
{
byte b= buffer.peek(i);
if (b <= SPACE)
{
if (started)
break;
}
else if (b >= '0' && b <= '9')
{
val= val * 10L + (b - '0');
started= true;
}
else if (b == MINUS && !started)
{
minus= true;
}
else
break;
}
if (started)
return minus ? (-val) : val;
throw new NumberFormatException(buffer.toString());
}
public static void putHexInt(Buffer buffer, int n)
{
if (n < 0)
{
buffer.put((byte)'-');
if (n == Integer.MIN_VALUE)
{
buffer.put((byte)(0x7f&'8'));
buffer.put((byte)(0x7f&'0'));
buffer.put((byte)(0x7f&'0'));
buffer.put((byte)(0x7f&'0'));
buffer.put((byte)(0x7f&'0'));
buffer.put((byte)(0x7f&'0'));
buffer.put((byte)(0x7f&'0'));
buffer.put((byte)(0x7f&'0'));
return;
}
n= -n;
}
if (n < 0x10)
{
buffer.put(DIGIT[n]);
}
else
{
boolean started= false;
// This assumes constant time int arithmatic
for (int i= 0; i < hexDivisors.length; i++)
{
if (n < hexDivisors[i])
{
if (started)
buffer.put((byte)'0');
continue;
}
started= true;
int d= n / hexDivisors[i];
buffer.put(DIGIT[d]);
n= n - d * hexDivisors[i];
}
}
}
/* ------------------------------------------------------------ */
/**
* Add hex integer BEFORE current getIndex.
* @param buffer
* @param n
*/
public static void prependHexInt(Buffer buffer, int n)
{
if (n==0)
{
int gi=buffer.getIndex();
buffer.poke(--gi,(byte)'0');
buffer.setGetIndex(gi);
}
else
{
boolean minus=false;
if (n<0)
{
minus=true;
n=-n;
}
int gi=buffer.getIndex();
while(n>0)
{
int d = 0xf&n;
n=n>>4;
buffer.poke(--gi,DIGIT[d]);
}
if (minus)
buffer.poke(--gi,(byte)'-');
buffer.setGetIndex(gi);
}
}
/* ------------------------------------------------------------ */
public static void putDecInt(Buffer buffer, int n)
{
if (n < 0)
{
buffer.put((byte)'-');
if (n == Integer.MIN_VALUE)
{
buffer.put((byte)'2');
n= 147483648;
}
else
n= -n;
}
if (n < 10)
{
buffer.put(DIGIT[n]);
}
else
{
boolean started= false;
// This assumes constant time int arithmatic
for (int i= 0; i < decDivisors.length; i++)
{
if (n < decDivisors[i])
{
if (started)
buffer.put((byte)'0');
continue;
}
started= true;
int d= n / decDivisors[i];
buffer.put(DIGIT[d]);
n= n - d * decDivisors[i];
}
}
}
public static void putDecLong(Buffer buffer, long n)
{
if (n < 0)
{
buffer.put((byte)'-');
if (n == Long.MIN_VALUE)
{
buffer.put((byte)'9');
n= 223372036854775808L;
}
else
n= -n;
}
if (n < 10)
{
buffer.put(DIGIT[(int)n]);
}
else
{
boolean started= false;
// This assumes constant time int arithmatic
for (int i= 0; i < decDivisorsL.length; i++)
{
if (n < decDivisorsL[i])
{
if (started)
buffer.put((byte)'0');
continue;
}
started= true;
long d= n / decDivisorsL[i];
buffer.put(DIGIT[(int)d]);
n= n - d * decDivisorsL[i];
}
}
}
public static Buffer toBuffer(long value)
{
ByteArrayBuffer buf=new ByteArrayBuffer(32);
putDecLong(buf, value);
return buf;
}
private final static int[] decDivisors=
{
1000000000,
100000000,
10000000,
1000000,
100000,
10000,
1000,
100,
10,
1
};
private final static int[] hexDivisors=
{
0x10000000,
0x1000000,
0x100000,
0x10000,
0x1000,
0x100,
0x10,
0x1
};
private final static long[] decDivisorsL=
{
1000000000000000000L,
100000000000000000L,
10000000000000000L,
1000000000000000L,
100000000000000L,
10000000000000L,
1000000000000L,
100000000000L,
10000000000L,
1000000000L,
100000000L,
10000000L,
1000000L,
100000L,
10000L,
1000L,
100L,
10L,
1L
};
public static void putCRLF(Buffer buffer)
{
buffer.put((byte)13);
buffer.put((byte)10);
}
public static boolean isPrefix(Buffer prefix,Buffer buffer)
{
if (prefix.length()>buffer.length())
return false;
int bi=buffer.getIndex();
for (int i=prefix.getIndex(); i