1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "precompile.h"
22 #include <comphelper/newarray.hxx>
23 #include <comphelper/configuration.hxx>
24 #include <sal/log.hxx>
25 #include <tools/long.hxx>
36 static short fboxnum
= 1;
37 static int zindex
= 1;
38 static int lnnumber
= 0;
40 bool HBox::Read(HWPFile
& )
47 bool SkipData::Read(HWPFile
& hwpf
)
50 hwpf
.Read4b(data_block_len
);
53 if (!hwpf
.Read2b(dummy
))
54 return hwpf
.SetState(HWP_InvalidFileFormat
);
56 if (!(IS_SP_SKIP_BLOCK(hh
) && (hh
== dummy
))){
57 return hwpf
.SetState(HWP_InvalidFileFormat
);
60 return hwpf
.SkipBlock(data_block_len
);
64 bool FieldCode::Read(HWPFile
& hwpf
)
68 uint len1
; /* Length of hchar type string DATA #1 */
69 uint len2
; /* Length of hchar type string DATA #2 */
70 uint len3
; /* Length of hchar type string DATA #3 */
71 uint binlen
; /* Length of any binary data format */
74 if (!hwpf
.Read2b(dummy
))
76 hwpf
.ReadBlock(&type
, 2);
77 hwpf
.ReadBlock(reserved1
.data(), 4);
78 if (!hwpf
.Read2b(location_info
))
80 hwpf
.ReadBlock(reserved2
.data(), 22);
84 if (!hwpf
.Read4b(binlen
))
87 uint
const len1_
= std::min
<uint
>(len1
, 1024) / sizeof(hchar
);
88 uint
const len2_
= std::min
<uint
>(len2
, 1024) / sizeof(hchar
);
89 uint
const len3_
= std::min
<uint
>(len3
, 1024) / sizeof(hchar
);
91 str1
.reset( new hchar
[len1_
? len1_
: 1] );
92 str2
.reset( new hchar
[len2_
? len2_
: 1] );
93 str3
.reset( new hchar
[len3_
? len3_
: 1] );
95 if (hwpf
.Read2b(str1
.get(), len1_
) != len1_
)
97 hwpf
.SkipBlock(len1
- (len1_
* sizeof(hchar
)));
98 str1
[len1_
? (len1_
- 1) : 0] = 0;
99 if (hwpf
.Read2b(str2
.get(), len2_
) != len2_
)
101 hwpf
.SkipBlock(len2
- (len2_
* sizeof(hchar
)));
102 str2
[len2_
? (len2_
- 1) : 0] = 0;
103 if (hwpf
.Read2b(str3
.get(), len3_
) != len3_
)
105 hwpf
.SkipBlock(len3
- (len3_
* sizeof(hchar
)));
106 str3
[len3_
? (len3_
- 1) : 0] = 0;
108 hwpf
.SkipBlock(binlen
);
110 if( type
[0] == 3 && type
[1] == 2 ){ /* It must create a format as created date. */
111 DateCode
*pDate
= new DateCode
;
112 for (uint i
= 0 ; i
< len3_
; i
++) {
113 if(str3
[i
] == 0 ) break;
114 if( i
>= DATE_SIZE
) break;
115 pDate
->format
[i
] = str3
[i
];
117 hwpf
.AddDateFormat(pDate
);
118 m_pDate
.reset( pDate
);
125 bool Bookmark::Read(HWPFile
& hwpf
)
130 if (!hwpf
.Read2b(dummy
))
133 if (len
!= 34)// 2 * (BMK_COMMENT_LEN + 1) + 2
135 return hwpf
.SetState(HWP_InvalidFileFormat
);
137 if (hh
!= dummy
|| dummy
!= CH_BOOKMARK
) {
138 return hwpf
.SetState(HWP_InvalidFileFormat
);
141 hwpf
.Read2b(id
, BMK_COMMENT_LEN
+ 1);
142 hwpf
.Read2b(&type
, 1);
147 bool DateFormat::Read(HWPFile
& hwpf
)
149 hwpf
.Read2b(format
, DATE_SIZE
);
150 if (!hwpf
.Read2b(dummy
))
152 if (hh
!= dummy
|| CH_DATE_FORM
!= dummy
) {
153 return hwpf
.SetState(HWP_InvalidFileFormat
);
159 bool DateCode::Read(HWPFile
& hwpf
)
161 hwpf
.Read2b(format
, DATE_SIZE
);
162 hwpf
.Read2b(date
, 6);
163 if (!hwpf
.Read2b(dummy
))
165 if (hh
!= dummy
|| CH_DATE_CODE
!= dummy
) {
166 return hwpf
.SetState(HWP_InvalidFileFormat
);
168 hwpf
.AddDateFormat(this);
173 bool Tab::Read(HWPFile
& hwpf
)
175 unsigned short tmp16
;
176 if (!hwpf
.Read2b(tmp16
))
179 if (!hwpf
.Read2b(leader
))
181 if (!hwpf
.Read2b(dummy
))
183 if (hh
!= dummy
|| CH_TAB
!= dummy
) {
184 return hwpf
.SetState(HWP_InvalidFileFormat
);
189 // tbox(10) TABLE BOX MATH BUTTON HYPERTEXT
190 static void UpdateBBox(FBox
* fbox
)
192 fbox
->boundsy
= fbox
->pgy
;
193 fbox
->boundey
= fbox
->pgy
+ fbox
->ys
- 1;
196 bool Cell::Read(HWPFile
& hwpf
)
199 hwpf
.Read2b(&color
, 1);
204 hwpf
.Read2b(&txthigh
, 1);
205 hwpf
.Read2b(&cellhigh
, 1);
208 hwpf
.Read1b(changed
);
210 hwpf
.Read1b(ver_align
);
211 hwpf
.ReadBlock(linetype
, 4);
213 hwpf
.Read1b(diagonal
);
214 return hwpf
.Read1b(protect
);
217 bool TxtBox::Read(HWPFile
& hwpf
)
221 hwpf
.Read2b(reserved
, 2);
222 hwpf
.Read2b(&dummy
, 1);
224 if (hh
!= dummy
|| CH_TEXT_BOX
!= dummy
) {
225 return hwpf
.SetState(HWP_InvalidFileFormat
);
227 hwpf
.Read2b(&style
.cap_len
, 1);
228 hwpf
.Read2b(&dummy1
, 1);
230 hwpf
.Read2b(&next
, 1);
231 hwpf
.Read2b(&dummy2
, 1);
233 style
.boxnum
= fboxnum
++;
235 hwpf
.Read1b(style
.anchor_type
);
236 hwpf
.Read1b(style
.txtflow
);
237 hwpf
.Read2b(&style
.xpos
, 1);
238 hwpf
.Read2b(&style
.ypos
, 1);
239 hwpf
.Read2b(&option
, 1);
240 hwpf
.Read2b(&ctrl_ch
, 1);
241 hwpf
.Read2b(style
.margin
, 12);
242 hwpf
.Read2b(&box_xs
, 1);
243 hwpf
.Read2b(&box_ys
, 1);
244 hwpf
.Read2b(&cap_xs
, 1);
245 hwpf
.Read2b(&cap_ys
, 1);
246 hwpf
.Read2b(&style
.cap_len
, 1);
249 hwpf
.Read2b(&cap_margin
, 1);
250 hwpf
.Read1b(xpos_type
);
251 hwpf
.Read1b(ypos_type
);
252 hwpf
.Read1b(smart_linesp
);
253 hwpf
.Read1b(reserved1
);
254 hwpf
.Read2b(&pgx
, 1);
255 hwpf
.Read2b(&pgy
, 1);
256 hwpf
.Read2b(&pgno
, 1);
257 if( ( pgno
+1 ) != hwpf
.getCurrentPage() )
258 pgno
= sal::static_int_cast
<short>(hwpf
.getCurrentPage() -1) ;
260 hwpf
.Read2b(&showpg
, 1);
261 hwpf
.Read2b(&cap_pos
, 1);
262 hwpf
.Read2b(&num
, 1);
263 hwpf
.Read2b(&dummy3
, 1);
264 hwpf
.Read2b(&baseline
, 1);
265 hwpf
.Read2b(&type
, 1);
266 hwpf
.Read2b(&nCell
, 1);
267 hwpf
.Read2b(&protect
, 1);
291 return hwpf
.SetState(HWP_InvalidFileFormat
);
294 if (ncell
> 4096 && comphelper::IsFuzzing()) {
295 // cut off at an arbitrary size to speed up fuzzing
296 return hwpf
.SetState(HWP_InvalidFileFormat
);
299 cell
.reset( ::comphelper::newArray_null
<Cell
>(ncell
) );
301 return hwpf
.SetState(HWP_InvalidFileFormat
);
303 bool bSuccess
= true;
304 for (ii
= 0; ii
< ncell
&& bSuccess
; ii
++)
306 bSuccess
= cell
[ii
].Read(hwpf
);
307 cell
[ii
].key
= sal::static_int_cast
<unsigned char>(ii
);
312 style
.cell
= &cell
[0];
313 plists
.resize(ncell
);
314 for (ii
= 0; ii
< ncell
; ii
++)
315 hwpf
.ReadParaList(plists
[ii
]);
317 hwpf
.ReadParaList(caption
);
319 if( type
== 0 ){ // if table?
320 std::unique_ptr
<TCell
*[]> pArr(new TCell
*[ncell
]);
321 std::fill(pArr
.get(), pArr
.get() + ncell
, nullptr);
323 return hwpf
.SetState(HWP_InvalidFileFormat
);
325 std::unique_ptr
<Table
> tbl(new Table
);
326 for( ii
= 0 ; ii
< ncell
; ii
++)
328 tbl
->columns
.insert(cell
[ii
].x
);
329 tbl
->columns
.insert(cell
[ii
].x
+ cell
[ii
].w
);
330 tbl
->rows
.insert(cell
[ii
].y
);
331 tbl
->rows
.insert(cell
[ii
].y
+ cell
[ii
].h
);
333 for( ii
= 0 ; ii
< ncell
; ii
++)
335 TCell
*tcell
= new TCell
;
336 tcell
->nColumnIndex
= tbl
->columns
.getIndex(cell
[ii
].x
);
337 tcell
->nColumnSpan
= tbl
->columns
.getIndex(cell
[ii
].x
+ cell
[ii
].w
) -
339 tcell
->nRowIndex
= tbl
->rows
.getIndex(cell
[ii
].y
);
340 tcell
->nRowSpan
= tbl
->rows
.getIndex(cell
[ii
].y
+ cell
[ii
].h
) -
342 tcell
->pCell
= &cell
[ii
];
346 // Sort by row and column
347 for( ii
= 0 ; ii
< ncell
- 1; ii
++ ){
348 for( int jj
= ii
; jj
< ncell
; jj
++){
349 if( pArr
[ii
]->nRowIndex
> pArr
[jj
]->nRowIndex
){
350 std::swap(pArr
[ii
], pArr
[jj
]);
353 for( int kk
= ii
; kk
> 0 ; kk
--){
354 if( ( pArr
[kk
]->nRowIndex
== pArr
[kk
-1]->nRowIndex
) &&
355 (pArr
[kk
]->nColumnIndex
< pArr
[kk
-1]->nColumnIndex
)){
356 std::swap(pArr
[kk
], pArr
[kk
-1]);
360 for( ii
= 0 ; ii
< ncell
; ii
++ ){
361 tbl
->cells
.emplace_back(pArr
[ii
]);
364 m_pTable
= tbl
.get();
365 hwpf
.AddTable(std::move(tbl
));
370 bSuccess
= !hwpf
.State();
372 hwpf
.AddFBoxStyle(&style
);
382 std::unique_ptr
<HMemIODev
> m_xNewMem
;
384 ChangeMemGuard(unsigned char* data
, size_t nLen
)
386 , m_xNewMem(std::make_unique
<HMemIODev
>(reinterpret_cast<char*>(data
), nLen
))
388 hmem
= m_xNewMem
.get();
392 assert(hmem
== m_xNewMem
.get());
399 bool Picture::Read(HWPFile
& hwpf
)
401 hwpf
.Read2b(reserved
, 2);
402 hwpf
.Read2b(&dummy
, 1);
404 if (hh
!= dummy
|| CH_PICTURE
!= dummy
) {
405 return hwpf
.SetState(HWP_InvalidFileFormat
);
408 hwpf
.Read4b(follow_block_size
);
410 //when fuzzing with a max len set, max decompress to 10 times that limit
411 static size_t nMaxAllowedDecompression
= [](const char* pEnv
) { size_t nRet
= pEnv
? std::atoi(pEnv
) : 0; return nRet
* 10; }(std::getenv("FUZZ_MAX_INPUT_LEN"));
413 hwpf
.Read2b(&dummy1
, 1); /* Reserved 4 bytes */
414 hwpf
.Read2b(&dummy2
, 1);
416 style
.boxnum
= fboxnum
++;
418 hwpf
.Read1b(style
.anchor_type
); /* Reference position */
419 hwpf
.Read1b(style
.txtflow
); /* Avoid painting. 0-2 (seat occupied, transparency, harmony) */
420 hwpf
.Read2b(&style
.xpos
, 1); /* Horizontal position: 1=left, 2=right, 3=center, and others=any */
421 hwpf
.Read2b(&style
.ypos
, 1); /* Vertical position: 1=top, 2=down, 3=middle, and others=any */
422 hwpf
.Read2b(&option
, 1); /* Other options: Borders, reverse picture, and so on. Save as bit. */
423 hwpf
.Read2b(&ctrl_ch
, 1); /* Always 11 */
424 hwpf
.Read2b(style
.margin
, 12); /* Margin: [0-2] [] out / in / cell, [], [0-3] left / right / top / bottom margins */
425 hwpf
.Read2b(&box_xs
, 1); /* Box Size Width */
426 hwpf
.Read2b(&box_ys
, 1); /* Vertical */
427 hwpf
.Read2b(&cap_xs
, 1); /* Caption Size Width */
428 hwpf
.Read2b(&cap_ys
, 1); /* Vertical */
429 hwpf
.Read2b(&style
.cap_len
, 1); /* Length */
430 hwpf
.Read2b(&xs
, 1); /* The total size (box size + caption + margin) Horizontal */
431 hwpf
.Read2b(&ys
, 1); /* Vertical */
432 hwpf
.Read2b(&cap_margin
, 1); /* Caption margins */
433 hwpf
.Read1b(xpos_type
);
434 hwpf
.Read1b(ypos_type
);
435 hwpf
.Read1b(smart_linesp
); /* Line Spacing protection: 0 unprotected 1 protected */
436 hwpf
.Read1b(reserved1
);
437 hwpf
.Read2b(&pgx
, 1); /* Real Calculated box width */
438 hwpf
.Read2b(&pgy
, 1); /* Height */
439 hwpf
.Read2b(&pgno
, 1); /* Page number: starts from 0 */
440 hwpf
.Read2b(&showpg
, 1); /* Show the Box */
441 hwpf
.Read2b(&cap_pos
, 1); /* Caption positions 0-7 Menu Order. */
442 hwpf
.Read2b(&num
, 1); /* Box number, serial number which starts from 0 */
444 hwpf
.Read1b(pictype
); /* Picture type */
446 unsigned short tmp16
;
447 if (!hwpf
.Read2b(tmp16
)) /* the real horizontal starting point where shows the picture */
450 if (!hwpf
.Read2b(tmp16
)) /* Vertical */
453 if (!hwpf
.Read2b(tmp16
)) /* Zoom Ratio: 0:fixed, others are percentage for horizontal */
456 if (!hwpf
.Read2b(tmp16
)) /* Vertical */
460 hwpf
.ReadBlock(picinfo
.picun
.path
, 256); /* Picture File Name: when type is not a Drawing. */
461 picinfo
.picun
.path
[255] = 0; // ensure null terminated
462 hwpf
.ReadBlock(reserved3
, 9); /* Brightness / Contrast / Picture Effect, etc. */
465 if( pictype
!= PICTYPE_DRAW
)
466 style
.cell
= reserved3
;
469 //picinfo.picun read above is unioned with
470 //picinfo.picdraw and so wrote to the hdo pointer
471 //value, which is definitely not useful to us
472 picinfo
.picdraw
.hdo
= nullptr;
475 if (follow_block_size
!= 0)
479 //read potentially compressed data in blocks as it's more
480 //likely large values are simply broken and we'll run out
481 //of data before we need to realloc
482 for (size_t i
= 0; i
< follow_block_size
; i
+= SAL_N_ELEMENTS(hwpf
.scratch
))
484 size_t nOldSize
= follow
.size();
485 size_t nBlock
= std::min(SAL_N_ELEMENTS(hwpf
.scratch
), follow_block_size
- nOldSize
);
486 size_t nReadBlock
= hwpf
.ReadBlock(hwpf
.scratch
, nBlock
);
489 follow
.insert(follow
.end(), hwpf
.scratch
, hwpf
.scratch
+ nReadBlock
);
491 if (nBlock
!= nReadBlock
)
493 if (nMaxAllowedDecompression
&& follow
.size() > nMaxAllowedDecompression
)
495 SAL_WARN("filter.hwp", "too much decompression, abandoning");
500 follow_block_size
= follow
.size();
502 if (pictype
== PICTYPE_DRAW
)
504 ChangeMemGuard
aGuard(follow
.data(), follow_block_size
);
505 LoadDrawingObjectBlock(this, hwpf
);
506 style
.cell
= picinfo
.picdraw
.hdo
;
508 else if (follow_block_size
>= 4)
510 if ((follow
[3] << 24 | follow
[2] << 16 | follow
[1] << 8 | follow
[0]) == 0x269)
523 hwpf
.ReadParaList(caption
);
525 bool bSuccess
= !hwpf
.State();
527 hwpf
.AddFBoxStyle(&style
);
545 bool Line::Read(HWPFile
& hwpf
)
547 hwpf
.Read2b(reserved
, 2);
548 hwpf
.Read2b(&dummy
, 1);
550 if (hh
!= dummy
|| CH_LINE
!= dummy
) {
551 return hwpf
.SetState(HWP_InvalidFileFormat
);
554 style
.boxnum
= fboxnum
++;
557 hwpf
.ReadBlock(&reserved2
, 8);
558 hwpf
.Read1b(style
.anchor_type
);
559 hwpf
.Read1b(style
.txtflow
);
560 hwpf
.Read2b(&style
.xpos
, 1);
561 hwpf
.Read2b(&style
.ypos
, 1);
562 hwpf
.Read2b(&option
, 1);
563 hwpf
.Read2b(&ctrl_ch
, 1);
564 hwpf
.Read2b(style
.margin
, 12);
565 hwpf
.Read2b(&box_xs
, 1);
566 hwpf
.Read2b(&box_ys
, 1);
567 hwpf
.Read2b(&cap_xs
, 1);
568 hwpf
.Read2b(&cap_ys
, 1);
569 hwpf
.Read2b(&style
.cap_len
, 1);
572 lnnumber
= style
.boxnum
;
574 hwpf
.Read2b(&boundsy
, 1);
575 hwpf
.Read2b(&boundey
, 1);
579 hwpf
.Read2b(&pgx
, 1);
580 hwpf
.Read2b(&pgy
, 1);
581 hwpf
.Read2b(&pgno
, 1);
582 hwpf
.Read2b(&showpg
, 1);
588 hwpf
.Read2b(&width
, 1);
589 hwpf
.Read2b(&shade
, 1);
590 hwpf
.Read2b(&color
, 1);
593 bool bSuccess
= !hwpf
.State();
595 hwpf
.AddFBoxStyle(&style
);
606 bool Hidden::Read(HWPFile
& hwpf
)
608 hwpf
.Read2b(reserved
, 2);
609 hwpf
.Read2b(&dummy
, 1);
610 if (hh
!= dummy
|| CH_HIDDEN
!= dummy
) {
611 return hwpf
.SetState(HWP_InvalidFileFormat
);
614 hwpf
.ReadBlock(info
, 8);
615 hwpf
.ReadParaList(plist
);
617 return !hwpf
.State();
621 HeaderFooter::HeaderFooter()
622 : HBox(CH_HEADER_FOOTER
)
631 bool HeaderFooter::Read(HWPFile
& hwpf
)
633 hwpf
.Read2b(reserved
, 2);
634 hwpf
.Read2b(&dummy
, 1);
635 if (hh
!= dummy
|| CH_HEADER_FOOTER
!= dummy
) {
636 return hwpf
.SetState(HWP_InvalidFileFormat
);
639 hwpf
.ReadBlock(info
, 8);
643 hwpf
.ReadParaList(plist
, CH_HEADER_FOOTER
);
644 linenumber
= sal::static_int_cast
<unsigned char>(lnnumber
);
645 m_nPageNumber
= hwpf
.getCurrentPage();
646 hwpf
.setMaxSettedPage();
647 hwpf
.AddHeaderFooter(this);
649 return !hwpf
.State();
663 bool Footnote::Read(HWPFile
& hwpf
)
665 hwpf
.Read2b(reserved
, 2);
666 hwpf
.Read2b(&dummy
, 1);
667 if (hh
!= dummy
|| CH_FOOTNOTE
!= dummy
) {
668 return hwpf
.SetState(HWP_InvalidFileFormat
);
671 hwpf
.ReadBlock(info
, 8);
672 hwpf
.Read2b(&number
, 1);
673 hwpf
.Read2b(&type
, 1);
674 unsigned short tmp16
;
675 if (!hwpf
.Read2b(tmp16
))
678 hwpf
.ReadParaList(plist
, CH_FOOTNOTE
);
680 return !hwpf
.State();
692 bool AutoNum::Read(HWPFile
& hwpf
)
694 hwpf
.Read2b(&type
, 1);
695 hwpf
.Read2b(&number
, 1);
696 hwpf
.Read2b(&dummy
, 1);
699 return hwpf
.SetState(HWP_InvalidFileFormat
);
701 return !hwpf
.State();
715 bool NewNum::Read(HWPFile
& hwpf
)
717 hwpf
.Read2b(&type
, 1);
718 hwpf
.Read2b(&number
, 1);
719 hwpf
.Read2b(&dummy
, 1);
722 return hwpf
.SetState(HWP_InvalidFileFormat
);
724 return !hwpf
.State();
727 // show page number (20)
728 ShowPageNum::ShowPageNum()
729 : HBox(CH_SHOW_PAGE_NUM
)
737 bool ShowPageNum::Read(HWPFile
& hwpf
)
739 hwpf
.Read2b(&where
, 1);
740 hwpf
.Read2b(&shape
, 1);
741 hwpf
.Read2b(&dummy
, 1);
744 return hwpf
.SetState(HWP_InvalidFileFormat
);
746 m_nPageNumber
= hwpf
.getCurrentPage();
747 hwpf
.setMaxSettedPage();
748 hwpf
.AddPageNumber(this);
749 return !hwpf
.State();
753 PageNumCtrl::PageNumCtrl()
754 : HBox(CH_PAGE_NUM_CTRL
)
761 bool PageNumCtrl::Read(HWPFile
& hwpf
)
763 hwpf
.Read2b(&kind
, 1);
764 hwpf
.Read2b(&what
, 1);
765 hwpf
.Read2b(&dummy
, 1);
768 return hwpf
.SetState(HWP_InvalidFileFormat
);
770 return !hwpf
.State();
774 MailMerge::MailMerge()
775 : HBox(CH_MAIL_MERGE
)
780 bool MailMerge::Read(HWPFile
& hwpf
)
782 hwpf
.ReadBlock(field_name
, 20);
783 hwpf
.Read2b(&dummy
, 1);
786 return hwpf
.SetState(HWP_InvalidFileFormat
);
788 return !hwpf
.State();
791 // char composition(23)
798 bool Compose::Read(HWPFile
& hwpf
)
800 hwpf
.Read2b(compose
, 3);
801 hwpf
.Read2b(&dummy
, 1);
804 return hwpf
.SetState(HWP_InvalidFileFormat
);
806 return !hwpf
.State();
817 bool Hyphen::Read(HWPFile
& hwpf
)
819 hwpf
.Read2b(&width
, 1);
820 hwpf
.Read2b(&dummy
, 1);
823 return hwpf
.SetState(HWP_InvalidFileFormat
);
825 return !hwpf
.State();
838 bool TocMark::Read(HWPFile
& hwpf
)
840 hwpf
.Read2b(&kind
, 1);
841 hwpf
.Read2b(&dummy
, 1);
844 return hwpf
.SetState(HWP_InvalidFileFormat
);
846 return !hwpf
.State();
850 IndexMark::IndexMark()
851 : HBox(CH_INDEX_MARK
)
857 bool IndexMark::Read(HWPFile
& hwpf
)
859 hwpf
.Read2b(&keyword1
, 60);
860 hwpf
.Read2b(&keyword2
, 60);
861 hwpf
.Read2b(&pgno
, 1);
862 hwpf
.Read2b(&dummy
, 1);
865 return hwpf
.SetState(HWP_InvalidFileFormat
);
867 return !hwpf
.State();
880 bool Outline::Read(HWPFile
& hwpf
)
882 hwpf
.Read2b(&kind
, 1);
885 hwpf
.Read2b(number
, 7);
886 hwpf
.Read2b(user_shape
, 7);
887 hwpf
.Read2b(deco
, 14);
888 hwpf
.Read2b(&dummy
, 1);
891 return hwpf
.SetState(HWP_InvalidFileFormat
);
893 return !hwpf
.State();
897 /* Bundle of spaces (30)*/
898 KeepSpace::KeepSpace()
899 : HBox(CH_KEEP_SPACE
)
905 bool KeepSpace::Read(HWPFile
& hwpf
)
907 hwpf
.Read2b(&dummy
, 1);
910 return hwpf
.SetState(HWP_InvalidFileFormat
);
912 return !hwpf
.State();
916 /* Fixed-width spaces (31) */
917 FixedSpace::FixedSpace()
918 : HBox(CH_FIXED_SPACE
)
924 bool FixedSpace::Read(HWPFile
& hwpf
)
926 hwpf
.Read2b(&dummy
, 1);
929 return hwpf
.SetState(HWP_InvalidFileFormat
);
931 return !hwpf
.State();
934 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */