slang_rs_reflect_utils.cpp revision b1980a2eedc56df92786afc291e00f26659a60ad
1#include "slang_rs_reflect_utils.hpp" 2 3#include <cstdlib> 4#include <cstdio> 5#include <cstring> 6#include <fstream> 7 8#include <sys/stat.h> 9#include <sys/types.h> 10 11namespace slang { 12 13using std::string; 14 15string RSSlangReflectUtils::ComputePackagedPath( 16 const std::string& prefixPath, const std::string& packageName) { 17 string packaged_path(prefixPath); 18 if (!prefixPath.empty() && (prefixPath[prefixPath.length() - 1] != '/')) { 19 packaged_path += "/"; 20 } 21 size_t s = packaged_path.length(); 22 packaged_path += packageName; 23 while (s < packaged_path.length()) { 24 if (packaged_path[s] == '.') { 25 packaged_path[s] = '/'; 26 } 27 ++s; 28 } 29 return packaged_path; 30} 31 32static string InternalFileNameConvert(const char* rsFileName, bool camelCase) { 33 const char* dot = rsFileName + strlen(rsFileName); 34 const char* slash = dot - 1; 35 while (slash >= rsFileName) { 36 if (*slash == '/') { 37 break; 38 } 39 if ((*slash == '.') && (*dot == 0)) { 40 dot = slash; 41 } 42 --slash; 43 } 44 ++slash; 45 char ret[256]; 46 bool need_cap = true; 47 int i = 0; 48 for (; (i < 255) && (slash < dot); ++slash) { 49 if (isalnum(*slash)) { 50 if (need_cap && camelCase) { 51 ret[i] = toupper(*slash); 52 } else { 53 ret[i] = *slash; 54 } 55 need_cap = false; 56 ++i; 57 } else { 58 need_cap = true; 59 } 60 } 61 ret[i] = 0; 62 return string(ret); 63} 64 65std::string RSSlangReflectUtils::JavaClassNameFromRSFileName( 66 const char* rsFileName) { 67 return InternalFileNameConvert(rsFileName, true); 68} 69 70 71std::string RSSlangReflectUtils::BCFileNameFromRSFileName( 72 const char* rsFileName) { 73 return InternalFileNameConvert(rsFileName, false); 74} 75 76bool RSSlangReflectUtils::mkdir_p(const char* path) { 77 char buf[256]; 78 char *tmp, *p = NULL; 79 size_t len = strlen(path); 80 81 if (len + 1 <= sizeof(buf)) 82 tmp = buf; 83 else 84 tmp = new char [len + 1]; 85 86 strcpy(tmp, path); 87 88 if (tmp[len - 1] == '/') 89 tmp[len - 1] = 0; 90 91 for (p = tmp + 1; *p; p++) { 92 if (*p == '/') { 93 *p = 0; 94 mkdir(tmp, S_IRWXU); 95 *p = '/'; 96 } 97 } 98 mkdir(tmp, S_IRWXU); 99 100 if (tmp != buf) 101 delete[] tmp; 102 103 return true; 104} 105 106bool RSSlangReflectUtils::EncodeBitcodeToJavaFile( 107 const char* rsFileName, const char* inputBCFileName, 108 const std::string& outputPath, const std::string& packageName) { 109 110 FILE* pfin = fopen(inputBCFileName, "rb"); 111 if (pfin == NULL) { 112 return false; 113 } 114 115 string output_path = ComputePackagedPath(outputPath, packageName); 116 if (!mkdir_p(output_path.c_str())) { 117 return false; 118 } 119 120 string clazz_name(JavaClassNameFromRSFileName(rsFileName)); 121 clazz_name += "BitCode"; 122 string filename(clazz_name); 123 filename += ".java"; 124 125 string output_filename(output_path); 126 output_filename += "/"; 127 output_filename += filename; 128 printf("Generating %s ...\n", filename.c_str()); 129 FILE* pfout = fopen(output_filename.c_str(), "w"); 130 if (pfout == NULL) { 131 return false; 132 } 133 134 // Output the header 135 fprintf(pfout, "/*\n"); 136 fprintf(pfout, " * This file is auto-generated. DO NOT MODIFY!\n"); 137 fprintf(pfout, " * The source RenderScript file: %s\n", rsFileName); 138 fprintf(pfout, " */\n\n"); 139 fprintf(pfout, "package %s;\n\n", packageName.c_str()); 140 fprintf(pfout, "/**\n"); 141 fprintf(pfout, " * @hide\n"); 142 fprintf(pfout, " */\n"); 143 fprintf(pfout, "public class %s {\n", clazz_name.c_str()); 144 fprintf(pfout, "\n"); 145 fprintf(pfout, " // return byte array representation of the bitcode file.\n"); 146 fprintf(pfout, " public static byte[] getBitCode() {\n"); 147 fprintf(pfout, " byte[] bc = new byte[data.length];\n"); 148 fprintf(pfout, " System.arraycopy(data, 0, bc, 0, data.length);\n"); 149 fprintf(pfout, " return bc;\n"); 150 fprintf(pfout, " }\n"); 151 fprintf(pfout, "\n"); 152 fprintf(pfout, " // byte array representation of the bitcode file.\n"); 153 fprintf(pfout, " private static final byte[] data = {\n"); 154 155 // output the data 156 const static int BUFF_SIZE = 0x10000; 157 char* buff = new char[BUFF_SIZE]; 158 int read_length; 159 while ((read_length = fread(buff, 1, BUFF_SIZE, pfin)) > 0) { 160 const static int LINE_BYTE_NUM = 16; 161 char out_line[LINE_BYTE_NUM*6 + 10]; 162 const char* out_line_end = out_line + sizeof(out_line); 163 char* p = out_line; 164 165 int write_length = 0; 166 while (write_length < read_length) { 167 p += snprintf(p, out_line_end - p, " %4d,", (int)buff[write_length]); 168 ++write_length; 169 if (((write_length % LINE_BYTE_NUM) == 0) 170 || (write_length == read_length)) { 171 fprintf(pfout, " "); 172 fprintf(pfout, out_line); 173 fprintf(pfout, "\n"); 174 p = out_line; 175 } 176 } 177 178 } 179 delete []buff; 180 181 // the rest of the java file. 182 fprintf(pfout, " };\n"); 183 fprintf(pfout, "}\n"); 184 185 fclose(pfin); 186 fclose(pfout); 187 return true; 188} 189 190} 191