slang_rs_reflect_utils.cpp revision b1980a2eedc56df92786afc291e00f26659a60ad
13f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang#include "slang_rs_reflect_utils.hpp" 23f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang 33f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang#include <cstdlib> 43f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang#include <cstdio> 5b1980a2eedc56df92786afc291e00f26659a60adMike Lockwood#include <cstring> 63f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang#include <fstream> 73f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang 83f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang#include <sys/stat.h> 93f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang#include <sys/types.h> 103f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang 113f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wangnamespace slang { 123f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang 133f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wangusing std::string; 143f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang 153f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wangstring RSSlangReflectUtils::ComputePackagedPath( 163f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang const std::string& prefixPath, const std::string& packageName) { 173f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang string packaged_path(prefixPath); 183f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang if (!prefixPath.empty() && (prefixPath[prefixPath.length() - 1] != '/')) { 193f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang packaged_path += "/"; 203f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang } 213f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang size_t s = packaged_path.length(); 223f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang packaged_path += packageName; 233f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang while (s < packaged_path.length()) { 243f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang if (packaged_path[s] == '.') { 253f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang packaged_path[s] = '/'; 263f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang } 273f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang ++s; 283f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang } 293f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang return packaged_path; 303f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang} 313f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang 323f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wangstatic string InternalFileNameConvert(const char* rsFileName, bool camelCase) { 333f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang const char* dot = rsFileName + strlen(rsFileName); 343f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang const char* slash = dot - 1; 353f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang while (slash >= rsFileName) { 363f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang if (*slash == '/') { 373f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang break; 383f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang } 393f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang if ((*slash == '.') && (*dot == 0)) { 403f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang dot = slash; 413f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang } 423f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang --slash; 433f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang } 443f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang ++slash; 453f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang char ret[256]; 463f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang bool need_cap = true; 473f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang int i = 0; 483f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang for (; (i < 255) && (slash < dot); ++slash) { 493f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang if (isalnum(*slash)) { 503f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang if (need_cap && camelCase) { 513f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang ret[i] = toupper(*slash); 523f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang } else { 533f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang ret[i] = *slash; 543f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang } 553f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang need_cap = false; 563f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang ++i; 573f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang } else { 583f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang need_cap = true; 593f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang } 603f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang } 613f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang ret[i] = 0; 623f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang return string(ret); 633f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang} 643f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang 653f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wangstd::string RSSlangReflectUtils::JavaClassNameFromRSFileName( 663f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang const char* rsFileName) { 673f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang return InternalFileNameConvert(rsFileName, true); 683f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang} 693f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang 703f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang 713f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wangstd::string RSSlangReflectUtils::BCFileNameFromRSFileName( 723f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang const char* rsFileName) { 733f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang return InternalFileNameConvert(rsFileName, false); 743f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang} 753f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang 763f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wangbool RSSlangReflectUtils::mkdir_p(const char* path) { 773f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang char buf[256]; 783f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang char *tmp, *p = NULL; 793f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang size_t len = strlen(path); 803f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang 813f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang if (len + 1 <= sizeof(buf)) 823f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang tmp = buf; 833f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang else 843f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang tmp = new char [len + 1]; 853f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang 863f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang strcpy(tmp, path); 873f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang 883f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang if (tmp[len - 1] == '/') 893f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang tmp[len - 1] = 0; 903f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang 913f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang for (p = tmp + 1; *p; p++) { 923f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang if (*p == '/') { 933f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang *p = 0; 943f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang mkdir(tmp, S_IRWXU); 953f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang *p = '/'; 963f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang } 973f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang } 983f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang mkdir(tmp, S_IRWXU); 993f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang 1003f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang if (tmp != buf) 1013f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang delete[] tmp; 1023f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang 1033f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang return true; 1043f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang} 1053f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang 1063f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wangbool RSSlangReflectUtils::EncodeBitcodeToJavaFile( 1073f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang const char* rsFileName, const char* inputBCFileName, 1083f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang const std::string& outputPath, const std::string& packageName) { 1093f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang 1103f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang FILE* pfin = fopen(inputBCFileName, "rb"); 1113f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang if (pfin == NULL) { 1123f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang return false; 1133f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang } 1143f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang 1153f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang string output_path = ComputePackagedPath(outputPath, packageName); 1163f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang if (!mkdir_p(output_path.c_str())) { 1173f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang return false; 1183f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang } 1193f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang 1203f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang string clazz_name(JavaClassNameFromRSFileName(rsFileName)); 1213f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang clazz_name += "BitCode"; 1223f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang string filename(clazz_name); 1233f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang filename += ".java"; 1243f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang 1253f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang string output_filename(output_path); 1263f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang output_filename += "/"; 1273f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang output_filename += filename; 1283f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang printf("Generating %s ...\n", filename.c_str()); 1293f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang FILE* pfout = fopen(output_filename.c_str(), "w"); 1303f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang if (pfout == NULL) { 1313f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang return false; 1323f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang } 1333f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang 1343f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang // Output the header 1353f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang fprintf(pfout, "/*\n"); 1363f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang fprintf(pfout, " * This file is auto-generated. DO NOT MODIFY!\n"); 1373f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang fprintf(pfout, " * The source RenderScript file: %s\n", rsFileName); 1383f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang fprintf(pfout, " */\n\n"); 1393f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang fprintf(pfout, "package %s;\n\n", packageName.c_str()); 1403f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang fprintf(pfout, "/**\n"); 1413f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang fprintf(pfout, " * @hide\n"); 1423f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang fprintf(pfout, " */\n"); 1433f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang fprintf(pfout, "public class %s {\n", clazz_name.c_str()); 1443f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang fprintf(pfout, "\n"); 1453f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang fprintf(pfout, " // return byte array representation of the bitcode file.\n"); 1463f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang fprintf(pfout, " public static byte[] getBitCode() {\n"); 1473f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang fprintf(pfout, " byte[] bc = new byte[data.length];\n"); 1483f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang fprintf(pfout, " System.arraycopy(data, 0, bc, 0, data.length);\n"); 1493f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang fprintf(pfout, " return bc;\n"); 1503f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang fprintf(pfout, " }\n"); 1513f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang fprintf(pfout, "\n"); 1523f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang fprintf(pfout, " // byte array representation of the bitcode file.\n"); 1533f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang fprintf(pfout, " private static final byte[] data = {\n"); 1543f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang 1553f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang // output the data 1563f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang const static int BUFF_SIZE = 0x10000; 1573f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang char* buff = new char[BUFF_SIZE]; 1583f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang int read_length; 1593f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang while ((read_length = fread(buff, 1, BUFF_SIZE, pfin)) > 0) { 1603f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang const static int LINE_BYTE_NUM = 16; 1613f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang char out_line[LINE_BYTE_NUM*6 + 10]; 1623f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang const char* out_line_end = out_line + sizeof(out_line); 1633f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang char* p = out_line; 1643f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang 1653f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang int write_length = 0; 1663f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang while (write_length < read_length) { 1673f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang p += snprintf(p, out_line_end - p, " %4d,", (int)buff[write_length]); 1683f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang ++write_length; 1693f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang if (((write_length % LINE_BYTE_NUM) == 0) 1703f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang || (write_length == read_length)) { 1713f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang fprintf(pfout, " "); 1723f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang fprintf(pfout, out_line); 1733f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang fprintf(pfout, "\n"); 1743f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang p = out_line; 1753f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang } 1763f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang } 1773f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang 1783f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang } 1793f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang delete []buff; 1803f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang 1813f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang // the rest of the java file. 1823f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang fprintf(pfout, " };\n"); 1833f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang fprintf(pfout, "}\n"); 1843f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang 1853f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang fclose(pfin); 1863f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang fclose(pfout); 1873f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang return true; 1883f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang} 1893f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang 1903f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang} 191