感谢David A
的评论,实现这些更改非常简单(格式化源代码并理解库代码的工作原理之后)。所有格式都在TSuperObject.Write
中实现,所有这样的更改都可以在此处进行。
我只遇到了一个问题,就是除对象外的其他类型的数组 - 值将移至下一行。但至少数组结尾和对象数组具有所需的换行和缩进。
以下是TSuperObject.Write
的修改版本(为节省空间,大多数子程序未包含)。更改已加注释:
常量:
const
TOK_SP: PSOChar =
子程序:
procedure _indent(I: shortint; r: boolean);
begin
Inc(level, I);
if r then
with writer do
begin
{$IFDEF MSWINDOWS}
Append(TOK_CRLF, 2);
{$ELSE}
Append(TOK_LF, 1);
{$ENDIF}
for I := 0 to level - 1 do
Append(TOK_SP, 2);
end;
end;
过程体:
begin
if FProcessing then
begin
Result := writer.Append(TOK_NULL, 4);
Exit;
end;
FProcessing := true;
with writer do
try
case FDataType of
stObject:
if FO.c_object.FCount > 0 then
begin
k := 0;
Append(TOK_CBL, 1);
if indent then
_indent(1, false);
if ObjectFindFirst(Self, iter) then
repeat
{$IFDEF SUPER_METHOD}
if (iter.val = nil) or not ObjectIsType(iter.val, stMethod) then
begin
{$ENDIF}
if (iter.val = nil) or (not iter.val.Processing) then
begin
if (k <> 0) then
Append(TOK_COM, 1);
if indent then
_indent(0, true);
Append(TOK_DQT, 1);
if escape then
DoEscape(PSOChar(iter.key), Length(iter.key))
else
DoMinimalEscape(PSOChar(iter.key), Length(iter.key));
if indent then
Append(ENDSTR_A, 3)
else
Append(ENDSTR_B, 2);
if (iter.val = nil) then
Append(TOK_NULL, 4)
else
iter.val.Write(writer, indent, escape, level);
Inc(k);
end;
{$IFDEF SUPER_METHOD}
end;
{$ENDIF}
until not ObjectFindNext(iter);
ObjectFindClose(iter);
if indent then
_indent(-1, true);
Result := Append(TOK_CBR, 1);
end
else
Result := Append(TOK_OBJ, 2);
stBoolean:
begin
if (FO.c_boolean) then
Result := Append(TOK_TRUE, 4)
else
Result := Append(TOK_FALSE, 5);
end;
stInt:
begin
str(FO.c_int, st);
Result := Append(PSOChar(SOString(st)));
end;
stDouble:
Result := Append(PSOChar(SOString(gcvt(FO.c_double, 15, fbuffer))));
stCurrency:
begin
Result := Append(PSOChar(CurrToStr(FO.c_currency)));
end;
stString:
begin
Append(TOK_DQT, 1);
if escape then
DoEscape(PSOChar(FOString), Length(FOString))
else
DoMinimalEscape(PSOChar(FOString), Length(FOString));
Append(TOK_DQT, 1);
Result := 0;
end;
stArray:
if FO.c_array.FLength > 0 then
begin
Append(TOK_ARL, 1);
if indent then
_indent(1, true);
k := 0;
j := 0;
while k < FO.c_array.FLength do
begin
val := FO.c_array.GetO(k);
{$IFDEF SUPER_METHOD}
if not ObjectIsType(val, stMethod) then
begin
{$ENDIF}
if (val = nil) or (not val.Processing) then
begin
if (j <> 0) then begin
Append(TOK_COM, 1);
if ObjectIsType(val, stObject) then begin
if indent then
_indent(0, true);
end;
end;
if (val = nil) then
Append(TOK_NULL, 4)
else
val.Write(writer, indent, escape, level);
Inc(j);
end;
{$IFDEF SUPER_METHOD}
end;
{$ENDIF}
Inc(k);
end;
if indent then
_indent(-1, true);
Result := Append(TOK_ARR, 1);
end
else
Result := Append(TOK_ARRAY, 2);
stNull:
Result := Append(TOK_NULL, 4);
else
Result := 0;
end;
finally
FProcessing := false;
end;
end;
那段代码将生成以下JSON数据:
{
"name": "value",
"int_arr": [
1,2,3
],
"obj_arr": [
{
"this": "that"
},
{
"some": "thing"
}
],
"another": 123
}
TSuperObject.Write
中完成的,其中 Indent = True。 - David A