blob: b718913333ef0e73809ada8245d90e702b9f871a [file] [log] [blame]
Ying Wang3f8b44d2010-09-04 01:17:01 -07001#include "slang_rs_reflect_utils.hpp"
2
3#include <cstdlib>
4#include <cstdio>
Mike Lockwoodb1980a22010-09-08 10:20:40 -04005#include <cstring>
Ying Wang3f8b44d2010-09-04 01:17:01 -07006#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}