Version 6.4.0.3, tag libreoffice-6.4.0.3
[LibreOffice.git] / hwpfilter / source / hwpread.cxx
blob12f29a38925ee4da4a8eb491db3540d90b91fe48
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <unotools/configmgr.hxx>
25 #include <assert.h>
26 #include <list>
28 #include "hwpfile.h"
29 #include "hbox.h"
30 #include "hpara.h"
31 #include "drawing.h"
32 #include "htags.h"
33 #include "hcode.h"
35 static short fboxnum = 1;
36 static int zindex = 1;
37 static int lnnumber = 0;
39 bool HBox::Read(HWPFile & )
41 // already read
42 return true;
46 // skip block
48 bool SkipData::Read(HWPFile & hwpf)
50 uint data_block_len;
51 hwpf.Read4b(&data_block_len, 1);
53 hchar dummy;
54 hwpf.Read2b(&dummy, 1);
56 if (!(IS_SP_SKIP_BLOCK(hh) && (hh == dummy))){
57 return hwpf.SetState(HWP_InvalidFileFormat);
60 return hwpf.SkipBlock(data_block_len);
63 // Field code(5)
64 bool FieldCode::Read(HWPFile & hwpf)
66 uint size;
67 hchar dummy;
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 */
73 hwpf.Read4b(&size, 1);
74 hwpf.Read2b(&dummy, 1);
75 hwpf.ReadBlock(&type, 2);
76 hwpf.Read4b(reserved1.data(), 1);
77 hwpf.Read2b(&location_info, 1);
78 hwpf.ReadBlock(reserved2.data(), 22);
79 hwpf.Read4b(&len1, 1);
80 hwpf.Read4b(&len2, 1);
81 hwpf.Read4b(&len3, 1);
82 hwpf.Read4b(&binlen, 1);
84 uint const len1_ = std::min<uint>(len1, 1024) / sizeof(hchar);
85 uint const len2_ = std::min<uint>(len2, 1024) / sizeof(hchar);
86 uint const len3_ = std::min<uint>(len3, 1024) / sizeof(hchar);
88 str1.reset( new hchar[len1_ ? len1_ : 1] );
89 str2.reset( new hchar[len2_ ? len2_ : 1] );
90 str3.reset( new hchar[len3_ ? len3_ : 1] );
92 hwpf.Read2b(str1.get(), len1_);
93 hwpf.SkipBlock(len1 - (len1_ * sizeof(hchar)));
94 str1[len1_ ? (len1_ - 1) : 0] = 0;
95 hwpf.Read2b(str2.get(), len2_);
96 hwpf.SkipBlock(len2 - (len2_ * sizeof(hchar)));
97 str2[len2_ ? (len2_ - 1) : 0] = 0;
98 hwpf.Read2b(str3.get(), len3_);
99 hwpf.SkipBlock(len3 - (len3_ * sizeof(hchar)));
100 str3[len3_ ? (len3_ - 1) : 0] = 0;
102 hwpf.SkipBlock(binlen);
104 if( type[0] == 3 && type[1] == 2 ){ /* It must create a format as created date. */
105 DateCode *pDate = new DateCode;
106 for (int i = 0 ; i < static_cast<int>(len3_); i++) {
107 if(str3[i] == 0 ) break;
108 if( i >= DATE_SIZE ) break;
109 pDate->format[i] = str3[i];
111 hwpf.AddDateFormat(pDate);
112 m_pDate.reset( pDate );
115 return true;
118 // book mark(6)
119 bool Bookmark::Read(HWPFile & hwpf)
121 long len;
123 hwpf.Read4b(&len, 1);
124 if (!hwpf.Read2b(dummy))
125 return false;
127 if (len != 34)// 2 * (BMK_COMMENT_LEN + 1) + 2
129 return hwpf.SetState(HWP_InvalidFileFormat);
131 if (!(hh == dummy && dummy == CH_BOOKMARK)){
132 return hwpf.SetState(HWP_InvalidFileFormat);
135 hwpf.Read2b(id, BMK_COMMENT_LEN + 1);
136 hwpf.Read2b(&type, 1);
137 return true;
140 // date format(7)
141 bool DateFormat::Read(HWPFile & hwpf)
143 hwpf.Read2b(format, DATE_SIZE);
144 if (!hwpf.Read2b(dummy))
145 return false;
146 if (!(hh == dummy && CH_DATE_FORM == dummy)){
147 return hwpf.SetState(HWP_InvalidFileFormat);
149 return true;
152 // date code(8)
153 bool DateCode::Read(HWPFile & hwpf)
155 hwpf.Read2b(format, DATE_SIZE);
156 hwpf.Read2b(date, 6);
157 if (!hwpf.Read2b(dummy))
158 return false;
159 if (!(hh == dummy && CH_DATE_CODE == dummy)){
160 return hwpf.SetState(HWP_InvalidFileFormat);
162 hwpf.AddDateFormat(this);
163 return true;
166 // tab(9)
167 bool Tab::Read(HWPFile & hwpf)
169 unsigned short tmp16;
170 if (!hwpf.Read2b(tmp16))
171 return false;
172 width = tmp16;
173 if (!hwpf.Read2b(leader))
174 return false;
175 if (!hwpf.Read2b(dummy))
176 return false;
177 if (!(hh == dummy && CH_TAB == dummy)){
178 return hwpf.SetState(HWP_InvalidFileFormat);
180 return true;
183 // tbox(10) TABLE BOX MATH BUTTON HYPERTEXT
184 static void UpdateBBox(FBox * fbox)
186 fbox->boundsy = fbox->pgy;
187 fbox->boundey = fbox->pgy + fbox->ys - 1;
190 bool Cell::Read(HWPFile & hwpf)
192 hwpf.Read2b(&p, 1);
193 hwpf.Read2b(&color, 1);
194 hwpf.Read2b(&x, 1);
195 hwpf.Read2b(&y, 1);
196 hwpf.Read2b(&w, 1);
197 hwpf.Read2b(&h, 1);
198 hwpf.Read2b(&txthigh, 1);
199 hwpf.Read2b(&cellhigh, 1);
201 hwpf.Read1b(flag);
202 hwpf.Read1b(changed);
203 hwpf.Read1b(used);
204 hwpf.Read1b(ver_align);
205 hwpf.ReadBlock(linetype, 4);
206 hwpf.Read1b(shade);
207 hwpf.Read1b(diagonal);
208 return hwpf.Read1b(protect);
211 bool TxtBox::Read(HWPFile & hwpf)
213 int ii, ncell;
215 hwpf.Read2b(reserved, 2);
216 hwpf.Read2b(&dummy, 1);
218 if (!(hh == dummy && CH_TEXT_BOX == dummy)){
219 return hwpf.SetState(HWP_InvalidFileFormat);
221 hwpf.AddBox(this);
222 hwpf.Read2b(&style.cap_len, 1);
223 hwpf.Read2b(&dummy1, 1);
224 unsigned short next;
225 hwpf.Read2b(&next, 1);
226 hwpf.Read2b(&dummy2, 1);
228 style.boxnum = fboxnum++;
229 zorder = zindex++;
230 hwpf.Read1b(style.anchor_type);
231 hwpf.Read1b(style.txtflow);
232 hwpf.Read2b(&style.xpos, 1);
233 hwpf.Read2b(&style.ypos, 1);
234 hwpf.Read2b(&option, 1);
235 hwpf.Read2b(&ctrl_ch, 1);
236 hwpf.Read2b(style.margin, 12);
237 hwpf.AddFBoxStyle(&style);
238 hwpf.Read2b(&box_xs, 1);
239 hwpf.Read2b(&box_ys, 1);
240 hwpf.Read2b(&cap_xs, 1);
241 hwpf.Read2b(&cap_ys, 1);
242 hwpf.Read2b(&style.cap_len, 1);
243 hwpf.Read2b(&xs, 1);
244 hwpf.Read2b(&ys, 1);
245 hwpf.Read2b(&cap_margin, 1);
246 hwpf.Read1b(xpos_type);
247 hwpf.Read1b(ypos_type);
248 hwpf.Read1b(smart_linesp);
249 hwpf.Read1b(reserved1);
250 hwpf.Read2b(&pgx, 1);
251 hwpf.Read2b(&pgy, 1);
252 hwpf.Read2b(&pgno, 1);
253 if( ( pgno +1 ) != hwpf.getCurrentPage() )
254 pgno = sal::static_int_cast<short>(hwpf.getCurrentPage() -1) ;
256 hwpf.Read2b(&showpg, 1);
257 hwpf.Read2b(&cap_pos, 1);
258 hwpf.Read2b(&num, 1);
259 hwpf.Read2b(&dummy3, 1);
260 hwpf.Read2b(&baseline, 1);
261 hwpf.Read2b(&type, 1);
262 hwpf.Read2b(&nCell, 1);
263 hwpf.Read2b(&protect, 1);
264 switch (type)
266 case 0: //table
267 style.boxtype = 'T';
268 break;
269 case 1: // text-box
270 style.boxtype = 'X';
271 break;
272 case 2: // equation
273 style.boxtype = 'E';
274 break;
275 case 3: // button
276 style.boxtype = 'B';
277 break;
278 default: // other
279 style.boxtype = 'O';
280 break;
283 UpdateBBox(this);
285 ncell = nCell;
286 if (ncell <= 0){
287 return hwpf.SetState(HWP_InvalidFileFormat);
290 cell.reset( ::comphelper::newArray_null<Cell>(ncell) );
291 if (!cell) {
292 return hwpf.SetState(HWP_InvalidFileFormat);
294 bool bSuccess = true;
295 for (ii = 0; ii < ncell && bSuccess; ii++)
297 bSuccess = cell[ii].Read(hwpf);
298 cell[ii].key = sal::static_int_cast<unsigned char>(ii);
300 if (!bSuccess)
301 return false;
302 if (ncell == 1)
303 style.cell = &cell[0];
304 plists.resize(ncell);
305 for (ii = 0; ii < ncell; ii++)
306 hwpf.ReadParaList(plists[ii]);
307 // caption
308 hwpf.ReadParaList(caption);
310 if( type == 0 ){ // if table?
311 std::unique_ptr<TCell*[]> pArr(new TCell*[ncell]);
312 std::fill(pArr.get(), pArr.get() + ncell, nullptr);
313 if (!pArr) {
314 return hwpf.SetState(HWP_InvalidFileFormat);
316 std::unique_ptr<Table> tbl(new Table);
317 for( ii = 0 ; ii < ncell; ii++)
319 tbl->columns.insert(cell[ii].x);
320 tbl->columns.insert(cell[ii].x + cell[ii].w);
321 tbl->rows.insert(cell[ii].y);
322 tbl->rows.insert(cell[ii].y + cell[ii].h);
324 for( ii = 0 ; ii < ncell; ii++)
326 TCell *tcell = new TCell;
327 tcell->nColumnIndex = tbl->columns.getIndex(cell[ii].x);
328 tcell->nColumnSpan = tbl->columns.getIndex(cell[ii].x + cell[ii].w) -
329 tcell->nColumnIndex;
330 tcell->nRowIndex = tbl->rows.getIndex(cell[ii].y);
331 tcell->nRowSpan = tbl->rows.getIndex(cell[ii].y + cell[ii].h) -
332 tcell->nRowIndex;
333 tcell->pCell = &cell[ii];
334 pArr[ii] = tcell;
336 TCell *tmp;
337 // Sort by row and column
338 for( ii = 0 ; ii < ncell - 1; ii++ ){
339 for( int jj = ii ; jj < ncell ; jj++){
340 if( pArr[ii]->nRowIndex > pArr[jj]->nRowIndex ){
341 tmp = pArr[ii];
342 pArr[ii] = pArr[jj];
343 pArr[jj] = tmp;
346 for( int kk = ii ; kk > 0 ; kk--){
347 if( ( pArr[kk]->nRowIndex == pArr[kk-1]->nRowIndex ) &&
348 (pArr[kk]->nColumnIndex < pArr[kk-1]->nColumnIndex )){
349 tmp = pArr[kk];
350 pArr[kk] = pArr[kk-1];
351 pArr[kk-1] = tmp;
355 for( ii = 0 ; ii < ncell ; ii++ ){
356 tbl->cells.emplace_back(pArr[ii]);
358 tbl->box = this;
359 m_pTable = tbl.get();
360 hwpf.AddTable(std::move(tbl));
362 else
363 m_pTable = nullptr;
365 return !hwpf.State();
368 namespace
370 class ChangeMemGuard
372 private:
373 HIODev* m_pOldMem;
374 std::unique_ptr<HMemIODev> m_xNewMem;
375 public:
376 ChangeMemGuard(unsigned char* data, size_t nLen)
377 : m_pOldMem(hmem)
378 , m_xNewMem(std::make_unique<HMemIODev>(reinterpret_cast<char*>(data), nLen))
380 hmem = m_xNewMem.get();
382 ~ChangeMemGuard()
384 assert(hmem == m_xNewMem.get());
385 hmem = m_pOldMem;
390 // picture(11)
391 bool Picture::Read(HWPFile & hwpf)
393 hwpf.Read2b(reserved, 2);
394 hwpf.Read2b(&dummy, 1);
396 if (!(hh == dummy && CH_PICTURE == dummy)) {
397 return hwpf.SetState(HWP_InvalidFileFormat);
399 hwpf.AddBox(this);
401 hwpf.Read4b(&follow_block_size, 1);
403 //when fuzzing with a max len set, max decompress to 10 times that limit
404 static size_t nMaxAllowedDecompression = [](const char* pEnv) { size_t nRet = pEnv ? std::atoi(pEnv) : 0; return nRet * 10; }(std::getenv("FUZZ_MAX_INPUT_LEN"));
406 hwpf.Read2b(&dummy1, 1); /* Reserved 4 bytes */
407 hwpf.Read2b(&dummy2, 1);
409 style.boxnum = fboxnum++;
410 zorder = zindex++;
411 hwpf.Read1b(style.anchor_type); /* Reference position */
412 hwpf.Read1b(style.txtflow); /* Avoid painting. 0-2 (seat occupied, transparency, harmony) */
413 hwpf.Read2b(&style.xpos, 1); /* Horizontal position: 1=left, 2=right, 3=center, and others=any */
414 hwpf.Read2b(&style.ypos, 1); /* Vertical position: 1=top, 2=down, 3=middle, and others=any */
415 hwpf.Read2b(&option, 1); /* Other options: Borders, reverse picture, and so on. Save as bit. */
416 hwpf.Read2b(&ctrl_ch, 1); /* Always 11 */
417 hwpf.Read2b(style.margin, 12); /* Margin: [0-2] [] out / in / cell, [], [0-3] left / right / top / bottom margins */
418 hwpf.Read2b(&box_xs, 1); /* Box Size Width */
419 hwpf.Read2b(&box_ys, 1); /* Vertical */
420 hwpf.Read2b(&cap_xs, 1); /* Caption Size Width */
421 hwpf.Read2b(&cap_ys, 1); /* Vertical */
422 hwpf.Read2b(&style.cap_len, 1); /* Length */
423 hwpf.Read2b(&xs, 1); /* The total size (box size + caption + margin) Horizontal */
424 hwpf.Read2b(&ys, 1); /* Vertical */
425 hwpf.Read2b(&cap_margin, 1); /* Caption margins */
426 hwpf.Read1b(xpos_type);
427 hwpf.Read1b(ypos_type);
428 hwpf.Read1b(smart_linesp); /* Line Spacing protection: 0 unprotected 1 protected */
429 hwpf.Read1b(reserved1);
430 hwpf.Read2b(&pgx, 1); /* Real Calculated box width */
431 hwpf.Read2b(&pgy, 1); /* Height */
432 hwpf.Read2b(&pgno, 1); /* Page number: starts from 0 */
433 hwpf.Read2b(&showpg, 1); /* Show the Box */
434 hwpf.Read2b(&cap_pos, 1); /* Caption positions 0-7 Menu Order. */
435 hwpf.Read2b(&num, 1); /* Box number, serial number which starts from 0 */
437 hwpf.Read1b(pictype); /* Picture type */
439 unsigned short tmp16;
440 if (!hwpf.Read2b(tmp16)) /* the real horizontal starting point where shows the picture */
441 return false;
442 skip[0] = tmp16;
443 if (!hwpf.Read2b(tmp16)) /* Vertical */
444 return false;
445 skip[1] = tmp16;
446 if (!hwpf.Read2b(tmp16)) /* Zoom Ratio: 0:fixed, others are percentage for horizontal */
447 return false;
448 scale[0] = tmp16;
449 if (!hwpf.Read2b(tmp16)) /* Vertical */
450 return false;
451 scale[1] = tmp16;
453 hwpf.ReadBlock(picinfo.picun.path, 256); /* Picture File Name: when type is not a Drawing. */
454 hwpf.ReadBlock(reserved3, 9); /* Brightness / Contrast / Picture Effect, etc. */
456 UpdateBBox(this);
457 if( pictype != PICTYPE_DRAW )
458 style.cell = reserved3;
459 else
461 //picinfo.picun read above is unioned with
462 //picinfo.picdraw and so wrote to the hdo pointer
463 //value, which is definitely not useful to us
464 picinfo.picdraw.hdo = nullptr;
467 if (follow_block_size != 0)
469 follow.clear();
471 //read potentially compressed data in blocks as its more
472 //likely large values are simply broken and we'll run out
473 //of data before we need to realloc
474 for (size_t i = 0; i < follow_block_size; i+= SAL_N_ELEMENTS(hwpf.scratch))
476 size_t nOldSize = follow.size();
477 size_t nBlock = std::min(SAL_N_ELEMENTS(hwpf.scratch), follow_block_size - nOldSize);
478 size_t nReadBlock = hwpf.ReadBlock(hwpf.scratch, nBlock);
479 if (nReadBlock)
481 follow.insert(follow.end(), hwpf.scratch, hwpf.scratch + nReadBlock);
483 if (nBlock != nReadBlock)
484 break;
485 if (nMaxAllowedDecompression && follow.size() > nMaxAllowedDecompression)
486 break;
488 follow_block_size = follow.size();
490 if (pictype == PICTYPE_DRAW)
492 auto xGuard(std::make_unique<ChangeMemGuard>(follow.data(), follow_block_size));
493 LoadDrawingObjectBlock(this);
494 style.cell = picinfo.picdraw.hdo;
495 xGuard.reset();
497 else if (follow_block_size >= 4)
499 if ((follow[3] << 24 | follow[2] << 16 | follow[1] << 8 | follow[0]) == 0x269)
501 ishyper = true;
504 else
505 fprintf(stderr, "arse\n");
508 if( pictype != 3 )
509 style.boxtype = 'G';
510 else
511 style.boxtype = 'D';
512 hwpf.AddFBoxStyle(&style);
514 // caption
515 hwpf.ReadParaList(caption);
517 return !hwpf.State();
520 // line(15)
521 Line::Line()
522 : FBox(CH_LINE)
523 , dummy(0)
524 , sx(0)
525 , sy(0)
526 , ex(0)
527 , ey(0)
528 , width(0)
529 , shade(0)
530 , color(0)
534 bool Line::Read(HWPFile & hwpf)
536 hwpf.Read2b(reserved, 2);
537 hwpf.Read2b(&dummy, 1);
539 if (!(hh == dummy && CH_LINE == dummy)){
540 return hwpf.SetState(HWP_InvalidFileFormat);
542 hwpf.AddBox(this);
544 style.boxnum = fboxnum++;
545 zorder = zindex++;
546 style.boxtype = 'L';
547 hwpf.ReadBlock(&reserved2, 8);
548 hwpf.Read1b(style.anchor_type);
549 hwpf.Read1b(style.txtflow);
550 hwpf.Read2b(&style.xpos, 1);
551 hwpf.Read2b(&style.ypos, 1);
552 hwpf.Read2b(&option, 1);
553 hwpf.Read2b(&ctrl_ch, 1);
554 hwpf.Read2b(style.margin, 12);
555 hwpf.AddFBoxStyle(&style);
556 hwpf.Read2b(&box_xs, 1);
557 hwpf.Read2b(&box_ys, 1);
558 hwpf.Read2b(&cap_xs, 1);
559 hwpf.Read2b(&cap_ys, 1);
560 hwpf.Read2b(&style.cap_len, 1);
561 hwpf.Read2b(&xs, 1);
562 hwpf.Read2b(&ys, 1);
563 lnnumber = style.boxnum;
564 hwpf.linenumber = 1;
565 hwpf.Read2b(&boundsy, 1);
566 hwpf.Read2b(&boundey, 1);
567 hwpf.Read1b(boundx);
568 hwpf.Read1b(draw);
570 hwpf.Read2b(&pgx, 1);
571 hwpf.Read2b(&pgy, 1);
572 hwpf.Read2b(&pgno, 1);
573 hwpf.Read2b(&showpg, 1);
575 hwpf.Read2b(&sx, 1);
576 hwpf.Read2b(&sy, 1);
577 hwpf.Read2b(&ex, 1);
578 hwpf.Read2b(&sy, 1);
579 hwpf.Read2b(&width, 1);
580 hwpf.Read2b(&shade, 1);
581 hwpf.Read2b(&color, 1);
582 style.xpos = width;
584 return !hwpf.State();
587 // hidden(15)
588 Hidden::Hidden()
589 : HBox(CH_HIDDEN)
590 , dummy(0)
594 bool Hidden::Read(HWPFile & hwpf)
596 hwpf.Read2b(reserved, 2);
597 hwpf.Read2b(&dummy, 1);
598 if (!(hh == dummy && CH_HIDDEN == dummy)){
599 return hwpf.SetState(HWP_InvalidFileFormat);
602 hwpf.ReadBlock(info, 8);
603 hwpf.ReadParaList(plist);
605 return !hwpf.State();
608 // header/footer(16)
609 HeaderFooter::HeaderFooter()
610 : HBox(CH_HEADER_FOOTER)
611 , dummy(0)
612 , type(0)
613 , where(0)
614 , linenumber(0)
615 , m_nPageNumber(0)
619 bool HeaderFooter::Read(HWPFile & hwpf)
621 hwpf.Read2b(reserved, 2);
622 hwpf.Read2b(&dummy, 1);
623 if (!(hh == dummy && CH_HEADER_FOOTER == dummy)){
624 return hwpf.SetState(HWP_InvalidFileFormat);
627 hwpf.ReadBlock(info, 8);
628 hwpf.Read1b(type);
629 hwpf.Read1b(where);
630 lnnumber = 0;
631 hwpf.ReadParaList(plist, CH_HEADER_FOOTER);
632 linenumber = sal::static_int_cast<unsigned char>(lnnumber);
633 m_nPageNumber = hwpf.getCurrentPage();
634 hwpf.setMaxSettedPage();
635 hwpf.AddHeaderFooter(this);
637 return !hwpf.State();
641 // footnote(17)
642 Footnote::Footnote()
643 : HBox(CH_FOOTNOTE)
644 , dummy(0)
645 , number(0)
646 , type(0)
647 , width(0)
651 bool Footnote::Read(HWPFile & hwpf)
653 hwpf.Read2b(reserved, 2);
654 hwpf.Read2b(&dummy, 1);
655 if (!(hh == dummy && CH_FOOTNOTE == dummy)){
656 return hwpf.SetState(HWP_InvalidFileFormat);
659 hwpf.ReadBlock(info, 8);
660 hwpf.Read2b(&number, 1);
661 hwpf.Read2b(&type, 1);
662 unsigned short tmp16;
663 if (!hwpf.Read2b(tmp16))
664 return false;
665 width = tmp16;
666 hwpf.ReadParaList(plist, CH_FOOTNOTE);
668 return !hwpf.State();
671 // auto number(18)
672 AutoNum::AutoNum()
673 : HBox(CH_AUTO_NUM)
674 , type(0)
675 , number(0)
676 , dummy(0)
680 bool AutoNum::Read(HWPFile & hwpf)
682 hwpf.Read2b(&type, 1);
683 hwpf.Read2b(&number, 1);
684 hwpf.Read2b(&dummy, 1);
686 if (hh != dummy){
687 return hwpf.SetState(HWP_InvalidFileFormat);
689 return !hwpf.State();
693 // new number(19)
694 NewNum::NewNum()
695 : HBox(CH_NEW_NUM)
696 , type(0)
697 , number(0)
698 , dummy(0)
703 bool NewNum::Read(HWPFile & hwpf)
705 hwpf.Read2b(&type, 1);
706 hwpf.Read2b(&number, 1);
707 hwpf.Read2b(&dummy, 1);
709 if (hh != dummy){
710 return hwpf.SetState(HWP_InvalidFileFormat);
712 return !hwpf.State();
715 // show page number (20)
716 ShowPageNum::ShowPageNum()
717 : HBox(CH_SHOW_PAGE_NUM)
718 , where(0)
719 , m_nPageNumber(0)
720 , shape(0)
721 , dummy(0)
725 bool ShowPageNum::Read(HWPFile & hwpf)
727 hwpf.Read2b(&where, 1);
728 hwpf.Read2b(&shape, 1);
729 hwpf.Read2b(&dummy, 1);
731 if (hh != dummy){
732 return hwpf.SetState(HWP_InvalidFileFormat);
734 m_nPageNumber = hwpf.getCurrentPage();
735 hwpf.setMaxSettedPage();
736 hwpf.AddPageNumber(this);
737 return !hwpf.State();
740 /* 홀수쪽시작/감추기 (21) */
741 PageNumCtrl::PageNumCtrl()
742 : HBox(CH_PAGE_NUM_CTRL)
743 , kind(0)
744 , what(0)
745 , dummy(0)
749 bool PageNumCtrl::Read(HWPFile & hwpf)
751 hwpf.Read2b(&kind, 1);
752 hwpf.Read2b(&what, 1);
753 hwpf.Read2b(&dummy, 1);
755 if (hh != dummy){
756 return hwpf.SetState(HWP_InvalidFileFormat);
758 return !hwpf.State();
761 // mail merge(22)
762 MailMerge::MailMerge()
763 : HBox(CH_MAIL_MERGE)
764 , dummy(0)
768 bool MailMerge::Read(HWPFile & hwpf)
770 hwpf.ReadBlock(field_name, 20);
771 hwpf.Read2b(&dummy, 1);
773 if (hh != dummy){
774 return hwpf.SetState(HWP_InvalidFileFormat);
776 return !hwpf.State();
779 // char composition(23)
780 Compose::Compose()
781 : HBox(CH_COMPOSE)
782 , dummy(0)
786 bool Compose::Read(HWPFile & hwpf)
788 hwpf.Read2b(compose, 3);
789 hwpf.Read2b(&dummy, 1);
791 if (hh != dummy){
792 return hwpf.SetState(HWP_InvalidFileFormat);
794 return !hwpf.State();
797 // hyphen(24)
798 Hyphen::Hyphen()
799 : HBox(CH_HYPHEN)
800 , width(0)
801 , dummy(0)
805 bool Hyphen::Read(HWPFile & hwpf)
807 hwpf.Read2b(&width, 1);
808 hwpf.Read2b(&dummy, 1);
810 if (hh != dummy){
811 return hwpf.SetState(HWP_InvalidFileFormat);
813 return !hwpf.State();
817 // toc mark(25)
818 TocMark::TocMark()
819 : HBox(CH_TOC_MARK)
820 , kind(0)
821 , dummy(0)
826 bool TocMark::Read(HWPFile & hwpf)
828 hwpf.Read2b(&kind, 1);
829 hwpf.Read2b(&dummy, 1);
831 if (hh != dummy){
832 return hwpf.SetState(HWP_InvalidFileFormat);
834 return !hwpf.State();
837 // index mark(26)
838 IndexMark::IndexMark()
839 : HBox(CH_INDEX_MARK)
840 , pgno(0)
841 , dummy(0)
845 bool IndexMark::Read(HWPFile & hwpf)
847 hwpf.Read2b(&keyword1, 60);
848 hwpf.Read2b(&keyword2, 60);
849 hwpf.Read2b(&pgno, 1);
850 hwpf.Read2b(&dummy, 1);
852 if (hh != dummy){
853 return hwpf.SetState(HWP_InvalidFileFormat);
855 return !hwpf.State();
858 // outline(28)
859 Outline::Outline()
860 : HBox(CH_OUTLINE)
861 , kind(0)
862 , shape(0)
863 , level(0)
864 , dummy(0)
868 bool Outline::Read(HWPFile & hwpf)
870 hwpf.Read2b(&kind, 1);
871 hwpf.Read1b(shape);
872 hwpf.Read1b(level);
873 hwpf.Read2b(number, 7);
874 hwpf.Read2b(user_shape, 7);
875 hwpf.Read2b(deco, 14);
876 hwpf.Read2b(&dummy, 1);
878 if (hh != dummy){
879 return hwpf.SetState(HWP_InvalidFileFormat);
881 return !hwpf.State();
885 /* Bundle of spaces (30)*/
886 KeepSpace::KeepSpace()
887 : HBox(CH_KEEP_SPACE)
888 , dummy(0)
893 bool KeepSpace::Read(HWPFile & hwpf)
895 hwpf.Read2b(&dummy, 1);
897 if (hh != dummy){
898 return hwpf.SetState(HWP_InvalidFileFormat);
900 return !hwpf.State();
904 /* Fixed-width spaces (31) */
905 FixedSpace::FixedSpace()
906 : HBox(CH_FIXED_SPACE)
907 , dummy(0)
912 bool FixedSpace::Read(HWPFile & hwpf)
914 hwpf.Read2b(&dummy, 1);
916 if (hh != dummy){
917 return hwpf.SetState(HWP_InvalidFileFormat);
919 return !hwpf.State();
922 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */