diff --git a/hbrtl/json.go b/hbrtl/json.go index db44c44..ece4e87 100644 --- a/hbrtl/json.go +++ b/hbrtl/json.go @@ -58,7 +58,17 @@ func HbJsonEncode(t *hbrt.Thread) { t.RetString(string(data)) } -// HB_JSONDECODE(cJSON) → xValue +// HB_JSONDECODE(cJSON [, @xOut]) → xValue | nBytesParsed +// +// Two Harbour-spec calling forms: +// +// - 1 arg : returns the decoded value (or NIL on parse error). +// - 2 args: writes the decoded value into the byref @xOut and +// returns the number of bytes parsed (0 on error). This is the +// form mod_harbour / fivenode PRG code uses for ctx_get and the +// like. Five previously implemented only the 1-arg form, so any +// PRG that relied on the byref output saw NIL and silently fell +// through to a default. func HbJsonDecode(t *hbrt.Thread) { nParams := t.ParamCount() t.Frame(nParams, 0) @@ -66,10 +76,21 @@ func HbJsonDecode(t *hbrt.Thread) { s := t.Local(1).AsString() var raw interface{} if err := json.Unmarshal([]byte(s), &raw); err != nil { - t.RetNil() + if nParams >= 2 { + t.SetLocal(2, hbrt.MakeNil()) + t.RetInt(0) + } else { + t.RetNil() + } return } - t.RetVal(goToValue(raw)) + v := goToValue(raw) + if nParams >= 2 { + t.SetLocal(2, v) + t.RetInt(int64(len(s))) + return + } + t.RetVal(v) } // === Five Extensions ===