View Javadoc

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