Skip to content
Snippets Groups Projects
Commit dba84ae4 authored by Rob Swindell's avatar Rob Swindell :speech_balloon:
Browse files

Add a read() method which I think is pretty cool

Read and return (as a string) any text file from an archive.
parent def7c955
No related branches found
No related tags found
1 merge request!123New file base
Pipeline #1731 failed
...@@ -429,12 +429,113 @@ js_list(JSContext *cx, uintN argc, jsval *arglist) ...@@ -429,12 +429,113 @@ js_list(JSContext *cx, uintN argc, jsval *arglist)
return retval; return retval;
} }
static JSBool
js_read(JSContext *cx, uintN argc, jsval *arglist)
{
jsval *argv = JS_ARGV(cx, arglist);
JSObject *obj = JS_THIS_OBJECT(cx, arglist);
jsrefcount rc;
struct archive *ar;
struct archive_entry *entry;
int result;
const char* filename;
char pattern[MAX_PATH + 1] = "";
if((filename = js_GetClassPrivate(cx, obj, &js_archive_class)) == NULL)
return JS_FALSE;
if(!js_argc(cx, argc, 1))
return JS_FALSE;
JS_SET_RVAL(cx, arglist, JSVAL_NULL);
uintN argn = 0;
if(argc > argn && JSVAL_IS_STRING(argv[argn])) {
JSString* js_str = JS_ValueToString(cx, argv[argn]);
if(js_str == NULL) {
JS_ReportError(cx, "string conversion error");
return JS_FALSE;
}
JSSTRING_TO_STRBUF(cx, js_str, pattern, sizeof(pattern), NULL);
argn++;
}
if((ar = archive_read_new()) == NULL) {
JS_ReportError(cx, "archive_read_new() returned NULL");
return JS_FALSE;
}
archive_read_support_filter_all(ar);
archive_read_support_format_all(ar);
if((result = archive_read_open_filename(ar, filename, 10240)) != ARCHIVE_OK) {
JS_ReportError(cx, "archive_read_open_filename() returned %d: %s"
,result, archive_error_string(ar));
archive_read_free(ar);
return JS_FALSE;
}
JSBool retval = JS_TRUE;
rc = JS_SUSPENDREQUEST(cx);
jsint len = 0;
while(1) {
result = archive_read_next_header(ar, &entry);
if(result != ARCHIVE_OK) {
if(result != ARCHIVE_EOF) {
JS_ReportError(cx, "archive_read_next_header() returned %d: %s"
,result, archive_error_string(ar));
retval = JS_FALSE;
}
break;
}
if(archive_entry_filetype(entry) != AE_IFREG)
continue;
const char* pathname = archive_entry_pathname(entry);
if(pathname == NULL)
continue;
if(stricmp(pathname, pattern) != 0)
continue;
char* p = NULL;
size_t total = 0;
const void *buff;
size_t size;
la_int64_t offset;
for(;;) {
result = archive_read_data_block(ar, &buff, &size, &offset);
if(result != ARCHIVE_OK)
break;
char* np = realloc(p, total + size);
if(np == NULL)
break;
p = np;
memcpy(p + total, buff, size);
total += size;
}
JSString* js_str = JS_NewStringCopyN(cx, p, total);
JS_SET_RVAL(cx, arglist, STRING_TO_JSVAL(js_str));
free(p);
break;
}
archive_read_free(ar);
JS_RESUMEREQUEST(cx, rc);
return retval;
}
static jsSyncMethodSpec js_archive_functions[] = { static jsSyncMethodSpec js_archive_functions[] = {
{ "create", js_create, 1, JSTYPE_NUMBER { "create", js_create, 1, JSTYPE_NUMBER
,JSDOCSTR("[string format] [,boolean with_path = false] [,array file_list]") ,JSDOCSTR("[string format] [,boolean with_path = false] [,array file_list]")
,JSDOCSTR("create an archive of the specified format, returns the number of files archived, will throw exception upon error") ,JSDOCSTR("create an archive of the specified format, returns the number of files archived, will throw exception upon error")
,31900 ,31900
}, },
{ "read", js_read, 1, JSTYPE_STRING
,JSDOCSTR("string path/filename")
,JSDOCSTR("read and return the contents of the specified archived text file")
,31900
},
{ "extract", js_extract, 1, JSTYPE_NUMBER { "extract", js_extract, 1, JSTYPE_NUMBER
,JSDOCSTR("output_directory [,boolean with_path = false] [,number max_files = 0] [,string file/pattern [...]]") ,JSDOCSTR("output_directory [,boolean with_path = false] [,number max_files = 0] [,string file/pattern [...]]")
,JSDOCSTR("extract files from an archive to specified output directory, returns the number of files extracted, will throw exception upon error") ,JSDOCSTR("extract files from an archive to specified output directory, returns the number of files extracted, will throw exception upon error")
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment