Skip to content

Commit

Permalink
Expose additional parsing options in C API
Browse files Browse the repository at this point in the history
This now allows you to specify the file path and whether you want to load external files via the C API.
  • Loading branch information
CryZe committed Sep 26, 2017
1 parent 625d721 commit 9f2c5a4
Show file tree
Hide file tree
Showing 10 changed files with 65 additions and 36 deletions.
4 changes: 2 additions & 2 deletions capi/bind_gen/src/csharp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -346,15 +346,15 @@ namespace LiveSplitCore
writer,
"{}",
r#"
public static ParseRunResult Parse(Stream stream)
public static ParseRunResult Parse(Stream stream, string path, bool loadFiles)
{
var data = new byte[stream.Length];
stream.Read(data, 0, data.Length);
IntPtr pnt = Marshal.AllocHGlobal(data.Length);
try
{
Marshal.Copy(data, 0, pnt, data.Length);
return Parse(pnt, data.Length);
return Parse(pnt, data.Length, path, loadFiles);
}
finally
{
Expand Down
20 changes: 12 additions & 8 deletions capi/bind_gen/src/emscripten.rs
Original file line number Diff line number Diff line change
Expand Up @@ -542,22 +542,22 @@ export "#.to_string()
writer,
"{}",
r#"
static parseArray(data: Int8Array): ParseRunResult {
static parseArray(data: Int8Array, path: string, loadFiles: boolean): ParseRunResult {
const buf = emscriptenModule._malloc(data.length);
try {
emscriptenModule.writeArrayToMemory(data, buf);
const ptr = liveSplitCoreNative.Run_parse(buf, data.length);
const ptr = liveSplitCoreNative.Run_parse(buf, data.length, path, loadFiles ? 1 : 0);
return new ParseRunResult(ptr);
} finally {
emscriptenModule._free(buf);
}
}
static parseString(text: string): ParseRunResult {
static parseString(text: string, path: string, loadFiles: boolean): ParseRunResult {
const len = (text.length << 2) + 1;
const buf = emscriptenModule._malloc(len);
try {
const actualLen = emscriptenModule.stringToUTF8(text, buf, len);
const ptr = liveSplitCoreNative.Run_parse(buf, actualLen);
const ptr = liveSplitCoreNative.Run_parse(buf, actualLen, path, loadFiles ? 1 : 0);
return new ParseRunResult(ptr);
} finally {
emscriptenModule._free(buf);
Expand All @@ -571,28 +571,32 @@ export "#.to_string()
r#"
/**
* @param {Int8Array} data
* @param {string} path
* @param {boolean} loadFiles
* @return {ParseRunResult}
*/
static parseArray(data) {
static parseArray(data, path, loadFiles) {
const buf = emscriptenModule._malloc(data.length);
try {
emscriptenModule.writeArrayToMemory(data, buf);
const ptr = liveSplitCoreNative.Run_parse(buf, data.length);
const ptr = liveSplitCoreNative.Run_parse(buf, data.length, path, loadFiles ? 1 : 0);
return new ParseRunResult(ptr);
} finally {
emscriptenModule._free(buf);
}
}
/**
* @param {string} text
* @param {string} path
* @param {boolean} loadFiles
* @return {ParseRunResult}
*/
static parseString(text) {
static parseString(text, path, loadFiles) {
const len = (text.length << 2) + 1;
const buf = emscriptenModule._malloc(len);
try {
const actualLen = emscriptenModule.stringToUTF8(text, buf, len);
const ptr = liveSplitCoreNative.Run_parse(buf, actualLen);
const ptr = liveSplitCoreNative.Run_parse(buf, actualLen, path, loadFiles ? 1 : 0);
return new ParseRunResult(ptr);
} finally {
emscriptenModule._free(buf);
Expand Down
4 changes: 2 additions & 2 deletions capi/bind_gen/src/java/jna.rs
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ public class {class} extends {base_class} implements AutoCloseable {{
writer,
"{}",
r#"
public static ParseRunResult parse(java.io.InputStream stream) throws java.io.IOException {
public static ParseRunResult parse(java.io.InputStream stream, String path, boolean loadFiles) throws java.io.IOException {
java.io.ByteArrayOutputStream out = new java.io.ByteArrayOutputStream();
byte[] buffer = new byte[1024];
while (true) {
Expand All @@ -360,7 +360,7 @@ public class {class} extends {base_class} implements AutoCloseable {{
byte[] arr = out.toByteArray();
java.nio.ByteBuffer nativeBuf = java.nio.ByteBuffer.allocateDirect(arr.length);
nativeBuf.put(arr);
return Run.parse(Native.getDirectBufferPointer(nativeBuf), arr.length);
return Run.parse(Native.getDirectBufferPointer(nativeBuf), arr.length, path, loadFiles);
}"#
)?;
}
Expand Down
4 changes: 2 additions & 2 deletions capi/bind_gen/src/java/jni.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,8 +325,8 @@ public class {class} extends {base_class} implements AutoCloseable {{
writer,
"{}",
r#"
public static ParseRunResult parse(String data) {
ParseRunResult result = new ParseRunResult(LiveSplitCoreNative.Run_parseString(data));
public static ParseRunResult parse(String data, String path, boolean loadFiles) {
ParseRunResult result = new ParseRunResult(LiveSplitCoreNative.Run_parseString(data, path, loadFiles));
return result;
}"#
)?;
Expand Down
6 changes: 4 additions & 2 deletions capi/bind_gen/src/jni_cpp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,9 +177,11 @@ pub fn write<W: Write>(mut writer: W, classes: &BTreeMap<String, Class>) -> Resu
using namespace LiveSplit;
extern "C" JNIEXPORT jlong Java_livesplitcore_LiveSplitCoreNative_Run_1parseString(JNIEnv* jni_env, jobject, jstring data) {
extern "C" JNIEXPORT jlong Java_livesplitcore_LiveSplitCoreNative_Run_1parseString(JNIEnv* jni_env, jobject, jstring data, jstring path, jboolean load_files) {
auto cstr_data = jni_env->GetStringUTFChars(data, nullptr);
auto result = (jlong)Run_parse(cstr_data, strlen(cstr_data));
auto cstr_path = jni_env->GetStringUTFChars(path, nullptr);
auto result = (jlong)Run_parse(cstr_data, strlen(cstr_data), cstr_path, (uint8_t)load_files);
jni_env->ReleaseStringUTFChars(path, cstr_path);
jni_env->ReleaseStringUTFChars(data, cstr_data);
return result;
}
Expand Down
4 changes: 2 additions & 2 deletions capi/bind_gen/src/kotlin/jni.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,8 +338,8 @@ open class {class} : {base_class}, AutoCloseable {{
writer,
"{}",
r#"
fun parse(data: String): ParseRunResult {
val result = ParseRunResult(LiveSplitCoreNative.Run_parseString(data))
fun parse(data: String, path: String, loadFiles: Boolean): ParseRunResult {
val result = ParseRunResult(LiveSplitCoreNative.Run_parseString(data, path, loadFiles))
return result
}"#
)?;
Expand Down
30 changes: 18 additions & 12 deletions capi/bind_gen/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -554,20 +554,20 @@ export "#.to_string()
writer,
"{}",
r#"
static parseArray(data: Int8Array): ParseRunResult {
static parseArray(data: Int8Array, path: string, loadFiles: boolean): ParseRunResult {
let buf = Buffer.from(data.buffer);
if (data.byteLength !== data.buffer.byteLength) {
buf = buf.slice(data.byteOffset, data.byteOffset + data.byteLength);
}
return Run.parse(buf, buf.byteLength);
return Run.parse(buf, buf.byteLength, path, loadFiles);
}
static parseFile(file: any): ParseRunResult {
static parseFile(file: any, path: string, loadFiles: boolean): ParseRunResult {
const data = fs.readFileSync(file);
return Run.parse(data, data.byteLength);
return Run.parse(data, data.byteLength, path, loadFiles);
}
static parseString(text: string): ParseRunResult {
static parseString(text: string, path: string, loadFiles: boolean): ParseRunResult {
const data = new Buffer(text);
return Run.parse(data, data.byteLength);
return Run.parse(data, data.byteLength, path, loadFiles);
}"#
)?;
} else {
Expand All @@ -577,30 +577,36 @@ export "#.to_string()
r#"
/**
* @param {Int8Array} data
* @param {string} path
* @param {boolean} loadFiles
* @return {ParseRunResult}
*/
static parseArray(data) {
static parseArray(data, path, loadFiles) {
let buf = Buffer.from(data.buffer);
if (data.byteLength !== data.buffer.byteLength) {
buf = buf.slice(data.byteOffset, data.byteOffset + data.byteLength);
}
return Run.parse(buf, buf.byteLength);
return Run.parse(buf, buf.byteLength, path, loadFiles);
}
/**
* @param {string | Buffer | number} file
* @param {string} path
* @param {boolean} loadFiles
* @return {ParseRunResult}
*/
static parseFile(file) {
static parseFile(file, path, loadFiles) {
const data = fs.readFileSync(file);
return Run.parse(data, data.byteLength);
return Run.parse(data, data.byteLength, path, loadFiles);
}
/**
* @param {string} text
* @param {string} path
* @param {boolean} loadFiles
* @return {ParseRunResult}
*/
static parseString(text) {
static parseString(text, path, loadFiles) {
const data = new Buffer(text);
return Run.parse(data, data.byteLength);
return Run.parse(data, data.byteLength, path, loadFiles);
}"#
)?;
}
Expand Down
4 changes: 2 additions & 2 deletions capi/bind_gen/src/python.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,15 +288,15 @@ class {class}({base_class}):
writer,
r#"
@staticmethod
def parse_file(file):
def parse_file(file, path, load_files):
data = file.read()
if sys.version_info[0] > 2:
if isinstance(data, str):
raise TypeError("File must be opened in binary mode!")
bytes = bytearray(data)
bufferType = c_byte * len(bytes)
buffer = bufferType(*bytes)
return Run.parse(buffer, len(bytes))"#
return Run.parse(buffer, len(bytes), path, load_files)"#
)?;
}

Expand Down
6 changes: 5 additions & 1 deletion capi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,11 @@ where
}

unsafe fn str(s: *const c_char) -> &'static str {
CStr::from_ptr(s as _).to_str().unwrap()
if s.is_null() {
""
} else {
CStr::from_ptr(s as _).to_str().unwrap()
}
}

fn alloc<T>(data: T) -> *mut T {
Expand Down
19 changes: 16 additions & 3 deletions capi/src/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use livesplit_core::run::{parser, saver};
use super::{acc, acc_mut, alloc, output_str, output_time_span, output_vec, own, own_drop, str};
use std::io::Cursor;
use std::slice;
use std::path::PathBuf;
use libc::c_char;
use segment::OwnedSegment;
use parse_run_result::OwnedParseRunResult;
Expand All @@ -21,11 +22,23 @@ pub unsafe extern "C" fn Run_drop(this: OwnedRun) {
}

#[no_mangle]
pub unsafe extern "C" fn Run_parse(data: *const u8, length: usize) -> OwnedParseRunResult {
pub unsafe extern "C" fn Run_parse(
data: *const u8,
length: usize,
path: *const c_char,
load_files: bool,
) -> OwnedParseRunResult {
let path = str(path);
let path = if !path.is_empty() {
Some(PathBuf::from(path))
} else {
None
};

alloc(parser::composite::parse(
Cursor::new(slice::from_raw_parts(data, length)),
None,
false,
path,
load_files,
))
}

Expand Down

0 comments on commit 9f2c5a4

Please sign in to comment.