mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2025-01-01 05:25:50 +01:00
Improve JSON stringification for Bangle.js - much more compact, and now handles non-ASCII chars correctly
This commit is contained in:
parent
9dbdb3da93
commit
5211540e03
@ -231,9 +231,8 @@ public class BangleJSDeviceSupport extends AbstractBTLEDeviceSupport {
|
||||
|
||||
/// Write a string of data, and chunk it up
|
||||
private void uartTx(TransactionBuilder builder, String str) {
|
||||
byte[] bytes = str.getBytes(StandardCharsets.ISO_8859_1);
|
||||
LOG.info("UART TX: " + str);
|
||||
byte[] bytes;
|
||||
bytes = str.getBytes(StandardCharsets.ISO_8859_1);
|
||||
// FIXME: somehow this is still giving us UTF8 data when we put images in strings. Maybe JSON.stringify is converting to UTF-8?
|
||||
for (int i=0;i<bytes.length;i+=mtuSize) {
|
||||
int l = bytes.length-i;
|
||||
@ -244,26 +243,70 @@ public class BangleJSDeviceSupport extends AbstractBTLEDeviceSupport {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Write a string of data, and chunk it up
|
||||
public String jsonToString(JSONObject jsonObj) {
|
||||
String json = jsonObj.toString();
|
||||
// toString creates '\u0000' instead of '\0'
|
||||
// FIXME: there have got to be nicer ways of handling this - maybe we just make our own JSON.toString (see below)
|
||||
json = json.replaceAll("\\\\u000([01234567])", "\\\\$1");
|
||||
json = json.replaceAll("\\\\u00([0123456789abcdef][0123456789abcdef])", "\\\\x$1");
|
||||
return json;
|
||||
/*String json = "{";
|
||||
Iterator<String> iter = jsonObj.keys();
|
||||
while (iter.hasNext()) {
|
||||
String key = iter.next();
|
||||
Object v = jsonObj.get(key);
|
||||
if (v instanceof Integer) {
|
||||
// ...
|
||||
} else // ..
|
||||
if (iter.hasNext()) json+=",";
|
||||
/// Converts an object to a JSON string. see jsonToString
|
||||
private String jsonToStringInternal(Object v) {
|
||||
if (v instanceof String) {
|
||||
/* Convert a string, escaping chars we can't send over out UART connection */
|
||||
String s = (String)v;
|
||||
String json = "\"";
|
||||
for (int i=0;i<s.length();i++) {
|
||||
int ch = (int)s.charAt(i);
|
||||
if (ch<8) json += "\\"+ch;
|
||||
else if (ch==8) json += "\\b";
|
||||
else if (ch==9) json += "\\t";
|
||||
else if (ch==10) json += "\\n";
|
||||
else if (ch==11) json += "\\v";
|
||||
else if (ch==12) json += "\\f";
|
||||
else if (ch==34) json += "\\\""; // quote
|
||||
else if (ch==92) json += "\\\\"; // slash
|
||||
else if (ch<32 || ch==26 || ch==27 || ch==127 || ch==173) json += "\\x"+Integer.toHexString((ch&255)|256).substring(1);
|
||||
else json += s.charAt(i);
|
||||
}
|
||||
json += "\"";
|
||||
} else if (v instanceof JSONArray) {
|
||||
JSONArray a = (JSONArray)v;
|
||||
String json = "[";
|
||||
for (int i=0;i<a.length();i++) {
|
||||
if (i>0) json += ",";
|
||||
Object o = null;
|
||||
try {
|
||||
o = a.get(i);
|
||||
} catch (JSONException e) {
|
||||
LOG.warn("jsonToString array error: " + e.getLocalizedMessage());
|
||||
}
|
||||
json += jsonToStringInternal(o));
|
||||
}
|
||||
return json+"]";
|
||||
} else if (v instanceof JSONObject) {
|
||||
JSONObject obj = (JSONObject)v;
|
||||
String json = "{";
|
||||
Iterator<String> iter = obj.keys();
|
||||
while (iter.hasNext()) {
|
||||
String key = iter.next();
|
||||
Object o = null;
|
||||
try {
|
||||
o = obj.get(key);
|
||||
} catch (JSONException e) {
|
||||
LOG.warn("jsonToString object error: " + e.getLocalizedMessage());
|
||||
}
|
||||
json += key+":"+jsonToStringInternal(o);
|
||||
if (iter.hasNext()) json+=",";
|
||||
}
|
||||
return json+"}";
|
||||
} else { // int/double/null
|
||||
return v.toString();
|
||||
}
|
||||
return json+"}";*/
|
||||
}
|
||||
|
||||
/// Convert a JSON object to a JSON String (NOT 100% JSON compliant)
|
||||
public String jsonToString(JSONObject jsonObj) {
|
||||
/* jsonObj.toString() works but breaks char codes>128 (encodes as UTF8?) and also uses
|
||||
\u0000 when just \0 would do (and so on).
|
||||
|
||||
So we do it manually, which can be more compact anyway.
|
||||
This is JSON-ish, so not exactly as per JSON1 spec but good enough for Espruino.
|
||||
*/
|
||||
return jsonToStringInternal(jsonObj);
|
||||
}
|
||||
|
||||
/// Write a JSON object of data
|
||||
@ -291,10 +334,10 @@ public class BangleJSDeviceSupport extends AbstractBTLEDeviceSupport {
|
||||
|
||||
private void handleUartRxLine(String line) {
|
||||
LOG.info("UART RX LINE: " + line);
|
||||
|
||||
if (line.length()==0) return;
|
||||
if (">Uncaught ReferenceError: \"GB\" is not defined".equals(line))
|
||||
GB.toast(getContext(), "Gadgetbridge plugin not installed on Bangle.js", Toast.LENGTH_LONG, GB.ERROR);
|
||||
else if (line.length() > 0 && line.charAt(0)=='{') {
|
||||
else if (line.charAt(0)=='{') {
|
||||
// JSON - we hope!
|
||||
try {
|
||||
JSONObject json = new JSONObject(line);
|
||||
|
Loading…
Reference in New Issue
Block a user