/usr/share/doc/libserp-java/api/src-html/serp/bytecode/NameCache.html is in libserp-java-doc 1.15.1-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head>
<title>Source code</title>
<link rel="stylesheet" type="text/css" href="../../../stylesheet.css" title="Style">
</head>
<body>
<div class="sourceContainer">
<pre><span class="sourceLineNo">001</span>package serp.bytecode;<a name="line.1"></a>
<span class="sourceLineNo">002</span><a name="line.2"></a>
<span class="sourceLineNo">003</span>import java.util.*;<a name="line.3"></a>
<span class="sourceLineNo">004</span><a name="line.4"></a>
<span class="sourceLineNo">005</span>/**<a name="line.5"></a>
<span class="sourceLineNo">006</span> * Caching and conversion of names in both internal and external form.<a name="line.6"></a>
<span class="sourceLineNo">007</span> *<a name="line.7"></a>
<span class="sourceLineNo">008</span> * @author Abe White<a name="line.8"></a>
<span class="sourceLineNo">009</span> */<a name="line.9"></a>
<span class="sourceLineNo">010</span>public class NameCache {<a name="line.10"></a>
<span class="sourceLineNo">011</span> static final Object[][] _codes = new Object[][] {<a name="line.11"></a>
<span class="sourceLineNo">012</span> { byte.class, "B" },<a name="line.12"></a>
<span class="sourceLineNo">013</span> { char.class, "C" },<a name="line.13"></a>
<span class="sourceLineNo">014</span> { double.class, "D" },<a name="line.14"></a>
<span class="sourceLineNo">015</span> { float.class, "F" },<a name="line.15"></a>
<span class="sourceLineNo">016</span> { int.class, "I" },<a name="line.16"></a>
<span class="sourceLineNo">017</span> { long.class, "J" },<a name="line.17"></a>
<span class="sourceLineNo">018</span> { short.class, "S" },<a name="line.18"></a>
<span class="sourceLineNo">019</span> { boolean.class, "Z" },<a name="line.19"></a>
<span class="sourceLineNo">020</span> { void.class, "V" },<a name="line.20"></a>
<span class="sourceLineNo">021</span> };<a name="line.21"></a>
<span class="sourceLineNo">022</span><a name="line.22"></a>
<span class="sourceLineNo">023</span> // caches of internal and external forms of strings<a name="line.23"></a>
<span class="sourceLineNo">024</span> private final Map _internal = new HashMap();<a name="line.24"></a>
<span class="sourceLineNo">025</span> private final Map _internalDescriptor = new HashMap();<a name="line.25"></a>
<span class="sourceLineNo">026</span> private final Map _external = new HashMap();<a name="line.26"></a>
<span class="sourceLineNo">027</span> private final Map _externalHuman = new HashMap();<a name="line.27"></a>
<span class="sourceLineNo">028</span><a name="line.28"></a>
<span class="sourceLineNo">029</span> /**<a name="line.29"></a>
<span class="sourceLineNo">030</span> * Converts the given class name to its internal form.<a name="line.30"></a>
<span class="sourceLineNo">031</span> *<a name="line.31"></a>
<span class="sourceLineNo">032</span> * @param className the name to convert<a name="line.32"></a>
<span class="sourceLineNo">033</span> * @param descriptor true if the name is to be used for a descriptor<a name="line.33"></a>
<span class="sourceLineNo">034</span> * section -- the difference seems to be that for<a name="line.34"></a>
<span class="sourceLineNo">035</span> * descriptors, non-primitives are prefixed with 'L' and ended with ';'<a name="line.35"></a>
<span class="sourceLineNo">036</span> */<a name="line.36"></a>
<span class="sourceLineNo">037</span> public String getInternalForm(String className, boolean descriptor) {<a name="line.37"></a>
<span class="sourceLineNo">038</span> if (className == null || className.length() == 0)<a name="line.38"></a>
<span class="sourceLineNo">039</span> return className;<a name="line.39"></a>
<span class="sourceLineNo">040</span><a name="line.40"></a>
<span class="sourceLineNo">041</span> Map cache = (descriptor) ? _internalDescriptor : _internal;<a name="line.41"></a>
<span class="sourceLineNo">042</span> String cached = (String) cache.get(className);<a name="line.42"></a>
<span class="sourceLineNo">043</span> if (cached != null)<a name="line.43"></a>
<span class="sourceLineNo">044</span> return cached;<a name="line.44"></a>
<span class="sourceLineNo">045</span><a name="line.45"></a>
<span class="sourceLineNo">046</span> String ret = getInternalFormInternal(className, descriptor);<a name="line.46"></a>
<span class="sourceLineNo">047</span> cache.put(className, ret);<a name="line.47"></a>
<span class="sourceLineNo">048</span> return ret;<a name="line.48"></a>
<span class="sourceLineNo">049</span> }<a name="line.49"></a>
<span class="sourceLineNo">050</span><a name="line.50"></a>
<span class="sourceLineNo">051</span> /**<a name="line.51"></a>
<span class="sourceLineNo">052</span> * @see #getInternalForm<a name="line.52"></a>
<span class="sourceLineNo">053</span> */<a name="line.53"></a>
<span class="sourceLineNo">054</span> private String getInternalFormInternal(String cls, boolean descriptor) {<a name="line.54"></a>
<span class="sourceLineNo">055</span> // handle array types, whether already in internal form or not<a name="line.55"></a>
<span class="sourceLineNo">056</span> StringBuilder prefix = new StringBuilder();<a name="line.56"></a>
<span class="sourceLineNo">057</span> while (true) {<a name="line.57"></a>
<span class="sourceLineNo">058</span> if (cls.endsWith("[]")) {<a name="line.58"></a>
<span class="sourceLineNo">059</span> prefix.append("[");<a name="line.59"></a>
<span class="sourceLineNo">060</span> cls = cls.substring(0, cls.length() - 2);<a name="line.60"></a>
<span class="sourceLineNo">061</span> } else if (cls.startsWith("[")) {<a name="line.61"></a>
<span class="sourceLineNo">062</span> prefix.append("[");<a name="line.62"></a>
<span class="sourceLineNo">063</span> cls = cls.substring(1);<a name="line.63"></a>
<span class="sourceLineNo">064</span> } else<a name="line.64"></a>
<span class="sourceLineNo">065</span> break;<a name="line.65"></a>
<span class="sourceLineNo">066</span> }<a name="line.66"></a>
<span class="sourceLineNo">067</span><a name="line.67"></a>
<span class="sourceLineNo">068</span> // handle primitive array types<a name="line.68"></a>
<span class="sourceLineNo">069</span> for (int i = 0; i < _codes.length; i++)<a name="line.69"></a>
<span class="sourceLineNo">070</span> if (cls.equals(_codes[i][1].toString()) <a name="line.70"></a>
<span class="sourceLineNo">071</span> || cls.equals(_codes[i][0].toString()))<a name="line.71"></a>
<span class="sourceLineNo">072</span> return prefix.append(_codes[i][1]).toString();<a name="line.72"></a>
<span class="sourceLineNo">073</span><a name="line.73"></a>
<span class="sourceLineNo">074</span> // if in descriptor form, strip leading 'L' and trailing ';'<a name="line.74"></a>
<span class="sourceLineNo">075</span> if (cls.startsWith("L") && cls.endsWith(";"))<a name="line.75"></a>
<span class="sourceLineNo">076</span> cls = cls.substring(1, cls.length() - 1);<a name="line.76"></a>
<span class="sourceLineNo">077</span><a name="line.77"></a>
<span class="sourceLineNo">078</span> // non-primitive; make sure we don't prefix method descriptors with 'L'<a name="line.78"></a>
<span class="sourceLineNo">079</span> cls = cls.replace('.', '/');<a name="line.79"></a>
<span class="sourceLineNo">080</span> if ((descriptor || prefix.length() > 0) && cls.charAt(0) != '(')<a name="line.80"></a>
<span class="sourceLineNo">081</span> return prefix.append("L").append(cls).append(";").toString();<a name="line.81"></a>
<span class="sourceLineNo">082</span> return prefix.append(cls).toString();<a name="line.82"></a>
<span class="sourceLineNo">083</span> }<a name="line.83"></a>
<span class="sourceLineNo">084</span><a name="line.84"></a>
<span class="sourceLineNo">085</span> /**<a name="line.85"></a>
<span class="sourceLineNo">086</span> * Given the internal name of the class, return the 'normal' java name.<a name="line.86"></a>
<span class="sourceLineNo">087</span> *<a name="line.87"></a>
<span class="sourceLineNo">088</span> * @param internalName the internal name being used<a name="line.88"></a>
<span class="sourceLineNo">089</span> * @param humanReadable if the returned name should be in human-readable<a name="line.89"></a>
<span class="sourceLineNo">090</span> * form, rather than a form suitable for a<a name="line.90"></a>
<span class="sourceLineNo">091</span> * {@link Class#forName} call -- the difference<a name="line.91"></a>
<span class="sourceLineNo">092</span> * lies in the handling of arrays<a name="line.92"></a>
<span class="sourceLineNo">093</span> */<a name="line.93"></a>
<span class="sourceLineNo">094</span> public String getExternalForm(String internalName, boolean humanReadable) {<a name="line.94"></a>
<span class="sourceLineNo">095</span> if (internalName == null || internalName.length() == 0)<a name="line.95"></a>
<span class="sourceLineNo">096</span> return internalName;<a name="line.96"></a>
<span class="sourceLineNo">097</span><a name="line.97"></a>
<span class="sourceLineNo">098</span> Map cache = (humanReadable) ? _externalHuman : _external;<a name="line.98"></a>
<span class="sourceLineNo">099</span> String cached = (String) cache.get(internalName);<a name="line.99"></a>
<span class="sourceLineNo">100</span> if (cached != null)<a name="line.100"></a>
<span class="sourceLineNo">101</span> return cached;<a name="line.101"></a>
<span class="sourceLineNo">102</span><a name="line.102"></a>
<span class="sourceLineNo">103</span> String ret = getExternalFormInternal(internalName, humanReadable);<a name="line.103"></a>
<span class="sourceLineNo">104</span> cache.put(internalName, ret);<a name="line.104"></a>
<span class="sourceLineNo">105</span> return ret;<a name="line.105"></a>
<span class="sourceLineNo">106</span> }<a name="line.106"></a>
<span class="sourceLineNo">107</span><a name="line.107"></a>
<span class="sourceLineNo">108</span> /**<a name="line.108"></a>
<span class="sourceLineNo">109</span> * @see #getExternalForm<a name="line.109"></a>
<span class="sourceLineNo">110</span> */<a name="line.110"></a>
<span class="sourceLineNo">111</span> private String getExternalFormInternal(String intern, <a name="line.111"></a>
<span class="sourceLineNo">112</span> boolean humanReadable) {<a name="line.112"></a>
<span class="sourceLineNo">113</span> if (!humanReadable) {<a name="line.113"></a>
<span class="sourceLineNo">114</span> // check against primitives<a name="line.114"></a>
<span class="sourceLineNo">115</span> for (int i = 0; i < _codes.length; i++) {<a name="line.115"></a>
<span class="sourceLineNo">116</span> if (intern.equals(_codes[i][1].toString()))<a name="line.116"></a>
<span class="sourceLineNo">117</span> return _codes[i][0].toString();<a name="line.117"></a>
<span class="sourceLineNo">118</span> if (intern.equals(_codes[i][0].toString()))<a name="line.118"></a>
<span class="sourceLineNo">119</span> return intern;<a name="line.119"></a>
<span class="sourceLineNo">120</span> }<a name="line.120"></a>
<span class="sourceLineNo">121</span> intern = getInternalForm(intern, false);<a name="line.121"></a>
<span class="sourceLineNo">122</span> return intern.replace('/', '.');<a name="line.122"></a>
<span class="sourceLineNo">123</span> }<a name="line.123"></a>
<span class="sourceLineNo">124</span><a name="line.124"></a>
<span class="sourceLineNo">125</span> // handle arrays<a name="line.125"></a>
<span class="sourceLineNo">126</span> StringBuilder postfix = new StringBuilder(2);<a name="line.126"></a>
<span class="sourceLineNo">127</span> while (intern.startsWith("[")) {<a name="line.127"></a>
<span class="sourceLineNo">128</span> intern = intern.substring(1);<a name="line.128"></a>
<span class="sourceLineNo">129</span> postfix.append("[]");<a name="line.129"></a>
<span class="sourceLineNo">130</span> }<a name="line.130"></a>
<span class="sourceLineNo">131</span><a name="line.131"></a>
<span class="sourceLineNo">132</span> // strip off leading 'L' and trailing ';'<a name="line.132"></a>
<span class="sourceLineNo">133</span> if (intern.endsWith(";"))<a name="line.133"></a>
<span class="sourceLineNo">134</span> intern = intern.substring(1, intern.length() - 1);<a name="line.134"></a>
<span class="sourceLineNo">135</span><a name="line.135"></a>
<span class="sourceLineNo">136</span> // check primitives<a name="line.136"></a>
<span class="sourceLineNo">137</span> for (int i = 0; i < _codes.length; i++)<a name="line.137"></a>
<span class="sourceLineNo">138</span> if (intern.equals(_codes[i][1].toString()))<a name="line.138"></a>
<span class="sourceLineNo">139</span> return _codes[i][0].toString() + postfix;<a name="line.139"></a>
<span class="sourceLineNo">140</span> return intern.replace('/', '.') + postfix;<a name="line.140"></a>
<span class="sourceLineNo">141</span> }<a name="line.141"></a>
<span class="sourceLineNo">142</span><a name="line.142"></a>
<span class="sourceLineNo">143</span> /**<a name="line.143"></a>
<span class="sourceLineNo">144</span> * Construct a method descriptor from the given return and parameter<a name="line.144"></a>
<span class="sourceLineNo">145</span> * types, which will be converted to internal form.<a name="line.145"></a>
<span class="sourceLineNo">146</span> */<a name="line.146"></a>
<span class="sourceLineNo">147</span> public String getDescriptor(String returnType, String[] paramTypes) {<a name="line.147"></a>
<span class="sourceLineNo">148</span> StringBuilder buf = new StringBuilder();<a name="line.148"></a>
<span class="sourceLineNo">149</span> buf.append("(");<a name="line.149"></a>
<span class="sourceLineNo">150</span> if (paramTypes != null) {<a name="line.150"></a>
<span class="sourceLineNo">151</span> for (int i = 0; i < paramTypes.length; i++) {<a name="line.151"></a>
<span class="sourceLineNo">152</span> if (paramTypes[i] == null) <a name="line.152"></a>
<span class="sourceLineNo">153</span> throw new NullPointerException("paramTypes[" + i <a name="line.153"></a>
<span class="sourceLineNo">154</span> + "] = null");<a name="line.154"></a>
<span class="sourceLineNo">155</span> buf.append(getInternalForm(paramTypes[i], true));<a name="line.155"></a>
<span class="sourceLineNo">156</span> }<a name="line.156"></a>
<span class="sourceLineNo">157</span> }<a name="line.157"></a>
<span class="sourceLineNo">158</span><a name="line.158"></a>
<span class="sourceLineNo">159</span> buf.append(")");<a name="line.159"></a>
<span class="sourceLineNo">160</span> if (returnType == null)<a name="line.160"></a>
<span class="sourceLineNo">161</span> throw new NullPointerException("returnType = null");<a name="line.161"></a>
<span class="sourceLineNo">162</span><a name="line.162"></a>
<span class="sourceLineNo">163</span> buf.append(getInternalForm(returnType, true));<a name="line.163"></a>
<span class="sourceLineNo">164</span> return buf.toString();<a name="line.164"></a>
<span class="sourceLineNo">165</span> }<a name="line.165"></a>
<span class="sourceLineNo">166</span><a name="line.166"></a>
<span class="sourceLineNo">167</span> /**<a name="line.167"></a>
<span class="sourceLineNo">168</span> * Return the return type, in internal form, for the given method<a name="line.168"></a>
<span class="sourceLineNo">169</span> * descriptor string.<a name="line.169"></a>
<span class="sourceLineNo">170</span> */<a name="line.170"></a>
<span class="sourceLineNo">171</span> public String getDescriptorReturnName(String descriptor) {<a name="line.171"></a>
<span class="sourceLineNo">172</span> int index = descriptor.indexOf(')');<a name="line.172"></a>
<span class="sourceLineNo">173</span> if (index == -1)<a name="line.173"></a>
<span class="sourceLineNo">174</span> return "";<a name="line.174"></a>
<span class="sourceLineNo">175</span> return descriptor.substring(descriptor.indexOf(')') + 1);<a name="line.175"></a>
<span class="sourceLineNo">176</span> }<a name="line.176"></a>
<span class="sourceLineNo">177</span><a name="line.177"></a>
<span class="sourceLineNo">178</span> /**<a name="line.178"></a>
<span class="sourceLineNo">179</span> * Return the parameter types, in internal form, for the given method<a name="line.179"></a>
<span class="sourceLineNo">180</span> * descriptor string.<a name="line.180"></a>
<span class="sourceLineNo">181</span> */<a name="line.181"></a>
<span class="sourceLineNo">182</span> public String[] getDescriptorParamNames(String descriptor) {<a name="line.182"></a>
<span class="sourceLineNo">183</span> if (descriptor == null || descriptor.length() == 0)<a name="line.183"></a>
<span class="sourceLineNo">184</span> return new String[0];<a name="line.184"></a>
<span class="sourceLineNo">185</span><a name="line.185"></a>
<span class="sourceLineNo">186</span> int index = descriptor.indexOf(')');<a name="line.186"></a>
<span class="sourceLineNo">187</span> if (index == -1)<a name="line.187"></a>
<span class="sourceLineNo">188</span> return new String[0];<a name="line.188"></a>
<span class="sourceLineNo">189</span><a name="line.189"></a>
<span class="sourceLineNo">190</span> // get rid of the parens and the return type<a name="line.190"></a>
<span class="sourceLineNo">191</span> descriptor = descriptor.substring(1, index);<a name="line.191"></a>
<span class="sourceLineNo">192</span><a name="line.192"></a>
<span class="sourceLineNo">193</span> // break the param string into individual params<a name="line.193"></a>
<span class="sourceLineNo">194</span> List tokens = new LinkedList();<a name="line.194"></a>
<span class="sourceLineNo">195</span> while (descriptor.length() > 0) {<a name="line.195"></a>
<span class="sourceLineNo">196</span> index = 0;<a name="line.196"></a>
<span class="sourceLineNo">197</span><a name="line.197"></a>
<span class="sourceLineNo">198</span> // skip the '[' up to the first letter code<a name="line.198"></a>
<span class="sourceLineNo">199</span> while (!Character.isLetter(descriptor.charAt(index)))<a name="line.199"></a>
<span class="sourceLineNo">200</span> index++;<a name="line.200"></a>
<span class="sourceLineNo">201</span><a name="line.201"></a>
<span class="sourceLineNo">202</span> // non-primitives always start with 'L' and end with ';'<a name="line.202"></a>
<span class="sourceLineNo">203</span> if (descriptor.charAt(index) == 'L')<a name="line.203"></a>
<span class="sourceLineNo">204</span> index = descriptor.indexOf(';');<a name="line.204"></a>
<span class="sourceLineNo">205</span><a name="line.205"></a>
<span class="sourceLineNo">206</span> tokens.add(descriptor.substring(0, index + 1));<a name="line.206"></a>
<span class="sourceLineNo">207</span> descriptor = descriptor.substring(index + 1);<a name="line.207"></a>
<span class="sourceLineNo">208</span> }<a name="line.208"></a>
<span class="sourceLineNo">209</span> return (String[]) tokens.toArray(new String[tokens.size()]);<a name="line.209"></a>
<span class="sourceLineNo">210</span> }<a name="line.210"></a>
<span class="sourceLineNo">211</span><a name="line.211"></a>
<span class="sourceLineNo">212</span> /**<a name="line.212"></a>
<span class="sourceLineNo">213</span> * Return the component type name for the given array type, or null<a name="line.213"></a>
<span class="sourceLineNo">214</span> * if the given string does not represent an array type name. The name<a name="line.214"></a>
<span class="sourceLineNo">215</span> * given should be in proper {@link Class#forName} form.<a name="line.215"></a>
<span class="sourceLineNo">216</span> */<a name="line.216"></a>
<span class="sourceLineNo">217</span> public String getComponentName(String name) {<a name="line.217"></a>
<span class="sourceLineNo">218</span> if (name == null || !name.startsWith("["))<a name="line.218"></a>
<span class="sourceLineNo">219</span> return null;<a name="line.219"></a>
<span class="sourceLineNo">220</span><a name="line.220"></a>
<span class="sourceLineNo">221</span> name = name.substring(1);<a name="line.221"></a>
<span class="sourceLineNo">222</span> if (!name.startsWith("[") && name.endsWith(";"))<a name="line.222"></a>
<span class="sourceLineNo">223</span> name = name.substring(1, name.length() - 1);<a name="line.223"></a>
<span class="sourceLineNo">224</span><a name="line.224"></a>
<span class="sourceLineNo">225</span> // will convert primitive type codes to names<a name="line.225"></a>
<span class="sourceLineNo">226</span> return getExternalForm(name, false);<a name="line.226"></a>
<span class="sourceLineNo">227</span> }<a name="line.227"></a>
<span class="sourceLineNo">228</span><a name="line.228"></a>
<span class="sourceLineNo">229</span> /**<a name="line.229"></a>
<span class="sourceLineNo">230</span> * Clear the cache.<a name="line.230"></a>
<span class="sourceLineNo">231</span> */<a name="line.231"></a>
<span class="sourceLineNo">232</span> public void clear() {<a name="line.232"></a>
<span class="sourceLineNo">233</span> _internal.clear();<a name="line.233"></a>
<span class="sourceLineNo">234</span> _internalDescriptor.clear();<a name="line.234"></a>
<span class="sourceLineNo">235</span> _external.clear();<a name="line.235"></a>
<span class="sourceLineNo">236</span> _externalHuman.clear();<a name="line.236"></a>
<span class="sourceLineNo">237</span> }<a name="line.237"></a>
<span class="sourceLineNo">238</span>}<a name="line.238"></a>
</pre>
</div>
</body>
</html>
|