1 /* 2 * Copyright 2010, 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 #ifndef _FRAMEWORKS_COMPILE_SLANG_SLANG_REFLECT_UTILS_H_ // NOLINT 18 #define _FRAMEWORKS_COMPILE_SLANG_SLANG_REFLECT_UTILS_H_ 19 20 #include <fstream> 21 #include <string> 22 23 namespace slang { 24 25 // BitCode storage type 26 enum BitCodeStorageType { BCST_APK_RESOURCE, BCST_JAVA_CODE, BCST_CPP_CODE }; 27 28 class RSSlangReflectUtils { 29 public: 30 // Encode a binary bitcode file into a Java source file. 31 // rsFileName: the original .rs file name (with or without path). 32 // bc32FileName: path of the 32-bit bitcode file 33 // bc64FileName: path of the 64-bit bitcode file 34 // reflectPath: where to output the generated Java file, no package name in 35 // it. 36 // packageName: the package of the output Java file. 37 // verbose: whether or not to print out additional info about compilation. 38 // bcStorage: where to emit bitcode to (resource file or embedded). 39 struct BitCodeAccessorContext { 40 const char *rsFileName; 41 const char *bc32FileName; 42 const char *bc64FileName; 43 const char *reflectPath; 44 const char *packageName; 45 const std::string *licenseNote; 46 bool verbose; 47 BitCodeStorageType bcStorage; 48 }; 49 50 // Return the stem of the file name, i.e., remove the dir and the extension. 51 // Eg, foo.ext -> foo 52 // foo.bar.ext -> foo.bar 53 // ./path/foo.ext -> foo 54 static std::string GetFileNameStem(const char *fileName); 55 56 // Compute a Java source file path from a given prefixPath and its package. 57 // Eg, given prefixPath=./foo/bar and packageName=com.x.y, then it returns 58 // ./foo/bar/com/x/y 59 static std::string ComputePackagedPath(const char *prefixPath, 60 const char *packageName); 61 62 // Compute Java class name from a .rs file name. 63 // Any non-alnum, non-underscore characters will be discarded. 64 // E.g. with rsFileName=./foo/bar/my-Renderscript_file.rs it returns 65 // "myRenderscript_file". 66 // rsFileName: the input .rs file name (with or without path). 67 static std::string JavaClassNameFromRSFileName(const char *rsFileName); 68 69 // Compute a bitcode file name (no extension) from a .rs file name. 70 // Because the bitcode file name may be used as Resource ID in the generated 71 // class (something like R.raw.<bitcode_filename>), Any non-alnum, 72 // non-underscore character will be discarded. 73 // The difference from JavaClassNameFromRSFileName() is that the result is 74 // converted to lowercase. 75 // E.g. with rsFileName=./foo/bar/my-Renderscript_file.rs it returns 76 // "myrenderscript_file" 77 // rsFileName: the input .rs file name (with or without path). 78 static std::string BCFileNameFromRSFileName(const char *rsFileName); 79 80 // Compute the bitcode-containing class name from a .rs filename. 81 // Any non-alnum, non-underscore characters will be discarded. 82 // E.g. with rsFileName=./foo/bar/my-Renderscript_file.rs it returns 83 // "myRenderscript_fileBitCode". 84 // rsFileName: the input .rs file name (with or without path). 85 static std::string JavaBitcodeClassNameFromRSFileName(const char *rsFileName); 86 87 // Generate the bit code accessor Java source file. 88 static bool GenerateJavaBitCodeAccessor(const BitCodeAccessorContext &context); 89 }; 90 91 // Joins two sections of a path, inserting a separator if needed. 92 // E.g. JoinPath("foo/bar", "baz/a.java") returns "foo/bar/baz/a.java", 93 // JoinPath("foo", "/bar/baz") returns "foo/bar/baz", and 94 // JoinPath("foo/", "/bar") returns "foo/bar". 95 std::string JoinPath(const std::string &path1, const std::string &path2); 96 97 /* Compute a safe root name from a .rs file name. Any non-alphanumeric, 98 * non-underscore characters will be discarded. 99 * E.g. RootNameFromRSFileName("./foo/bar/my-Renderscript_file.rs") returns 100 * "myRenderscript_file". 101 */ 102 std::string RootNameFromRSFileName(const std::string &rsFileName); 103 104 /* This class is used to generate one source file. There will be one instance 105 * for each generated file. 106 */ 107 class GeneratedFile : public std::ofstream { 108 public: 109 /* Starts the file by: 110 * - creating the parent directories (if needed), 111 * - opening the stream, 112 * - writing out the license, 113 * - writing a message that this file has been auto-generated. 114 * If optionalLicense is nullptr, a default license is used. 115 */ 116 bool startFile(const std::string &outPath, const std::string &outFileName, 117 const std::string &sourceFileName, 118 const std::string *optionalLicense, bool isJava, bool verbose); 119 void closeFile(); 120 121 void increaseIndent(); // Increases the new line indentation by 4. 122 void decreaseIndent(); // Decreases the new line indentation by 4. 123 void comment(const std::string& s); // Outputs a multiline comment. 124 125 // Starts a control block. This works both for Java and C++. startBlock()126 void startBlock() { 127 *this << " {\n"; 128 increaseIndent(); 129 } 130 131 // Ends a control block. 132 void endBlock(bool addSemicolon = false) { 133 decreaseIndent(); 134 indent() << "}" << (addSemicolon ? ";" : "") << "\n\n"; 135 } 136 137 /* Indents the line. By returning *this, we can use like this: 138 * mOut.ident() << "a = b;\n"; 139 */ indent()140 std::ofstream &indent() { 141 *this << mIndent; 142 return *this; 143 } 144 145 private: 146 std::string mIndent; // The correct spacing at the beginning of each line. 147 }; 148 149 } // namespace slang 150 151 #endif // _FRAMEWORKS_COMPILE_SLANG_SLANG_REFLECT_UTILS_H_ NOLINT 152