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