00001
00011 #include "demangle_java_symbol.h"
00012
00013 #include <algorithm>
00014
00015 using namespace std;
00016
00017 namespace {
00018
00039 bool array_type(string & result,
00040 string::const_iterator & begin, string::const_iterator end);
00041 bool object_type(string & result,
00042 string::const_iterator & begin, string::const_iterator end);
00043
00044
00045 bool base_type(string & result,
00046 string::const_iterator & begin, string::const_iterator end)
00047 {
00048 bool ret = true;
00049
00050 if (begin == end)
00051 return false;
00052
00053 switch (*begin) {
00054 case 'B': result += "byte"; break;
00055 case 'C': result += "char"; break;
00056 case 'D': result += "double"; break;
00057 case 'F': result += "float"; break;
00058 case 'I': result += "int"; break;
00059 case 'J': result += "long"; break;
00060 case 'S': result += "short"; break;
00061 case 'Z': result += "boolean"; break;
00062 default: ret = false; break;
00063 }
00064
00065 if (ret)
00066 ++begin;
00067 return ret;
00068 }
00069
00070
00071 bool field_type(string & result,
00072 string::const_iterator & begin, string::const_iterator end)
00073 {
00074 if (base_type(result, begin, end))
00075 return true;
00076
00077 if (object_type(result, begin, end))
00078 return true;
00079
00080 if (array_type(result, begin, end))
00081 return true;
00082
00083 return false;
00084 }
00085
00086
00087 bool array_type(string & result,
00088 string::const_iterator & begin, string::const_iterator end)
00089 {
00090 if (begin == end || *begin != '[')
00091 return false;
00092
00093 ++begin;
00094 if (field_type(result, begin, end)) {
00095 result += "[]";
00096 return true;
00097 }
00098
00099 return false;
00100 }
00101
00102
00103 bool list_of_field_type(string & result,
00104 string::const_iterator & begin, string::const_iterator end)
00105 {
00106 bool first = false;
00107 while (begin != end) {
00108 if (first)
00109 result += ", ";
00110
00111 if (!field_type(result, begin, end))
00112 return false;
00113
00114 first = true;
00115 }
00116
00117 return true;
00118 }
00119
00120
00121 bool return_descriptor(string & result,
00122 string::const_iterator & begin, string::const_iterator end)
00123 {
00124 if (begin == end)
00125 return false;
00126 if (*begin == 'V') {
00127 ++begin;
00128 result = "void " + result;
00129 return true;
00130 }
00131
00132 string temp;
00133 if (!field_type(temp, begin, end))
00134 return false;
00135 result = temp + " " + result;
00136
00137 return true;
00138 }
00139
00140
00141 bool method_descriptor(string & result,
00142 string::const_iterator & begin, string::const_iterator end)
00143 {
00144 if (begin == end || *begin != '(')
00145 return false;
00146 ++begin;
00147 string::const_iterator pos = find(begin, end, ')');
00148 if (pos == end)
00149 return false;
00150
00151 result += "(";
00152
00153 if (!list_of_field_type(result, begin, pos))
00154 return false;
00155
00156 if (begin == end || *begin != ')')
00157 return false;
00158
00159 ++begin;
00160
00161 if (!return_descriptor(result, begin, end))
00162 return false;
00163
00164 result += ')';
00165
00166 return true;
00167 }
00168
00169
00170 bool methode_name(string & result,
00171 string::const_iterator & begin, string::const_iterator end)
00172 {
00173 if (begin == end)
00174 return false;
00175
00176 string::const_iterator pos = find(begin, end, '(');
00177 if (pos == end)
00178 return false;
00179
00180 result += '.' + string(begin, pos);
00181 begin = pos;
00182
00183 return true;
00184 }
00185
00186
00187 bool object_type(string & result,
00188 string::const_iterator & begin, string::const_iterator end)
00189 {
00190 if (begin == end || *begin != 'L')
00191 return false;
00192 string::const_iterator pos = find(begin, end, ';');
00193 if (pos == end)
00194 return false;
00195
00196 string temp = string(begin + 1, pos);
00197 replace(temp.begin(), temp.end(), '/', '.');
00198 result += temp;
00199
00200 begin = pos + 1;
00201
00202 return true;
00203 }
00204
00205
00206 string demangle_symbol(string::const_iterator begin,
00207 string::const_iterator end)
00208 {
00209 string result;
00210
00211 if (!object_type(result, begin, end))
00212 return string();
00213
00214 if (!methode_name(result, begin, end))
00215 return string();
00216
00217 if (!method_descriptor(result, begin, end))
00218 return string();
00219
00220 if (begin != end) {
00221 if (*begin == '~') {
00222
00223 result += string(begin, end);
00224 } else {
00225 return string();
00226 }
00227 }
00228
00229 return result;
00230 }
00231
00232 }
00233
00234
00235 string const demangle_java_symbol(string const & name)
00236 {
00237 return demangle_symbol(name.begin(), name.end());
00238 }