xP: further optimize JSON marshalling

This commit is contained in:
Přemysl Eric Janouch 2022-09-15 03:15:52 +02:00
parent 9cf44aa4dd
commit 98b0a4ef3d
Signed by: p
GPG Key ID: A0420B94F92B9493

View File

@ -15,6 +15,9 @@ function define_sint(size, shortname, gotype) {
gotype = "int" size
define_internal(shortname, gotype)
CodegenAppendJSON[shortname] = \
"\tb = strconv.AppendInt(b, int64(%s), 10)\n"
if (size == 8) {
CodegenSerialize[shortname] = "\tdata = append(data, uint8(%s))\n"
CodegenDeserialize[shortname] = \
@ -42,6 +45,9 @@ function define_uint(size, shortname, gotype) {
gotype = "uint" size
define_internal(shortname, gotype)
CodegenAppendJSON[shortname] = \
"\tb = strconv.AppendUint(b, uint64(%s), 10)\n"
# Both byte and uint8 luckily marshal as base64-encoded JSON strings.
if (size == 8) {
CodegenSerialize[shortname] = "\tdata = append(data, %s)\n"
@ -76,6 +82,8 @@ function codegen_begin() {
define_uint("64")
define_internal("bool", "bool")
CodegenAppendJSON["bool"] = \
"\tb = strconv.AppendBool(b, %s)\n"
CodegenSerialize["bool"] = \
"\tif %s {\n" \
"\t\tdata = append(data, 1)\n" \
@ -254,24 +262,32 @@ function codegen_enum(name, cg, gotype, fields) {
delete cg[i]
}
function codegen_marshal(type, f, marshal) {
if (CodegenAppendJSON[type])
return sprintf(CodegenAppendJSON[type], f)
if (CodegenIsMarshaler[type])
marshal = f ".MarshalJSON()"
else
marshal = "json.Marshal(" f ")"
return \
"\tif j, err := " marshal "; err != nil {\n" \
"\t\treturn nil, err\n" \
"\t} else {\n" \
"\t\tb = append(b, j...)\n" \
"\t}\n"
}
function codegen_struct_field_marshal(d, cg, camel, f, marshal) {
camel = snaketocamel(d["name"])
f = "s." camel
# Complex types are json.Marshalers, there's no need to json.Marshal(&f).
if (!d["isarray"]) {
if (CodegenIsMarshaler[d["type"]])
marshal = f ".MarshalJSON()"
else
marshal = "json.Marshal(" f ")"
append(cg, "marshal",
"\tb = append(b, `,\"" decapitalize(camel) "\":`...)\n" \
"\tif j, err := " marshal "; err != nil {\n" \
"\t\treturn nil, err\n" \
"\t} else {\n" \
"\t\tb = append(b, j...)\n" \
"\t}\n")
codegen_marshal(d["type"], f))
return
}
@ -283,22 +299,13 @@ function codegen_struct_field_marshal(d, cg, camel, f, marshal) {
return
}
if (CodegenIsMarshaler[d["type"]])
marshal = f "[i].MarshalJSON()"
else
marshal = "json.Marshal(" f "[i])"
append(cg, "marshal",
"\tb = append(b, `,\"" decapitalize(camel) "\":[`...)\n" \
"\tfor i := 0; i < len(" f "); i++ {\n" \
"\t\tif i > 0 {\n" \
"\t\t\tb = append(b, ',')\n" \
"\t\t}\n" \
"\t\tif j, err := " marshal "; err != nil {\n" \
"\t\t\treturn nil, err\n" \
"\t\t} else {\n" \
"\t\t\tb = append(b, j...)\n" \
"\t\t}\n" \
indent(codegen_marshal(d["type"], f "[i]")) \
"\t}\n" \
"\tb = append(b, ']')\n")
}