You are not logged in.
Pages: 1
hello, I have created a small example to be able to generate demonstrate the error, before it worked in previous versions of mormot something happens now
Var
Main:TDocVariantData;
PArray1,PArray2,PArray3:PDocVariantData;
begin
Main.Init();
Main.AddValue('value0',10);
Main.AddValue('object',_Obj([]));
PArray1:=Main._[Main.AddValue('array1',_Arr([]))];
PArray2:=Main._[Main.AddValue('array2',_Arr([]))];
PArray3:=Main._[Main.AddValue('array3',_Arr([]))];
PArray3.AddItem(_Obj(['value3',30]));
PArray2.AddItem(_Obj(['value2',20]));
PArray1.AddItem(_Obj(['value1',10]));
writeln(Main.ToJSON());
readln;
end.
the correct result expected in earlier versions of mormot 1 is this
{"value0": 10, "object": {}, "array1": [{"value1": 10}], "array2": [{"value2" : 20}], "array3": [{"value3": 30}]}
now in the latest version of mormot 1 is this
{"value0":10,"object":{},"array1":[],"array2":[],"array3":[{"value3":30}]}
Offline
Your code was not correct from the start, I am afraid.
You are calling AddValue() and putting the pointer into a local variable.
This works by change, because each time you call AdValue() the array location may change, so the pointer may be invalid.
Use indexes when you want to access a TDocVariantData.Values[] item using a pointer.
Offline
Thanks for your prompt response, I understand your answer and I had already done the test by using indexes, if it works, the strange thing is that I change the mormot to a previous version and if it works, but well I'll change it to work with indexes, and how the project is quite long I'm afraid I must check carefully, but I repeat before it worked.
Offline
It worked by chance.
The memory reallocation of a lot of structures, including TDocVariantData, has evolved with mORMot 2 for something more tuned in most cases.
This is why AddValue() behavior may have changed.
For your exact need, remember that you can nest the _ObjFast() and _ArrayFast() functions, and also that you can use '{' / '}' and '[' / ']' for adding items with some hierarchy.
Please check the doc again.
Offline
ab, sorry I already found the line that makes it work differently than what I expected,
here I show how it was before and how it is now, this change was made in one of your fixes.
function TDocVariantData.InternalAdd(const aName: RawUTF8): integer;
var len: integer;
begin
if aName<>'' then begin
if dvoIsArray in VOptions then
raise EDocVariant.CreateUTF8('Add: Unexpected [%] object property in an array',[aName]);
if not(dvoIsObject in VOptions) then begin
VType := DocVariantVType; // may not be set yet
include(VOptions,dvoIsObject);
end;
end else begin
if dvoIsObject in VOptions then
raise EDocVariant.Create('Add: Unexpected array item in an object');
if not(dvoIsArray in VOptions) then begin
VType := DocVariantVType; // may not be set yet
include(VOptions,dvoIsArray);
end;
end;
********************************NOT WORK actual version mormot ************************
// len := length(VValue);
// if VCount>=len then begin
// len := NextGrow(VCount);
// SetLength(VValue,len);
// end;
// if aName<>'' then begin
******************************************************************
*************IT WORKS previous version mormot*******************
if VValue=nil then
SetLength(VValue,16) else
if VCount>=length(VValue) then
SetLength(VValue,VCount+VCount shr 3+32);
if aName<>'' then begin
len := length(VValue);
*****************************************
if Length(VName)<>len then
SetLength(VName,len);
if dvoInternNames in VOptions then begin // inlined InternNames method
if DocVariantType.fInternNames=nil then
DocVariantType.fInternNames := TRawUTF8Interning.Create;
DocVariantType.fInternNames.Unique(VName[VCount],aName);
end else
VName[VCount] := aName;
end;
result := VCount;
inc(VCount);
end;
Last edited by Ghiber (2021-12-11 19:22:23)
Offline
Pages: 1