-
Notifications
You must be signed in to change notification settings - Fork 62
Record Models
각 레코드들은 서로 다른 속성 집합을 갖는 객체로 파싱된다. 파서는 각 레코드의
바이너리 payload를 특정 속성 집합으로 파싱하는데, 레코드에 대응하는 레코드
모델이 이 속성 집합을 정의한다. 가령 HWPTAG_PARA_RANGE_TAG
레코드는 start
,
end
, tag
속성을 갖는 ParaRangeTag
모델로 파싱된다.
이렇게 각 레코드에 대응하는 레코드 모델은 기본적으로 HWPTAG 값에 따라 결정되나,
특정한 속성 값이나 레코드가 나타난 문맥에 따라 달리 결정되기도 한다. 가령
HWPTAG_LIST_HEADER
레코드는 기본적으로 ListHeader
모델에 대응되어 해당 속성
집합을 갖게 되나, 문맥에 따라 TableCell
, FooterParagraphList
등의 모델로
더욱 구체화되어 추가적인 속성들을 갖게 된다.
이렇게 각 레코드를 레코드 모델로 구체화하는 방법에 따라 레코드 모델을 크게 단순 레코드 모델, 속성 결정 레코드 모델, 문맥 결정 레코드 모델 세 가지로 구분할 수 있다.
단순히 HWPTAG에 따라 레코드 모델이 결정된다. 대부분의 HWPTAG 레코드들이 여기에
해당한다. 가령 HWPTAG_PARA_HEADER
는 항상 Paragraph
모델로 구체화된다.
레코드의 특정 속성에 따라 구체 모델이 결정된다.
가령 HWPTAG_BIN_DATA
레코드는 기본적으로 BinData
레코드 모델에 대응하여 해당
속성 집합을 갖지만, 이 중 flags
속성의 값에 따라 각각 BinLink
,
BinEmbedded
, BinStorage
로 더욱 구체화되어 추가적인 속성 값들을 갖는다.
HWPTAG_CTRL_HEADER
레코드는 chid
라는 단일 속성을 갖는 Control
레코드
모델에 대응하지만, chid
속성에 따라 TableControl
, GShapeObjectControl
등의
레코드 모델로 더욱 구체화되어 각각에 맞는 추가적인 속성 집합을 갖는다.
HWPTAG_BIN_DATA
, HWPTAG_CTRL_HEADER
가 여기에 속한다.
문맥 결정 모델은 HWPTAG 값에 더해, 레코드가 나타난 문맥에 따라 구체적인 레코드 모델이 결정된다. 이 결정 과정은 다소 복잡하다. 어떤 경우 부모 레코드의 모델이 무엇이냐만으로 자식 레코드의 모델이 결정되나, 어떤 경우에는 특정한 레코드 타입이 부모 레코드의 선행 자식 레코드(즉 파싱 중인 레코드의 '언니' 레코드)로 나타났는지 여부에 따라 구체화 방법이 달라진다. 또한 어떤 경우에는 모델 과 속성 집합 자체는 쉽게 결정가능하나, 속성을 파싱하기 위한 파라미터가 부모 레코드의 속성을 참조하기도 한다.
가령 모든 HWPTAG_LIST_HEADER
레코드는 기본적으로 ListHeader
모델로 파싱되며
ListHeader
모델이 정의하는 속성집합을 갖지만, 이 레코드가 Footer
의 하위
레코드로 나타나는 경우에는 FooterParagraphList
로 구체화되며 추가적인 속성
집합을 갖는다.
HWPTAG_LIST_HEADER
가 TableControl
의 자식 레코드로 나타날 경우는 좀 더
복잡한데, 이 레코드의 HWPTAG_TABLE
레코드의 선행 여부에 따라
TableCaption
이나 TableCell
로 구체화된다.
HWPTAG_SHAPE_COMPONENT
레코드는 미묘한데, 기본적으로 chid
와 기타 속성을
갖는 ShapeComponent
모델로 구체화된다. 단 부모 레코드가
GShapeObjectControl
인 경우, 속성 집합의 맨 처음에 chid
속성을 한 개 더
갖는다.
HWPTAG_PARA_TEXT
, HWPTAG_PARA_CHAR_SHAPE
, HWPTAG_PARA_LINE_SEGS
레코드는
각각 ParaText
, ParaCharShape
, ParaLineSeg
모델로 대응되는데, 각 모델의
속성을 파싱할 때 부모 레코드인 HWPTAG_PARA_HEADER
, 즉 Paragraph
모델의 특정
속성을 참조한다.
HWPTAG_LIST_HEADER
, HWPTAG_SHAPE_COMPONENT
와 HWPTAG_PARA_TEXT
,
HWPTAG_PARA_CHAR_SHAPE
, HWPTAG_PARA_LINESEG
가 문맥 결정 레코드 모델에
속한다.
레코드 파서는 스트림 내의 레코드들을 레코드 모델 종류와 속성 집합으로 변환한다.
변환은 대략
- 레코드의 HWPTAG로 기본 모델 타입을 결정/속성 집합을 파싱하고, 필요시 특정 속성 값에 따라 한단계 더 레코드 모델 타입을 구체화하는 pass1,
- 문맥, 즉 부모 레코드 모델의 타입/속성/상태에 따라 레코드 모델 타입을 더욱 구체화하는 pass2 의 단계로 구성된다.
레코드는 HWPTAG에 따라 pass1이나 pass2, 혹은 둘 다를 거쳐 최종적인 레코드 모델 타입과 속성 집합을 갖게 된다.
먼저 tag_models
에서 레코드의 tagid
값을 키로 기본 모델 타입을 얻는다. 기본
모델 타입에 parse_pass1
메소드가 정의되어 있으면 이를 호출, 기본 속성 집합을
얻는다.
만약 기본 모델 타입이 속성 결정 레코드 모델이라면, 추가적인 모델 타입과 속성 집합을 파싱한다.
pass1에서는 현재 파싱 중인 레코드의 헤더와 정보만 참조한다. 대부분의 HWPTAG 레코드는 이 단계에서 파싱이 끝난다.
pass2에서는 pass1에서 결정된 모델 타입과 속성 집합을 기반으로, 문맥 정보 (부모 레코드 모델의 타입/속성/상태)에 따라 추가적인 속성 집합을 파싱한다. (문맥 결정 레코드 모델)
이 단계에서는 모델 타입에 정의된 parse_with_parent
나 parse_child
를 호출하여
속성 집합을 파싱한다.