From 9522a7767282022fd859621dedfb6b208abe9282 Mon Sep 17 00:00:00 2001 From: pult Date: Sun, 13 Dec 2020 20:49:09 +0200 Subject: [PATCH] some fixes Add new SA function Fix SA for vtInterface https://github.com/hgourvest/superobject/pull/39 Safe Destructors --- Lib/superobject.pas | 91 +++++++++++++++++++++++++++++++-------------- 1 file changed, 64 insertions(+), 27 deletions(-) diff --git a/Lib/superobject.pas b/Lib/superobject.pas index 0207bf5..ddb410c 100644 --- a/Lib/superobject.pas +++ b/Lib/superobject.pas @@ -1,4 +1,4 @@ -{ superobject.pas } // version: 2020.1213.1955 +{ superobject.pas } // version: 2020.1213.2045 (* * Super Object Toolkit * @@ -1164,6 +1164,14 @@ TSuperObjectIter = record Ite: TSuperAvlIterator; end; + {$if not declared(TStringDynArray)} + {$IFDEF HAVE_RTTI} + TStringDynArray = TArray; + {$ELSE} + TStringDynArray = array of string; + {$ENDIF} + {$ifend} + function ObjectIsError(obj: TSuperObject): boolean; function ObjectIsType(const obj: ISuperObject; typ: TSuperType): boolean; function ObjectGetType(const obj: ISuperObject): TSuperType; @@ -1181,6 +1189,7 @@ function soStream(stream: TStream; ACodePage: Integer = CP_UNKNOWN): ISuperObjec function soFile(const FileName: string; ACodePage: Integer = CP_UNKNOWN): ISuperObject; {+.} function SA(const Args: array of const): ISuperObject; overload; +function SA(const AStrings: TStringDynArray): ISuperObject; overload; {+} function SA(const s: SOString = '[]'): ISuperObject; overload; {+.} @@ -1698,7 +1707,8 @@ function SA(const Args: array of const): ISuperObject; overload; if TVarRec(Args[j]).VInterface = nil then Add(nil) else if IInterface(TVarRec(Args[j]).VInterface).QueryInterface(ISuperObject, intf) = 0 then - Add(ISuperObject(intf)) else + //Add(ISuperObject(intf)) else + Add(TSuperObject(intf)) else // https://github.com/hgourvest/superobject/pull/39 // TODO: test it Add(nil); vtPointer : if TVarRec(Args[j]).VPointer = nil then @@ -1729,6 +1739,15 @@ function SA(const Args: array of const): ISuperObject; overload; end; end; +function SA(const AStrings: TStringDynArray): ISuperObject; overload; +var // https://github.com/hgourvest/superobject/pull/39 + i: integer; +begin + Result := TSuperObject.Create(stArray); + for i := 0 to High(AStrings) do + Result.AsArray.Add(TSuperObject.Create(AStrings[i])); +end; + {+} function SA(const s: SOString = '[]'): ISuperObject; overload; var @@ -2620,6 +2639,7 @@ procedure TInterfacedObject.BeforeDestruction; constructor TSuperEnumerator.Create(const obj: ISuperObject); begin + inherited Create; FObj := obj; FCount := -1; if ObjectIsType(FObj, stObject) then @@ -2629,11 +2649,9 @@ constructor TSuperEnumerator.Create(const obj: ISuperObject); destructor TSuperEnumerator.Destroy; begin - if FObjEnum <> nil then - begin - FObjEnum.Free; - FObjEnum := nil; - end; + if Assigned(FObjEnum) then + FreeAndNil(FObjEnum); + inherited; end; function TSuperEnumerator.MoveNext: Boolean; @@ -2727,8 +2745,7 @@ destructor TSuperObject.Destroy; {+} if Assigned(FO.c_object) then begin - FO.c_object.Free; - FO.c_object := nil; + FreeAndNil(FO.c_object); end; {+.} stArray: @@ -5442,7 +5459,8 @@ constructor TSuperObject.Create(const s: SOString); procedure TSuperObject.Clear(all: boolean); begin - if FProcessing then exit; + if FProcessing then + Exit; FProcessing := true; try case FDataType of @@ -6743,14 +6761,18 @@ procedure TSuperArray.Insert(index: Integer; const value: ISuperObject); procedure TSuperArray.Clear(all: boolean); var j: Integer; + so: ^ISuperObject; begin - for j := 0 to FLength - 1 do - if FArray^[j] <> nil then + for j := FLength - 1 downto 0 do + begin + so := @FArray^[j]; + if Assigned(so^) then begin if all then - FArray^[j].Clear(all); - FArray^[j] := nil; + so^.Clear(all); + so^ := nil; end; + end; FLength := 0; end; @@ -6799,8 +6821,12 @@ constructor TSuperArray.Create; destructor TSuperArray.Destroy; begin - Clear; - FreeMem(FArray); + Clear((*?{all:}True*)); // TODO: ?all + if Assigned(FArray) then + begin + FreeMem(FArray); + FArray := nil; + end; inherited; end; @@ -6993,8 +7019,11 @@ constructor TSuperWriterString.Create; destructor TSuperWriterString.Destroy; begin inherited; - if FBuf <> nil then - FreeMem(FBuf) + if Assigned(FBuf) then + begin + FreeMem(FBuf); + FBuf := nil; + end; end; function TSuperWriterString.GetString: SOString; @@ -7204,7 +7233,7 @@ function TSuperWriterFake.Append(buf: PSOChar): Integer; constructor TSuperWriterFake.Create; begin - inherited Create; + inherited; FSize := 0; end; @@ -7314,16 +7343,17 @@ procedure TSuperWriterSock.Reset; constructor TSuperTokenizer.Create; begin + inherited; pb := TSuperWriterString.Create; line := 1; col := 0; - Reset; + Reset(); end; destructor TSuperTokenizer.Destroy; begin - Reset; - pb.Free; + Reset(); + FreeAndNil(pb); inherited; end; @@ -7354,17 +7384,18 @@ constructor TSuperAvlTree.Create; begin FRoot := nil; FCount := 0; + inherited; end; destructor TSuperAvlTree.Destroy; begin - Clear; + Clear((*?{all:}True*)); // TODO: ?all inherited; end; function TSuperAvlTree.IsEmpty: boolean; begin - result := FRoot = nil; + Result := FRoot = nil; end; function TSuperAvlTree.balance(bal: TSuperAvlEntry): TSuperAvlEntry; @@ -7892,6 +7923,7 @@ function TSuperAvlTree.CompareNodeNode(node1, node2: TSuperAvlEntry): integer; constructor TSuperAvlIterator.Create(tree: TSuperAvlTree); begin + inherited Create; FDepth := not 0; FTree := tree; end; @@ -8089,6 +8121,7 @@ function TSuperAvlTree.GetEnumerator: TSuperAvlIterator; constructor TSuperAvlEntry.Create(const AName: SOString; Obj: Pointer); begin + inherited Create; FName := AName; FPtr := Obj; FHash := Hash(FName); @@ -8334,6 +8367,7 @@ function TSuperTableString.GetN(const k: SOString): ISuperObject; constructor TSuperAttribute.Create(const AName: string); begin + inherited Create; FName := AName; end; @@ -8387,6 +8421,7 @@ function TRttiObjectHelper.GetCustomAttributes(attributeType: TClass): TArray.Create; SerialToJson := TDictionary.Create; @@ -8407,9 +8442,10 @@ constructor TSuperRttiContext.Create; destructor TSuperRttiContext.Destroy; begin - SerialFromJson.Free; - SerialToJson.Free; - Context.Free; + FreeAndNil(SerialFromJson); + FreeAndNil(SerialToJson); + Context.Free; // record + inherited; end; class function TSuperRttiContext.GetFieldName(r: TRttiField): string; @@ -9281,6 +9317,7 @@ constructor TSuperObjectHelper.FromJson(const obj: ISuperObject; ctx: TSuperRtti v: TValue; ctxowned: Boolean; begin + inherited; if ctx = nil then begin ctx := TSuperRttiContext.Create;