From e94559dddb078355c782a69d0af3b9b18105e781 Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Fri, 28 Oct 2016 11:07:16 +0200 Subject: [PATCH] json: correctly treat multidimensional arrays of objects Multi-dimensional JSON array will be created for the members like std::string fArr3[3][4][5]; In JavaScript one can use: var obj = JSROOT.parse(json_str); console.log('Array item', obj.fArr[1][2][3]); Signed-off-by: Sergey Linev --- io/io/src/TBufferJSON.cxx | 101 ++++++++++++++++++++++++-------------- 1 file changed, 64 insertions(+), 37 deletions(-) diff --git a/io/io/src/TBufferJSON.cxx b/io/io/src/TBufferJSON.cxx index 51600b5d33d3e..3a3174ac4078d 100644 --- a/io/io/src/TBufferJSON.cxx +++ b/io/io/src/TBufferJSON.cxx @@ -2449,26 +2449,44 @@ void TBufferJSON::WriteFastArray(void *start, const TClass *cl, Int_t n, if (!n) n = 1; int size = cl->Size(); - if (n > 1) { - JsonDisablePostprocessing(); - AppendOutput("["); - /* fJsonrCnt++; */ // count array, but do not add to references - } + TStreamerElement* elem = Stack(0)->fElem; + Bool_t isarray = (n>1) || (elem && (elem->GetArrayDim()>0)); + Bool_t usindicies = isarray && (elem!=0) && (elem->GetArrayDim() > 1) && (elem->GetArrayLength()==n); + TArrayI indexes(usindicies ? elem->GetArrayDim() : 1); + indexes.Reset(0); + Int_t cnt = 0; + + if (isarray) JsonDisablePostprocessing(); for (Int_t j = 0; j < n; j++, obj += size) { - if (j > 0) AppendOutput(fArraySepar.Data()); + if (isarray) { + if (usindicies) { + while ((cnt >= 0) && (cnt < indexes.GetSize())) { + if (indexes[cnt] >= elem->GetMaxIndex(cnt)) { + AppendOutput("]"); + indexes[cnt--] = 0; + if (cnt >= 0) indexes[cnt]++; + continue; + } + AppendOutput(indexes[cnt] == 0 ? "[" : fArraySepar.Data()); + cnt++; + } + if (cnt>0) indexes[--cnt]++; + } else { + AppendOutput((j==0) ? "[" : fArraySepar.Data()); + } + } JsonWriteObject(obj, cl, kFALSE); - if ((n > 1) && (fValue.Length() > 0)) { + if (isarray && (fValue.Length() > 0)) { AppendOutput(fValue.Data()); fValue.Clear(); } } - if (n > 1) { - AppendOutput("]"); - } + if (isarray) + for (Int_t k=0;k 1) { - JsonDisablePostprocessing(); - AppendOutput("["); - /* fJsonrCnt++; */ // count array, but do not add to references - } + if (n<=0) return 0; - if (!isPreAlloc) { + Int_t res = 0; - for (Int_t j = 0; j < n; j++) { - if (j > 0) AppendOutput(fArraySepar.Data()); - res |= WriteObjectAny(start[j], cl); - if ((n > 1) && (fValue.Length() > 0)) { - AppendOutput(fValue.Data()); - fValue.Clear(); + TStreamerElement* elem = Stack(0)->fElem; + Bool_t isarray = (n>1) || (elem && (elem->GetArrayDim()>0)); + Bool_t usindicies = isarray && (elem!=0) && (elem->GetArrayDim() > 1) && (elem->GetArrayLength()==n); + TArrayI indexes(usindicies ? elem->GetArrayDim() : 1); + indexes.Reset(0); + Int_t cnt = 0; + + if (isarray) JsonDisablePostprocessing(); + + for (Int_t j = 0; j < n; j++) { + if (isarray) { + if (usindicies) { + while ((cnt >= 0) && (cnt < indexes.GetSize())) { + if (indexes[cnt] >= elem->GetMaxIndex(cnt)) { + AppendOutput("]"); + indexes[cnt--] = 0; + if (cnt >= 0) indexes[cnt]++; + continue; + } + AppendOutput(indexes[cnt] == 0 ? "[" : fArraySepar.Data()); + cnt++; + } + if (cnt>0) indexes[--cnt]++; + } else { + AppendOutput((j==0) ? "[" : fArraySepar.Data()); } } - } else { - //case //-> in comment - - for (Int_t j = 0; j < n; j++) { - if (j > 0) AppendOutput(fArraySepar.Data()); - + if (!isPreAlloc) { + res |= WriteObjectAny(start[j], cl); + } else { if (!start[j]) start[j] = ((TClass *)cl)->New(); // ((TClass*)cl)->Streamer(start[j],*this); JsonWriteObject(start[j], cl, kFALSE); + } - if ((n > 1) && (fValue.Length() > 0)) { - AppendOutput(fValue.Data()); - fValue.Clear(); - } + if (isarray && (fValue.Length() > 0)) { + AppendOutput(fValue.Data()); + fValue.Clear(); } } - if (n > 1) { - AppendOutput("]"); - } + if (isarray) + for (Int_t k=0;k