2011-10-31 17 views
6

Tôi đang viết một công cụ nhỏ để thực hiện một số thao tác của các tệp SWF, sử dụng Delphi XE2. Cho đến nay, tôi chỉ đơn giản theo dõi the SWF specification và bây giờ tôi đã gặp phải một vấn đề nhỏ trong việc triển khai cấu trúc dữ liệu để biểu diễn các hình dạng.Nhiều phần biến thể trong một bản ghi

Hình dạng SWF chứa một số bản ghi hình dạng. Bản ghi hình dạng có thể là bản ghi cạnh hoặc bản ghi không cạnh và mỗi loại trong hai loại này có hai loại phụ bổ sung.

Cụ thể, trên trang 135 của đặc tả, hai loại bản ghi không cạnh được mô tả; EndShapeRecordStyleChangeRecord. Trong tệp SWF, cách phân biệt giữa các tệp này là kiểm tra xem tất cả năm bit cờ (sau TypeFlag) là 0 hay không; nếu có, đó là số EndShapeRecord, nếu không thì là StyleChangeRecord.

Để giúp tôi xử lý các bản ghi hình dạng sau này, tôi muốn hợp nhất các bản ghi cạnh và không cạnh thành một loại bản ghi duy nhất, sử dụng một bản ghi biến thể. Phân biệt giữa các loại hồ sơ khác nhau là đủ dễ dàng; một bản ghi biến thể lồng nhau cho phép tôi dễ dàng để các hồ sơ cạnh này ngoài, và cho các hồ sơ không cạnh, tôi có thể tuyên bố 5 lá cờ từ StyleChangeRecord và viết một chức năng IsEndRecord.

Tuy nhiên, để làm cho mã nguồn của tôi phản ánh đặc điểm kỹ càng nhất có thể, tôi muốn tiến thêm một bước nữa. Sự hiện diện của các trường khác trong một StyleChangeRecord được xác định dựa trên giá trị của 5 cờ này, vì vậy tôi muốn có thể khai báo 5 bản ghi biến thể, một bản ghi cho mỗi cờ, có chứa các trường được thêm bởi mỗi cờ. (Tôi nhận thấy điều này sẽ không ảnh hưởng đến việc sử dụng bộ nhớ theo bất kỳ cách nào, nhưng đó không phải là vấn đề.)

Thật không may, Delphi dường như không cho phép nhiều hơn một phần biến thể cho mỗi cấp độ và cố gắng xác định 5 các phần biến thể cùng cấp chỉ ném một tấn lỗi cú pháp.

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; 

Về hơi đơn giản, mục tiêu là để có thể xây dựng một kỷ lục như vậy:

TNonEdgeRecord = record 
    case StateMoveTo: Boolean of 
     True: (
     MoveBits: Byte; 
     MoveDeltaX: Int32; 
     MoveDeltaY: Int32; 
    ); 
    case StateLineStyle: Boolean of 
     True: (LineStyle: UInt16); 
end; 

... mà không cần tháo phần biến thể của các hồ sơ, và không làm tổ họ (kể từ lồng nhau sẽ ngụ ý một quan hệ không chính xác từ một quan điểm cú pháp).

Có cách nào khác để tôi có thể khai báo nhiều phần biến thể (không lồng nhau) trong một bản ghi hay tôi chỉ cần quay lại không sử dụng các bản ghi biến thể cho phần bên trong?

+0

tôi không hoàn toàn hiểu những gì bạn đang cố gắng để đạt được nhưng có vẻ như bạn muốn cuộn xử lý bản ghi biến thể của riêng bạn. Điều này là dễ dàng, đủ để làm bằng cách sử dụng tài sản ghi lại. –

+0

@DavidHeffernan: Không, điều đó không hoàn toàn. Tôi muốn làm cho * định nghĩa kiểu * cho thấy các trường nào có mặt, được gán cho giá trị của một cờ hoặc biến nào đó - đó là cơ bản những gì một bản ghi biến thể làm, và điều đó đơn giản là đủ.Vấn đề đối với tôi là nhận được * nhiều * của những người trong một bản ghi * duy nhất *; điều tốt nhất tôi có thể làm là lồng ghép chúng, nhưng điều đó sẽ là ngớ ngẩn, vì những lá cờ này độc lập với nhau. Tôi sẽ cố gắng viết lại câu hỏi một chút để hy vọng làm cho nó rõ ràng hơn. –

+0

Cú pháp không hỗ trợ nhiều cờ độc lập. Làm tổ là một lựa chọn. Hồ sơ với các phương pháp/tài sản là khác mà tôi có thể nghĩ đến. –

Trả lời

5

Không. Nhánh Borland của Pascal chỉ cho phép các phần biến thể ở cuối bản ghi.

Làm tổ là cách duy nhất.

Đối với một số ví dụ thú vị và quan sát, xem bài viết này bởi Rudy Velthuis:

http://rvelthuis.de/articles/articles-convert.html (tìm kiếm cho phần "công đoàn")

Các vấn đề liên quan