uses
  dansiview,
  dnodeview;

procedure WriteNodeView(const NodeView: TNodeView; const Spaces: AnsiString = '');
var
  It, ItEnd: PNodeView;
  Bucket, BucketEnd: PNodeBucket;
  Pair: PNodePair;
begin
  case NodeView._Type of
    NODE_NULL: Writeln(Spaces, 'null');
    NODE_INT: Writeln(Spaces, NodeView.I);
    NODE_FLOAT: Writeln(Spaces, NodeView.F);
    NODE_STRING: Writeln(Spaces, '"', AnsiView(NodeView.S, NodeView.Count).ToString, '"');
    NODE_BOOLEAN: Writeln(Spaces, NodeView.B);
    NODE_USERDATA .. 255: Writeln(Spaces, 'Userdata of type ', NodeView._Type, '$', HexStr(PtrUInt(NodeView.U), 2 * SizeOf(PtrUInt)));
    NODE_ARRAY: begin
        It := NodeView.A;
        ItEnd := NodeView.A + NodeView.Count;
        Writeln(Spaces, '[');
        while It < ItEnd do begin
          WriteNodeView(It^, Spaces + '  ');
          Inc(It);
        end;
        Writeln(Spaces, ']');
      end;
    NODE_HASHMAP: begin
        Writeln(Spaces, '{');
        if NodeView.Count = 0 then begin
          Pair := PNodePair(NodeView.H);
          while Pair <> nil do begin
            Writeln(Spaces, '"', AnsiView(Pair^.Key.S, Pair^.Key.Len).ToString, '"');
            WriteNodeView(Pair^.Value, Spaces + '  ');
            Pair := Pair^.Next;
          end;
        end else begin
          Bucket := NodeView.H;
          BucketEnd := Bucket + NodeView.Count;
          while Bucket < BucketEnd do begin
            Pair := Bucket^.First;
            while Pair <> nil do begin
              Writeln(Spaces, '"', AnsiView(Pair^.Key.S, Pair^.Key.Len).ToString, '"');
              WriteNodeView(Pair^.Value, Spaces + '  ');
              Pair := Pair^.Next;
            end;
            Inc(Bucket);
          end;
        end;
        Writeln(Spaces, '}');
      end;
  else
    Writeln(Spaces, 'Error: unknown type ', NodeView._Type);
  end;
end;

const
  TEST = 'some test string';

var
  NodeView: TNodeView;
  Arr: array[0 .. 5 - 1] of TNodeView;
  Buckets: array[0 .. 4 - 1] of TNodeBucket;
  I: LongInt;
  Pairs: array[0 .. 10] of TNodePair;
  N: TNodeView;

begin
  Writeln('=============================');
  Writeln('Dumping primitive values:');
  NodeView.SetNull;
  WriteNodeView(NodeView);
  NodeView.SetInt(55);
  WriteNodeView(NodeView);
  NodeView.SetFloat(0.5);
  WriteNodeView(NodeView);
  NodeView.SetBoolean(True);
  WriteNodeView(NodeView);
  NodeView.SetString(@TEST[1], Length(TEST));
  WriteNodeView(NodeView);
  NodeView.SetUserdata(NODE_USERDATA or 106, 0, Pointer($123456ff));
  Writeln('=============================');
  Writeln('');

  NodeView.SetArray(@Arr[0], Length(Arr));
  Arr[0].SetNull;
  Arr[1].SetInt(123);
  Arr[2].SetBoolean(True);
  Arr[3].SetFloat(1.5);
  Arr[4].SetString('test string');
  WriteNodeView(NodeView);

  Pairs[0].SetInt('aaa', 1);
  Pairs[1].SetInt('bbb', 2);
  Pairs[2].SetInt('ccc', 3);

  for I := 0 to Length(Buckets) - 1 do begin
    Buckets[I].SetEmpty;
  end;
  NodeView.SetHashMap(@Buckets[0], Length(Buckets));
  for I := 0 to 2 do
    NodeView.PushPair(@Pairs[I]);
  WriteNodeView(NodeView);
  Writeln(NodeView.FindPair('aaa', N));
  Writeln(NodeView.FindPair('xxx', N));

  NodeView.SetHashMap(nil, 0);
  for I := 0 to 2 do
    NodeView.PushPair(@Pairs[I]);
  WriteNodeView(NodeView);
end.
