View Javadoc

1   // ========================================================================
2   // Copyright (c) 2004-2009 Mort Bay Consulting Pty. Ltd.
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   // and Apache License v2.0 which accompanies this distribution.
7   // The Eclipse Public License is available at 
8   // http://www.eclipse.org/legal/epl-v10.html
9   // The Apache License v2.0 is available at
10  // http://www.opensource.org/licenses/apache2.0.php
11  // You may elect to redistribute this code under either of these licenses. 
12  // ========================================================================
13  
14  package org.eclipse.jetty.io;
15  
16  import org.eclipse.jetty.io.BufferCache.CachedBuffer;
17  import org.eclipse.jetty.util.StringUtil;
18  
19  /* ------------------------------------------------------------------------------- */
20  /** Buffer utility methods.
21   * 
22   * 
23   */
24  public class BufferUtil
25  {
26      static final byte SPACE= 0x20;
27      static final byte MINUS= '-';
28      static final byte[] DIGIT=
29      {(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'};
30  
31      /**
32       * Convert buffer to an integer.
33       * Parses up to the first non-numeric character. If no number is found an
34       * IllegalArgumentException is thrown
35       * @param buffer A buffer containing an integer. The position is not changed.
36       * @return an int 
37       */
38      public static int toInt(Buffer buffer)
39      {
40          int val= 0;
41          boolean started= false;
42          boolean minus= false;
43          for (int i= buffer.getIndex(); i < buffer.putIndex(); i++)
44          {
45              byte b= buffer.peek(i);
46              if (b <= SPACE)
47              {
48                  if (started)
49                      break;
50              }
51              else if (b >= '0' && b <= '9')
52              {
53                  val= val * 10 + (b - '0');
54                  started= true;
55              }
56              else if (b == MINUS && !started)
57              {
58                  minus= true;
59              }
60              else
61                  break;
62          }
63  
64          if (started)
65              return minus ? (-val) : val;
66          throw new NumberFormatException(buffer.toString());
67      }
68      
69      /**
70       * Convert buffer to an long.
71       * Parses up to the first non-numeric character. If no number is found an
72       * IllegalArgumentException is thrown
73       * @param buffer A buffer containing an integer. The position is not changed.
74       * @return an int 
75       */
76      public static long toLong(Buffer buffer)
77      {
78          long val= 0;
79          boolean started= false;
80          boolean minus= false;
81          for (int i= buffer.getIndex(); i < buffer.putIndex(); i++)
82          {
83              byte b= buffer.peek(i);
84              if (b <= SPACE)
85              {
86                  if (started)
87                      break;
88              }
89              else if (b >= '0' && b <= '9')
90              {
91                  val= val * 10L + (b - '0');
92                  started= true;
93              }
94              else if (b == MINUS && !started)
95              {
96                  minus= true;
97              }
98              else
99                  break;
100         }
101 
102         if (started)
103             return minus ? (-val) : val;
104         throw new NumberFormatException(buffer.toString());
105     }
106 
107     public static void putHexInt(Buffer buffer, int n)
108     {
109 
110         if (n < 0)
111         {
112             buffer.put((byte)'-');
113 
114             if (n == Integer.MIN_VALUE)
115             {
116                 buffer.put((byte)(0x7f&'8'));
117                 buffer.put((byte)(0x7f&'0'));
118                 buffer.put((byte)(0x7f&'0'));
119                 buffer.put((byte)(0x7f&'0'));
120                 buffer.put((byte)(0x7f&'0'));
121                 buffer.put((byte)(0x7f&'0'));
122                 buffer.put((byte)(0x7f&'0'));
123                 buffer.put((byte)(0x7f&'0'));
124                 
125                 return;
126             }
127             n= -n;
128         }
129 
130         if (n < 0x10)
131         {
132             buffer.put(DIGIT[n]);
133         }
134         else
135         {
136             boolean started= false;
137             // This assumes constant time int arithmatic
138             for (int i= 0; i < hexDivisors.length; i++)
139             {
140                 if (n < hexDivisors[i])
141                 {
142                     if (started)
143                         buffer.put((byte)'0');
144                     continue;
145                 }
146 
147                 started= true;
148                 int d= n / hexDivisors[i];
149                 buffer.put(DIGIT[d]);
150                 n= n - d * hexDivisors[i];
151             }
152         }
153     }
154 
155     /* ------------------------------------------------------------ */
156     /**
157      * Add hex integer BEFORE current getIndex.
158      * @param buffer
159      * @param n
160      */
161     public static void prependHexInt(Buffer buffer, int n)
162     {
163         if (n==0)
164         {
165             int gi=buffer.getIndex();
166             buffer.poke(--gi,(byte)'0');
167             buffer.setGetIndex(gi);
168         }
169         else
170         {
171             boolean minus=false;
172             if (n<0)
173             {
174                 minus=true;
175                 n=-n;
176             }
177 
178             int gi=buffer.getIndex();
179             while(n>0)
180             {
181                 int d = 0xf&n;
182                 n=n>>4;
183                 buffer.poke(--gi,DIGIT[d]);
184             }
185             
186             if (minus)
187                 buffer.poke(--gi,(byte)'-');
188             buffer.setGetIndex(gi);
189         }
190     }
191     
192 
193     /* ------------------------------------------------------------ */
194     public static void putDecInt(Buffer buffer, int n)
195     {
196         if (n < 0)
197         {
198             buffer.put((byte)'-');
199 
200             if (n == Integer.MIN_VALUE)
201             {
202                 buffer.put((byte)'2');
203                 n= 147483648;
204             }
205             else
206                 n= -n;
207         }
208 
209         if (n < 10)
210         {
211             buffer.put(DIGIT[n]);
212         }
213         else
214         {
215             boolean started= false;
216             // This assumes constant time int arithmatic
217             for (int i= 0; i < decDivisors.length; i++)
218             {
219                 if (n < decDivisors[i])
220                 {
221                     if (started)
222                         buffer.put((byte)'0');
223                     continue;
224                 }
225 
226                 started= true;
227                 int d= n / decDivisors[i];
228                 buffer.put(DIGIT[d]);
229                 n= n - d * decDivisors[i];
230             }
231         }
232     }
233     
234     public static void putDecLong(Buffer buffer, long n)
235     {
236         if (n < 0)
237         {
238             buffer.put((byte)'-');
239 
240             if (n == Long.MIN_VALUE)
241             {
242                 buffer.put((byte)'9');
243                 n= 223372036854775808L;
244             }
245             else
246                 n= -n;
247         }
248 
249         if (n < 10)
250         {
251             buffer.put(DIGIT[(int)n]);
252         }
253         else
254         {
255             boolean started= false;
256             // This assumes constant time int arithmatic
257             for (int i= 0; i < decDivisorsL.length; i++)
258             {
259                 if (n < decDivisorsL[i])
260                 {
261                     if (started)
262                         buffer.put((byte)'0');
263                     continue;
264                 }
265 
266                 started= true;
267                 long d= n / decDivisorsL[i];
268                 buffer.put(DIGIT[(int)d]);
269                 n= n - d * decDivisorsL[i];
270             }
271         }
272     }
273     
274     public static Buffer toBuffer(long value)
275     {
276         ByteArrayBuffer buf=new ByteArrayBuffer(32);
277         putDecLong(buf, value);
278         return buf;
279     }
280 
281     private final static int[] decDivisors=
282     { 
283         1000000000,
284         100000000,
285         10000000,
286         1000000,
287         100000,
288         10000,
289         1000,
290         100,
291         10,
292         1 
293     };
294 
295     private final static int[] hexDivisors=
296     {
297         0x10000000,
298         0x1000000, 
299         0x100000, 
300         0x10000, 
301         0x1000, 
302         0x100, 
303         0x10, 
304         0x1 
305     };
306 
307     private final static long[] decDivisorsL=
308     { 
309         1000000000000000000L,
310         100000000000000000L,
311         10000000000000000L,
312         1000000000000000L,
313         100000000000000L,
314         10000000000000L,
315         1000000000000L,
316         100000000000L,
317         10000000000L,
318         1000000000L,
319         100000000L,
320         10000000L,
321         1000000L,
322         100000L,
323         10000L,
324         1000L,
325         100L,
326         10L,
327         1L 
328     };
329 
330 
331     public static void putCRLF(Buffer buffer)
332     {
333         buffer.put((byte)13);
334         buffer.put((byte)10);
335     }
336     
337     public static boolean isPrefix(Buffer prefix,Buffer buffer)
338     {
339         if (prefix.length()>buffer.length())
340             return false;
341         int bi=buffer.getIndex();
342         for (int i=prefix.getIndex(); i<prefix.putIndex();i++)
343             if (prefix.peek(i)!=buffer.peek(bi++))
344                 return false;
345         return true;
346     }
347 
348     public static String to8859_1_String(Buffer buffer)
349     {
350         if (buffer instanceof CachedBuffer)
351             return buffer.toString();
352         return buffer.toString(StringUtil.__ISO_8859_1);
353     }
354 }