#1 Re: mORMot 1 » How to merge parms in url and params in content ( TDocVariantData) » 2022-03-17 08:15:16

Thanks but AddFrom doesn't work (Delphi XE5)  I get E2010 Incompatible types: 'Variant' and 'TDocVariantData'

I wrote this, but still have problem with some complexe requests :

function MergeParams(
  inplace: TDocVariantData;
  const toadd: TDocVariantData): TDocVariantData;
var
  i: integer;
  n: string;
  v: variant;
begin
  // inplace.AddFrom(toadd); // E2010 Incompatible types: 'Variant' and 'TDocVariantData'
  for i := 0 to toadd.Count - 1 do begin
    n := toadd.Names[i];
    if n <> '' then
      inplace.AddValue(n, toadd[i])
  end;
  result := inplace;
end;

#2 mORMot 1 » How to merge parms in url and params in content ( TDocVariantData) » 2022-03-16 15:34:44

Goulu
Replies: 3

I have a simple server derived from TSQLHttpServer that overrides function Request(Ctxt: TServerRequest)

in this function I extract params passed in the Ctxt.url using my own code (did not find it in SynCommons...) that returns them as a TDocVariantData

and I extract other params with InitJSON(Ctxt.InContent) which also returns a TDocVariantData

How can I merge both to have all my params regardless on how they are passed ?

Or did I miss the function that does both ?

Thanks !

#3 mORMot 1 » buffer size related problems when streaming VCL interfaces » 2019-11-06 08:34:09

Goulu
Replies: 1

I use mORMot to jSONify an old VCL interface and "teleoperate" it from a webpage.

Sometime I get invalid JSON with two consecutive commas :

"sbtBase7": {
                    "ClassName": "TBSAImageButton",
                    "AutoRepeat": false,
                    "AllowAllUp": false,
                    "Anchors": [
                        "akLeft",
                        "akTop"
                    ],
                    "BiDiMode": "bdLeftToRight",
                    ,
                    "GroupIndex": 0,
                    "Down": false,
                    "Caption": "View Line",

I noticed it is related to the buffer size I assign in the constructor, the position of the double commas (8168 in the case above) is always a bit before the buffer size (8192).

Increasing the buffer size "solves" the problem, but my VCL interface needs more than 1Mb in some cases, so I preferred to "patch" the result as below :

TVCLSerializer = class(TJSONSerializer) 
...

const
  CStreamOptions: TTextWriterWriteObjectOptions = [woStoreClassName,
    woEnumSetsAsText, woInt64AsHex, woDontStoreEmptyString, woStoreStoredFalse];

constructor TVCLSerializer.Create;
begin
  inherited CreateOwnedStream(8192);
  include(fCustomOptions, twoForceJSONStandard);
  FStreamedObjects := TStreamedObjects.Create();
end;

function TVCLSerializer.ObjectToJSON(
  value: TObject;
  aName: string): RawUTF8;
begin
  Clear; // calls CancelAll
  AddString('{"' + aName + '":');
  if assigned(value) then
    WriteObject(value, CStreamOptions) // custom method
  else
    AddString(NULL_STR_VAR);
  Add('}');
  FlushToStream; // to make sure, but doesn't seem to change anything
  SetText(result);

  // ugly cure to mORMot(?) problem:
  result := StringReplace(result, ',,', ',', [rfReplaceAll]);
end;

Well, to be honest, my custom TVCLSerializer.WriteObject method is quite tricky, with calls like

  CancelLastComma; CancelLastChar('}');

to append some fields to the published properties, but it's tested with a lot of simple components (JSON shorter than 8192...).

Could it be a problem ? Should I use a different approach in ObjectToJSON ? I will try to use the stream output directly to see if it makes a difference ...

Delphi XE5.

Thanks for any advice and for your GREAT job.

#5 mORMot 1 » How to handle TTextWriterWriteObjectOptions in a custom serializer ? » 2019-03-26 09:07:17

Goulu
Replies: 2

I have custom class serializers that calls aJSONSerializer.AddJSONEscape(['pairof',Fields]),
but I notice the Fields aren't written using the options I passed to the calling ObjectToJSON(myObject, myTextWriterWriteObjectOptions)
because in

procedure TTextWriter.AddJSONEscape(const V: TVarRec);
begin
  with V do
  case VType of
    (* other cases *)
    vtObject:   WriteObject(VObject); // has no Options
  end;
end;

Did I miss something ?

#6 mORMot 1 » (Noob) how to stream a TDynArray of TObject ? » 2018-09-18 13:09:26

Goulu
Replies: 1

I came across your (great) TDynArray while trying to add support for dynamic arrays to our ClassStreamer which streams published properties in XML.
I have something like this:

TheObjValue := GetObjectProp(AClass, APPropInfo);
      TheTypeInfo := APPropInfo.PropType^;
      case TheTypeInfo^.Kind of
        tkClass : begin
          if TheObjValue is TStrings then 
            TheStrConfig.AddValue(string(APPropInfo^.Name), TStrings(TheObjValue).Text)
          else begin
            AddObj(TheObjValue, string(APPropInfo^.Name), false);
          end; //else
        end; // tkClass
        tkDynArray : begin
          TheElTypeInfo := TheTypeInfo.TypeData^.elType2^; // .eltype returns nil on XE5
          TheObjValue := GetObjectProp(AClass, APPropInfo);
          TheArray.InitSpecific(TheTypeInfo,TheObjValue, djObject); // Why not TheElTypeInfo.Kind ?
          LBuffer := JSONtoXML(TheArray.SaveToJSON());
          TheStrConfig.AddValue(string(APPropInfo^.Name), LBuffer);
        end // tkClass
        else if TheTypeInfo^.Kind in KNOW_TYPE_KIND then begin
          LVal := GetPropValue(AClass, string(APPropInfo^.Name));
          TheStrConfig.AddValue(string(APPropInfo^.Name), LVal);
        end //else if
      end; // case

A few stupid questions and remarks:
1. in TDynArray.Init I had to add

fElemType := PTypeInfo(aTypeInfo)^.elType;
  if fElemType = nil then
    fElemType := PTypeInfo(aTypeInfo)^.elType2;
  if fElemType<>nil then begin

to have something in my array. It probably needs to be guarded by $ifdef for other compilers (I use XE5)
2. why does TDynArray.InitSpecific require a TDynArrayKind and not a TTypeKind ? They look similar and it would be very handy... or am I missing something ?
3. TheArray.SaveToJSON() produces an array with the adresses of the TObject s in the array, which is a good start ... but how should I stream the objects themselves ?

Sorry for the Noob questions... A short link to a tutorial or example code will do as well as a long answer...

Thank you very much !

Board footer

Powered by FluxBB