001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.harmony.luni.util;
019:
020: import java.io.ByteArrayOutputStream;
021: import java.io.UTFDataFormatException;
022: import java.util.Calendar;
023: import java.util.TimeZone;
024:
025: public final class Util {
026:
027: private static String[] WEEKDAYS = new String[] { "", "Sunday",
028: "Monday", "Tuesday", "Wednesday", "Thursday", "Friday",
029: "Saturday" };
030:
031: private static String[] MONTHS = new String[] { "January",
032: "February", "March", "April", "May", "June", "July",
033: "August", "September", "October", "November", "December" };
034:
035: private static final String defaultEncoding;
036:
037: static {
038: String encoding = System.getProperty("os.encoding");
039: if (encoding != null) {
040: try {
041: "".getBytes(encoding);
042: } catch (Throwable t) {
043: encoding = null;
044: }
045: }
046: defaultEncoding = encoding;
047: }
048:
049: /**
050: * Get bytes from String using default encoding; default encoding can
051: * be changed via "os.encoding" property
052: * @param name input String
053: * @return byte array
054: */
055: public static byte[] getBytes(String name) {
056: if (defaultEncoding != null) {
057: try {
058: return name.getBytes(defaultEncoding);
059: } catch (java.io.UnsupportedEncodingException e) {
060: }
061: }
062: return name.getBytes();
063: }
064:
065: /**
066: * Get bytes from String with UTF8 encoding
067: * @param name
068: * input String
069: * @return byte array
070: */
071: public static byte[] getUTF8Bytes(String name) {
072: try {
073: return name.getBytes("UTF-8");
074: } catch (java.io.UnsupportedEncodingException e) {
075: return getBytes(name);
076: }
077: }
078:
079: public static String toString(byte[] bytes) {
080: if (defaultEncoding != null) {
081: try {
082: return new String(bytes, 0, bytes.length,
083: defaultEncoding);
084: } catch (java.io.UnsupportedEncodingException e) {
085: }
086: }
087: return new String(bytes, 0, bytes.length);
088: }
089:
090: public static String toUTF8String(byte[] bytes) {
091: return toUTF8String(bytes, 0, bytes.length);
092: }
093:
094: public static String toString(byte[] bytes, int offset, int length) {
095: if (defaultEncoding != null) {
096: try {
097: return new String(bytes, offset, length,
098: defaultEncoding);
099: } catch (java.io.UnsupportedEncodingException e) {
100: }
101: }
102: return new String(bytes, offset, length);
103: }
104:
105: public static String toUTF8String(byte[] bytes, int offset,
106: int length) {
107: try {
108: return new String(bytes, offset, length, "UTF-8");
109: } catch (java.io.UnsupportedEncodingException e) {
110: return toString(bytes, offset, length);
111: }
112: }
113:
114: /**
115: * Answers the millisecond value of the date and time parsed from the
116: * specified String. Many date/time formats are recognized
117: *
118: * @param string
119: * the String to parse
120: * @return the millisecond value parsed from the String
121: */
122: public static long parseDate(String string) {
123: int offset = 0, length = string.length(), state = 0;
124: int year = -1, month = -1, date = -1;
125: int hour = -1, minute = -1, second = -1;
126: final int PAD = 0, LETTERS = 1, NUMBERS = 2;
127: StringBuffer buffer = new StringBuffer();
128:
129: while (offset <= length) {
130: char next = offset < length ? string.charAt(offset) : '\r';
131: offset++;
132:
133: int nextState;
134: if ((next >= 'a' && next <= 'z')
135: || (next >= 'A' && next <= 'Z'))
136: nextState = LETTERS;
137: else if (next >= '0' && next <= '9')
138: nextState = NUMBERS;
139: else if (" ,-:\r\t".indexOf(next) == -1)
140: throw new IllegalArgumentException();
141: else
142: nextState = PAD;
143:
144: if (state == NUMBERS && nextState != NUMBERS) {
145: int digit = Integer.parseInt(buffer.toString());
146: buffer.setLength(0);
147: if (digit >= 70) {
148: if (year != -1
149: || (next != ' ' && next != ',' && next != '\r'))
150: throw new IllegalArgumentException();
151: year = digit;
152: } else if (next == ':') {
153: if (hour == -1)
154: hour = digit;
155: else if (minute == -1)
156: minute = digit;
157: else
158: throw new IllegalArgumentException();
159: } else if (next == ' ' || next == ',' || next == '-'
160: || next == '\r') {
161: if (hour != -1 && minute == -1)
162: minute = digit;
163: else if (minute != -1 && second == -1)
164: second = digit;
165: else if (date == -1)
166: date = digit;
167: else if (year == -1)
168: year = digit;
169: else
170: throw new IllegalArgumentException();
171: } else if (year == -1 && month != -1 && date != -1)
172: year = digit;
173: else
174: throw new IllegalArgumentException();
175: } else if (state == LETTERS && nextState != LETTERS) {
176: String text = buffer.toString().toUpperCase();
177: buffer.setLength(0);
178: if (text.length() < 3)
179: throw new IllegalArgumentException();
180: if (parse(text, WEEKDAYS) != -1) {
181: } else if (month == -1
182: && (month = parse(text, MONTHS)) != -1) {
183: } else if (text.equals("GMT")) {
184: } else
185: throw new IllegalArgumentException();
186: }
187:
188: if (nextState == LETTERS || nextState == NUMBERS)
189: buffer.append(next);
190: state = nextState;
191: }
192:
193: if (year != -1 && month != -1 && date != -1) {
194: if (hour == -1)
195: hour = 0;
196: if (minute == -1)
197: minute = 0;
198: if (second == -1)
199: second = 0;
200: Calendar cal = Calendar.getInstance(TimeZone
201: .getTimeZone("GMT"));
202: int current = cal.get(Calendar.YEAR) - 80;
203: if (year < 100) {
204: year += current / 100 * 100;
205: if (year < current)
206: year += 100;
207: }
208: cal.set(Calendar.YEAR, year);
209: cal.set(Calendar.MONTH, month);
210: cal.set(Calendar.DATE, date);
211: cal.set(Calendar.HOUR_OF_DAY, hour);
212: cal.set(Calendar.MINUTE, minute);
213: cal.set(Calendar.SECOND, second);
214: cal.set(Calendar.MILLISECOND, 0);
215: return cal.getTime().getTime();
216: }
217: throw new IllegalArgumentException();
218: }
219:
220: private static int parse(String string, String[] array) {
221: int length = string.length();
222: for (int i = 0; i < array.length; i++) {
223: if (string.regionMatches(true, 0, array[i], 0, length))
224: return i;
225: }
226: return -1;
227: }
228:
229: public static String convertFromUTF8(byte[] buf, int offset,
230: int utfSize) throws UTFDataFormatException {
231: return convertUTF8WithBuf(buf, new char[utfSize], offset,
232: utfSize);
233: }
234:
235: public static String convertUTF8WithBuf(byte[] buf, char[] out,
236: int offset, int utfSize) throws UTFDataFormatException {
237: int count = 0, s = 0, a;
238: while (count < utfSize) {
239: if ((out[s] = (char) buf[offset + count++]) < '\u0080')
240: s++;
241: else if (((a = out[s]) & 0xe0) == 0xc0) {
242: if (count >= utfSize)
243: throw new UTFDataFormatException(Msg.getString(
244: "K0062", count));
245: int b = buf[count++];
246: if ((b & 0xC0) != 0x80)
247: throw new UTFDataFormatException(Msg.getString(
248: "K0062", (count - 1)));
249: out[s++] = (char) (((a & 0x1F) << 6) | (b & 0x3F));
250: } else if ((a & 0xf0) == 0xe0) {
251: if (count + 1 >= utfSize)
252: throw new UTFDataFormatException(Msg.getString(
253: "K0063", (count + 1)));
254: int b = buf[count++];
255: int c = buf[count++];
256: if (((b & 0xC0) != 0x80) || ((c & 0xC0) != 0x80))
257: throw new UTFDataFormatException(Msg.getString(
258: "K0064", (count - 2)));
259: out[s++] = (char) (((a & 0x0F) << 12)
260: | ((b & 0x3F) << 6) | (c & 0x3F));
261: } else {
262: throw new UTFDataFormatException(Msg.getString("K0065",
263: (count - 1)));
264: }
265: }
266: return new String(out, 0, s);
267: }
268:
269: /**
270: * '%' and two following hex digit characters are converted to the
271: * equivalent byte value. All other characters are passed through
272: * unmodified. e.g. "ABC %24%25" -> "ABC $%"
273: *
274: * @param s
275: * java.lang.String The encoded string.
276: * @return java.lang.String The decoded version.
277: */
278: public static String decode(String s, boolean convertPlus) {
279: if (!convertPlus && s.indexOf('%') == -1)
280: return s;
281: StringBuffer result = new StringBuffer(s.length());
282: ByteArrayOutputStream out = new ByteArrayOutputStream();
283: for (int i = 0; i < s.length();) {
284: char c = s.charAt(i);
285: if (convertPlus && c == '+')
286: result.append(' ');
287: else if (c == '%') {
288: out.reset();
289: do {
290: if (i + 2 >= s.length())
291: throw new IllegalArgumentException(Msg
292: .getString("K01fe", i));
293: int d1 = Character.digit(s.charAt(i + 1), 16);
294: int d2 = Character.digit(s.charAt(i + 2), 16);
295: if (d1 == -1 || d2 == -1)
296: throw new IllegalArgumentException(Msg
297: .getString("K01ff", s.substring(i,
298: i + 3), String.valueOf(i)));
299: out.write((byte) ((d1 << 4) + d2));
300: i += 3;
301: } while (i < s.length() && s.charAt(i) == '%');
302: result.append(out.toString());
303: continue;
304: } else
305: result.append(c);
306: i++;
307: }
308: return result.toString();
309: }
310:
311: public static String toASCIILowerCase(String s) {
312: int len = s.length();
313: StringBuilder buffer = new StringBuilder(len);
314: for (int i = 0; i < len; i++) {
315: char c = s.charAt(i);
316: if ('A' <= c && c <= 'Z') {
317: buffer.append((char) (c + ('a' - 'A')));
318: } else {
319: buffer.append(c);
320: }
321: }
322: return buffer.toString();
323: }
324:
325: public static String toASCIIUpperCase(String s) {
326: int len = s.length();
327: StringBuilder buffer = new StringBuilder(len);
328: for (int i = 0; i < len; i++) {
329: char c = s.charAt(i);
330: if ('a' <= c && c <= 'z') {
331: buffer.append((char) (c - ('a' - 'A')));
332: } else {
333: buffer.append(c);
334: }
335: }
336: return buffer.toString();
337: }
338: }
|