slang_rs_reflect_utils.cpp revision b1980a2eedc56df92786afc291e00f26659a60ad
13f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang#include "slang_rs_reflect_utils.hpp"
23f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
33f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang#include <cstdlib>
43f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang#include <cstdio>
5b1980a2eedc56df92786afc291e00f26659a60adMike Lockwood#include <cstring>
63f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang#include <fstream>
73f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
83f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang#include <sys/stat.h>
93f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang#include <sys/types.h>
103f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
113f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wangnamespace slang {
123f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
133f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wangusing std::string;
143f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
153f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wangstring RSSlangReflectUtils::ComputePackagedPath(
163f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    const std::string& prefixPath, const std::string& packageName) {
173f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    string packaged_path(prefixPath);
183f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    if (!prefixPath.empty() && (prefixPath[prefixPath.length() - 1] != '/')) {
193f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang        packaged_path += "/";
203f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    }
213f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    size_t s = packaged_path.length();
223f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    packaged_path += packageName;
233f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    while (s < packaged_path.length()) {
243f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang        if (packaged_path[s] == '.') {
253f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang            packaged_path[s] = '/';
263f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang        }
273f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang        ++s;
283f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    }
293f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    return packaged_path;
303f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang}
313f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
323f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wangstatic string InternalFileNameConvert(const char* rsFileName, bool camelCase) {
333f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    const char* dot = rsFileName + strlen(rsFileName);
343f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    const char* slash = dot - 1;
353f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    while (slash >= rsFileName) {
363f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang        if (*slash == '/') {
373f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang            break;
383f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang        }
393f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang        if ((*slash == '.') && (*dot == 0)) {
403f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang            dot = slash;
413f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang        }
423f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang        --slash;
433f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    }
443f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    ++slash;
453f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    char ret[256];
463f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    bool need_cap = true;
473f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    int i = 0;
483f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    for (; (i < 255) && (slash < dot); ++slash) {
493f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang        if (isalnum(*slash)) {
503f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang            if (need_cap && camelCase) {
513f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang                ret[i] = toupper(*slash);
523f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang            } else {
533f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang                ret[i] = *slash;
543f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang            }
553f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang            need_cap = false;
563f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang            ++i;
573f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang        } else {
583f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang            need_cap = true;
593f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang        }
603f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    }
613f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    ret[i] = 0;
623f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    return string(ret);
633f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang}
643f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
653f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wangstd::string RSSlangReflectUtils::JavaClassNameFromRSFileName(
663f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    const char* rsFileName) {
673f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    return InternalFileNameConvert(rsFileName, true);
683f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang}
693f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
703f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
713f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wangstd::string RSSlangReflectUtils::BCFileNameFromRSFileName(
723f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    const char* rsFileName) {
733f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    return InternalFileNameConvert(rsFileName, false);
743f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang}
753f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
763f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wangbool RSSlangReflectUtils::mkdir_p(const char* path) {
773f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    char buf[256];
783f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    char *tmp, *p = NULL;
793f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    size_t len = strlen(path);
803f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
813f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    if (len + 1 <= sizeof(buf))
823f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang        tmp = buf;
833f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    else
843f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang        tmp = new char [len + 1];
853f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
863f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    strcpy(tmp, path);
873f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
883f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    if (tmp[len - 1] == '/')
893f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang        tmp[len - 1] = 0;
903f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
913f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    for (p = tmp + 1; *p; p++) {
923f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang        if (*p == '/') {
933f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang            *p = 0;
943f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang            mkdir(tmp, S_IRWXU);
953f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang            *p = '/';
963f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang        }
973f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    }
983f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    mkdir(tmp, S_IRWXU);
993f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
1003f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    if (tmp != buf)
1013f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang        delete[] tmp;
1023f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
1033f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    return true;
1043f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang}
1053f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
1063f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wangbool RSSlangReflectUtils::EncodeBitcodeToJavaFile(
1073f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    const char* rsFileName, const char* inputBCFileName,
1083f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    const std::string& outputPath, const std::string& packageName) {
1093f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
1103f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    FILE* pfin = fopen(inputBCFileName, "rb");
1113f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    if (pfin == NULL) {
1123f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang        return false;
1133f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    }
1143f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
1153f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    string output_path = ComputePackagedPath(outputPath, packageName);
1163f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    if (!mkdir_p(output_path.c_str())) {
1173f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang      return false;
1183f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    }
1193f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
1203f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    string clazz_name(JavaClassNameFromRSFileName(rsFileName));
1213f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    clazz_name += "BitCode";
1223f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    string filename(clazz_name);
1233f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    filename += ".java";
1243f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
1253f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    string output_filename(output_path);
1263f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    output_filename += "/";
1273f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    output_filename += filename;
1283f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    printf("Generating %s ...\n", filename.c_str());
1293f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    FILE* pfout = fopen(output_filename.c_str(), "w");
1303f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    if (pfout == NULL) {
1313f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang        return false;
1323f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    }
1333f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
1343f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    // Output the header
1353f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    fprintf(pfout, "/*\n");
1363f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    fprintf(pfout, " * This file is auto-generated. DO NOT MODIFY!\n");
1373f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    fprintf(pfout, " * The source RenderScript file: %s\n", rsFileName);
1383f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    fprintf(pfout, " */\n\n");
1393f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    fprintf(pfout, "package %s;\n\n", packageName.c_str());
1403f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    fprintf(pfout, "/**\n");
1413f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    fprintf(pfout, " * @hide\n");
1423f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    fprintf(pfout, " */\n");
1433f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    fprintf(pfout, "public class %s {\n", clazz_name.c_str());
1443f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    fprintf(pfout, "\n");
1453f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    fprintf(pfout, "  // return byte array representation of the bitcode file.\n");
1463f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    fprintf(pfout, "  public static byte[] getBitCode() {\n");
1473f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    fprintf(pfout, "    byte[] bc = new byte[data.length];\n");
1483f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    fprintf(pfout, "    System.arraycopy(data, 0, bc, 0, data.length);\n");
1493f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    fprintf(pfout, "    return bc;\n");
1503f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    fprintf(pfout, "  }\n");
1513f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    fprintf(pfout, "\n");
1523f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    fprintf(pfout, "  // byte array representation of the bitcode file.\n");
1533f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    fprintf(pfout, "  private static final byte[] data = {\n");
1543f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
1553f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    // output the data
1563f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    const static int BUFF_SIZE = 0x10000;
1573f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    char* buff = new char[BUFF_SIZE];
1583f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    int read_length;
1593f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    while ((read_length = fread(buff, 1, BUFF_SIZE, pfin)) > 0) {
1603f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang        const static int LINE_BYTE_NUM = 16;
1613f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang        char out_line[LINE_BYTE_NUM*6 + 10];
1623f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang        const char* out_line_end = out_line + sizeof(out_line);
1633f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang        char* p = out_line;
1643f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
1653f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang        int write_length = 0;
1663f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang        while (write_length < read_length) {
1673f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang            p += snprintf(p, out_line_end - p, " %4d,", (int)buff[write_length]);
1683f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang            ++write_length;
1693f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang            if (((write_length % LINE_BYTE_NUM) == 0)
1703f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang                || (write_length == read_length)) {
1713f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang                fprintf(pfout, "   ");
1723f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang                fprintf(pfout, out_line);
1733f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang                fprintf(pfout, "\n");
1743f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang                p = out_line;
1753f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang            }
1763f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang        }
1773f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
1783f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    }
1793f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    delete []buff;
1803f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
1813f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    // the rest of the java file.
1823f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    fprintf(pfout, "  };\n");
1833f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    fprintf(pfout, "}\n");
1843f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
1853f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    fclose(pfin);
1863f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    fclose(pfout);
1873f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    return true;
1883f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang}
1893f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
1903f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang}
191