View Javadoc

1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License.
18   *
19   */
20  package org.apache.mina.proxy.utils;
21  
22  import java.io.UnsupportedEncodingException;
23  
24  /**
25   * ByteUtilities.java - Byte manipulation functions.
26   * 
27   * @author The Apache MINA Project (dev@mina.apache.org)
28   * @version $Rev: 685703 $, $Date: 2008-08-14 00:14:47 +0200 (Thu, 14 Aug 2008) $
29   * @since MINA 2.0.0-M3
30   */
31  public class ByteUtilities {
32      /**
33       * Returns the integer represented by 4 bytes in network byte order.
34       */
35      public static int networkByteOrderToInt(byte[] buf, int start, int count) {
36          if (count > 4) {
37              throw new IllegalArgumentException(
38                      "Cannot handle more than 4 bytes");
39          }
40  
41          int result = 0;
42  
43          for (int i = 0; i < count; i++) {
44              result <<= 8;
45              result |= ((int) buf[start + i] & 0xff);
46          }
47  
48          return result;
49      }
50  
51      /**
52       * Encodes an integer into 4 bytes in network byte order in the buffer
53       * supplied.
54       */
55      public static byte[] intToNetworkByteOrder(int num, byte[] buf, int start,
56              int count) {
57          if (count > 4) {
58              throw new IllegalArgumentException(
59                      "Cannot handle more than 4 bytes");
60          }
61  
62          for (int i = count - 1; i >= 0; i--) {
63              buf[start + i] = (byte) (num & 0xff);
64              num >>>= 8;
65          }
66  
67          return buf;
68      }
69  
70      /**
71       * Write a 16 bit short as LITTLE_ENDIAN.
72       * 
73       * @param v the short to write
74       */
75      public final static byte[] writeShort(short v) {
76          return writeShort(v, new byte[2], 0);
77      }
78  
79      /**
80       * Write a 16 bit short as LITTLE_ENDIAN to
81       * the given array <code>b</code> at offset <code>offset</code>.
82       * 
83       * @param v the short to write
84       */
85      public final static byte[] writeShort(short v, byte[] b, int offset) {
86          b[offset] = (byte) v;
87          b[offset + 1] = (byte) (v >> 8);
88  
89          return b;
90      }
91  
92      /**
93       * Write a 32 bit int as LITTLE_ENDIAN.
94       * 
95       * @param v the int to write
96       */
97      public final static byte[] writeInt(int v) {
98          return writeInt(v, new byte[4], 0);
99      }
100 
101     /**
102      * Write a 32 bit int as LITTLE_ENDIAN to
103      * the given array <code>b</code> at offset <code>offset</code>.
104      * 
105      * @param v the int to write
106      */
107     public final static byte[] writeInt(int v, byte[] b, int offset) {
108         b[offset] = (byte) v;
109         b[offset + 1] = (byte) (v >> 8);
110         b[offset + 2] = (byte) (v >> 16);
111         b[offset + 3] = (byte) (v >> 24);
112 
113         return b;
114     }
115 
116     public final static void changeWordEndianess(byte[] b, int offset,
117             int length) {
118         byte tmp;
119 
120         for (int i = offset; i < offset + length; i += 4) {
121             tmp = b[i];
122             b[i] = b[i + 3];
123             b[i + 3] = tmp;
124             tmp = b[i + 1];
125             b[i + 1] = b[i + 2];
126             b[i + 2] = tmp;
127         }
128     }
129 
130     public final static void changeByteEndianess(byte[] b, int offset,
131             int length) {
132         byte tmp;
133 
134         for (int i = offset; i < offset + length; i += 2) {
135             tmp = b[i];
136             b[i] = b[i + 1];
137             b[i + 1] = tmp;
138         }
139     }
140 
141     public final static byte[] getOEMStringAsByteArray(String s)
142             throws UnsupportedEncodingException {
143         return s.getBytes("ASCII");
144     }
145 
146     public final static byte[] getUTFStringAsByteArray(String s)
147             throws UnsupportedEncodingException {
148         return s.getBytes("UTF-16LE");
149     }
150 
151     public final static byte[] encodeString(String s, boolean useUnicode)
152             throws UnsupportedEncodingException {
153         if (useUnicode) {
154             return getUTFStringAsByteArray(s);
155         } else {
156             return getOEMStringAsByteArray(s);
157         }
158     }
159 
160     public static String asHex(byte[] bytes) {
161         return asHex(bytes, null);
162     }
163 
164     public static String asHex(byte[] bytes, String separator) {
165         StringBuilder sb = new StringBuilder();
166         for (int i = 0; i < bytes.length; i++) {
167             String code = Integer.toHexString(bytes[i] & 0xFF);
168             if ((bytes[i] & 0xFF) < 16) {
169                 sb.append('0');
170             }
171 
172             sb.append(code);
173 
174             if (separator != null && i < bytes.length - 1) {
175                 sb.append(separator);
176             }
177         }
178 
179         return sb.toString();
180     }
181 
182     public static byte[] asByteArray(String hex) {
183         byte[] bts = new byte[hex.length() / 2];
184         for (int i = 0; i < bts.length; i++) {
185             bts[i] = (byte) Integer.parseInt(hex.substring(2 * i, 2 * i + 2),
186                     16);
187         }
188 
189         return bts;
190     }
191 
192     public static final int makeIntFromByte4(byte[] b) {
193         return makeIntFromByte4(b, 0);
194     }
195 
196     public static final int makeIntFromByte4(byte[] b, int offset) {
197         return b[offset] << 24 | (b[offset + 1] & 0xff) << 16
198                 | (b[offset + 2] & 0xff) << 8 | (b[offset + 3] & 0xff);
199     }
200 
201     public static final int makeIntFromByte2(byte[] b) {
202         return makeIntFromByte2(b, 0);
203     }
204 
205     public static final int makeIntFromByte2(byte[] b, int offset) {
206         return (b[offset] & 0xff) << 8 | (b[offset + 1] & 0xff);
207     }
208 
209     /**
210      * Return true if the flag <code>testFlag</code> is set in the
211      * <code>flags</code> flagset.
212      * 
213      * @param flagset the flagset to test
214      * @param testFlag the flag we search the presence of
215      * @return true if testFlag is present in the flagset, false otherwise.
216      */
217     public final static boolean isFlagSet(int flagSet, int testFlag) {
218         return (flagSet & testFlag) > 0;
219     }
220 }