blob: f0b2dc0392169d9cba596bdac395b46533bd4daa [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.harmony.tools;
/**
* A helper class to mangle a string according to the Java Native Interface
* Specification.
*/
public class Mangler {
/**
* An array of the <code>String</code> pairs. This array
* contains the common substitute string pairs.
*/
private static final String COMMON_TABLE[] = {
"_", "_1",
";", "_2",
"[", "_3",
"./", "_"
};
/**
* A field names substitution table.
*/
private static final String FIELD_TABLE[][] = {
{ ".$", "_" }
};
/**
* A method names substitution table.
*/
private static final String METHOD_TABLE[][] = {
COMMON_TABLE,
{ "$", "_" }
};
/**
* A class names substitution table.
*/
private static final String CLASS_TABLE[][] = {
COMMON_TABLE,
{ "$", "_00024" }
};
/**
* A macros substitution table.
*/
private static final String MACRO_TABLE[][] = {
{ ".$", "_" }
};
/**
* A file names substitution table.
*/
private static final String FILE_TABLE[][] = {
{ ".$", "_" }
};
/**
* Returns a mangled string. The given string will be translated according
* the given substitution table. This table consists of one or more
* <code>String</code> arrays that contain the substitute string pair.
* The first element of each <code>String</code> pair in the array
* contains a set of chars represented as a string. Any of the given
* chars will be replaced with the second string of the pair
* in the result string. If table is null all the unicode
* chars will be replaced with an appropriate substitute string only.
*
* @param name - a string to be mangled.
* @param table - a substitution table. <code>null</code> is possible.
* @return a mangled string.
*/
private static String mangle(String name, String table[][]) {
StringBuffer result = new StringBuffer();
for (int i = 0; i < name.length(); i++) {
char c = name.charAt(i);
// Check the given table, if it is not null.
if (table != null) {
boolean found = false;
for (int k = 0; !found && k < table.length; k++) {
int l = 0;
while (l < table[k].length) {
if (table[k][l].indexOf(c) != -1) {
result.append(table[k][l + 1]);
found = true;
break;
}
l += 2;
}
}
// If c is found in the given substitution table we continue.
if (found) {
continue;
}
}
if (Character.UnicodeBlock.of(c) != Character.UnicodeBlock.BASIC_LATIN) {
// We have to prepare a string that looks like "_0XXXX",
// where "XXXX" is a string representation of a Unicode
// character. If the given string length is less than 4
// we have to prepend a missing number of '0' to the result.
String s = Integer.toHexString((int) c);
char code[] = new char[] {'0','0','0','0'};
int len = s.length();
int align = code.length - len;
int begin = len - code.length;
s.getChars(begin < 0 ? 0 : begin, len, code,
align < 0 ? 0 : align);
result.append("_0").append(code);
} else {
result.append(c);
}
}
return result.toString();
}
/**
* Returns a mangled string. All the unicode chars of the given string
* will be replaced with the <code>_0XXXX</code> char sequence,
* where XXXX is a numeric representation of a Unicode character.
*
* @param name - a string to be mangled.
* @return a mangled string.
*/
public static String mangleUnicode(String name) {
return Mangler.mangle(name, null);
}
/**
* Returns a mangled string that represents the given field name.
*
* @param name - a string to be mangled.
* @return a mangled string.
*/
public static String mangleFieldName(String name) {
return Mangler.mangle(name, FIELD_TABLE);
}
/**
* Returns a mangled string that represents the given method name.
*
* @param name - a string to be mangled.
* @return a mangled string.
*/
public static String mangleMethodName(String name) {
return Mangler.mangle(name, METHOD_TABLE);
}
/**
* Returns a mangled string that represents the given class name.
*
* @param name - a string to be mangled.
* @return a mangled string.
*/
public static String mangleClassName(String name) {
return Mangler.mangle(name, CLASS_TABLE);
}
/**
* Returns a mangled string that represents the given macro.
*
* @param name - a string to be mangled.
* @return a mangled string.
*/
public static String mangleMacro(String name) {
return Mangler.mangle(name, MACRO_TABLE);
}
/**
* Returns a mangled string that represents the given file name.
*
* @param name - a string to be mangled.
* @return a mangled string.
*/
public static String mangleFileName(String name) {
return Mangler.mangle(name, FILE_TABLE);
}
}