1 /*
2 * Copyright 2004-2010 the Seasar Foundation and the Others.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13 * either express or implied. See the License for the specific language
14 * governing permissions and limitations under the License.
15 */
16
17 package org.seasar.cubby.internal.util;
18
19 import java.io.ByteArrayOutputStream;
20 import java.io.UnsupportedEncodingException;
21 import java.util.BitSet;
22
23 /**
24 * URL ボディ部のエンコーダです。
25 *
26 * @author baba
27 */
28 public class URLBodyEncoder {
29
30 protected static byte ESCAPE_CHAR = '%';
31
32 /**
33 * BitSet of www-form-url safe characters.
34 */
35 protected static final BitSet WWW_FORM_URL = new BitSet(256);
36
37 // Static initializer for www_form_url
38 static {
39 // alpha characters
40 for (int i = 'a'; i <= 'z'; i++) {
41 WWW_FORM_URL.set(i);
42 }
43 for (int i = 'A'; i <= 'Z'; i++) {
44 WWW_FORM_URL.set(i);
45 }
46 // numeric characters
47 for (int i = '0'; i <= '9'; i++) {
48 WWW_FORM_URL.set(i);
49 }
50 // special chars
51 WWW_FORM_URL.set('-');
52 WWW_FORM_URL.set('_');
53 WWW_FORM_URL.set('.');
54 WWW_FORM_URL.set('*');
55 // blank to be replaced with +
56 // WWW_FORM_URL.set(' ');
57 }
58
59 /**
60 * Default constructor.
61 */
62 private URLBodyEncoder() {
63 super();
64 }
65
66 /**
67 * Encodes an array of bytes into an array of URL safe 7-bit characters.
68 * Unsafe characters are escaped.
69 *
70 * @param urlsafe
71 * bitset of characters deemed URL safe
72 * @param bytes
73 * array of bytes to convert to URL safe characters
74 * @return array of bytes containing URL safe characters
75 */
76 public static final byte[] encodeUrl(BitSet urlsafe, final byte[] bytes) {
77 if (bytes == null) {
78 return null;
79 }
80 if (urlsafe == null) {
81 urlsafe = WWW_FORM_URL;
82 }
83
84 final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
85 for (final byte b : bytes) {
86 final int b1 = b;
87 final int b2;
88 if (b1 < 0) {
89 b2 = b1 + 256;
90 } else {
91 b2 = b1;
92 }
93
94 if (urlsafe.get(b2)) {
95 buffer.write(b2);
96 } else {
97 buffer.write('%');
98 final char hex1 = Character.toUpperCase(Character.forDigit(
99 (b2 >> 4) & 0xF, 16));
100 final char hex2 = Character.toUpperCase(Character.forDigit(
101 b2 & 0xF, 16));
102 buffer.write(hex1);
103 buffer.write(hex2);
104 }
105 }
106 return buffer.toByteArray();
107 }
108
109 /**
110 * Encodes an array of bytes into an array of URL safe 7-bit characters.
111 * Unsafe characters are escaped.
112 *
113 * @param bytes
114 * array of bytes to convert to URL safe characters
115 * @return array of bytes containing URL safe characters
116 */
117 public static byte[] encode(final byte[] bytes) {
118 return encodeUrl(WWW_FORM_URL, bytes);
119 }
120
121 /**
122 * Encodes a string into its URL safe form using the specified string
123 * charset. Unsafe characters are escaped.
124 *
125 * @param pString
126 * string to convert to a URL safe form
127 * @param charset
128 * the charset for pString
129 * @return URL safe string
130 * @throws UnsupportedEncodingException
131 * Thrown if charset is not supported
132 */
133 public static String encode(final String pString, final String charset)
134 throws UnsupportedEncodingException {
135 if (pString == null) {
136 return null;
137 }
138 return new String(encode(pString.getBytes(charset)), "US-ASCII");
139 }
140
141 }