mirror of
https://github.com/libretro/RetroArch
synced 2025-02-28 12:40:23 +00:00
Replace custom JSON parser/writer in translation service with rjson
This commit is contained in:
parent
a16784b7c3
commit
c20b01e9e1
@ -1163,8 +1163,8 @@ struct rjsonwriter
|
|||||||
void *user_data;
|
void *user_data;
|
||||||
|
|
||||||
const char* error_text;
|
const char* error_text;
|
||||||
char option_flags;
|
char option_flags, decimal_sep;
|
||||||
char decimal_sep;
|
bool buf_is_output, final_flush;
|
||||||
|
|
||||||
char inline_buf[1024];
|
char inline_buf[1024];
|
||||||
};
|
};
|
||||||
@ -1178,9 +1178,9 @@ rjsonwriter_t *rjsonwriter_open_user(rjsonwriter_io_t io, void *user_data)
|
|||||||
writer->buf_num = 0;
|
writer->buf_num = 0;
|
||||||
writer->buf_cap = sizeof(writer->inline_buf);
|
writer->buf_cap = sizeof(writer->inline_buf);
|
||||||
|
|
||||||
writer->option_flags = 0;
|
|
||||||
writer->decimal_sep = 0;
|
|
||||||
writer->error_text = NULL;
|
writer->error_text = NULL;
|
||||||
|
writer->option_flags = writer->decimal_sep = 0;
|
||||||
|
writer->buf_is_output = writer->final_flush = false;
|
||||||
|
|
||||||
writer->io = io;
|
writer->io = io;
|
||||||
writer->user_data = user_data;
|
writer->user_data = user_data;
|
||||||
@ -1208,9 +1208,53 @@ rjsonwriter_t *rjsonwriter_open_rfile(RFILE *rfile)
|
|||||||
return rjsonwriter_open_user(_rjsonwriter_rfile_io, rfile);
|
return rjsonwriter_open_user(_rjsonwriter_rfile_io, rfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _rjsonwriter_memory_io(const void* buf, int len, void *user)
|
||||||
|
{
|
||||||
|
rjsonwriter_t *writer = (rjsonwriter_t *)user;
|
||||||
|
bool is_append = (buf != writer->buf);
|
||||||
|
bool can_realloc = (writer->buf != writer->inline_buf);
|
||||||
|
int new_cap = writer->buf_num + (is_append ? len : 0) + 512;
|
||||||
|
if (!writer->final_flush && (is_append || new_cap > writer->buf_cap))
|
||||||
|
{
|
||||||
|
char* new_buf = (char*)(can_realloc ? realloc(writer->buf, new_cap) : malloc(new_cap));
|
||||||
|
if (!new_buf) return 0;
|
||||||
|
if (!can_realloc) memcpy(new_buf, writer->buf, writer->buf_num);
|
||||||
|
if (is_append)
|
||||||
|
{
|
||||||
|
memcpy(new_buf + writer->buf_num, buf, len);
|
||||||
|
writer->buf_num += len;
|
||||||
|
}
|
||||||
|
writer->buf = new_buf;
|
||||||
|
writer->buf_cap = new_cap;
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
rjsonwriter_t *rjsonwriter_open_memory()
|
||||||
|
{
|
||||||
|
rjsonwriter_t *writer = rjsonwriter_open_user(_rjsonwriter_memory_io, NULL);
|
||||||
|
if (!writer) return NULL;
|
||||||
|
writer->user_data = writer;
|
||||||
|
writer->buf_is_output = true;
|
||||||
|
return writer;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* rjsonwriter_get_memory_buffer(rjsonwriter_t *writer, int* len)
|
||||||
|
{
|
||||||
|
if (writer->io != _rjsonwriter_memory_io || writer->error_text)
|
||||||
|
return NULL;
|
||||||
|
if (writer->buf_num == writer->buf_cap)
|
||||||
|
rjsonwriter_flush(writer);
|
||||||
|
writer->buf[writer->buf_num] = '\0';
|
||||||
|
if (len) *len = writer->buf_num;
|
||||||
|
return writer->buf;
|
||||||
|
}
|
||||||
|
|
||||||
bool rjsonwriter_free(rjsonwriter_t *writer)
|
bool rjsonwriter_free(rjsonwriter_t *writer)
|
||||||
{
|
{
|
||||||
bool res = rjsonwriter_flush(writer);
|
bool res;
|
||||||
|
writer->final_flush = true;
|
||||||
|
res = rjsonwriter_flush(writer);
|
||||||
if (writer->buf != writer->inline_buf)
|
if (writer->buf != writer->inline_buf)
|
||||||
free(writer->buf);
|
free(writer->buf);
|
||||||
free(writer);
|
free(writer);
|
||||||
@ -1227,7 +1271,8 @@ bool rjsonwriter_flush(rjsonwriter_t *writer)
|
|||||||
if (writer->buf_num && !writer->error_text && writer->io(writer->buf,
|
if (writer->buf_num && !writer->error_text && writer->io(writer->buf,
|
||||||
writer->buf_num, writer->user_data) != writer->buf_num)
|
writer->buf_num, writer->user_data) != writer->buf_num)
|
||||||
writer->error_text = "output error";
|
writer->error_text = "output error";
|
||||||
writer->buf_num = 0;
|
if (!writer->buf_is_output || writer->error_text)
|
||||||
|
writer->buf_num = 0;
|
||||||
return !writer->error_text;
|
return !writer->error_text;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1245,25 +1290,25 @@ void rjsonwriter_raw(rjsonwriter_t *writer, const char *buf, int len)
|
|||||||
if (buf[0] > ' ' ||
|
if (buf[0] > ' ' ||
|
||||||
!(writer->option_flags & RJSONWRITER_OPTION_SKIP_WHITESPACE))
|
!(writer->option_flags & RJSONWRITER_OPTION_SKIP_WHITESPACE))
|
||||||
writer->buf[writer->buf_num++] = buf[0];
|
writer->buf[writer->buf_num++] = buf[0];
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (writer->buf_num > 0 || len < writer->buf_cap)
|
else
|
||||||
{
|
{
|
||||||
unsigned int add = (unsigned int)(writer->buf_cap - writer->buf_num);
|
int add = writer->buf_cap - writer->buf_num;
|
||||||
if (add > (unsigned int)len) add = (unsigned int)len;
|
if (add > len) add = len;
|
||||||
memcpy(writer->buf + writer->buf_num, buf, add);
|
memcpy(writer->buf + writer->buf_num, buf, add);
|
||||||
writer->buf_num += add;
|
writer->buf_num += add;
|
||||||
if ((unsigned int)len == add) return;
|
if (len == add) return;
|
||||||
rjsonwriter_flush(writer);
|
rjsonwriter_flush(writer);
|
||||||
len -= add;
|
len -= add;
|
||||||
buf += add;
|
buf += add;
|
||||||
|
if (writer->buf_num + len <= writer->buf_cap)
|
||||||
|
{
|
||||||
|
memcpy(writer->buf, buf, len);
|
||||||
|
writer->buf_num += len;
|
||||||
|
}
|
||||||
|
else if (writer->io(buf, len, writer->user_data) != len)
|
||||||
|
writer->error_text = "output error";
|
||||||
}
|
}
|
||||||
if (len < writer->buf_cap)
|
|
||||||
{
|
|
||||||
memcpy(writer->buf, buf, len);
|
|
||||||
writer->buf_num += len;
|
|
||||||
}
|
|
||||||
else writer->io(buf, len, writer->user_data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rjsonwriter_rawf(rjsonwriter_t *writer, const char *fmt, ...)
|
void rjsonwriter_rawf(rjsonwriter_t *writer, const char *fmt, ...)
|
||||||
@ -1283,23 +1328,47 @@ void rjsonwriter_rawf(rjsonwriter_t *writer, const char *fmt, ...)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
rjsonwriter_flush(writer);
|
rjsonwriter_flush(writer);
|
||||||
if (need >= writer->buf_cap)
|
if (writer->buf_num + need >= writer->buf_cap)
|
||||||
{
|
{
|
||||||
char* newbuf = (char*)malloc(need + 1);
|
int newcap = writer->buf_num + need + 1;
|
||||||
|
char* newbuf = (char*)malloc(newcap);
|
||||||
if (!newbuf)
|
if (!newbuf)
|
||||||
{
|
{
|
||||||
if (!writer->error_text) writer->error_text = "out of memory";
|
if (!writer->error_text) writer->error_text = "out of memory";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (writer->buf_num) memcpy(newbuf, writer->buf, writer->buf_num);
|
||||||
if (writer->buf != writer->inline_buf)
|
if (writer->buf != writer->inline_buf)
|
||||||
free(writer->buf);
|
free(writer->buf);
|
||||||
writer->buf = newbuf;
|
writer->buf = newbuf;
|
||||||
writer->buf_cap = need + 1;
|
writer->buf_cap = newcap;
|
||||||
}
|
}
|
||||||
va_start(ap2, fmt);
|
va_start(ap2, fmt);
|
||||||
vsnprintf(writer->buf, writer->buf_cap, fmt, ap2);
|
vsnprintf(writer->buf + writer->buf_num, writer->buf_cap - writer->buf_num, fmt, ap2);
|
||||||
va_end(ap2);
|
va_end(ap2);
|
||||||
writer->buf_num = need;
|
writer->buf_num += need;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _rjsonwriter_add_escaped(rjsonwriter_t *writer, unsigned char c)
|
||||||
|
{
|
||||||
|
char esc_buf[8], esc_len = 2;
|
||||||
|
const char* esc;
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case '\b': esc = "\\b"; break;
|
||||||
|
case '\t': esc = "\\t"; break;
|
||||||
|
case '\n': esc = "\\n"; break;
|
||||||
|
case '\f': esc = "\\f"; break;
|
||||||
|
case '\r': esc = "\\r"; break;
|
||||||
|
case '\"': esc = "\\\""; break;
|
||||||
|
case '\\': esc = "\\\\"; break;
|
||||||
|
case '/': esc = "\\/"; break;
|
||||||
|
default:
|
||||||
|
snprintf(esc_buf, sizeof(esc_buf), "\\u%04x", c);
|
||||||
|
esc = esc_buf;
|
||||||
|
esc_len = 6;
|
||||||
|
}
|
||||||
|
rjsonwriter_raw(writer, esc, esc_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rjsonwriter_add_string(rjsonwriter_t *writer, const char *value)
|
void rjsonwriter_add_string(rjsonwriter_t *writer, const char *value)
|
||||||
@ -1312,38 +1381,34 @@ void rjsonwriter_add_string(rjsonwriter_t *writer, const char *value)
|
|||||||
{
|
{
|
||||||
/* forward slash is special, it should be escaped if the previous character
|
/* forward slash is special, it should be escaped if the previous character
|
||||||
* was a < (intended to avoid having </script> html tags in JSON files) */
|
* was a < (intended to avoid having </script> html tags in JSON files) */
|
||||||
if (c < 0x20 || c == '\"' || c == '\\' ||
|
if (c >= 0x20 && c != '\"' && c != '\\' &&
|
||||||
(c == '/' && p > value + 1 && p[-2] == '<'))
|
(c != '/' || p < value + 2 || p[-2] != '<')) continue;
|
||||||
{
|
if (raw != p - 1) rjsonwriter_raw(writer, raw, (int)(p - 1 - raw));
|
||||||
char esc_buf[8], esc_len = 2;
|
_rjsonwriter_add_escaped(writer, c);
|
||||||
const char* esc;
|
raw = p;
|
||||||
if (raw != p - 1)
|
|
||||||
rjsonwriter_raw(writer, raw, (int)(p - 1 - raw));
|
|
||||||
switch (c)
|
|
||||||
{
|
|
||||||
case '\b': esc = "\\b"; break;
|
|
||||||
case '\t': esc = "\\t"; break;
|
|
||||||
case '\n': esc = "\\n"; break;
|
|
||||||
case '\f': esc = "\\f"; break;
|
|
||||||
case '\r': esc = "\\r"; break;
|
|
||||||
case '\"': esc = "\\\""; break;
|
|
||||||
case '\\': esc = "\\\\"; break;
|
|
||||||
case '/': esc = "\\/"; break;
|
|
||||||
default:
|
|
||||||
snprintf(esc_buf, sizeof(esc_buf), "\\u%04x", c);
|
|
||||||
esc = esc_buf;
|
|
||||||
esc_len = 6;
|
|
||||||
}
|
|
||||||
rjsonwriter_raw(writer, esc, esc_len);
|
|
||||||
raw = p;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (raw != p - 1)
|
if (raw != p - 1) rjsonwriter_raw(writer, raw, (int)(p - 1 - raw));
|
||||||
rjsonwriter_raw(writer, raw, (int)(p - 1 - raw));
|
|
||||||
string_end:
|
string_end:
|
||||||
rjsonwriter_raw(writer, "\"", 1);
|
rjsonwriter_raw(writer, "\"", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void rjsonwriter_add_string_len(rjsonwriter_t *writer, const char *value, int len)
|
||||||
|
{
|
||||||
|
const char *p = (const char*)value, *raw = p, *end = p + len;
|
||||||
|
rjsonwriter_raw(writer, "\"", 1);
|
||||||
|
while (p != end)
|
||||||
|
{
|
||||||
|
unsigned char c = (unsigned char)*p++;
|
||||||
|
if (c >= 0x20 && c != '\"' && c != '\\' &&
|
||||||
|
(c != '/' || p < value + 2 || p[-2] != '<')) continue;
|
||||||
|
if (raw != p - 1) rjsonwriter_raw(writer, raw, (int)(p - 1 - raw));
|
||||||
|
_rjsonwriter_add_escaped(writer, c);
|
||||||
|
raw = p;
|
||||||
|
}
|
||||||
|
if (raw != end) rjsonwriter_raw(writer, raw, (int)(end - raw));
|
||||||
|
rjsonwriter_raw(writer, "\"", 1);
|
||||||
|
}
|
||||||
|
|
||||||
void rjsonwriter_add_double(rjsonwriter_t *writer, double value)
|
void rjsonwriter_add_double(rjsonwriter_t *writer, double value)
|
||||||
{
|
{
|
||||||
int old_buf_num = writer->buf_num;
|
int old_buf_num = writer->buf_num;
|
||||||
@ -1365,20 +1430,16 @@ void rjsonwriter_add_double(rjsonwriter_t *writer, double value)
|
|||||||
|
|
||||||
void rjsonwriter_add_spaces(rjsonwriter_t *writer, int count)
|
void rjsonwriter_add_spaces(rjsonwriter_t *writer, int count)
|
||||||
{
|
{
|
||||||
int add;
|
if (!(writer->option_flags & RJSONWRITER_OPTION_SKIP_WHITESPACE))
|
||||||
if (count <= 0 || (writer->option_flags & RJSONWRITER_OPTION_SKIP_WHITESPACE))
|
for (; count > 0; count -= 8)
|
||||||
return;
|
rjsonwriter_raw(writer, " ", (count > 8 ? 8 : count));
|
||||||
for (; (add = (count > 8 ? 8 : count)) != 0; count -= add)
|
|
||||||
rjsonwriter_raw(writer, " ", add);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rjsonwriter_add_tabs(rjsonwriter_t *writer, int count)
|
void rjsonwriter_add_tabs(rjsonwriter_t *writer, int count)
|
||||||
{
|
{
|
||||||
int add;
|
if (!(writer->option_flags & RJSONWRITER_OPTION_SKIP_WHITESPACE))
|
||||||
if (count <= 0 || (writer->option_flags & RJSONWRITER_OPTION_SKIP_WHITESPACE))
|
for (; count > 0; count -= 8)
|
||||||
return;
|
rjsonwriter_raw(writer, "\t\t\t\t\t\t\t\t", (count > 8 ? 8 : count));
|
||||||
for (; (add = (count > 8 ? 8 : count)) != 0; count -= add)
|
|
||||||
rjsonwriter_raw(writer, "\t\t\t\t\t\t\t\t", add);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef _rJSON_EOF
|
#undef _rJSON_EOF
|
||||||
|
@ -186,8 +186,16 @@ typedef struct rjsonwriter rjsonwriter_t;
|
|||||||
/* Create a new writer instance to various targets */
|
/* Create a new writer instance to various targets */
|
||||||
rjsonwriter_t *rjsonwriter_open_stream(struct intfstream_internal *stream);
|
rjsonwriter_t *rjsonwriter_open_stream(struct intfstream_internal *stream);
|
||||||
rjsonwriter_t *rjsonwriter_open_rfile(struct RFILE *rfile);
|
rjsonwriter_t *rjsonwriter_open_rfile(struct RFILE *rfile);
|
||||||
|
rjsonwriter_t *rjsonwriter_open_memory();
|
||||||
rjsonwriter_t *rjsonwriter_open_user(rjsonwriter_io_t io, void *user_data);
|
rjsonwriter_t *rjsonwriter_open_user(rjsonwriter_io_t io, void *user_data);
|
||||||
|
|
||||||
|
/* When opened with rjsonwriter_open_memory, will return the generated JSON.
|
||||||
|
* Result is always null-terminated. Passed len can be NULL if not needed,
|
||||||
|
* otherwise returned len will be string length without null-terminator.
|
||||||
|
* Returns NULL if writing ran out of memory or not opened from memory.
|
||||||
|
* Returned buffer is only valid until writer is modified or freed. */
|
||||||
|
char* rjsonwriter_get_memory_buffer(rjsonwriter_t *writer, int* len);
|
||||||
|
|
||||||
/* Free rjsonwriter handle and return result of final rjsonwriter_flush call */
|
/* Free rjsonwriter handle and return result of final rjsonwriter_flush call */
|
||||||
bool rjsonwriter_free(rjsonwriter_t *writer);
|
bool rjsonwriter_free(rjsonwriter_t *writer);
|
||||||
|
|
||||||
@ -214,6 +222,7 @@ void rjsonwriter_rawf(rjsonwriter_t *writer, const char *fmt, ...);
|
|||||||
* Special and control characters are automatically escaped.
|
* Special and control characters are automatically escaped.
|
||||||
* If NULL is passed an empty string will be written (not JSON null). */
|
* If NULL is passed an empty string will be written (not JSON null). */
|
||||||
void rjsonwriter_add_string(rjsonwriter_t *writer, const char *value);
|
void rjsonwriter_add_string(rjsonwriter_t *writer, const char *value);
|
||||||
|
void rjsonwriter_add_string_len(rjsonwriter_t *writer, const char *value, int len);
|
||||||
|
|
||||||
/* Add a signed or unsigned integer or a double number */
|
/* Add a signed or unsigned integer or a double number */
|
||||||
static INLINE void rjsonwriter_add_int(rjsonwriter_t *writer, int value)
|
static INLINE void rjsonwriter_add_int(rjsonwriter_t *writer, int value)
|
||||||
|
314
retroarch.c
314
retroarch.c
@ -180,6 +180,7 @@
|
|||||||
#include <encodings/base64.h>
|
#include <encodings/base64.h>
|
||||||
#include <formats/rbmp.h>
|
#include <formats/rbmp.h>
|
||||||
#include <formats/rpng.h>
|
#include <formats/rpng.h>
|
||||||
|
#include <formats/rjson.h>
|
||||||
#include "translation_defines.h"
|
#include "translation_defines.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -13607,10 +13608,8 @@ static void handle_translation_cb(
|
|||||||
void *user_data, const char *error)
|
void *user_data, const char *error)
|
||||||
{
|
{
|
||||||
size_t pitch;
|
size_t pitch;
|
||||||
char curr;
|
|
||||||
unsigned width, height;
|
unsigned width, height;
|
||||||
unsigned image_width, image_height;
|
unsigned image_width, image_height;
|
||||||
char* body_copy = NULL;
|
|
||||||
uint8_t* raw_output_data = NULL;
|
uint8_t* raw_output_data = NULL;
|
||||||
char* raw_image_file_data = NULL;
|
char* raw_image_file_data = NULL;
|
||||||
struct scaler_ctx* scaler = NULL;
|
struct scaler_ctx* scaler = NULL;
|
||||||
@ -13624,14 +13623,12 @@ static void handle_translation_cb(
|
|||||||
void* raw_image_data_alpha = NULL;
|
void* raw_image_data_alpha = NULL;
|
||||||
void* raw_sound_data = NULL;
|
void* raw_sound_data = NULL;
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
int i = 0;
|
rjson_t* json = NULL;
|
||||||
int start = -1;
|
int json_current_key = 0;
|
||||||
char* found_string = NULL;
|
|
||||||
char* err_string = NULL;
|
char* err_string = NULL;
|
||||||
char* text_string = NULL;
|
char* text_string = NULL;
|
||||||
char* auto_string = NULL;
|
char* auto_string = NULL;
|
||||||
char* key_string = NULL;
|
char* key_string = NULL;
|
||||||
int curr_state = 0;
|
|
||||||
struct rarch_state *p_rarch = &rarch_st;
|
struct rarch_state *p_rarch = &rarch_st;
|
||||||
settings_t* settings = p_rarch->configuration_settings;
|
settings_t* settings = p_rarch->configuration_settings;
|
||||||
bool was_paused = p_rarch->runloop_paused;
|
bool was_paused = p_rarch->runloop_paused;
|
||||||
@ -13655,96 +13652,66 @@ static void handle_translation_cb(
|
|||||||
if (!data || error)
|
if (!data || error)
|
||||||
goto finish;
|
goto finish;
|
||||||
|
|
||||||
data->data = (char*)realloc(data->data, data->len + 1);
|
json = rjson_open_buffer(data->data, data->len);
|
||||||
if (!data->data)
|
if (!json)
|
||||||
goto finish;
|
goto finish;
|
||||||
|
|
||||||
data->data[data->len] = '\0';
|
|
||||||
|
|
||||||
/* Parse JSON body for the image and sound data */
|
/* Parse JSON body for the image and sound data */
|
||||||
body_copy = strdup(data->data);
|
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
curr = (char)*(body_copy+i);
|
static const char* keys[] = { "image", "sound", "text", "error", "auto", "press" };
|
||||||
if (curr == '\0')
|
|
||||||
break;
|
const char* string;
|
||||||
if (curr == '\"')
|
size_t string_len;
|
||||||
|
|
||||||
|
enum rjson_type json_type = rjson_next(json);
|
||||||
|
if (json_type == RJSON_DONE || json_type == RJSON_ERROR) break;
|
||||||
|
if (json_type != RJSON_STRING) continue;
|
||||||
|
if (rjson_get_context_type(json) != RJSON_OBJECT) continue;
|
||||||
|
string = rjson_get_string(json, &string_len);
|
||||||
|
|
||||||
|
if ((rjson_get_context_count(json) & 1) == 1)
|
||||||
{
|
{
|
||||||
if (start == -1)
|
int i;
|
||||||
start = i;
|
json_current_key = -1;
|
||||||
else
|
for (i = 0; i != (sizeof(keys)/sizeof(keys[0])); i++)
|
||||||
{
|
{
|
||||||
size_t found_string_len;
|
if (string_is_equal(string, keys[i]))
|
||||||
found_string = (char*)malloc(i-start+1);
|
|
||||||
strlcpy(found_string, body_copy+start+1, i-start);
|
|
||||||
|
|
||||||
found_string_len = strlen(found_string);
|
|
||||||
|
|
||||||
if (curr_state == 1)/*image*/
|
|
||||||
{
|
{
|
||||||
raw_image_file_data = (char*)unbase64(found_string,
|
json_current_key = i;
|
||||||
found_string_len,
|
break;
|
||||||
&new_image_size);
|
|
||||||
curr_state = 0;
|
|
||||||
}
|
|
||||||
#ifdef HAVE_AUDIOMIXER
|
|
||||||
else if (curr_state == 2)
|
|
||||||
{
|
|
||||||
raw_sound_data = (void*)unbase64(found_string,
|
|
||||||
found_string_len, &new_sound_size);
|
|
||||||
curr_state = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else if (curr_state == 3)
|
|
||||||
{
|
|
||||||
text_string = (char*)malloc(i-start+1);
|
|
||||||
strlcpy(text_string, body_copy+start+1, i-start);
|
|
||||||
curr_state = 0;
|
|
||||||
}
|
|
||||||
else if (curr_state == 4)
|
|
||||||
{
|
|
||||||
err_string = (char*)malloc(i-start+1);
|
|
||||||
strlcpy(err_string, body_copy+start+1, i-start);
|
|
||||||
curr_state = 0;
|
|
||||||
}
|
|
||||||
else if (curr_state == 5)
|
|
||||||
{
|
|
||||||
auto_string = (char*)malloc(i-start+1);
|
|
||||||
strlcpy(auto_string, body_copy+start+1, i-start);
|
|
||||||
curr_state = 0;
|
|
||||||
}
|
|
||||||
else if (curr_state == 6)
|
|
||||||
{
|
|
||||||
key_string = (char*)malloc(i-start+1);
|
|
||||||
strlcpy(key_string, body_copy+start+1, i-start);
|
|
||||||
curr_state = 0;
|
|
||||||
}
|
|
||||||
else if (string_is_equal(found_string, "image"))
|
|
||||||
curr_state = 1;
|
|
||||||
else if (string_is_equal(found_string, "sound"))
|
|
||||||
curr_state = 2;
|
|
||||||
else if (string_is_equal(found_string, "text"))
|
|
||||||
curr_state = 3;
|
|
||||||
else if (string_is_equal(found_string, "error"))
|
|
||||||
curr_state = 4;
|
|
||||||
else if (string_is_equal(found_string, "auto"))
|
|
||||||
curr_state = 5;
|
|
||||||
else if (string_is_equal(found_string, "press"))
|
|
||||||
curr_state = 6;
|
|
||||||
else
|
|
||||||
curr_state = 0;
|
|
||||||
|
|
||||||
start = -1;
|
|
||||||
|
|
||||||
if (found_string)
|
|
||||||
{
|
|
||||||
free(found_string);
|
|
||||||
found_string = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i++;
|
else
|
||||||
|
{
|
||||||
|
switch (json_current_key)
|
||||||
|
{
|
||||||
|
case 0: /* image */
|
||||||
|
raw_image_file_data = (char*)unbase64(string,
|
||||||
|
string_len, &new_image_size);
|
||||||
|
break;
|
||||||
|
#ifdef HAVE_AUDIOMIXER
|
||||||
|
case 1: /* sound */
|
||||||
|
raw_sound_data = (void*)unbase64(string,
|
||||||
|
string_len, &new_sound_size);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case 2: /* text */
|
||||||
|
text_string = strdup(string);
|
||||||
|
break;
|
||||||
|
case 3: /* error */
|
||||||
|
err_string = strdup(string);
|
||||||
|
break;
|
||||||
|
case 4: /* auto */
|
||||||
|
auto_string = strdup(string);
|
||||||
|
break;
|
||||||
|
case 5: /* press */
|
||||||
|
key_string = strdup(string);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
json_current_key = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string_is_equal(err_string, "No text found."))
|
if (string_is_equal(err_string, "No text found."))
|
||||||
@ -14095,8 +14062,8 @@ finish:
|
|||||||
if (user_data)
|
if (user_data)
|
||||||
free(user_data);
|
free(user_data);
|
||||||
|
|
||||||
if (body_copy)
|
if (json)
|
||||||
free(body_copy);
|
rjson_free(json);
|
||||||
if (raw_image_file_data)
|
if (raw_image_file_data)
|
||||||
free(raw_image_file_data);
|
free(raw_image_file_data);
|
||||||
if (raw_image_data_alpha)
|
if (raw_image_data_alpha)
|
||||||
@ -14109,8 +14076,6 @@ finish:
|
|||||||
free(err_string);
|
free(err_string);
|
||||||
if (text_string)
|
if (text_string)
|
||||||
free(text_string);
|
free(text_string);
|
||||||
if (found_string)
|
|
||||||
free(found_string);
|
|
||||||
if (raw_output_data)
|
if (raw_output_data)
|
||||||
free(raw_output_data);
|
free(raw_output_data);
|
||||||
|
|
||||||
@ -14322,16 +14287,10 @@ static bool run_translation_service(
|
|||||||
uint8_t *bmp_buffer = NULL;
|
uint8_t *bmp_buffer = NULL;
|
||||||
uint64_t buffer_bytes = 0;
|
uint64_t buffer_bytes = 0;
|
||||||
char *bmp64_buffer = NULL;
|
char *bmp64_buffer = NULL;
|
||||||
char *json_buffer = NULL;
|
rjsonwriter_t* jsonwriter = NULL;
|
||||||
|
const char *json_buffer = NULL;
|
||||||
|
|
||||||
int out_length = 0;
|
int bmp64_length = 0;
|
||||||
int json_length = 0;
|
|
||||||
const char *rf1 = "{\"image\": \"";
|
|
||||||
const char *rf2 = "\"}\0";
|
|
||||||
char *rf3 = NULL;
|
|
||||||
char *state_son = NULL;
|
|
||||||
int state_son_length = 177;
|
|
||||||
int curr_length = 0;
|
|
||||||
bool TRANSLATE_USE_BMP = false;
|
bool TRANSLATE_USE_BMP = false;
|
||||||
bool use_overlay = false;
|
bool use_overlay = false;
|
||||||
|
|
||||||
@ -14500,120 +14459,75 @@ static bool run_translation_service(
|
|||||||
|
|
||||||
bmp64_buffer = base64((void *)bmp_buffer,
|
bmp64_buffer = base64((void *)bmp_buffer,
|
||||||
sizeof(uint8_t)*buffer_bytes,
|
sizeof(uint8_t)*buffer_bytes,
|
||||||
&out_length);
|
&bmp64_length);
|
||||||
|
|
||||||
if (!bmp64_buffer)
|
if (!bmp64_buffer)
|
||||||
goto finish;
|
goto finish;
|
||||||
|
|
||||||
|
jsonwriter = rjsonwriter_open_memory();
|
||||||
|
if (!jsonwriter)
|
||||||
|
goto finish;
|
||||||
|
|
||||||
|
rjsonwriter_add_start_object(jsonwriter);
|
||||||
|
rjsonwriter_add_space(jsonwriter);
|
||||||
|
rjsonwriter_add_string(jsonwriter, "image");
|
||||||
|
rjsonwriter_add_colon(jsonwriter);
|
||||||
|
rjsonwriter_add_space(jsonwriter);
|
||||||
|
rjsonwriter_add_string_len(jsonwriter, bmp64_buffer, bmp64_length);
|
||||||
|
|
||||||
/* Form request... */
|
/* Form request... */
|
||||||
if (system_label)
|
if (system_label)
|
||||||
{
|
{
|
||||||
unsigned i;
|
rjsonwriter_add_comma(jsonwriter);
|
||||||
size_t system_label_len = strlen(system_label);
|
rjsonwriter_add_space(jsonwriter);
|
||||||
|
rjsonwriter_add_string(jsonwriter, "label");
|
||||||
|
rjsonwriter_add_colon(jsonwriter);
|
||||||
|
rjsonwriter_add_space(jsonwriter);
|
||||||
|
rjsonwriter_add_string(jsonwriter, system_label);
|
||||||
|
}
|
||||||
|
|
||||||
/* include game label if provided */
|
rjsonwriter_add_comma(jsonwriter);
|
||||||
rf3 = (char *)malloc(15 + system_label_len);
|
rjsonwriter_add_space(jsonwriter);
|
||||||
memcpy(rf3, ", \"label\": \"", 12*sizeof(uint8_t));
|
rjsonwriter_add_string(jsonwriter, "state");
|
||||||
memcpy(rf3 + 12, system_label, system_label_len);
|
rjsonwriter_add_colon(jsonwriter);
|
||||||
memcpy(rf3 + 12 + system_label_len, "\"}\0", 3*sizeof(uint8_t));
|
rjsonwriter_add_space(jsonwriter);
|
||||||
for (i = 12; i < system_label_len + 12; i++)
|
rjsonwriter_add_start_object(jsonwriter);
|
||||||
|
rjsonwriter_add_space(jsonwriter);
|
||||||
|
rjsonwriter_add_string(jsonwriter, "paused");
|
||||||
|
rjsonwriter_add_colon(jsonwriter);
|
||||||
|
rjsonwriter_add_space(jsonwriter);
|
||||||
|
rjsonwriter_add_unsigned(jsonwriter, (paused ? 1 : 0));
|
||||||
|
{
|
||||||
|
static const char* state_labels[] = { "b", "y", "select", "start", "up", "down", "left", "right", "a", "x", "l", "r", "l2", "r2", "l3", "r3" };
|
||||||
|
int i;
|
||||||
|
for (i = 0; i != (sizeof(state_labels)/sizeof(state_labels[0])); i++)
|
||||||
{
|
{
|
||||||
if (rf3[i] == '\"')
|
rjsonwriter_add_comma(jsonwriter);
|
||||||
rf3[i] = ' ';
|
rjsonwriter_add_space(jsonwriter);
|
||||||
}
|
rjsonwriter_add_string(jsonwriter, state_labels[i]);
|
||||||
json_length = 11 + out_length + 15 + system_label_len + 2;
|
rjsonwriter_add_colon(jsonwriter);
|
||||||
}
|
rjsonwriter_add_space(jsonwriter);
|
||||||
else
|
rjsonwriter_add_unsigned(jsonwriter,
|
||||||
json_length = 11 + out_length + 2;
|
|
||||||
|
|
||||||
state_son = (char*)malloc(state_son_length);
|
|
||||||
|
|
||||||
memcpy(state_son, ", \"state\": {\"paused\": 0, \"a\": 0, \"b\": 0, \"select\": 0, \"start\": 0, \"up\": 0, \"down\": 0, \"left\": 0, \"right\": 0, \"x\": 0, \"y\": 0, \"l\": 0, \"r\":0, \"l2\": 0, \"r2\": 0, \"l3\":0, \"r3\": 0}}\0",
|
|
||||||
state_son_length * sizeof(uint8_t));
|
|
||||||
|
|
||||||
if (paused)
|
|
||||||
state_son[22] = '1';
|
|
||||||
|
|
||||||
#ifdef HAVE_ACCESSIBILITY
|
#ifdef HAVE_ACCESSIBILITY
|
||||||
#ifdef HAVE_TRANSLATE
|
(p_rarch->ai_gamepad_state[i] ? 1 : 0)
|
||||||
if (p_rarch->ai_gamepad_state[8]) /* a */
|
#else
|
||||||
state_son[30] = '1';
|
0
|
||||||
if (p_rarch->ai_gamepad_state[0]) /* b */
|
|
||||||
state_son[38] = '1';
|
|
||||||
if (p_rarch->ai_gamepad_state[2]) /* select */
|
|
||||||
state_son[51] = '1';
|
|
||||||
if (p_rarch->ai_gamepad_state[3]) /* start */
|
|
||||||
state_son[63] = '1';
|
|
||||||
|
|
||||||
if (p_rarch->ai_gamepad_state[4]) /* up */
|
|
||||||
state_son[72] = '1';
|
|
||||||
if (p_rarch->ai_gamepad_state[5]) /* down */
|
|
||||||
state_son[83] = '1';
|
|
||||||
if (p_rarch->ai_gamepad_state[6]) /* left */
|
|
||||||
state_son[94] = '1';
|
|
||||||
if (p_rarch->ai_gamepad_state[7]) /* right */
|
|
||||||
state_son[106] = '1';
|
|
||||||
|
|
||||||
if (p_rarch->ai_gamepad_state[9]) /* x */
|
|
||||||
state_son[114] = '1';
|
|
||||||
if (p_rarch->ai_gamepad_state[1]) /* y */
|
|
||||||
state_son[122] = '1';
|
|
||||||
if (p_rarch->ai_gamepad_state[10]) /* l */
|
|
||||||
state_son[130] = '1';
|
|
||||||
if (p_rarch->ai_gamepad_state[11]) /* r */
|
|
||||||
state_son[138] = '1';
|
|
||||||
|
|
||||||
if (p_rarch->ai_gamepad_state[12]) /* l2 */
|
|
||||||
state_son[147] = '1';
|
|
||||||
if (p_rarch->ai_gamepad_state[13]) /* r2 */
|
|
||||||
state_son[156] = '1';
|
|
||||||
if (p_rarch->ai_gamepad_state[14]) /* l3 */
|
|
||||||
state_son[165] = '1';
|
|
||||||
if (p_rarch->ai_gamepad_state[15]) /* r3 */
|
|
||||||
state_son[174] = '1';
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rjsonwriter_add_space(jsonwriter);
|
||||||
|
rjsonwriter_add_end_object(jsonwriter);
|
||||||
|
rjsonwriter_add_space(jsonwriter);
|
||||||
|
rjsonwriter_add_end_object(jsonwriter);
|
||||||
|
|
||||||
json_length += state_son_length;
|
json_buffer = rjsonwriter_get_memory_buffer(jsonwriter, NULL);
|
||||||
|
|
||||||
json_buffer = (char*)malloc(json_length);
|
|
||||||
if (!json_buffer)
|
if (!json_buffer)
|
||||||
goto finish;
|
goto finish; /* ran out of memory */
|
||||||
|
|
||||||
json_buffer[json_length - 1] = '\0';
|
|
||||||
|
|
||||||
/* Image data */
|
|
||||||
memcpy(json_buffer, (const void*)rf1, 11 * sizeof(uint8_t));
|
|
||||||
memcpy(json_buffer + 11, bmp64_buffer, out_length * sizeof(uint8_t));
|
|
||||||
memcpy(json_buffer + 11 + out_length, "\"", 1 * sizeof(uint8_t));
|
|
||||||
curr_length = 11 + out_length + 1;
|
|
||||||
|
|
||||||
/* State data */
|
|
||||||
memcpy(json_buffer + curr_length, state_son,
|
|
||||||
state_son_length * sizeof(uint8_t));
|
|
||||||
curr_length += state_son_length;
|
|
||||||
|
|
||||||
/* System Label */
|
|
||||||
if (rf3)
|
|
||||||
{
|
|
||||||
size_t system_label_len = strlen(system_label);
|
|
||||||
|
|
||||||
memcpy(json_buffer + curr_length,
|
|
||||||
(const void*)rf3,
|
|
||||||
(15 + system_label_len) * sizeof(uint8_t));
|
|
||||||
curr_length += 15 + system_label_len;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
memcpy(json_buffer + curr_length,
|
|
||||||
(const void*)rf2,
|
|
||||||
3 * sizeof(uint8_t));
|
|
||||||
curr_length += 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (p_rarch->ai_service_auto != 2)
|
if (p_rarch->ai_service_auto != 2)
|
||||||
RARCH_LOG("Request size: %d\n", out_length);
|
RARCH_LOG("Request size: %d\n", bmp64_length);
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
char separator = '?';
|
char separator = '?';
|
||||||
@ -14730,14 +14644,10 @@ finish:
|
|||||||
|
|
||||||
if (bmp64_buffer)
|
if (bmp64_buffer)
|
||||||
free(bmp64_buffer);
|
free(bmp64_buffer);
|
||||||
if (rf3)
|
|
||||||
free(rf3);
|
|
||||||
if (system_label)
|
if (system_label)
|
||||||
free(system_label);
|
free(system_label);
|
||||||
if (json_buffer)
|
if (jsonwriter)
|
||||||
free(json_buffer);
|
rjsonwriter_free(jsonwriter);
|
||||||
if (state_son)
|
|
||||||
free(state_son);
|
|
||||||
return !error;
|
return !error;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user