• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2012, The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <sys/stat.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 
21 #include <cstdarg>
22 #include <cctype>
23 
24 #include <algorithm>
25 #include <sstream>
26 #include <string>
27 #include <utility>
28 
29 #include "os_sep.h"
30 #include "slang_rs_context.h"
31 #include "slang_rs_export_var.h"
32 #include "slang_rs_export_foreach.h"
33 #include "slang_rs_export_func.h"
34 #include "slang_rs_reflect_utils.h"
35 #include "slang_version.h"
36 #include "slang_utils.h"
37 
38 #include "slang_rs_reflection_cpp.h"
39 
40 using namespace std;
41 
42 namespace slang {
43 
RSReflectionCpp(const RSContext * con)44 RSReflectionCpp::RSReflectionCpp(const RSContext *con) :
45     RSReflectionBase(con) {
46 
47 }
48 
~RSReflectionCpp()49 RSReflectionCpp::~RSReflectionCpp() {
50 
51 }
52 
reflect(const string & OutputPathBase,const string & InputFileName,const string & OutputBCFileName)53 bool RSReflectionCpp::reflect(const string &OutputPathBase,
54                               const string &InputFileName,
55                               const string &OutputBCFileName) {
56     mInputFileName = InputFileName;
57     mOutputPath = OutputPathBase;
58     mOutputBCFileName = OutputBCFileName;
59     mClassName = string("ScriptC_") + stripRS(InputFileName);
60 
61     makeHeader("android::renderscriptCpp::ScriptC");
62     std::vector< std::string > header(mText);
63     mText.clear();
64 
65     makeImpl("android::renderscriptCpp::ScriptC");
66     std::vector< std::string > cpp(mText);
67     mText.clear();
68 
69 
70     RSReflectionBase::writeFile(mClassName + ".h", header);
71     RSReflectionBase::writeFile(mClassName + ".cpp", cpp);
72 
73 
74     return false;
75 }
76 
77 typedef std::vector<std::pair<std::string, std::string> > ArgTy;
78 
79 
80 #define RS_TYPE_CLASS_NAME_PREFIX        "ScriptField_"
81 
82 
83 
makeHeader(const std::string & baseClass)84 bool RSReflectionCpp::makeHeader(const std::string &baseClass) {
85     startFile(mClassName + ".h");
86 
87     write("");
88     write("#include \"ScriptC.h\"");
89     write("");
90 
91     // Imports
92     //for(unsigned i = 0; i < (sizeof(Import) / sizeof(const char*)); i++)
93         //out() << "import " << Import[i] << ";" << std::endl;
94     //out() << std::endl;
95 
96     if(!baseClass.empty()) {
97         write("class " + mClassName + " : public " + baseClass + " {");
98     } else {
99         write("class " + mClassName + " {");
100     }
101 
102     write("private:");
103     uint32_t slot = 0;
104     incIndent();
105     for (RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(),
106            E = mRSContext->export_vars_end(); I != E; I++, slot++) {
107 
108         const RSExportVar *ev = *I;
109         RSReflectionTypeData rtd;
110         ev->getType()->convertToRTD(&rtd);
111         if(!ev->isConst()) {
112             write(string(rtd.type->c_name) + " __" + ev->getName() + ";");
113         }
114     }
115     decIndent();
116 
117     write("public:");
118     incIndent();
119     write(mClassName + "(android::renderscriptCpp::RenderScript *rs," +
120             " const char *cacheDir, size_t cacheDirLength);");
121     write("virtual ~" + mClassName + "();");
122     write("");
123 
124 
125     // Reflect export variable
126     slot = 0;
127     for (RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(),
128            E = mRSContext->export_vars_end(); I != E; I++, slot++) {
129 
130         const RSExportVar *ev = *I;
131         RSReflectionTypeData rtd;
132         ev->getType()->convertToRTD(&rtd);
133 
134         if(!ev->isConst()) {
135             write(string("void set_") + ev->getName() + "(" + rtd.type->c_name + " v) {");
136             stringstream tmp;
137             tmp << slot;
138             write(string("    setVar(") + tmp.str() + ", v);");
139             write(string("    __") + ev->getName() + " = v;");
140             write("}");
141         }
142         write(string(rtd.type->c_name) + " get_" + ev->getName() + "() const {");
143         if(ev->isConst()) {
144             const clang::APValue &val = ev->getInit();
145             bool isBool = !strcmp(rtd.type->c_name, "bool");
146             write(string("    return ") + genInitValue(val, isBool) + ";");
147         } else {
148             write(string("    return __") + ev->getName() + ";");
149         }
150         write("}");
151         write("");
152     }
153 
154     // Reflect export for each functions
155     for (RSContext::const_export_foreach_iterator I = mRSContext->export_foreach_begin(),
156              E = mRSContext->export_foreach_end(); I != E; I++) {
157 
158         const RSExportForEach *ef = *I;
159         if (ef->isDummyRoot()) {
160             write("// No forEach_root(...)");
161             continue;
162         }
163 
164         stringstream tmp;
165         tmp << "void forEach_" << ef->getName() << "(";
166         if(ef->hasIn() && ef->hasOut()) {
167             tmp << "android::sp<const android::renderscriptCpp::Allocation> ain";
168             tmp << ", android::sp<const android::renderscriptCpp::Allocation> aout";
169         } else if(ef->hasIn()) {
170             tmp << "android::sp<const android::renderscriptCpp::Allocation> ain";
171         } else {
172             tmp << "android::sp<const android::renderscriptCpp::Allocation> aout";
173         }
174 
175         if(ef->getParamPacketType()) {
176             for(RSExportForEach::const_param_iterator i = ef->params_begin(),
177                      e = ef->params_end(); i != e; i++) {
178 
179                 RSReflectionTypeData rtd;
180                 (*i)->getType()->convertToRTD(&rtd);
181                 tmp << rtd.type->c_name << " " << (*i)->getName();
182             }
183         }
184         tmp << ") const;";
185         write(tmp);
186     }
187 
188 
189     // Reflect export function
190     for (RSContext::const_export_func_iterator I = mRSContext->export_funcs_begin(),
191            E = mRSContext->export_funcs_end(); I != E; I++) {
192 
193         //genExportFunction(C, *I);
194     }
195 
196     decIndent();
197     write("};");
198     return true;
199 }
200 
writeBC()201 bool RSReflectionCpp::writeBC() {
202     FILE *pfin = fopen(mOutputBCFileName.c_str(), "rb");
203     if (pfin == NULL) {
204         fprintf(stderr, "Error: could not read file %s\n", mOutputBCFileName.c_str());
205         return false;
206     }
207 
208     unsigned char buf[16];
209     int read_length;
210     write("static const unsigned char __txt[] = {");
211     incIndent();
212     while ((read_length = fread(buf, 1, sizeof(buf), pfin)) > 0) {
213         string s;
214         for(int i = 0; i < read_length; i++) {
215             char buf2[16];
216             sprintf(buf2, "0x%02x,", buf[i]);
217             s += buf2;
218         }
219         write(s);
220     }
221     decIndent();
222     write("};");
223     write("");
224     return true;
225 }
226 
makeImpl(const std::string & baseClass)227 bool RSReflectionCpp::makeImpl(const std::string &baseClass) {
228     startFile(mClassName + ".h");
229 
230     write("");
231     write("#include \"" + mClassName + ".h\"");
232     write("");
233 
234     writeBC();
235 
236     // Imports
237     //for(unsigned i = 0; i < (sizeof(Import) / sizeof(const char*)); i++)
238         //out() << "import " << Import[i] << ";" << std::endl;
239     //out() << std::endl;
240 
241     write(mClassName + "::" + mClassName +
242           "(android::renderscriptCpp::RenderScript *rs, const char *cacheDir, size_t cacheDirLength) :");
243     write("        ScriptC(rs, __txt, sizeof(__txt), \"" + mInputFileName +
244           "\", 4, cacheDir, cacheDirLength) {");
245     incIndent();
246     //...
247     decIndent();
248     write("}");
249     write("");
250 
251     write(mClassName + "::~" + mClassName + "() {");
252     write("}");
253     write("");
254 
255     // Reflect export for each functions
256     uint32_t slot = 0;
257     for (RSContext::const_export_foreach_iterator I = mRSContext->export_foreach_begin(),
258              E = mRSContext->export_foreach_end(); I != E; I++, slot++) {
259 
260         const RSExportForEach *ef = *I;
261         if (ef->isDummyRoot()) {
262             write("// No forEach_root(...)");
263             continue;
264         }
265 
266         stringstream tmp;
267         tmp << "void " << mClassName << "::forEach_" << ef->getName() << "(";
268         if(ef->hasIn() && ef->hasOut()) {
269             tmp << "android::sp<const android::renderscriptCpp::Allocation> ain";
270             tmp << ", android::sp<const android::renderscriptCpp::Allocation> aout";
271         } else if(ef->hasIn()) {
272             tmp << "android::sp<const android::renderscriptCpp::Allocation> ain";
273         } else {
274             tmp << "android::sp<const android::renderscriptCpp::Allocation> aout";
275         }
276         tmp << ") const {";
277         write(tmp);
278         tmp.str("");
279 
280         tmp << "    forEach(" << slot << ", ";
281         if(ef->hasIn() && ef->hasOut()) {
282             tmp << "ain, aout, NULL, 0);";
283         } else if(ef->hasIn()) {
284             tmp << "ain, NULL, 0);";
285         } else {
286             tmp << "aout, NULL, 0);";
287         }
288         write(tmp);
289 
290         write("}");
291         write("");
292     }
293 
294 
295     // Reflect export function
296     slot = 0;
297     for (RSContext::const_export_func_iterator I = mRSContext->export_funcs_begin(),
298            E = mRSContext->export_funcs_end(); I != E; I++) {
299 
300         //genExportFunction(C, *I);
301     }
302 
303     decIndent();
304     return true;
305 }
306 
307 
308 
309 }
310