slang_rs_reflection_cpp.cpp revision 1b6a0883cd6984e11e59b0c847fb334df1f41afc
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
40using namespace std;
41
42namespace slang {
43
44RSReflectionCpp::RSReflectionCpp(const RSContext *con) :
45    RSReflectionBase(con) {
46
47}
48
49RSReflectionCpp::~RSReflectionCpp() {
50
51}
52
53bool 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("ScriptC");
62    std::vector< std::string > header(mText);
63    mText.clear();
64
65    makeImpl("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
77typedef std::vector<std::pair<std::string, std::string> > ArgTy;
78
79
80#define RS_TYPE_CLASS_NAME_PREFIX        "ScriptField_"
81
82
83
84bool 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("public:");
103    incIndent();
104    write(mClassName + "(RenderScript *rs, const char *cacheDir, size_t cacheDirLength);");
105    write("virtual ~" + mClassName + "();");
106
107
108    // Reflect export variable
109    uint32_t slot = 0;
110    for (RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(),
111           E = mRSContext->export_vars_end(); I != E; I++) {
112
113        const RSExportVar *ev = *I;
114        //const RSExportType *et = ev->getType();
115
116        char buf[256];
117        sprintf(buf, " = %i;", slot++);
118        write("const static int mExportVarIdx_" + ev->getName() + buf);
119
120        //switch (ET->getClass()) {
121
122        //genExportVariable(C, *I);
123    }
124
125    // Reflect export for each functions
126    for (RSContext::const_export_foreach_iterator I = mRSContext->export_foreach_begin(),
127             E = mRSContext->export_foreach_end(); I != E; I++, slot++) {
128
129        const RSExportForEach *ef = *I;
130        if (ef->isDummyRoot()) {
131            write("// No forEach_root(...)");
132            continue;
133        }
134
135        char buf[256];
136        sprintf(buf, " = %i;", slot);
137        write("const static int mExportForEachIdx_" + ef->getName() + buf);
138
139        string tmp("void forEach_" + ef->getName() + "(");
140        if(ef->hasIn())
141            tmp += "Allocation ain";
142        if(ef->hasOut())
143            tmp += "Allocation aout";
144
145        if(ef->getParamPacketType()) {
146            for(RSExportForEach::const_param_iterator i = ef->params_begin(),
147                     e = ef->params_end(); i != e; i++) {
148
149                RSReflectionTypeData rtd;
150                (*i)->getType()->convertToRTD(&rtd);
151                tmp += rtd.type->c_name;
152                tmp += " ";
153                tmp +=(*i)->getName();
154            }
155        }
156        tmp += ") const;";
157        write(tmp);
158    }
159
160
161    // Reflect export function
162    for (RSContext::const_export_func_iterator I = mRSContext->export_funcs_begin(),
163           E = mRSContext->export_funcs_end(); I != E; I++) {
164
165        //genExportFunction(C, *I);
166    }
167
168    decIndent();
169    write("};");
170    return true;
171}
172
173bool RSReflectionCpp::writeBC() {
174    FILE *pfin = fopen(mOutputBCFileName.c_str(), "rb");
175    if (pfin == NULL) {
176        fprintf(stderr, "Error: could not read file %s\n", mOutputBCFileName.c_str());
177        return false;
178    }
179
180    unsigned char buf[16];
181    int read_length;
182    write("static const unsigned char __txt[] = {");
183    incIndent();
184    while ((read_length = fread(buf, 1, sizeof(buf), pfin)) > 0) {
185        string s;
186        for(int i = 0; i < read_length; i++) {
187            char buf2[16];
188            sprintf(buf2, "0x%02x,", buf[i]);
189            s += buf2;
190        }
191        write(s);
192    }
193    decIndent();
194    write("};");
195    write("");
196    return true;
197}
198
199bool RSReflectionCpp::makeImpl(const std::string &baseClass) {
200    startFile(mClassName + ".h");
201
202    write("");
203    write("#include \"" + mClassName + ".h\"");
204    write("");
205
206    writeBC();
207
208    // Imports
209    //for(unsigned i = 0; i < (sizeof(Import) / sizeof(const char*)); i++)
210        //out() << "import " << Import[i] << ";" << std::endl;
211    //out() << std::endl;
212
213    write(mClassName + "::" + mClassName +
214          "(RenderScript *rs, const char *cacheDir, size_t cacheDirLength) :");
215    write("        ScriptC(rs, __txt, sizeof(__txt), " + mInputFileName +
216          ", 4, cacheDir, cacheDirLength) {");
217    incIndent();
218    //...
219    decIndent();
220    write("}");
221    write("");
222
223    write("virtual ~" + mClassName + "::" + mClassName + "() {");
224    write("}");
225    write("");
226
227
228    // Reflect export variable
229    uint32_t slot = 0;
230    for (RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(),
231           E = mRSContext->export_vars_end(); I != E; I++) {
232
233        const RSExportVar *ev = *I;
234        //const RSExportType *et = ev->getType();
235
236        char buf[256];
237        sprintf(buf, " = %i;", slot++);
238        write("const static int mExportVarIdx_" + ev->getName() + buf);
239
240        //switch (ET->getClass()) {
241
242        //genExportVariable(C, *I);
243    }
244
245    // Reflect export for each functions
246    slot = 0;
247    for (RSContext::const_export_foreach_iterator I = mRSContext->export_foreach_begin(),
248             E = mRSContext->export_foreach_end(); I != E; I++, slot++) {
249
250        const RSExportForEach *ef = *I;
251        if (ef->isDummyRoot()) {
252            write("// No forEach_root(...)");
253            continue;
254        }
255
256        char buf[256];
257        string tmp("void forEach_" + ef->getName() + "(");
258        if(ef->hasIn() && ef->hasOut()) {
259            tmp += "Allocation ain, Allocation aout";
260        } else if(ef->hasIn()) {
261            tmp += "Allocation ain";
262        } else {
263            tmp += "Allocation aout";
264        }
265        tmp += ") const {";
266        write(tmp);
267
268        incIndent();
269        sprintf(buf, "forEach(%i, ", slot);
270        tmp = buf;
271        if(ef->hasIn() && ef->hasOut()) {
272            tmp += "ain, aout, NULL, 0);";
273        } else if(ef->hasIn()) {
274            tmp += "ain, NULL, 0);";
275        } else {
276            tmp += "aout, NULL, 0);";
277        }
278        write(tmp);
279        decIndent();
280
281        write("}");
282        write("");
283    }
284
285
286    // Reflect export function
287    slot = 0;
288    for (RSContext::const_export_func_iterator I = mRSContext->export_funcs_begin(),
289           E = mRSContext->export_funcs_end(); I != E; I++) {
290
291        //genExportFunction(C, *I);
292    }
293
294    decIndent();
295    return true;
296}
297
298
299
300}
301