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.tools;
019:
020: /**
021: * A helper class to mangle a string according to the Java Native Interface
022: * Specification.
023: */
024: public class Mangler {
025:
026: /**
027: * An array of the <code>String</code> pairs. This array
028: * contains the common substitute string pairs.
029: */
030: private static final String COMMON_TABLE[] = { "_", "_1", ";",
031: "_2", "[", "_3", "./", "_" };
032:
033: /**
034: * A field names substitution table.
035: */
036: private static final String FIELD_TABLE[][] = { { ".$", "_" } };
037:
038: /**
039: * A method names substitution table.
040: */
041: private static final String METHOD_TABLE[][] = { COMMON_TABLE,
042: { "$", "_" } };
043:
044: /**
045: * A class names substitution table.
046: */
047: private static final String CLASS_TABLE[][] = { COMMON_TABLE,
048: { "$", "_00024" } };
049:
050: /**
051: * A macros substitution table.
052: */
053: private static final String MACRO_TABLE[][] = { { ".$", "_" } };
054:
055: /**
056: * A file names substitution table.
057: */
058: private static final String FILE_TABLE[][] = { { ".$", "_" } };
059:
060: /**
061: * Returns a mangled string. The given string will be translated according
062: * the given substitution table. This table consists of one or more
063: * <code>String</code> arrays that contain the substitute string pair.
064: * The first element of each <code>String</code> pair in the array
065: * contains a set of chars represented as a string. Any of the given
066: * chars will be replaced with the second string of the pair
067: * in the result string. If table is null all the unicode
068: * chars will be replaced with an appropriate substitute string only.
069: *
070: * @param name - a string to be mangled.
071: * @param table - a substitution table. <code>null</code> is possible.
072: * @return a mangled string.
073: */
074: private static String mangle(String name, String table[][]) {
075: StringBuffer result = new StringBuffer();
076:
077: for (int i = 0; i < name.length(); i++) {
078: char c = name.charAt(i);
079:
080: // Check the given table, if it is not null.
081: if (table != null) {
082: boolean found = false;
083: for (int k = 0; !found && k < table.length; k++) {
084: int l = 0;
085: while (l < table[k].length) {
086: if (table[k][l].indexOf(c) != -1) {
087: result.append(table[k][l + 1]);
088: found = true;
089: break;
090: }
091: l += 2;
092: }
093: }
094: // If c is found in the given substitution table we continue.
095: if (found) {
096: continue;
097: }
098: }
099:
100: if (Character.UnicodeBlock.of(c) != Character.UnicodeBlock.BASIC_LATIN) {
101: // We have to prepare a string that looks like "_0XXXX",
102: // where "XXXX" is a string representation of a Unicode
103: // character. If the given string length is less than 4
104: // we have to prepend a missing number of '0' to the result.
105: String s = Integer.toHexString((int) c);
106: char code[] = new char[] { '0', '0', '0', '0' };
107: int len = s.length();
108: int align = code.length - len;
109: int begin = len - code.length;
110: s.getChars(begin < 0 ? 0 : begin, len, code,
111: align < 0 ? 0 : align);
112: result.append("_0").append(code);
113: } else {
114: result.append(c);
115: }
116: }
117:
118: return result.toString();
119: }
120:
121: /**
122: * Returns a mangled string. All the unicode chars of the given string
123: * will be replaced with the <code>_0XXXX</code> char sequence,
124: * where XXXX is a numeric representation of a Unicode character.
125: *
126: * @param name - a string to be mangled.
127: * @return a mangled string.
128: */
129: public static String mangleUnicode(String name) {
130: return Mangler.mangle(name, null);
131: }
132:
133: /**
134: * Returns a mangled string that represents the given field name.
135: *
136: * @param name - a string to be mangled.
137: * @return a mangled string.
138: */
139: public static String mangleFieldName(String name) {
140: return Mangler.mangle(name, FIELD_TABLE);
141: }
142:
143: /**
144: * Returns a mangled string that represents the given method name.
145: *
146: * @param name - a string to be mangled.
147: * @return a mangled string.
148: */
149: public static String mangleMethodName(String name) {
150: return Mangler.mangle(name, METHOD_TABLE);
151: }
152:
153: /**
154: * Returns a mangled string that represents the given class name.
155: *
156: * @param name - a string to be mangled.
157: * @return a mangled string.
158: */
159: public static String mangleClassName(String name) {
160: return Mangler.mangle(name, CLASS_TABLE);
161: }
162:
163: /**
164: * Returns a mangled string that represents the given macro.
165: *
166: * @param name - a string to be mangled.
167: * @return a mangled string.
168: */
169: public static String mangleMacro(String name) {
170: return Mangler.mangle(name, MACRO_TABLE);
171: }
172:
173: /**
174: * Returns a mangled string that represents the given file name.
175: *
176: * @param name - a string to be mangled.
177: * @return a mangled string.
178: */
179: public static String mangleFileName(String name) {
180: return Mangler.mangle(name, FILE_TABLE);
181: }
182:
183: }
|