File: WP6VariableLengthGroup.cpp

package info (click to toggle)
libwpd 0.10.3-2
  • links: PTS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 4,948 kB
  • sloc: cpp: 28,095; sh: 4,433; makefile: 616; ansic: 4
file content (180 lines) | stat: -rw-r--r-- 5,744 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* libwpd
 * Version: MPL 2.0 / LGPLv2.1+
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Major Contributor(s):
 * Copyright (C) 2002 William Lachance (wrlach@gmail.com)
 * Copyright (C) 2002 Marc Maurer (uwog@uwog.net)
 * Copyright (C) 2006 Fridrich Strba (fridrich.strba@bluewin.ch)
 *
 * For minor contributions see the git repository.
 *
 * Alternatively, the contents of this file may be used under the terms
 * of the GNU Lesser General Public License Version 2.1 or later
 * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are
 * applicable instead of those above.
 *
 * For further information visit http://libwpd.sourceforge.net
 */

/* "This product is not manufactured, approved, or supported by
 * Corel Corporation or Corel Corporation Limited."
 */

#include "WP6VariableLengthGroup.h"
#include "WP6PageGroup.h"
#include "WP6CharacterGroup.h"
#include "WP6ColumnGroup.h"
#include "WP6EOLGroup.h"
#include "WP6ParagraphGroup.h"
#include "WP6FootnoteEndnoteGroup.h"
#include "WP6HeaderFooterGroup.h"
#include "WP6DisplayNumberReferenceGroup.h"
#include "WP6StyleGroup.h"
#include "WP6TabGroup.h"
#include "WP6BoxGroup.h"
#include "WP6UnsupportedVariableLengthGroup.h"
#include "WP6SetNumberGroup.h"
#include "WP6NumberingMethodGroup.h"

#include "libwpd_internal.h"


WP6VariableLengthGroup::WP6VariableLengthGroup() :
	m_subGroup(0),
	m_size(0),
	m_flags(0),
	m_prefixIDs(),
	m_sizeNonDeletable(0),
	m_sizeDeletable(0)
{
}

WP6VariableLengthGroup::~WP6VariableLengthGroup()
{
}

WP6VariableLengthGroup *WP6VariableLengthGroup::constructVariableLengthGroup(librevenge::RVNGInputStream *input, WPXEncryption *encryption, const unsigned char groupID)
{
	switch (groupID)
	{
	case WP6_TOP_NUMBERING_METHOD_GROUP:
		return new WP6NumberingMethodGroup(input, encryption);
	case WP6_TOP_SET_NUMBER_GROUP:
		return new WP6SetNumberGroup(input, encryption);
	case WP6_TOP_PAGE_GROUP:
		return new WP6PageGroup(input, encryption);
	case WP6_TOP_EOL_GROUP:
		return new WP6EOLGroup(input, encryption);
	case WP6_TOP_CHARACTER_GROUP:
		return new WP6CharacterGroup(input, encryption);
	case WP6_TOP_COLUMN_GROUP:
		return new WP6ColumnGroup(input, encryption);
	case WP6_TOP_PARAGRAPH_GROUP:
		return new WP6ParagraphGroup(input, encryption);
	case WP6_TOP_FOOTNOTE_ENDNOTE_GROUP:
		return new WP6FootnoteEndnoteGroup(input, encryption);
	case WP6_TOP_HEADER_FOOTER_GROUP:
		return new WP6HeaderFooterGroup(input, encryption);
	case WP6_TOP_DISPLAY_NUMBER_REFERENCE_GROUP:
		return new WP6DisplayNumberReferenceGroup(input, encryption);
	case WP6_TOP_STYLE_GROUP:
		return new WP6StyleGroup(input, encryption);
	case WP6_TOP_TAB_GROUP:
		return new WP6TabGroup(input, encryption);
	case WP6_TOP_BOX_GROUP:
		return new WP6BoxGroup(input, encryption);
	default:
		// this is an unhandled group, just skip it
		return new WP6UnsupportedVariableLengthGroup(input, encryption);
	}
}

bool WP6VariableLengthGroup::isGroupConsistent(librevenge::RVNGInputStream *input, WPXEncryption *encryption, const unsigned char groupID)
{
	long startPosition = input->tell();

	try
	{
		input->seek(1, librevenge::RVNG_SEEK_CUR);
		unsigned short size = readU16(input, encryption);

		if (input->seek((startPosition + size - 4), librevenge::RVNG_SEEK_SET) || input->isEnd())
		{
			input->seek(startPosition, librevenge::RVNG_SEEK_SET);
			return false;
		}
		if (size != readU16(input, encryption))
		{
			input->seek(startPosition, librevenge::RVNG_SEEK_SET);
			return false;
		}
		if (groupID != readU8(input, encryption))
		{
			input->seek(startPosition, librevenge::RVNG_SEEK_SET);
			return false;
		}

		input->seek(startPosition, librevenge::RVNG_SEEK_SET);
		return true;
	}
	catch (...)
	{
		input->seek(startPosition, librevenge::RVNG_SEEK_SET);
		return false;
	}
}

void WP6VariableLengthGroup::_read(librevenge::RVNGInputStream *input, WPXEncryption *encryption)
{
	long startPosition = input->tell();

	m_subGroup = readU8(input, encryption);
	if ((m_size = readU16(input, encryption)) == 0)
		throw FileException();
	m_flags = readU8(input, encryption);

	if (m_flags & WP6_VARIABLE_GROUP_PREFIX_ID_BIT)
	{
		const size_t numPrefixIDs = readU8(input, encryption);
		if (numPrefixIDs > 0)
		{
			m_prefixIDs.reserve(numPrefixIDs);
			for (unsigned i = 0; i < numPrefixIDs; i++)
			{
				m_prefixIDs.push_back(readU16(input, encryption));
			}
		}
	}

	m_sizeNonDeletable = readU16(input, encryption);
	if (m_sizeNonDeletable > m_size || (m_sizeNonDeletable & 0x8000))
	{
		WPD_DEBUG_MSG(("WordPerfect: Possible corruption detected, bailing out!\n"));
		throw FileException();
	}

	long tmpPosition = input->tell();
	input->seek(m_sizeNonDeletable, librevenge::RVNG_SEEK_CUR);
	m_sizeDeletable = (unsigned short)(startPosition + m_size - 4 - input->tell());
	input->seek(tmpPosition, librevenge::RVNG_SEEK_SET);

	WPD_DEBUG_MSG(("WordPerfect: Read variable group header (start_position: %li, sub_group: %i, size: %i, flags: %i, num_prefix_ids: %u, size_non_deletable: %i, size_deletable: %i)\n", startPosition, m_subGroup, m_size, m_flags, unsigned(m_prefixIDs), m_sizeNonDeletable, m_sizeDeletable));

	_readContents(input, encryption);

	input->seek((startPosition + m_size - 4), librevenge::RVNG_SEEK_SET);

	if (m_size != readU16(input, encryption))
	{
		WPD_DEBUG_MSG(("WordPerfect: Possible corruption detected, bailing out!\n"));
		throw FileException();
	}

	input->seek((startPosition + m_size - 1), librevenge::RVNG_SEEK_SET);
}
/* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */