QMsgPack专题-Delphi/C++ Builder下的跨平台MessagePack协议解析单元

QMsgPack-Delphi/C++ Builder下MessagePack协议的高效实现

QMsgPack-TClientDataSet内容直接保存到MessagePack数据流

QJson与QMsgPack中的RTTI调用演示

QJson/QMsgPack RTTI 注意事项

MsgPackView – MessagePack 格式数据查看工具

分享到:
  1. qmsgpack,如果hmp1.ForcePath(‘a.b.c’).AsString := ‘1’;hmp1.ForcePath(‘a’).asstring := ‘2’;这样用法,会内存泄漏

  2. function TQMsgPack.Add(ANode: TQMsgPack): Integer;
    begin
    ArrayNeeded(mptArray);
    Result := FItems.Add(ANode);
    end;
    这个函数有可能有一个BUG,因为ANode的FParent会为nil,是不是应该改成
    function TQMsgPack.Add(ANode: TQMsgPack): Integer;
    begin
    ArrayNeeded(mptArray);
    ANode.FParent := Self;
    Result := FItems.Add(ANode);
    end;

  3. 测试时,发现了TQHashedMsgPack的两个问题:
    1、路径的第二层开始就不是采用哈希查找的了,第二层开始是直接用了TQmsgpack的IndexOf函数,而且不是用TQHashedMsgPack重载后的indexof函数。这个问题有可能是在add的方法时,第二层的add是返回的类型父类的TQmsgpack, 而不是TQHashedMsgPack类型.
    2、TQHashedMsgPack.Items[0].delete后,后面的所有经哈希indexof函数的返回值都是错误的了,因为delete后,fitems的下标发生了变化,但是Fhashedtable里面桶的data值保存的还是原来items的index,这样造成会报错。如果在delete后,重新算一遍哈希值,就能正常,但是效率不是很高,能不能 Fhashedtable里面桶的data直接保存items的地址,然后indexof函数直接根据地址返回查找到的对象呢?
    希望后大位大神指教

  4. 发现procedure TQHashedMsgPack.Assign(ANode: TQMsgPack);这个方法有一个问题,
    测试代码:
    procedure TForm1.FormCreate(Sender: TObject);
    var
    a : TQHashedMsgPack;
    b : TQHashedMsgPack;
    begin
    try
    a := TQHashedMsgPack.Create;
    a.ForcePath(‘hhh’).AsString := ‘hello’;
    a. ForcePath(‘abc.a.jason’).AsString := ‘test’;
    b := a.Copy;
    ShowMessage(b.ValueByPath(‘hhh’,”)); //执行结果是’hello ‘;
    ShowMessage(b.ValueByPath(‘abc.a.jason’,”)); //执行结果是’ ‘, 正确结果应该是:‘test’
    //如果a,b 是TQMsgPack类型,则都能够正确返回结果
    ShowMessage(b.AsJson);
    finally
    FreeAndNil(a);
    FreeAndNil(b);
    end;
    end;

    跟踪代码发现
    FKeyHash := HashOf(PQCharW(FKey), Length(FKey) shl 1); 这里算哈希值的时候是用TBytes类型,如果FKey只有一个字符时, Length(FKey) 的长度是2,例如:如果key=A,则FKey=[97,0] 这样算出来的哈希值与ValueByPath里面的IndexOf函数里key是用QStringW的,这样Length(key) =1 ,造成 IndexOf函数计算出来的哈希值与Assign方法计算出来的哈希值不一样,后来我将Assign修改如下:
    procedure TQHashedMsgPack.Assign(ANode: TQMsgPack);
    var
    Key_S : QStringW; //BY QQ 2016-2-6
    begin
    inherited;
    if (Length(FKey) > 0) then
    begin
    if FKeyHash = 0 then
    begin
    //BY QQ 2016-2-6
    //FKeyHash := HashOf(PQCharW(FKey), Length(FKey) shl 1); 原来的代码
    //修改为如下代码
    Key_S := GetKeyAsString;
    FKeyHash := HashOf(PQCharW(Key_S), Length(Key_S) shl 1);
    end;
    if Assigned(Parent) then
    TQHashedMsgPack(Parent).FHashTable.Add(Pointer(Parent.Count – 1), FKeyHash);
    end;
    end;

    经过这样修改为Assign方法后,上面的测试例子,多层路径的也能够正确返回结果了,这样修改是否正确,请各位大神指正。