demangle_java_symbol.cpp

Go to the documentation of this file.
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             // special case for disambiguated symbol.
00223             result += string(begin, end);
00224         } else {
00225             return string();
00226         }
00227     }
00228 
00229     return result;
00230 }
00231 
00232 } // anonymous namespace
00233 
00234 
00235 string const demangle_java_symbol(string const & name)
00236 {
00237     return demangle_symbol(name.begin(), name.end());
00238 }

Generated on 8 Nov 2012 for Oprofile by  doxygen 1.6.1