Ying Wang | 3f8b44d | 2010-09-04 01:17:01 -0700 | [diff] [blame] | 1 | #include "slang_rs_reflect_utils.hpp" |
| 2 | |
| 3 | #include <cstdlib> |
| 4 | #include <cstdio> |
Mike Lockwood | b1980a2 | 2010-09-08 10:20:40 -0400 | [diff] [blame^] | 5 | #include <cstring> |
Ying Wang | 3f8b44d | 2010-09-04 01:17:01 -0700 | [diff] [blame] | 6 | #include <fstream> |
| 7 | |
| 8 | #include <sys/stat.h> |
| 9 | #include <sys/types.h> |
| 10 | |
| 11 | namespace slang { |
| 12 | |
| 13 | using std::string; |
| 14 | |
| 15 | string 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 | |
| 32 | static 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 | |
| 65 | std::string RSSlangReflectUtils::JavaClassNameFromRSFileName( |
| 66 | const char* rsFileName) { |
| 67 | return InternalFileNameConvert(rsFileName, true); |
| 68 | } |
| 69 | |
| 70 | |
| 71 | std::string RSSlangReflectUtils::BCFileNameFromRSFileName( |
| 72 | const char* rsFileName) { |
| 73 | return InternalFileNameConvert(rsFileName, false); |
| 74 | } |
| 75 | |
| 76 | bool 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 | |
| 106 | bool 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 | } |