1c383a500aa59423264811be3874461bf8adbfea0Zonr Chang/*
2c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Copyright 2010, The Android Open Source Project
3c383a500aa59423264811be3874461bf8adbfea0Zonr Chang *
4c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Licensed under the Apache License, Version 2.0 (the "License");
5c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * you may not use this file except in compliance with the License.
6c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * You may obtain a copy of the License at
7c383a500aa59423264811be3874461bf8adbfea0Zonr Chang *
8c383a500aa59423264811be3874461bf8adbfea0Zonr Chang *     http://www.apache.org/licenses/LICENSE-2.0
9c383a500aa59423264811be3874461bf8adbfea0Zonr Chang *
10c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Unless required by applicable law or agreed to in writing, software
11c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * distributed under the License is distributed on an "AS IS" BASIS,
12c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * See the License for the specific language governing permissions and
14c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * limitations under the License.
15c383a500aa59423264811be3874461bf8adbfea0Zonr Chang */
16c383a500aa59423264811be3874461bf8adbfea0Zonr Chang
176315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_reflect_utils.h"
183f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
193f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang#include <cstdio>
20b1980a2eedc56df92786afc291e00f26659a60adMike Lockwood#include <cstring>
21e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <string>
223f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
238c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang#include "llvm/ADT/StringRef.h"
248c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang
258d5a2f6ab321615bfb3a46f68aff0b643a71caa0Raphael#include "os_sep.h"
268c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang#include "slang_utils.h"
273f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
283f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wangnamespace slang {
293f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
303f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wangusing std::string;
313f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
32dba3111408b307d8454830107ff61089ab7c5d6dYing Wangstring RSSlangReflectUtils::GetFileNameStem(const char* fileName) {
33dba3111408b307d8454830107ff61089ab7c5d6dYing Wang    const char *dot = fileName + strlen(fileName);
34dba3111408b307d8454830107ff61089ab7c5d6dYing Wang    const char *slash = dot - 1;
35dba3111408b307d8454830107ff61089ab7c5d6dYing Wang    while (slash >= fileName) {
368d5a2f6ab321615bfb3a46f68aff0b643a71caa0Raphael        if (*slash == OS_PATH_SEPARATOR) {
37dba3111408b307d8454830107ff61089ab7c5d6dYing Wang            break;
38dba3111408b307d8454830107ff61089ab7c5d6dYing Wang        }
39dba3111408b307d8454830107ff61089ab7c5d6dYing Wang        if ((*slash == '.') && (*dot == 0)) {
40dba3111408b307d8454830107ff61089ab7c5d6dYing Wang            dot = slash;
41dba3111408b307d8454830107ff61089ab7c5d6dYing Wang        }
42dba3111408b307d8454830107ff61089ab7c5d6dYing Wang        --slash;
43dba3111408b307d8454830107ff61089ab7c5d6dYing Wang    }
44dba3111408b307d8454830107ff61089ab7c5d6dYing Wang    ++slash;
45dba3111408b307d8454830107ff61089ab7c5d6dYing Wang    return string(slash, dot - slash);
46dba3111408b307d8454830107ff61089ab7c5d6dYing Wang}
47dba3111408b307d8454830107ff61089ab7c5d6dYing Wang
483f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wangstring RSSlangReflectUtils::ComputePackagedPath(
496315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    const char *prefixPath, const char *packageName) {
503f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    string packaged_path(prefixPath);
516315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    if (!packaged_path.empty() &&
528d5a2f6ab321615bfb3a46f68aff0b643a71caa0Raphael        (packaged_path[packaged_path.length() - 1] != OS_PATH_SEPARATOR)) {
538d5a2f6ab321615bfb3a46f68aff0b643a71caa0Raphael        packaged_path += OS_PATH_SEPARATOR_STR;
543f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    }
553f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    size_t s = packaged_path.length();
563f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    packaged_path += packageName;
573f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    while (s < packaged_path.length()) {
583f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang        if (packaged_path[s] == '.') {
598d5a2f6ab321615bfb3a46f68aff0b643a71caa0Raphael            packaged_path[s] = OS_PATH_SEPARATOR;
603f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang        }
613f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang        ++s;
623f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    }
633f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    return packaged_path;
643f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang}
653f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
666315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrstatic string InternalFileNameConvert(const char *rsFileName, bool toLower) {
676315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    const char *dot = rsFileName + strlen(rsFileName);
686315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    const char *slash = dot - 1;
693f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    while (slash >= rsFileName) {
708d5a2f6ab321615bfb3a46f68aff0b643a71caa0Raphael        if (*slash == OS_PATH_SEPARATOR) {
713f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang            break;
723f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang        }
733f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang        if ((*slash == '.') && (*dot == 0)) {
743f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang            dot = slash;
753f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang        }
763f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang        --slash;
773f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    }
783f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    ++slash;
793f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    char ret[256];
803f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    int i = 0;
813f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    for (; (i < 255) && (slash < dot); ++slash) {
82d41764036b098cc192aa8b7c9f0a1bb72f35f96cStephen Hines        if (isalnum(*slash) || *slash == '_') {
83d41764036b098cc192aa8b7c9f0a1bb72f35f96cStephen Hines            if (toLower) {
84d41764036b098cc192aa8b7c9f0a1bb72f35f96cStephen Hines                ret[i] = tolower(*slash);
853f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang            } else {
863f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang                ret[i] = *slash;
873f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang            }
883f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang            ++i;
893f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang        }
903f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    }
913f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    ret[i] = 0;
923f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    return string(ret);
933f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang}
943f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
953f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wangstd::string RSSlangReflectUtils::JavaClassNameFromRSFileName(
966315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    const char *rsFileName) {
97d41764036b098cc192aa8b7c9f0a1bb72f35f96cStephen Hines    return InternalFileNameConvert(rsFileName, false);
983f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang}
993f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
1003f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
1013f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wangstd::string RSSlangReflectUtils::BCFileNameFromRSFileName(
1026315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    const char *rsFileName) {
103d41764036b098cc192aa8b7c9f0a1bb72f35f96cStephen Hines    return InternalFileNameConvert(rsFileName, true);
1043f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang}
1053f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
1060877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wangstatic bool GenerateAccessorHeader(
1076315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    const RSSlangReflectUtils::BitCodeAccessorContext &context, FILE *pfout) {
1080877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    fprintf(pfout, "/*\n");
1090877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    fprintf(pfout, " * This file is auto-generated. DO NOT MODIFY!\n");
110b7d1269f983f28d9fe625a96439fa88b39dc96f6Stephen Hines    fprintf(pfout, " * The source Renderscript file: %s\n", context.rsFileName);
1110877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    fprintf(pfout, " */\n\n");
1120877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    fprintf(pfout, "package %s;\n\n", context.packageName);
1130877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang
1140877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    // add imports here.
1150877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang
1160877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    return true;
1170877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang}
1180877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang
1190877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wangstatic bool GenerateAccessorMethodSignature(
1206315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    const RSSlangReflectUtils::BitCodeAccessorContext &context, FILE *pfout) {
1210877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    // the prototype of the accessor method
1220877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    fprintf(pfout, "  // return byte array representation of the bitcode.\n");
1230877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    fprintf(pfout, "  public static byte[] getBitCode() {\n");
1240877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    return true;
1250877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang}
1260877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang
1270877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang// Java method size must not exceed 64k,
1280877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang// so we have to split the bitcode into multiple segments.
1290877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wangstatic bool GenerateSegmentMethod(
1306315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    const char *buff, int blen, int seg_num, FILE *pfout) {
1310877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang
1320877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    fprintf(pfout, "  private static byte[] getSegment_%d() {\n", seg_num);
1330877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    fprintf(pfout, "    byte[] data = {\n");
1340877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang
1356315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    static const int LINE_BYTE_NUM = 16;
1360877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    char out_line[LINE_BYTE_NUM*6 + 10];
1376315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    const char *out_line_end = out_line + sizeof(out_line);
1386315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    char *p = out_line;
1390877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang
1400877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    int write_length = 0;
1410877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    while (write_length < blen) {
1426315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr        p += snprintf(p, out_line_end - p,
1436315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr                      " %4d,", static_cast<int>(buff[write_length]));
1440877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang        ++write_length;
1450877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang        if (((write_length % LINE_BYTE_NUM) == 0)
1460877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang            || (write_length == blen)) {
1470877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang          fprintf(pfout, "     ");
14824f9b09fbb55725a6952b942418ac7902007a7f2Stephen Hines          fprintf(pfout, "%s", out_line);
1490877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang          fprintf(pfout, "\n");
1500877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang          p = out_line;
1510877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang        }
1520877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    }
1530877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang
1540877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    fprintf(pfout, "    };\n");
1550877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    fprintf(pfout, "    return data;\n");
1560877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    fprintf(pfout, "  }\n\n");
1573f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
1580877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    return true;
1590877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang}
1600877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang
1610877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wangstatic bool GenerateJavaCodeAccessorMethod(
1626315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    const RSSlangReflectUtils::BitCodeAccessorContext &context, FILE *pfout) {
1636315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    FILE *pfin = fopen(context.bcFileName, "rb");
1643f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    if (pfin == NULL) {
1650877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang        fprintf(stderr, "Error: could not read file %s\n", context.bcFileName);
1663f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang        return false;
1673f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    }
1683f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
1690877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    // start the accessor method
1700877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    GenerateAccessorMethodSignature(context, pfout);
1710877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    fprintf(pfout, "    return getBitCodeInternal();\n");
1720877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    // end the accessor method
1730877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    fprintf(pfout, "  };\n\n");
1740877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang
1750877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    // output the data
1760877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    // make sure the generated function for a segment won't break the Javac
1770877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    // size limitation (64K).
1786315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    static const int SEG_SIZE = 0x2000;
1796315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    char *buff = new char[SEG_SIZE];
1800877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    int read_length;
1810877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    int seg_num = 0;
1820877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    int total_length = 0;
1830877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    while ((read_length = fread(buff, 1, SEG_SIZE, pfin)) > 0) {
1840877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang        GenerateSegmentMethod(buff, read_length, seg_num, pfout);
1850877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang        ++seg_num;
1860877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang        total_length += read_length;
1870877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    }
1880877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    delete []buff;
1890877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    fclose(pfin);
1900877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang
1910877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    // output the internal accessor method
192e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    fprintf(pfout, "  private static int bitCodeLength = %d;\n\n",
193e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines        total_length);
1940877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    fprintf(pfout, "  private static byte[] getBitCodeInternal() {\n");
1950877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    fprintf(pfout, "    byte[] bc = new byte[bitCodeLength];\n");
1960877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    fprintf(pfout, "    int offset = 0;\n");
1970877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    fprintf(pfout, "    byte[] seg;\n");
1980877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    for (int i = 0; i < seg_num; ++i) {
1990877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    fprintf(pfout, "    seg = getSegment_%d();\n", i);
2000877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    fprintf(pfout, "    System.arraycopy(seg, 0, bc, offset, seg.length);\n");
2010877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    fprintf(pfout, "    offset += seg.length;\n");
2020877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    }
2030877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    fprintf(pfout, "    return bc;\n");
2040877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    fprintf(pfout, "  }\n\n");
2050877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang
2060877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    return true;
2070877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang}
2080877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang
2090877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wangstatic bool GenerateAccessorClass(
2106315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    const RSSlangReflectUtils::BitCodeAccessorContext &context,
2116315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    const char *clazz_name, FILE *pfout) {
2120877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    // begin the class.
2130877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    fprintf(pfout, "/**\n");
2140877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    fprintf(pfout, " * @hide\n");
2150877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    fprintf(pfout, " */\n");
2160877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    fprintf(pfout, "public class %s {\n", clazz_name);
2170877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    fprintf(pfout, "\n");
2180877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang
2190877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    bool ret = true;
2200877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    switch (context.bcStorage) {
2210877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang      case BCST_APK_RESOURCE:
2220877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang        break;
2230877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang      case BCST_JAVA_CODE:
2240877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang        ret = GenerateJavaCodeAccessorMethod(context, pfout);
2250877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang        break;
2260877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang      default:
2270877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang        ret = false;
2280877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    }
2290877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang
2300877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    // end the class.
2310877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    fprintf(pfout, "}\n");
2320877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang
2330877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    return ret;
2340877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang}
2350877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang
2360877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang
2370877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wangbool RSSlangReflectUtils::GenerateBitCodeAccessor(
2386315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    const BitCodeAccessorContext &context) {
2390877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    string output_path = ComputePackagedPath(context.reflectPath,
2400877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang                                             context.packageName);
2418c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang    if (!SlangUtils::CreateDirectoryWithParents(llvm::StringRef(output_path),
2428c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang                                                NULL)) {
2430877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang        fprintf(stderr, "Error: could not create dir %s\n",
2440877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang                output_path.c_str());
2450877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang        return false;
2463f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    }
2473f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
2480877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    string clazz_name(JavaClassNameFromRSFileName(context.rsFileName));
2493f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    clazz_name += "BitCode";
2503f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    string filename(clazz_name);
2513f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    filename += ".java";
2523f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
2533f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    string output_filename(output_path);
2548d5a2f6ab321615bfb3a46f68aff0b643a71caa0Raphael    output_filename += OS_PATH_SEPARATOR_STR;
2553f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    output_filename += filename;
2563f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    printf("Generating %s ...\n", filename.c_str());
2576315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    FILE *pfout = fopen(output_filename.c_str(), "w");
2583f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    if (pfout == NULL) {
2590877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang        fprintf(stderr, "Error: could not write to file %s\n",
2600877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang                output_filename.c_str());
2613f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang        return false;
2623f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    }
2633f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
2646315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    bool ret = GenerateAccessorHeader(context, pfout) &&
2656315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr               GenerateAccessorClass(context, clazz_name.c_str(), pfout);
2663f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
2673f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    fclose(pfout);
2680877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    return ret;
2693f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang}
270e67239de8d94975e7e2216ee6860ae2e6cb8b15aStephen Hines}  // namespace slang
271