Skip to content
mete0r sarangbang edited this page May 31, 2011 · 3 revisions

레코드 모델

각 레코드들은 서로 다른 속성 집합을 갖는 객체로 파싱된다. 파서는 각 레코드의 바이너리 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_HEADERTableControl의 자식 레코드로 나타날 경우는 좀 더 복잡한데, 이 레코드의 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_COMPONENTHWPTAG_PARA_TEXT, HWPTAG_PARA_CHAR_SHAPE, HWPTAG_PARA_LINESEG문맥 결정 레코드 모델에 속한다.

레코드 파서

레코드 파서는 스트림 내의 레코드들을 레코드 모델 종류와 속성 집합으로 변환한다.

변환은 대략

  1. 레코드의 HWPTAG로 기본 모델 타입을 결정/속성 집합을 파싱하고, 필요시 특정 속성 값에 따라 한단계 더 레코드 모델 타입을 구체화하는 pass1,
  2. 문맥, 즉 부모 레코드 모델의 타입/속성/상태에 따라 레코드 모델 타입을 더욱 구체화하는 pass2 의 단계로 구성된다.

레코드는 HWPTAG에 따라 pass1이나 pass2, 혹은 둘 다를 거쳐 최종적인 레코드 모델 타입과 속성 집합을 갖게 된다.

pass1

먼저 tag_models에서 레코드의 tagid값을 키로 기본 모델 타입을 얻는다. 기본 모델 타입에 parse_pass1 메소드가 정의되어 있으면 이를 호출, 기본 속성 집합을 얻는다.

만약 기본 모델 타입이 속성 결정 레코드 모델이라면, 추가적인 모델 타입과 속성 집합을 파싱한다.

pass1에서는 현재 파싱 중인 레코드의 헤더와 정보만 참조한다. 대부분의 HWPTAG 레코드는 이 단계에서 파싱이 끝난다.

pass2

pass2에서는 pass1에서 결정된 모델 타입과 속성 집합을 기반으로, 문맥 정보 (부모 레코드 모델의 타입/속성/상태)에 따라 추가적인 속성 집합을 파싱한다. (문맥 결정 레코드 모델)

이 단계에서는 모델 타입에 정의된 parse_with_parentparse_child를 호출하여 속성 집합을 파싱한다.