2011-10-31 17 views
6

我正在寫一個小工具來使用Delphi XE2對SWF文件進行一些操作。到目前爲止,我只是簡單地遵循the SWF specification,現在我在實現一個表示形狀的數據結構時遇到了一個小問題。記錄中的多個變體部分

SWF形狀包含若干形狀記錄。形狀記錄可以是邊緣記錄或非邊緣記錄,並且這兩種類型中的每一種都有兩個附加的子類型。

具體而言,本說明書中的第135頁上,兩個非邊緣記錄類型被描述; EndShapeRecordStyleChangeRecord。在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; 

...不刪除記錄的變異零件,沒有嵌套他們(因爲嵌套意味着從語法角度來看不正確的關係)。

有一些其他的方式,我可以在記錄中聲明多個(非嵌套)變異零件,或者我應該回去不使用變異記錄內的一部分?帕斯卡

+0

我不完全理解你想達到什麼目的,但它聽起來像你想推出自己的變體記錄處理。這很容易使用記錄屬性。 –

+0

@DavidHeffernan:不,那不是。我想讓*類型定義*顯示哪些字段存在,給定某個標誌或變量的值 - 這基本上是一個變體記錄的功能,而且非常簡單。對我來說,問題是在* single *記錄中獲得*多個*我所能做的最好的事情就是將它們嵌套在一起,但這很愚蠢,因爲這些標誌是相互獨立的。我會盡量重新編寫這個問題,希望更清楚地說明問題。 –

+0

語法不支持多個獨立標誌。嵌套是一種選擇。方法/屬性的記錄是我能想到的另一個。 –

回答

5

號Borland的分支只允許變異零件在一個記錄的結束。

嵌套是唯一的方法。

對於一些有趣的例子和意見,請參閱本文由魯迪Velthuis:

http://rvelthuis.de/articles/articles-convert.html(搜索的「聯盟」的一部分)