我正在使用Delphi XE2编写一个小工具来操作SWF文件。到目前为止,我只是简单地遵循SWF规范,现在在实现表示形状的数据结构时遇到了一个小问题。
SWF形状包含多个形状记录。形状记录可以是边缘记录或非边缘记录,这两种类型都有两个额外的子类型。
具体来说,在规范的第135页上描述了两种非边缘记录类型;
为了方便后续处理形状记录,我想将边缘和非边缘记录统一为单个记录类型,并使用变体记录。区分不同类型的记录很容易;嵌套的变体记录让我轻松地将边缘记录与非边缘记录分开,对于非边缘记录,我可以声明
然而,为了使我的源代码尽可能地反映规范,我想再进一步。
不幸的是,Delphi似乎不允许在同一“级别”上有多个变体部分,试图在同一级别上定义这5个变体部分只会产生大量语法错误。
在更简单的说法中,目标是能够像这样制定记录:
SWF形状包含多个形状记录。形状记录可以是边缘记录或非边缘记录,这两种类型都有两个额外的子类型。
具体来说,在规范的第135页上描述了两种非边缘记录类型;
EndShapeRecord
和StyleChangeRecord
。在SWF文件中,区分它们的方法是检查TypeFlag后的五个标志位是否都为0;如果是,则为EndShapeRecord
,否则为StyleChangeRecord
。为了方便后续处理形状记录,我想将边缘和非边缘记录统一为单个记录类型,并使用变体记录。区分不同类型的记录很容易;嵌套的变体记录让我轻松地将边缘记录与非边缘记录分开,对于非边缘记录,我可以声明
StyleChangeRecord
中的5个标志并编写一个IsEndRecord
函数。然而,为了使我的源代码尽可能地反映规范,我想再进一步。
StyleChangeRecord
中其他字段的存在取决于这5个标志的值,因此我希望能够声明5个变体记录,每个标志一个,其中包含每个标志添加的字段。(我意识到这不会以任何方式影响内存使用,但这不是重点。)不幸的是,Delphi似乎不允许在同一“级别”上有多个变体部分,试图在同一级别上定义这5个变体部分只会产生大量语法错误。
TShapeRecord = record
case EdgeRecord: Boolean of
False: (
case StateMoveTo: Boolean of
True: (
MoveBits: Byte;
MoveDeltaX: Int32;
MoveDeltaY: Int32;
);
case StateLineStyle: Boolean of // << Errors start here
True: (LineStyle: UInt16);
//Additional flags
);
//Fields for edge records
end;
在更简单的说法中,目标是能够像这样制定记录:
TNonEdgeRecord = record
case StateMoveTo: Boolean of
True: (
MoveBits: Byte;
MoveDeltaX: Int32;
MoveDeltaY: Int32;
);
case StateLineStyle: Boolean of
True: (LineStyle: UInt16);
end;
...不删除记录的变体部分,也不嵌套它们(因为嵌套会从语法上暗示错误的关系)。
是否有其他方法可以声明记录中的多个(非嵌套)变体部分,还是我应该回到不使用内部变体记录的方式?