/* This file is part of the LibMSWrite Library
   Copyright (C) 2001-2003 Clarence Dang <clarencedang@users.sourceforge.net>

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License Version 2 as published by the Free Software Foundation.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License Version 2 for more details.

   You should have received a copy of the GNU Library General Public License
   Version 2 along with this library; see the file COPYING.LIB.  If not,
   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.

   LibMSWrite Project Website:
   http://sourceforge.net/projects/libmswrite/
*/

/*
 * structures_generated - Internal MS Write file structures
 * This file was generated by make_structures_generated 0.51pre 2003/07/09.
 * ALL CHANGES MADE TO THIS FILE "WILL BE LOST IN TIME LIKE TEARS IN RAIN"!
 */

#include <assert.h>
#include <stdio.h>
#include <string.h>

#include "structures_generated.h"
#include "structures_private.h"	// for forward references to embedded structures
#include "structures.h"	// for forward references to embedded structures

namespace MSWrite
{
	// -------------------- BEGIN HeaderGenerated --------------------
	
	HeaderGenerated::HeaderGenerated ()
	{
		// --- set defaults for variables --
		m_magic = (Word) (0xBE31/*Write 3.0*/);
		m_zero = (Word) (0);
		m_magic2 = (Word) (0xAB00);
		memset (m_zero2, (Word) (0), 4 * sizeof (Word));
		// no default for m_numCharBytesPlus128
		// no default for m_pageParaInfo
		// no default for m_pageFootnoteTable
		// no default for m_pageSectionProperty
		// no default for m_pageSectionTable
		// no default for m_pagePageTable
		// no default for m_pageFontTable
		memset (m_zero3, (Word) (0), 33 * sizeof (Word));
		// no default for m_numPages
	}
	
	HeaderGenerated::~HeaderGenerated ()
	{
	}
	
	HeaderGenerated &HeaderGenerated::operator= (const HeaderGenerated &rhs)
	{
		if (this == &rhs)
			return *this;
		
		NeedsDevice::operator= (rhs);
		memcpy (m_data, rhs.m_data, s_size);
		
		m_magic = rhs.m_magic;
		m_zero = rhs.m_zero;
		m_magic2 = rhs.m_magic2;
		memcpy (m_zero2, rhs.m_zero2, 4 * sizeof (Word));
		m_numCharBytesPlus128 = rhs.m_numCharBytesPlus128;
		m_pageParaInfo = rhs.m_pageParaInfo;
		m_pageFootnoteTable = rhs.m_pageFootnoteTable;
		m_pageSectionProperty = rhs.m_pageSectionProperty;
		m_pageSectionTable = rhs.m_pageSectionTable;
		m_pagePageTable = rhs.m_pagePageTable;
		m_pageFontTable = rhs.m_pageFontTable;
		memcpy (m_zero3, rhs.m_zero3, 33 * sizeof (Word));
		m_numPages = rhs.m_numPages;
		
		return *this;
	}
	
	bool HeaderGenerated::verifyVariables (void)
	{
	CHECK_DEVICE;
	
		if (!Verify (Error::InvalidFormat, m_magic == 0xBE31 || m_magic == 0xBE32, DWord (m_magic))) return false;
		if (!Verify (Error::InvalidFormat, m_zero == 0, DWord (m_zero))) return false;
		if (!Verify (Error::InvalidFormat, m_magic2 == 0xAB00, DWord (m_magic2))) return false;
		for (int i = 0; i < 4; i++)
		{
                       if (!Verify (Error::InvalidFormat, m_zero2 [i] == 0, long (m_zero2))) return false;
		}
		if (!Verify (Error::InvalidFormat, m_numCharBytesPlus128 >= 128, DWord (m_numCharBytesPlus128))) return false;
		// m_pageParaInfo will not be checked
		// m_pageFootnoteTable will not be checked
		// m_pageSectionProperty will not be checked
		// m_pageSectionTable will not be checked
		// m_pagePageTable will not be checked
		// m_pageFontTable will not be checked
		for (int i = 0; i < 33; i++)
		{
                       if (!Verify (Error::Warn, m_zero3 [i] == 0, long (m_zero3))) return false;
		}
		if (!Verify (Error::InvalidFormat, m_numPages > 0, DWord (m_numPages))) return false;
		return true;
	}
	
	bool HeaderGenerated::readFromDevice (void)
	{
	CHECK_DEVICE;
	
		// read the data straight from the file
		if (!m_device->readInternal (m_data, s_size))
			ErrorAndQuit (Error::FileError, "could not read HeaderGenerated data");
		
		ReadWord (m_magic, m_data + 0);
		ReadWord (m_zero, m_data + 2);
		ReadWord (m_magic2, m_data + 4);
		for (int i = 0; i < 4; i++)
		{
			ReadWord (m_zero2 [i], m_data + 6 + i * sizeof (Word));
		}
		
		ReadDWord (m_numCharBytesPlus128, m_data + 14);
		ReadWord (m_pageParaInfo, m_data + 18);
		ReadWord (m_pageFootnoteTable, m_data + 20);
		ReadWord (m_pageSectionProperty, m_data + 22);
		ReadWord (m_pageSectionTable, m_data + 24);
		ReadWord (m_pagePageTable, m_data + 26);
		ReadWord (m_pageFontTable, m_data + 28);
		for (int i = 0; i < 33; i++)
		{
			ReadWord (m_zero3 [i], m_data + 30 + i * sizeof (Word));
		}
		
		ReadWord (m_numPages, m_data + 96);
		return verifyVariables ();
	}
	
	bool HeaderGenerated::writeToArray (void)
	{
	CHECK_DEVICE;
	
		WriteWord (m_magic, m_data + 0);
		WriteWord (m_zero, m_data + 2);
		WriteWord (m_magic2, m_data + 4);
		for (int i = 0; i < 4; i++)
		{
			WriteWord (m_zero2 [i], m_data + 6 + i * sizeof (Word));
		}
		
		WriteDWord (m_numCharBytesPlus128, m_data + 14);
		WriteWord (m_pageParaInfo, m_data + 18);
		WriteWord (m_pageFootnoteTable, m_data + 20);
		WriteWord (m_pageSectionProperty, m_data + 22);
		WriteWord (m_pageSectionTable, m_data + 24);
		WriteWord (m_pagePageTable, m_data + 26);
		WriteWord (m_pageFontTable, m_data + 28);
		for (int i = 0; i < 33; i++)
		{
			WriteWord (m_zero3 [i], m_data + 30 + i * sizeof (Word));
		}
		
		WriteWord (m_numPages, m_data + 96);
		return true;
	}
	
	bool HeaderGenerated::writeToDevice (void)
	{
	CHECK_DEVICE;
	
		// ensure that the variables are in range
		if (!verifyVariables ()) return false;
		
		// write the variables to the array
		if (!writeToArray ()) return false;
		
		// write the data straight to the file
		if (!m_device->writeInternal (m_data, s_size))
			ErrorAndQuit (Error::FileError, "could not write HeaderGenerated data");
		
		return true;
	}
	
	
	// -------------------- BEGIN PageLayoutGenerated --------------------
	
	PageLayoutGenerated::PageLayoutGenerated ()
	{
		// --- set defaults for variables --
		m_magic102 = (Byte) (102);
		m_magic512 = (Word) (512);
		m_pageHeight = (Word) (Inch2Twip (11));
		m_pageWidth = (Word) (Inch2Twip (8.5));
		m_pageNumberStart = (Word) (1);
		m_topMargin = (Word) (Inch2Twip (1));
		m_textHeight = (Word) (Inch2Twip (9));
		m_leftMargin = (Word) (Inch2Twip (1.25));
		m_textWidth = (Word) (Inch2Twip (6));
		m_magic256 = (Word) (256);
		m_headerFromTop = (Word) (Inch2Twip (0.75));
		m_footerFromTop = (Word) (Inch2Twip (11.0/*m_pageHeight*/ - 0.75));
		m_magic720 = (Word) (720);
		m_zero = (Word) (0);
		m_magic1080 = (Word) (1080);
		m_unknown = (Word) (0);
		m_zero2 = (Word) (0);
	}
	
	PageLayoutGenerated::~PageLayoutGenerated ()
	{
	}
	
	PageLayoutGenerated &PageLayoutGenerated::operator= (const PageLayoutGenerated &rhs)
	{
		if (this == &rhs)
			return *this;
		
		NeedsDevice::operator= (rhs);
		memcpy (m_data, rhs.m_data, s_size);
		
		m_magic102 = rhs.m_magic102;
		m_magic512 = rhs.m_magic512;
		m_pageHeight = rhs.m_pageHeight;
		m_pageWidth = rhs.m_pageWidth;
		m_pageNumberStart = rhs.m_pageNumberStart;
		m_topMargin = rhs.m_topMargin;
		m_textHeight = rhs.m_textHeight;
		m_leftMargin = rhs.m_leftMargin;
		m_textWidth = rhs.m_textWidth;
		m_magic256 = rhs.m_magic256;
		m_headerFromTop = rhs.m_headerFromTop;
		m_footerFromTop = rhs.m_footerFromTop;
		m_magic720 = rhs.m_magic720;
		m_zero = rhs.m_zero;
		m_magic1080 = rhs.m_magic1080;
		m_unknown = rhs.m_unknown;
		m_zero2 = rhs.m_zero2;
		
		return *this;
	}
	
	bool PageLayoutGenerated::verifyVariables (void)
	{
	CHECK_DEVICE;
	
		if (!Verify (Error::Warn, m_magic102 == 102, DWord (m_magic102))) return false;
		if (!Verify (Error::Warn, m_magic512 == 512, DWord (m_magic512))) return false;
		// m_pageHeight will not be checked
		// m_pageWidth will not be checked
		// m_pageNumberStart will not be checked
		// m_topMargin will not be checked
		// m_textHeight will not be checked
		// m_leftMargin will not be checked
		// m_textWidth will not be checked
		if (!Verify (Error::Warn, m_magic256 == 256, DWord (m_magic256))) return false;
		// m_headerFromTop will not be checked
		// m_footerFromTop will not be checked
		if (!Verify (Error::Warn, m_magic720 == 720, DWord (m_magic720))) return false;
		if (!Verify (Error::Warn, m_zero == 0, DWord (m_zero))) return false;
		if (!Verify (Error::Warn, m_magic1080 == 1080, DWord (m_magic1080))) return false;
		// m_unknown will not be checked
		if (!Verify (Error::Warn, m_zero2 == 0, DWord (m_zero2))) return false;
		return true;
	}
	
	bool PageLayoutGenerated::readFromDevice (void)
	{
	CHECK_DEVICE;
	
		// read the data straight from the file
		if (!m_device->readInternal (m_data, s_size))
			ErrorAndQuit (Error::FileError, "could not read PageLayoutGenerated data");
		
		ReadByte (m_magic102, m_data + 0);
		ReadWord (m_magic512, m_data + 1);
		ReadWord (m_pageHeight, m_data + 3);
		ReadWord (m_pageWidth, m_data + 5);
		ReadWord (m_pageNumberStart, m_data + 7);
		ReadWord (m_topMargin, m_data + 9);
		ReadWord (m_textHeight, m_data + 11);
		ReadWord (m_leftMargin, m_data + 13);
		ReadWord (m_textWidth, m_data + 15);
		ReadWord (m_magic256, m_data + 17);
		ReadWord (m_headerFromTop, m_data + 19);
		ReadWord (m_footerFromTop, m_data + 21);
		ReadWord (m_magic720, m_data + 23);
		ReadWord (m_zero, m_data + 25);
		ReadWord (m_magic1080, m_data + 27);
		ReadWord (m_unknown, m_data + 29);
		ReadWord (m_zero2, m_data + 31);
		return verifyVariables ();
	}
	
	bool PageLayoutGenerated::writeToArray (void)
	{
	CHECK_DEVICE;
	
		WriteByte (m_magic102, m_data + 0);
		WriteWord (m_magic512, m_data + 1);
		WriteWord (m_pageHeight, m_data + 3);
		WriteWord (m_pageWidth, m_data + 5);
		WriteWord (m_pageNumberStart, m_data + 7);
		WriteWord (m_topMargin, m_data + 9);
		WriteWord (m_textHeight, m_data + 11);
		WriteWord (m_leftMargin, m_data + 13);
		WriteWord (m_textWidth, m_data + 15);
		WriteWord (m_magic256, m_data + 17);
		WriteWord (m_headerFromTop, m_data + 19);
		WriteWord (m_footerFromTop, m_data + 21);
		WriteWord (m_magic720, m_data + 23);
		WriteWord (m_zero, m_data + 25);
		WriteWord (m_magic1080, m_data + 27);
		WriteWord (m_unknown, m_data + 29);
		WriteWord (m_zero2, m_data + 31);
		return true;
	}
	
	bool PageLayoutGenerated::writeToDevice (void)
	{
	CHECK_DEVICE;
	
		// ensure that the variables are in range
		if (!verifyVariables ()) return false;
		
		// write the variables to the array
		if (!writeToArray ()) return false;
		
		// write the data straight to the file
		if (!m_device->writeInternal (m_data, s_size))
			ErrorAndQuit (Error::FileError, "could not write PageLayoutGenerated data");
		
		return true;
	}
	
	
	// -------------------- BEGIN SectionDescriptorGenerated --------------------
	
	SectionDescriptorGenerated::SectionDescriptorGenerated ()
	{
		// --- set defaults for variables --
		// no default for m_afterEndCharByte
		m_undefined = (Word) (0);
		// no default for m_sectionPropertyLocation
	}
	
	SectionDescriptorGenerated::~SectionDescriptorGenerated ()
	{
	}
	
	SectionDescriptorGenerated &SectionDescriptorGenerated::operator= (const SectionDescriptorGenerated &rhs)
	{
		if (this == &rhs)
			return *this;
		
		NeedsDevice::operator= (rhs);
		memcpy (m_data, rhs.m_data, s_size);
		
		m_afterEndCharByte = rhs.m_afterEndCharByte;
		m_undefined = rhs.m_undefined;
		m_sectionPropertyLocation = rhs.m_sectionPropertyLocation;
		
		return *this;
	}
	
	bool SectionDescriptorGenerated::verifyVariables (void)
	{
	CHECK_DEVICE;
	
		// m_afterEndCharByte will not be checked
		// m_undefined will not be checked
		// m_sectionPropertyLocation will not be checked
		return true;
	}
	
	bool SectionDescriptorGenerated::readFromDevice (void)
	{
	CHECK_DEVICE;
	
		// read the data straight from the file
		if (!m_device->readInternal (m_data, s_size))
			ErrorAndQuit (Error::FileError, "could not read SectionDescriptorGenerated data");
		
		ReadDWord (m_afterEndCharByte, m_data + 0);
		ReadWord (m_undefined, m_data + 4);
		ReadDWord (m_sectionPropertyLocation, m_data + 6);
		return verifyVariables ();
	}
	
	bool SectionDescriptorGenerated::writeToArray (void)
	{
	CHECK_DEVICE;
	
		WriteDWord (m_afterEndCharByte, m_data + 0);
		WriteWord (m_undefined, m_data + 4);
		WriteDWord (m_sectionPropertyLocation, m_data + 6);
		return true;
	}
	
	bool SectionDescriptorGenerated::writeToDevice (void)
	{
	CHECK_DEVICE;
	
		// ensure that the variables are in range
		if (!verifyVariables ()) return false;
		
		// write the variables to the array
		if (!writeToArray ()) return false;
		
		// write the data straight to the file
		if (!m_device->writeInternal (m_data, s_size))
			ErrorAndQuit (Error::FileError, "could not write SectionDescriptorGenerated data");
		
		return true;
	}
	
	
	// -------------------- BEGIN SectionTableGenerated --------------------
	
	SectionTableGenerated::SectionTableGenerated ()
	{
		// --- set pointer(s) to NULL (prevent segfault with premature exit) ---
		for (int i = 0; i < 2; i++)
			m_sed [i] = NULL;
		
		// --- allocate memory for embedded structures ---
		for (int i = 0; i < 2; i++)
		{
			m_sed [i] = new SectionDescriptor;	// forward ref to structures*.cpp
			if (!m_sed [i]) return;
		}
		
		// --- set defaults for variables --
		m_numSectionDescriptors = (Word) (2);
		m_undefined = (Word) (0);
		// leaving constructor of m_sed to set its own defaults
	}
	
	SectionTableGenerated::~SectionTableGenerated ()
	{
		for (int i = 0; i < 2; i++)
			delete m_sed [i];
	}
	
	SectionTableGenerated &SectionTableGenerated::operator= (const SectionTableGenerated &rhs)
	{
		if (this == &rhs)
			return *this;
		
		NeedsDevice::operator= (rhs);
		memcpy (m_data, rhs.m_data, s_size);
		
		m_numSectionDescriptors = rhs.m_numSectionDescriptors;
		m_undefined = rhs.m_undefined;
		for (int i = 0; i < 2; i++)
			*m_sed [i] = *(rhs.m_sed [i]);
		
		return *this;
	}
	
	bool SectionTableGenerated::verifyVariables (void)
	{
	CHECK_DEVICE;
	
		// m_numSectionDescriptors will not be checked
		// m_undefined will not be checked
		for (int i = 0; i < 2; i++)
		{
			if (!m_sed [i])	{	ErrorAndQuit (Error::OutOfMemory, "could not allocate memory for sed in constructor");	}
		}
		return true;
	}
	
	bool SectionTableGenerated::readFromDevice (void)
	{
	CHECK_DEVICE;
	
		// read the data straight from the file
		if (!m_device->readInternal (m_data, s_size))
			ErrorAndQuit (Error::FileError, "could not read SectionTableGenerated data");
		
		ReadWord (m_numSectionDescriptors, m_data + 0);
		ReadWord (m_undefined, m_data + 2);
		for (int i = 0; i < 2; i++)
		{
			m_device->setCache (m_data + 4 + i * SectionDescriptorGenerated::s_size);
			m_sed [i]->setDevice (m_device);
			if (!m_sed [i]->readFromDevice ()) return false;
			m_device->setCache (NULL);
		}
		
		return verifyVariables ();
	}
	
	bool SectionTableGenerated::writeToArray (void)
	{
	CHECK_DEVICE;
	
		WriteWord (m_numSectionDescriptors, m_data + 0);
		WriteWord (m_undefined, m_data + 2);
		for (int i = 0; i < 2; i++)
		{
			m_device->setCache (m_data + 4 + i * SectionDescriptorGenerated::s_size);
			m_sed [i]->setDevice (m_device);
			if (!m_sed [i]->writeToDevice ()) return false;
			m_device->setCache (NULL);
		}
		
		return true;
	}
	
	bool SectionTableGenerated::writeToDevice (void)
	{
	CHECK_DEVICE;
	
		// ensure that the variables are in range
		if (!verifyVariables ()) return false;
		
		// write the variables to the array
		if (!writeToArray ()) return false;
		
		// write the data straight to the file
		if (!m_device->writeInternal (m_data, s_size))
			ErrorAndQuit (Error::FileError, "could not write SectionTableGenerated data");
		
		return true;
	}
	
	
	// -------------------- BEGIN FontGenerated --------------------
	
	FontGenerated::FontGenerated ()
	{
		// --- set defaults for variables --
		m_numDataBytes = (Word) (0);
		m_family = (Byte) (0);
	}
	
	FontGenerated::~FontGenerated ()
	{
	}
	
	FontGenerated &FontGenerated::operator= (const FontGenerated &rhs)
	{
		if (this == &rhs)
			return *this;
		
		NeedsDevice::operator= (rhs);
		memcpy (m_data, rhs.m_data, s_size);
		
		m_numDataBytes = rhs.m_numDataBytes;
		m_family = rhs.m_family;
		
		return *this;
	}
	
	bool FontGenerated::verifyVariables (void)
	{
	CHECK_DEVICE;
	
		// m_numDataBytes will not be checked
		// m_family will not be checked
		return true;
	}
	
	bool FontGenerated::readFromDevice (void)
	{
	CHECK_DEVICE;
	
		// read the data straight from the file
		if (!m_device->readInternal (m_data, s_size))
			ErrorAndQuit (Error::FileError, "could not read FontGenerated data");
		
		ReadWord (m_numDataBytes, m_data + 0);
		ReadByte (m_family, m_data + 2);
		return verifyVariables ();
	}
	
	bool FontGenerated::writeToArray (void)
	{
	CHECK_DEVICE;
	
		WriteWord (m_numDataBytes, m_data + 0);
		WriteByte (m_family, m_data + 2);
		return true;
	}
	
	bool FontGenerated::writeToDevice (void)
	{
	CHECK_DEVICE;
	
		// ensure that the variables are in range
		if (!verifyVariables ()) return false;
		
		// write the variables to the array
		if (!writeToArray ()) return false;
		
		// write the data straight to the file
		if (!m_device->writeInternal (m_data, s_size))
			ErrorAndQuit (Error::FileError, "could not write FontGenerated data");
		
		return true;
	}
	
	
	// -------------------- BEGIN FontTableGenerated --------------------
	
	FontTableGenerated::FontTableGenerated ()
	{
		// --- set defaults for variables --
		m_numFonts = (Word) (0);
	}
	
	FontTableGenerated::~FontTableGenerated ()
	{
	}
	
	FontTableGenerated &FontTableGenerated::operator= (const FontTableGenerated &rhs)
	{
		if (this == &rhs)
			return *this;
		
		NeedsDevice::operator= (rhs);
		memcpy (m_data, rhs.m_data, s_size);
		
		m_numFonts = rhs.m_numFonts;
		
		return *this;
	}
	
	bool FontTableGenerated::verifyVariables (void)
	{
	CHECK_DEVICE;
	
		// m_numFonts will not be checked
		return true;
	}
	
	bool FontTableGenerated::readFromDevice (void)
	{
	CHECK_DEVICE;
	
		// read the data straight from the file
		if (!m_device->readInternal (m_data, s_size))
			ErrorAndQuit (Error::FileError, "could not read FontTableGenerated data");
		
		ReadWord (m_numFonts, m_data + 0);
		return verifyVariables ();
	}
	
	bool FontTableGenerated::writeToArray (void)
	{
	CHECK_DEVICE;
	
		WriteWord (m_numFonts, m_data + 0);
		return true;
	}
	
	bool FontTableGenerated::writeToDevice (void)
	{
	CHECK_DEVICE;
	
		// ensure that the variables are in range
		if (!verifyVariables ()) return false;
		
		// write the variables to the array
		if (!writeToArray ()) return false;
		
		// write the data straight to the file
		if (!m_device->writeInternal (m_data, s_size))
			ErrorAndQuit (Error::FileError, "could not write FontTableGenerated data");
		
		return true;
	}
	
	
	// -------------------- BEGIN PagePointerGenerated --------------------
	
	PagePointerGenerated::PagePointerGenerated ()
	{
		// --- set defaults for variables --
		// no default for m_pageNumber
		// no default for m_firstCharByte
	}
	
	PagePointerGenerated::~PagePointerGenerated ()
	{
	}
	
	PagePointerGenerated &PagePointerGenerated::operator= (const PagePointerGenerated &rhs)
	{
		if (this == &rhs)
			return *this;
		
		NeedsDevice::operator= (rhs);
		memcpy (m_data, rhs.m_data, s_size);
		
		m_pageNumber = rhs.m_pageNumber;
		m_firstCharByte = rhs.m_firstCharByte;
		
		return *this;
	}
	
	bool PagePointerGenerated::verifyVariables (void)
	{
	CHECK_DEVICE;
	
		if (!Verify (Error::InvalidFormat, m_pageNumber > 0, DWord (m_pageNumber))) return false;
		// m_firstCharByte will not be checked
		return true;
	}
	
	bool PagePointerGenerated::readFromDevice (void)
	{
	CHECK_DEVICE;
	
		// read the data straight from the file
		if (!m_device->readInternal (m_data, s_size))
			ErrorAndQuit (Error::FileError, "could not read PagePointerGenerated data");
		
		ReadWord (m_pageNumber, m_data + 0);
		ReadDWord (m_firstCharByte, m_data + 2);
		return verifyVariables ();
	}
	
	bool PagePointerGenerated::writeToArray (void)
	{
	CHECK_DEVICE;
	
		WriteWord (m_pageNumber, m_data + 0);
		WriteDWord (m_firstCharByte, m_data + 2);
		return true;
	}
	
	bool PagePointerGenerated::writeToDevice (void)
	{
	CHECK_DEVICE;
	
		// ensure that the variables are in range
		if (!verifyVariables ()) return false;
		
		// write the variables to the array
		if (!writeToArray ()) return false;
		
		// write the data straight to the file
		if (!m_device->writeInternal (m_data, s_size))
			ErrorAndQuit (Error::FileError, "could not write PagePointerGenerated data");
		
		return true;
	}
	
	
	// -------------------- BEGIN PageTableGenerated --------------------
	
	PageTableGenerated::PageTableGenerated ()
	{
		// --- set defaults for variables --
		m_numPagePointers = (Word) (0);
		m_zero = (Word) (0);
	}
	
	PageTableGenerated::~PageTableGenerated ()
	{
	}
	
	PageTableGenerated &PageTableGenerated::operator= (const PageTableGenerated &rhs)
	{
		if (this == &rhs)
			return *this;
		
		NeedsDevice::operator= (rhs);
		memcpy (m_data, rhs.m_data, s_size);
		
		m_numPagePointers = rhs.m_numPagePointers;
		m_zero = rhs.m_zero;
		
		return *this;
	}
	
	bool PageTableGenerated::verifyVariables (void)
	{
	CHECK_DEVICE;
	
		// m_numPagePointers will not be checked
		if (!Verify (Error::Warn, m_zero == 0, DWord (m_zero))) return false;
		return true;
	}
	
	bool PageTableGenerated::readFromDevice (void)
	{
	CHECK_DEVICE;
	
		// read the data straight from the file
		if (!m_device->readInternal (m_data, s_size))
			ErrorAndQuit (Error::FileError, "could not read PageTableGenerated data");
		
		ReadWord (m_numPagePointers, m_data + 0);
		ReadWord (m_zero, m_data + 2);
		return verifyVariables ();
	}
	
	bool PageTableGenerated::writeToArray (void)
	{
	CHECK_DEVICE;
	
		WriteWord (m_numPagePointers, m_data + 0);
		WriteWord (m_zero, m_data + 2);
		return true;
	}
	
	bool PageTableGenerated::writeToDevice (void)
	{
	CHECK_DEVICE;
	
		// ensure that the variables are in range
		if (!verifyVariables ()) return false;
		
		// write the variables to the array
		if (!writeToArray ()) return false;
		
		// write the data straight to the file
		if (!m_device->writeInternal (m_data, s_size))
			ErrorAndQuit (Error::FileError, "could not write PageTableGenerated data");
		
		return true;
	}
	
	
	// -------------------- BEGIN FormatPointerGenerated --------------------
	
	FormatPointerGenerated::FormatPointerGenerated ()
	{
		// --- set defaults for variables --
		// no default for m_afterEndCharBytePlus128
		// no default for m_formatPropertyOffset
	}
	
	FormatPointerGenerated::~FormatPointerGenerated ()
	{
	}
	
	FormatPointerGenerated &FormatPointerGenerated::operator= (const FormatPointerGenerated &rhs)
	{
		if (this == &rhs)
			return *this;
		
		NeedsDevice::operator= (rhs);
		memcpy (m_data, rhs.m_data, s_size);
		
		m_afterEndCharBytePlus128 = rhs.m_afterEndCharBytePlus128;
		m_formatPropertyOffset = rhs.m_formatPropertyOffset;
		
		return *this;
	}
	
	bool FormatPointerGenerated::verifyVariables (void)
	{
	CHECK_DEVICE;
	
		if (!Verify (Error::InvalidFormat, m_afterEndCharBytePlus128 >= 128, DWord (m_afterEndCharBytePlus128))) return false;
		if (!Verify (Error::InvalidFormat, m_formatPropertyOffset == 0xFFFF || m_formatPropertyOffset < 123 - 1/*numDataBytes of either FormatProperty, can't have 0 byte FormatProperty*/, DWord (m_formatPropertyOffset))) return false;
		return true;
	}
	
	bool FormatPointerGenerated::readFromDevice (void)
	{
	CHECK_DEVICE;
	
		// read the data straight from the file
		if (!m_device->readInternal (m_data, s_size))
			ErrorAndQuit (Error::FileError, "could not read FormatPointerGenerated data");
		
		ReadDWord (m_afterEndCharBytePlus128, m_data + 0);
		ReadWord (m_formatPropertyOffset, m_data + 4);
		return verifyVariables ();
	}
	
	bool FormatPointerGenerated::writeToArray (void)
	{
	CHECK_DEVICE;
	
		WriteDWord (m_afterEndCharBytePlus128, m_data + 0);
		WriteWord (m_formatPropertyOffset, m_data + 4);
		return true;
	}
	
	bool FormatPointerGenerated::writeToDevice (void)
	{
	CHECK_DEVICE;
	
		// ensure that the variables are in range
		if (!verifyVariables ()) return false;
		
		// write the variables to the array
		if (!writeToArray ()) return false;
		
		// write the data straight to the file
		if (!m_device->writeInternal (m_data, s_size))
			ErrorAndQuit (Error::FileError, "could not write FormatPointerGenerated data");
		
		return true;
	}
	
	
	// -------------------- BEGIN FormatCharPropertyGenerated --------------------
	
	FormatCharPropertyGenerated::FormatCharPropertyGenerated ()
	{
		// --- set defaults in raw array (needed because it's a useThisMuch structure) ---
		WriteByte ((Byte) (1), m_data + 1);// unknown
		m_data [2] = 0;						// isBold, isItalic, fontCodeLow
		WriteByte ((Byte) (24), m_data + 3);// fontSize
		m_data [4] = 0;						// isUnderlined, zero, isPageNumber, zero2, fontCodeHigh, zero3, position
		m_data [5] = 0;
		m_data [6] = 0;
		
		// --- set defaults for variables --
		m_numDataBytes = (Byte) (0);
		m_unknown = (Byte) (1);
		m_isBold = (unsigned) (0);
		m_isItalic = (unsigned) (0);
		m_fontCodeLow = (unsigned) (0);
		m_fontSize = (Byte) (24);
		m_isUnderlined = (unsigned) (0);
		m_zero = (unsigned) (0);
		m_isPageNumber = (unsigned) (0);
		m_zero2 = (unsigned) (0);
		m_fontCodeHigh = (unsigned) (0);
		m_zero3 = (unsigned) (0);
		m_position = (Byte) (0);
	}
	
	FormatCharPropertyGenerated::~FormatCharPropertyGenerated ()
	{
	}
	
	FormatCharPropertyGenerated &FormatCharPropertyGenerated::operator= (const FormatCharPropertyGenerated &rhs)
	{
		if (this == &rhs)
			return *this;
		
		NeedsDevice::operator= (rhs);
		UseThisMuch::operator= (rhs);
		memcpy (m_data, rhs.m_data, s_size);
		
		m_numDataBytes = rhs.m_numDataBytes;
		m_unknown = rhs.m_unknown;
		m_isBold = rhs.m_isBold;
		m_isItalic = rhs.m_isItalic;
		m_fontCodeLow = rhs.m_fontCodeLow;
		m_fontSize = rhs.m_fontSize;
		m_isUnderlined = rhs.m_isUnderlined;
		m_zero = rhs.m_zero;
		m_isPageNumber = rhs.m_isPageNumber;
		m_zero2 = rhs.m_zero2;
		m_fontCodeHigh = rhs.m_fontCodeHigh;
		m_zero3 = rhs.m_zero3;
		m_position = rhs.m_position;
		
		return *this;
	}
	
	bool FormatCharPropertyGenerated::verifyVariables (void)
	{
	CHECK_DEVICE;
	
		if (!Verify (Error::InvalidFormat, m_numDataBytes >= 1 && m_numDataBytes <= s_size - sizeof (Byte), DWord (m_numDataBytes))) return false;
		if (!Verify (Error::Warn, m_unknown <= 1, DWord (m_unknown))) return false;
		// m_isBold will not be checked
		// m_isItalic will not be checked
		// m_fontCodeLow will not be checked
		// m_fontSize will not be checked
		// m_isUnderlined will not be checked
		if (!Verify (Error::Warn, m_zero == 0, DWord (m_zero))) return false;
		// m_isPageNumber will not be checked
		if (!Verify (Error::Warn, m_zero2 == 0, DWord (m_zero2))) return false;
		// m_fontCodeHigh will not be checked
		if (!Verify (Error::Warn, m_zero3 == 0, DWord (m_zero3))) return false;
		// m_position will not be checked
		return true;
	}
	
	bool FormatCharPropertyGenerated::readFromDevice (void)
	{
	CHECK_DEVICE;
	
		// find out how many bytes to read
		if (!m_device->readInternal (m_data, 1))
			ErrorAndQuit (Error::FileError, "could not read FormatCharPropertyGenerated numDataBytes");
		ReadByte (m_numDataBytes, m_data);
		if (!Verify (Error::InvalidFormat, m_numDataBytes >= 1 && m_numDataBytes <= s_size - sizeof (Byte), DWord (m_numDataBytes))) return false;
		if (!m_device->readInternal (m_data + 1, m_numDataBytes))
			ErrorAndQuit (Error::FileError, "could not read FormatCharPropertyGenerated data");
		
		ReadByte (m_unknown, m_data + 1);
		signalHaveSetData (m_unknown == Byte (1), 0/*offset*/ + 8/*size*/);
		ReadBitsFromByte (m_isBold, m_data [2], 0, 1);
		signalHaveSetData (m_isBold == bool (0), 8/*offset*/ + 1/*size*/);
		ReadBitsFromByte (m_isItalic, m_data [2], 1, 1);
		signalHaveSetData (m_isItalic == bool (0), 9/*offset*/ + 1/*size*/);
		ReadBitsFromByte (m_fontCodeLow, m_data [2], 2, 6);
		signalHaveSetData (m_fontCodeLow == unsigned (0), 10/*offset*/ + 6/*size*/);
		ReadByte (m_fontSize, m_data + 3);
		signalHaveSetData (m_fontSize == Byte (24), 16/*offset*/ + 8/*size*/);
		ReadBitsFromByte (m_isUnderlined, m_data [4], 0, 1);
		signalHaveSetData (m_isUnderlined == bool (0), 24/*offset*/ + 1/*size*/);
		ReadBitsFromByte (m_zero, m_data [4], 1, 5);
		signalHaveSetData (m_zero == unsigned (0), 25/*offset*/ + 5/*size*/);
		ReadBitsFromByte (m_isPageNumber, m_data [4], 6, 1);
		signalHaveSetData (m_isPageNumber == bool (0), 30/*offset*/ + 1/*size*/);
		ReadBitsFromByte (m_zero2, m_data [4], 7, 1);
		signalHaveSetData (m_zero2 == bool (0), 31/*offset*/ + 1/*size*/);
		ReadBitsFromByte (m_fontCodeHigh, m_data [5], 0, 3);
		signalHaveSetData (m_fontCodeHigh == unsigned (0), 32/*offset*/ + 3/*size*/);
		ReadBitsFromByte (m_zero3, m_data [5], 3, 5);
		signalHaveSetData (m_zero3 == unsigned (0), 35/*offset*/ + 5/*size*/);
		ReadByte (m_position, m_data + 6);
		signalHaveSetData (m_position == Byte (0), 40/*offset*/ + 8/*size*/);
		return verifyVariables ();
	}
	
	bool FormatCharPropertyGenerated::writeToArray (void)
	{
	CHECK_DEVICE;
	
		// set m_data to 0 to avoid problems with bit ops
		memset (m_data, 0, s_size);
		
		WriteByte (m_numDataBytes, m_data + 0);
		WriteByte (m_unknown, m_data + 1);
		WriteBitsToByte (m_isBold, m_data [2], 0, 1);
		WriteBitsToByte (m_isItalic, m_data [2], 1, 1);
		WriteBitsToByte (m_fontCodeLow, m_data [2], 2, 6);
		WriteByte (m_fontSize, m_data + 3);
		WriteBitsToByte (m_isUnderlined, m_data [4], 0, 1);
		WriteBitsToByte (m_zero, m_data [4], 1, 5);
		WriteBitsToByte (m_isPageNumber, m_data [4], 6, 1);
		WriteBitsToByte (m_zero2, m_data [4], 7, 1);
		WriteBitsToByte (m_fontCodeHigh, m_data [5], 0, 3);
		WriteBitsToByte (m_zero3, m_data [5], 3, 5);
		WriteByte (m_position, m_data + 6);
		return true;
	}
	
	bool FormatCharPropertyGenerated::writeToDevice (void)
	{
	CHECK_DEVICE;
	
		// sync m_numDataBytes with reality
		updateNumDataBytes ();
		
		// ensure that the variables are in range
		if (!verifyVariables ()) return false;
		
		// write the variables to the array
		if (!writeToArray ()) return false;
		
		// write the data straight to the file
		if (!m_device->writeInternal (m_data, 1 /*sizeof (m_numDataBytes)*/ + (m_numDataBytes ? m_numDataBytes : getNeedNumDataBytes ())))
			ErrorAndQuit (Error::FileError, "could not write FormatCharPropertyGenerated data");
		
		return true;
	}
	
	
	// -------------------- BEGIN FormatParaPropertyTabulatorGenerated --------------------
	
	FormatParaPropertyTabulatorGenerated::FormatParaPropertyTabulatorGenerated ()
	{
		// --- set defaults for variables --
		m_indent = (Word) (0);
		m_type = (Byte) (0);
		m_zero = (Byte) (0);
	}
	
	FormatParaPropertyTabulatorGenerated::~FormatParaPropertyTabulatorGenerated ()
	{
	}
	
	FormatParaPropertyTabulatorGenerated &FormatParaPropertyTabulatorGenerated::operator= (const FormatParaPropertyTabulatorGenerated &rhs)
	{
		if (this == &rhs)
			return *this;
		
		NeedsDevice::operator= (rhs);
		memcpy (m_data, rhs.m_data, s_size);
		
		m_indent = rhs.m_indent;
		m_type = rhs.m_type;
		m_zero = rhs.m_zero;
		
		return *this;
	}
	
	bool FormatParaPropertyTabulatorGenerated::verifyVariables (void)
	{
	CHECK_DEVICE;
	
		// m_indent will not be checked
		if (!Verify (Error::InvalidFormat, m_type == 0 || m_type == 3, DWord (m_type))) return false;
		if (!Verify (Error::Warn, m_zero == 0, DWord (m_zero))) return false;
		return true;
	}
	
	bool FormatParaPropertyTabulatorGenerated::readFromDevice (void)
	{
	CHECK_DEVICE;
	
		// read the data straight from the file
		if (!m_device->readInternal (m_data, s_size))
			ErrorAndQuit (Error::FileError, "could not read FormatParaPropertyTabulatorGenerated data");
		
		ReadWord (m_indent, m_data + 0);
		ReadByte (m_type, m_data + 2);
		ReadByte (m_zero, m_data + 3);
		return verifyVariables ();
	}
	
	bool FormatParaPropertyTabulatorGenerated::writeToArray (void)
	{
	CHECK_DEVICE;
	
		WriteWord (m_indent, m_data + 0);
		WriteByte (m_type, m_data + 2);
		WriteByte (m_zero, m_data + 3);
		return true;
	}
	
	bool FormatParaPropertyTabulatorGenerated::writeToDevice (void)
	{
	CHECK_DEVICE;
	
		// ensure that the variables are in range
		if (!verifyVariables ()) return false;
		
		// write the variables to the array
		if (!writeToArray ()) return false;
		
		// write the data straight to the file
		if (!m_device->writeInternal (m_data, s_size))
			ErrorAndQuit (Error::FileError, "could not write FormatParaPropertyTabulatorGenerated data");
		
		return true;
	}
	
	
	// -------------------- BEGIN FormatParaPropertyGenerated --------------------
	
	FormatParaPropertyGenerated::FormatParaPropertyGenerated ()
	{
		// --- set pointer(s) to NULL (prevent segfault with premature exit) ---
		for (int i = 0; i < 14; i++)
			m_tab [i] = NULL;
		
		// --- allocate memory for embedded structures ---
		for (int i = 0; i < 14; i++)
		{
			m_tab [i] = new FormatParaPropertyTabulator;	// forward ref to structures*.cpp
			if (!m_tab [i]) return;
		}
		
		// --- set defaults in raw array (needed because it's a useThisMuch structure) ---
		WriteByte ((Byte) (60), m_data + 1);// magic0_60_or_61
		m_data [2] = 0;						// alignment
		WriteWord ((Word) (30), m_data + 3);// magic30
		memset (m_data + 5, 0, 6);			// rightIndent, leftIndent, leftIndentFirstLine
		WriteWord ((Word) (240), m_data + 11);// lineSpacing
		memset (m_data + 13, 0, 10);		// zero, headerOrFooter, isNotNormalParagraph, isOnFirstPage, isObject, zero2, zero3
		memset (m_data + 23, 0, 56);		// HACK: default embedded structures is 0
		
		// --- set defaults for variables --
		m_numDataBytes = (Byte) (0);
		m_magic0_60_or_61 = (Byte) (60);
		m_alignment = (Byte) (0);
		m_magic30 = (Word) (30);
		m_rightIndent = (Word) (0);
		m_leftIndent = (Word) (0);
		m_leftIndentFirstLine = (Short) (0);
		m_lineSpacing = (Word) (240);
		for (int i = 0; i < 2; i++)
			m_zero [i] = (Word) (0);
		m_headerOrFooter = (unsigned) (0);
		m_isNotNormalParagraph = (unsigned) (0);
		m_isOnFirstPage = (unsigned) (0);
		m_isObject = (unsigned) (0);
		m_zero2 = (unsigned) (0);
		memset (m_zero3, (Byte) (0), 5 * sizeof (Byte));
		// leaving constructor of m_tab to set its own defaults
	}
	
	FormatParaPropertyGenerated::~FormatParaPropertyGenerated ()
	{
		for (int i = 0; i < 14; i++)
			delete m_tab [i];
	}
	
	FormatParaPropertyGenerated &FormatParaPropertyGenerated::operator= (const FormatParaPropertyGenerated &rhs)
	{
		if (this == &rhs)
			return *this;
		
		NeedsDevice::operator= (rhs);
		UseThisMuch::operator= (rhs);
		memcpy (m_data, rhs.m_data, s_size);
		
		m_numDataBytes = rhs.m_numDataBytes;
		m_magic0_60_or_61 = rhs.m_magic0_60_or_61;
		m_alignment = rhs.m_alignment;
		m_magic30 = rhs.m_magic30;
		m_rightIndent = rhs.m_rightIndent;
		m_leftIndent = rhs.m_leftIndent;
		m_leftIndentFirstLine = rhs.m_leftIndentFirstLine;
		m_lineSpacing = rhs.m_lineSpacing;
		memcpy (m_zero, rhs.m_zero, 2 * sizeof (Word));
		m_headerOrFooter = rhs.m_headerOrFooter;
		m_isNotNormalParagraph = rhs.m_isNotNormalParagraph;
		m_isOnFirstPage = rhs.m_isOnFirstPage;
		m_isObject = rhs.m_isObject;
		m_zero2 = rhs.m_zero2;
		memcpy (m_zero3, rhs.m_zero3, 5 * sizeof (Byte));
		for (int i = 0; i < 14; i++)
			*m_tab [i] = *(rhs.m_tab [i]);
		
		return *this;
	}
	
	bool FormatParaPropertyGenerated::verifyVariables (void)
	{
	CHECK_DEVICE;
	
		if (!Verify (Error::InvalidFormat, m_numDataBytes >= 1 && m_numDataBytes <= s_size - sizeof (Byte), DWord (m_numDataBytes))) return false;
		if (!Verify (Error::Warn, m_magic0_60_or_61 == 0 || m_magic0_60_or_61 == 60 || m_magic0_60_or_61 == 61, DWord (m_magic0_60_or_61))) return false;
		// m_alignment will not be checked
		if (!Verify (Error::Warn, m_magic30 == 30, DWord (m_magic30))) return false;
		// m_rightIndent will not be checked
		// m_leftIndent will not be checked
		// m_leftIndentFirstLine will not be checked
		// m_lineSpacing will not be checked
		for (int i = 0; i < 2; i++)
		{
                       if (!Verify (Error::Warn, m_zero [i] == 0, long (m_zero))) return false;
		}
		// m_headerOrFooter will not be checked
		// m_isNotNormalParagraph will not be checked
		// m_isOnFirstPage will not be checked
		// m_isObject will not be checked
		if (!Verify (Error::Warn, m_zero2 == 0, DWord (m_zero2))) return false;
		for (int i = 0; i < 5; i++)
		{
                       if (!Verify (Error::Warn, m_zero3 [i] == 0, long (m_zero3))) return false;
		}
		for (int i = 0; i < 14; i++)
		{
			if (!m_tab [i])	{	ErrorAndQuit (Error::OutOfMemory, "could not allocate memory for tab in constructor");	}
		}
		return true;
	}
	
	bool FormatParaPropertyGenerated::readFromDevice (void)
	{
	CHECK_DEVICE;
	
		// find out how many bytes to read
		if (!m_device->readInternal (m_data, 1))
			ErrorAndQuit (Error::FileError, "could not read FormatParaPropertyGenerated numDataBytes");
		ReadByte (m_numDataBytes, m_data);
		if (!Verify (Error::InvalidFormat, m_numDataBytes >= 1 && m_numDataBytes <= s_size - sizeof (Byte), DWord (m_numDataBytes))) return false;
		if (!m_device->readInternal (m_data + 1, m_numDataBytes))
			ErrorAndQuit (Error::FileError, "could not read FormatParaPropertyGenerated data");
		
		ReadByte (m_magic0_60_or_61, m_data + 1);
		signalHaveSetData (m_magic0_60_or_61 == Byte (60), 0/*offset*/ + 8/*size*/);
		ReadByte (m_alignment, m_data + 2);
		signalHaveSetData (m_alignment == Byte (0), 8/*offset*/ + 8/*size*/);
		ReadWord (m_magic30, m_data + 3);
		signalHaveSetData (m_magic30 == Word (30), 16/*offset*/ + 16/*size*/);
		ReadWord (m_rightIndent, m_data + 5);
		signalHaveSetData (m_rightIndent == Word (0), 32/*offset*/ + 16/*size*/);
		ReadWord (m_leftIndent, m_data + 7);
		signalHaveSetData (m_leftIndent == Word (0), 48/*offset*/ + 16/*size*/);
		ReadShort (m_leftIndentFirstLine, m_data + 9);
		signalHaveSetData (m_leftIndentFirstLine == Short (0), 64/*offset*/ + 16/*size*/);
		ReadWord (m_lineSpacing, m_data + 11);
		signalHaveSetData (m_lineSpacing == Word (240), 80/*offset*/ + 16/*size*/);
		for (int i = 0; i < 2; i++)
		{
			ReadWord (m_zero [i], m_data + 13 + i * sizeof (Word));
		}
		
		ReadBitsFromByte (m_headerOrFooter, m_data [17], 0, 1);
		signalHaveSetData (m_headerOrFooter == bool (0), 128/*offset*/ + 1/*size*/);
		ReadBitsFromByte (m_isNotNormalParagraph, m_data [17], 1, 2);
		signalHaveSetData (m_isNotNormalParagraph == unsigned (0), 129/*offset*/ + 2/*size*/);
		ReadBitsFromByte (m_isOnFirstPage, m_data [17], 3, 1);
		signalHaveSetData (m_isOnFirstPage == bool (0), 131/*offset*/ + 1/*size*/);
		ReadBitsFromByte (m_isObject, m_data [17], 4, 1);
		signalHaveSetData (m_isObject == bool (0), 132/*offset*/ + 1/*size*/);
		ReadBitsFromByte (m_zero2, m_data [17], 5, 3);
		signalHaveSetData (m_zero2 == unsigned (0), 133/*offset*/ + 3/*size*/);
		memcpy (m_zero3, m_data + 18, 5 * sizeof (Byte));
		for (int i = 0; i < 14; i++)
		{
			m_device->setCache (m_data + 23 + i * FormatParaPropertyTabulatorGenerated::s_size);
			m_tab [i]->setDevice (m_device);
			if (!m_tab [i]->readFromDevice ()) return false;
			m_device->setCache (NULL);
		}
		
		return verifyVariables ();
	}
	
	bool FormatParaPropertyGenerated::writeToArray (void)
	{
	CHECK_DEVICE;
	
		// set m_data to 0 to avoid problems with bit ops
		memset (m_data, 0, s_size);
		
		WriteByte (m_numDataBytes, m_data + 0);
		WriteByte (m_magic0_60_or_61, m_data + 1);
		WriteByte (m_alignment, m_data + 2);
		WriteWord (m_magic30, m_data + 3);
		WriteWord (m_rightIndent, m_data + 5);
		WriteWord (m_leftIndent, m_data + 7);
		WriteShort (m_leftIndentFirstLine, m_data + 9);
		WriteWord (m_lineSpacing, m_data + 11);
		for (int i = 0; i < 2; i++)
		{
			WriteWord (m_zero [i], m_data + 13 + i * sizeof (Word));
		}
		
		WriteBitsToByte (m_headerOrFooter, m_data [17], 0, 1);
		WriteBitsToByte (m_isNotNormalParagraph, m_data [17], 1, 2);
		WriteBitsToByte (m_isOnFirstPage, m_data [17], 3, 1);
		WriteBitsToByte (m_isObject, m_data [17], 4, 1);
		WriteBitsToByte (m_zero2, m_data [17], 5, 3);
		memcpy (m_data + 18, m_zero3, 5 * sizeof (Byte));
		for (int i = 0; i < 14; i++)
		{
			m_device->setCache (m_data + 23 + i * FormatParaPropertyTabulatorGenerated::s_size);
			m_tab [i]->setDevice (m_device);
			if (!m_tab [i]->writeToDevice ()) return false;
			m_device->setCache (NULL);
		}
		
		return true;
	}
	
	bool FormatParaPropertyGenerated::writeToDevice (void)
	{
	CHECK_DEVICE;
	
		// sync m_numDataBytes with reality
		updateNumDataBytes ();
		
		// ensure that the variables are in range
		if (!verifyVariables ()) return false;
		
		// write the variables to the array
		if (!writeToArray ()) return false;
		
		// write the data straight to the file
		if (!m_device->writeInternal (m_data, 1 /*sizeof (m_numDataBytes)*/ + (m_numDataBytes ? m_numDataBytes : getNeedNumDataBytes ())))
			ErrorAndQuit (Error::FileError, "could not write FormatParaPropertyGenerated data");
		
		return true;
	}
	
	
	// -------------------- BEGIN FormatInfoPageGenerated --------------------
	
	FormatInfoPageGenerated::FormatInfoPageGenerated ()
	{
		// --- set defaults for variables --
		// no default for m_firstCharBytePlus128
		memset (m_packedStructs, (Byte) (0), 123 * sizeof (Byte));
		m_numFormatPointers = (Byte) (0);
	}
	
	FormatInfoPageGenerated::~FormatInfoPageGenerated ()
	{
	}
	
	FormatInfoPageGenerated &FormatInfoPageGenerated::operator= (const FormatInfoPageGenerated &rhs)
	{
		if (this == &rhs)
			return *this;
		
		NeedsDevice::operator= (rhs);
		memcpy (m_data, rhs.m_data, s_size);
		
		m_firstCharBytePlus128 = rhs.m_firstCharBytePlus128;
		memcpy (m_packedStructs, rhs.m_packedStructs, 123 * sizeof (Byte));
		m_numFormatPointers = rhs.m_numFormatPointers;
		
		return *this;
	}
	
	bool FormatInfoPageGenerated::verifyVariables (void)
	{
	CHECK_DEVICE;
	
		if (!Verify (Error::InvalidFormat, m_firstCharBytePlus128 >= 128, DWord (m_firstCharBytePlus128))) return false;
		// m_packedStructs will not be checked
		// m_numFormatPointers will not be checked
		return true;
	}
	
	bool FormatInfoPageGenerated::readFromDevice (void)
	{
	CHECK_DEVICE;
	
		// read the data straight from the file
		if (!m_device->readInternal (m_data, s_size))
			ErrorAndQuit (Error::FileError, "could not read FormatInfoPageGenerated data");
		
		ReadDWord (m_firstCharBytePlus128, m_data + 0);
		memcpy (m_packedStructs, m_data + 4, 123 * sizeof (Byte));
		ReadByte (m_numFormatPointers, m_data + 127);
		return verifyVariables ();
	}
	
	bool FormatInfoPageGenerated::writeToArray (void)
	{
	CHECK_DEVICE;
	
		WriteDWord (m_firstCharBytePlus128, m_data + 0);
		memcpy (m_data + 4, m_packedStructs, 123 * sizeof (Byte));
		WriteByte (m_numFormatPointers, m_data + 127);
		return true;
	}
	
	bool FormatInfoPageGenerated::writeToDevice (void)
	{
	CHECK_DEVICE;
	
		// ensure that the variables are in range
		if (!verifyVariables ()) return false;
		
		// write the variables to the array
		if (!writeToArray ()) return false;
		
		// write the data straight to the file
		if (!m_device->writeInternal (m_data, s_size))
			ErrorAndQuit (Error::FileError, "could not write FormatInfoPageGenerated data");
		
		return true;
	}
	
	
	// -------------------- BEGIN BMP_BitmapFileHeaderGenerated --------------------
	
	BMP_BitmapFileHeaderGenerated::BMP_BitmapFileHeaderGenerated ()
	{
		// --- set defaults for variables --
		m_magic = (Word) (Word ('B') + (Word ('M') << 8));
		// no default for m_totalBytes
		for (int i = 0; i < 2; i++)
			m_zero [i] = (Word) (0);
		// no default for m_actualImageOffset
	}
	
	BMP_BitmapFileHeaderGenerated::~BMP_BitmapFileHeaderGenerated ()
	{
	}
	
	BMP_BitmapFileHeaderGenerated &BMP_BitmapFileHeaderGenerated::operator= (const BMP_BitmapFileHeaderGenerated &rhs)
	{
		if (this == &rhs)
			return *this;
		
		NeedsDevice::operator= (rhs);
		memcpy (m_data, rhs.m_data, s_size);
		
		m_magic = rhs.m_magic;
		m_totalBytes = rhs.m_totalBytes;
		memcpy (m_zero, rhs.m_zero, 2 * sizeof (Word));
		m_actualImageOffset = rhs.m_actualImageOffset;
		
		return *this;
	}
	
	bool BMP_BitmapFileHeaderGenerated::verifyVariables (void)
	{
	CHECK_DEVICE;
	
		if (!Verify (Error::InvalidFormat, m_magic == Word ('B') + (Word ('M') << 8), DWord (m_magic))) return false;
		// m_totalBytes will not be checked
		for (int i = 0; i < 2; i++)
		{
                       if (!Verify (Error::Warn, m_zero [i] == 0, long (m_zero))) return false;
		}
		// m_actualImageOffset will not be checked
		return true;
	}
	
	bool BMP_BitmapFileHeaderGenerated::readFromDevice (void)
	{
	CHECK_DEVICE;
	
		// read the data straight from the file
		if (!m_device->readInternal (m_data, s_size))
			ErrorAndQuit (Error::FileError, "could not read BMP_BitmapFileHeaderGenerated data");
		
		ReadWord (m_magic, m_data + 0);
		ReadDWord (m_totalBytes, m_data + 2);
		for (int i = 0; i < 2; i++)
		{
			ReadWord (m_zero [i], m_data + 6 + i * sizeof (Word));
		}
		
		ReadDWord (m_actualImageOffset, m_data + 10);
		return verifyVariables ();
	}
	
	bool BMP_BitmapFileHeaderGenerated::writeToArray (void)
	{
	CHECK_DEVICE;
	
		WriteWord (m_magic, m_data + 0);
		WriteDWord (m_totalBytes, m_data + 2);
		for (int i = 0; i < 2; i++)
		{
			WriteWord (m_zero [i], m_data + 6 + i * sizeof (Word));
		}
		
		WriteDWord (m_actualImageOffset, m_data + 10);
		return true;
	}
	
	bool BMP_BitmapFileHeaderGenerated::writeToDevice (void)
	{
	CHECK_DEVICE;
	
		// ensure that the variables are in range
		if (!verifyVariables ()) return false;
		
		// write the variables to the array
		if (!writeToArray ()) return false;
		
		// write the data straight to the file
		if (!m_device->writeInternal (m_data, s_size))
			ErrorAndQuit (Error::FileError, "could not write BMP_BitmapFileHeaderGenerated data");
		
		return true;
	}
	
	
	// -------------------- BEGIN BMP_BitmapInfoHeaderGenerated --------------------
	
	BMP_BitmapInfoHeaderGenerated::BMP_BitmapInfoHeaderGenerated ()
	{
		// --- set defaults for variables --
		m_numHeaderBytes = (DWord) (s_size);
		// no default for m_width
		// no default for m_height
		m_numPlanes = (Word) (1);
		// no default for m_bitsPerPixel
		m_compression = (DWord) (0);
		m_sizeImage = (DWord) (0);
		m_xPixelsPerMeter = (Long) (0);
		m_yPixelsPerMeter = (Long) (0);
		m_coloursUsed = (DWord) (0);
		// no default for m_coloursImportant
	}
	
	BMP_BitmapInfoHeaderGenerated::~BMP_BitmapInfoHeaderGenerated ()
	{
	}
	
	BMP_BitmapInfoHeaderGenerated &BMP_BitmapInfoHeaderGenerated::operator= (const BMP_BitmapInfoHeaderGenerated &rhs)
	{
		if (this == &rhs)
			return *this;
		
		NeedsDevice::operator= (rhs);
		memcpy (m_data, rhs.m_data, s_size);
		
		m_numHeaderBytes = rhs.m_numHeaderBytes;
		m_width = rhs.m_width;
		m_height = rhs.m_height;
		m_numPlanes = rhs.m_numPlanes;
		m_bitsPerPixel = rhs.m_bitsPerPixel;
		m_compression = rhs.m_compression;
		m_sizeImage = rhs.m_sizeImage;
		m_xPixelsPerMeter = rhs.m_xPixelsPerMeter;
		m_yPixelsPerMeter = rhs.m_yPixelsPerMeter;
		m_coloursUsed = rhs.m_coloursUsed;
		m_coloursImportant = rhs.m_coloursImportant;
		
		return *this;
	}
	
	bool BMP_BitmapInfoHeaderGenerated::verifyVariables (void)
	{
	CHECK_DEVICE;
	
		if (!Verify (Error::InvalidFormat, m_numHeaderBytes == DWord (s_size), DWord (m_numHeaderBytes))) return false;
		// m_width will not be checked
		// m_height will not be checked
		if (!Verify (Error::InvalidFormat, m_numPlanes == 1, DWord (m_numPlanes))) return false;
		if (!Verify (Error::Warn, m_bitsPerPixel == 1 || m_bitsPerPixel == 4 || m_bitsPerPixel == 8 || m_bitsPerPixel == 24, DWord (m_bitsPerPixel))) return false;
		// m_compression will not be checked
		// m_sizeImage will not be checked
		// m_xPixelsPerMeter will not be checked
		// m_yPixelsPerMeter will not be checked
		// m_coloursUsed will not be checked
		// m_coloursImportant will not be checked
		return true;
	}
	
	bool BMP_BitmapInfoHeaderGenerated::readFromDevice (void)
	{
	CHECK_DEVICE;
	
		// read the data straight from the file
		if (!m_device->readInternal (m_data, s_size))
			ErrorAndQuit (Error::FileError, "could not read BMP_BitmapInfoHeaderGenerated data");
		
		ReadDWord (m_numHeaderBytes, m_data + 0);
		ReadLong (m_width, m_data + 4);
		ReadLong (m_height, m_data + 8);
		ReadWord (m_numPlanes, m_data + 12);
		ReadWord (m_bitsPerPixel, m_data + 14);
		ReadDWord (m_compression, m_data + 16);
		ReadDWord (m_sizeImage, m_data + 20);
		ReadLong (m_xPixelsPerMeter, m_data + 24);
		ReadLong (m_yPixelsPerMeter, m_data + 28);
		ReadDWord (m_coloursUsed, m_data + 32);
		ReadDWord (m_coloursImportant, m_data + 36);
		return verifyVariables ();
	}
	
	bool BMP_BitmapInfoHeaderGenerated::writeToArray (void)
	{
	CHECK_DEVICE;
	
		WriteDWord (m_numHeaderBytes, m_data + 0);
		WriteLong (m_width, m_data + 4);
		WriteLong (m_height, m_data + 8);
		WriteWord (m_numPlanes, m_data + 12);
		WriteWord (m_bitsPerPixel, m_data + 14);
		WriteDWord (m_compression, m_data + 16);
		WriteDWord (m_sizeImage, m_data + 20);
		WriteLong (m_xPixelsPerMeter, m_data + 24);
		WriteLong (m_yPixelsPerMeter, m_data + 28);
		WriteDWord (m_coloursUsed, m_data + 32);
		WriteDWord (m_coloursImportant, m_data + 36);
		return true;
	}
	
	bool BMP_BitmapInfoHeaderGenerated::writeToDevice (void)
	{
	CHECK_DEVICE;
	
		// ensure that the variables are in range
		if (!verifyVariables ()) return false;
		
		// write the variables to the array
		if (!writeToArray ()) return false;
		
		// write the data straight to the file
		if (!m_device->writeInternal (m_data, s_size))
			ErrorAndQuit (Error::FileError, "could not write BMP_BitmapInfoHeaderGenerated data");
		
		return true;
	}
	
	
	// -------------------- BEGIN BMP_BitmapColourIndexGenerated --------------------
	
	BMP_BitmapColourIndexGenerated::BMP_BitmapColourIndexGenerated ()
	{
		// --- set defaults for variables --
		// no default for m_blue
		// no default for m_green
		// no default for m_red
		m_reserved = (Byte) (0);
	}
	
	BMP_BitmapColourIndexGenerated::~BMP_BitmapColourIndexGenerated ()
	{
	}
	
	BMP_BitmapColourIndexGenerated &BMP_BitmapColourIndexGenerated::operator= (const BMP_BitmapColourIndexGenerated &rhs)
	{
		if (this == &rhs)
			return *this;
		
		NeedsDevice::operator= (rhs);
		memcpy (m_data, rhs.m_data, s_size);
		
		m_blue = rhs.m_blue;
		m_green = rhs.m_green;
		m_red = rhs.m_red;
		m_reserved = rhs.m_reserved;
		
		return *this;
	}
	
	bool BMP_BitmapColourIndexGenerated::verifyVariables (void)
	{
	CHECK_DEVICE;
	
		// m_blue will not be checked
		// m_green will not be checked
		// m_red will not be checked
		// m_reserved will not be checked
		return true;
	}
	
	bool BMP_BitmapColourIndexGenerated::readFromDevice (void)
	{
	CHECK_DEVICE;
	
		// read the data straight from the file
		if (!m_device->readInternal (m_data, s_size))
			ErrorAndQuit (Error::FileError, "could not read BMP_BitmapColourIndexGenerated data");
		
		ReadByte (m_blue, m_data + 0);
		ReadByte (m_green, m_data + 1);
		ReadByte (m_red, m_data + 2);
		ReadByte (m_reserved, m_data + 3);
		return verifyVariables ();
	}
	
	bool BMP_BitmapColourIndexGenerated::writeToArray (void)
	{
	CHECK_DEVICE;
	
		WriteByte (m_blue, m_data + 0);
		WriteByte (m_green, m_data + 1);
		WriteByte (m_red, m_data + 2);
		WriteByte (m_reserved, m_data + 3);
		return true;
	}
	
	bool BMP_BitmapColourIndexGenerated::writeToDevice (void)
	{
	CHECK_DEVICE;
	
		// ensure that the variables are in range
		if (!verifyVariables ()) return false;
		
		// write the variables to the array
		if (!writeToArray ()) return false;
		
		// write the data straight to the file
		if (!m_device->writeInternal (m_data, s_size))
			ErrorAndQuit (Error::FileError, "could not write BMP_BitmapColourIndexGenerated data");
		
		return true;
	}
	
	
	// -------------------- BEGIN BitmapHeaderGenerated --------------------
	
	BitmapHeaderGenerated::BitmapHeaderGenerated ()
	{
		// --- set defaults for variables --
		m_zero = (Word) (0);
		m_width = (Word) (0);
		m_height = (Word) (0);
		m_widthBytes = (Word) (0);
		m_numPlanes = (Byte) (0);
		m_bitsPerPixel = (Byte) (0);
		m_zero2 = (DWord) (0);
	}
	
	BitmapHeaderGenerated::~BitmapHeaderGenerated ()
	{
	}
	
	BitmapHeaderGenerated &BitmapHeaderGenerated::operator= (const BitmapHeaderGenerated &rhs)
	{
		if (this == &rhs)
			return *this;
		
		NeedsDevice::operator= (rhs);
		memcpy (m_data, rhs.m_data, s_size);
		
		m_zero = rhs.m_zero;
		m_width = rhs.m_width;
		m_height = rhs.m_height;
		m_widthBytes = rhs.m_widthBytes;
		m_numPlanes = rhs.m_numPlanes;
		m_bitsPerPixel = rhs.m_bitsPerPixel;
		m_zero2 = rhs.m_zero2;
		
		return *this;
	}
	
	bool BitmapHeaderGenerated::verifyVariables (void)
	{
	CHECK_DEVICE;
	
		if (!Verify (Error::InvalidFormat, m_zero == 0, DWord (m_zero))) return false;
		// m_width will not be checked
		// m_height will not be checked
		// m_widthBytes will not be checked
		if (!Verify (Error::InvalidFormat, m_numPlanes == 0 || m_numPlanes == 1, DWord (m_numPlanes))) return false;
		// m_bitsPerPixel will not be checked
		if (!Verify (Error::InvalidFormat, m_zero2 == 0, DWord (m_zero2))) return false;
		return true;
	}
	
	bool BitmapHeaderGenerated::readFromDevice (void)
	{
	CHECK_DEVICE;
	
		// read the data straight from the file
		if (!m_device->readInternal (m_data, s_size))
			ErrorAndQuit (Error::FileError, "could not read BitmapHeaderGenerated data");
		
		ReadWord (m_zero, m_data + 0);
		ReadWord (m_width, m_data + 2);
		ReadWord (m_height, m_data + 4);
		ReadWord (m_widthBytes, m_data + 6);
		ReadByte (m_numPlanes, m_data + 8);
		ReadByte (m_bitsPerPixel, m_data + 9);
		ReadDWord (m_zero2, m_data + 10);
		return verifyVariables ();
	}
	
	bool BitmapHeaderGenerated::writeToArray (void)
	{
	CHECK_DEVICE;
	
		WriteWord (m_zero, m_data + 0);
		WriteWord (m_width, m_data + 2);
		WriteWord (m_height, m_data + 4);
		WriteWord (m_widthBytes, m_data + 6);
		WriteByte (m_numPlanes, m_data + 8);
		WriteByte (m_bitsPerPixel, m_data + 9);
		WriteDWord (m_zero2, m_data + 10);
		return true;
	}
	
	bool BitmapHeaderGenerated::writeToDevice (void)
	{
	CHECK_DEVICE;
	
		// ensure that the variables are in range
		if (!verifyVariables ()) return false;
		
		// write the variables to the array
		if (!writeToArray ()) return false;
		
		// write the data straight to the file
		if (!m_device->writeInternal (m_data, s_size))
			ErrorAndQuit (Error::FileError, "could not write BitmapHeaderGenerated data");
		
		return true;
	}
	
	
	// -------------------- BEGIN WMFHeaderGenerated --------------------
	
	WMFHeaderGenerated::WMFHeaderGenerated ()
	{
		// --- set defaults for variables --
		m_fieldType = (Word) (1);
		m_headerSize = (Word) (9);
		m_winVersion = (Word) (0x0300);
		// no default for m_fileSize
		m_numObjects = (Word) (0);
		// no default for m_maxRecordSize
		m_zero = (Word) (0);
	}
	
	WMFHeaderGenerated::~WMFHeaderGenerated ()
	{
	}
	
	WMFHeaderGenerated &WMFHeaderGenerated::operator= (const WMFHeaderGenerated &rhs)
	{
		if (this == &rhs)
			return *this;
		
		NeedsDevice::operator= (rhs);
		memcpy (m_data, rhs.m_data, s_size);
		
		m_fieldType = rhs.m_fieldType;
		m_headerSize = rhs.m_headerSize;
		m_winVersion = rhs.m_winVersion;
		m_fileSize = rhs.m_fileSize;
		m_numObjects = rhs.m_numObjects;
		m_maxRecordSize = rhs.m_maxRecordSize;
		m_zero = rhs.m_zero;
		
		return *this;
	}
	
	bool WMFHeaderGenerated::verifyVariables (void)
	{
	CHECK_DEVICE;
	
		if (!Verify (Error::InvalidFormat, m_fieldType == 1, DWord (m_fieldType))) return false;
		if (!Verify (Error::InvalidFormat, m_headerSize == 9, DWord (m_headerSize))) return false;
		if (!Verify (Error::Warn, m_winVersion <= 0x0300, DWord (m_winVersion))) return false;
		// m_fileSize will not be checked
		// m_numObjects will not be checked
		// m_maxRecordSize will not be checked
		if (!Verify (Error::Warn, m_zero == 0, DWord (m_zero))) return false;
		return true;
	}
	
	bool WMFHeaderGenerated::readFromDevice (void)
	{
	CHECK_DEVICE;
	
		// read the data straight from the file
		if (!m_device->readInternal (m_data, s_size))
			ErrorAndQuit (Error::FileError, "could not read WMFHeaderGenerated data");
		
		ReadWord (m_fieldType, m_data + 0);
		ReadWord (m_headerSize, m_data + 2);
		ReadWord (m_winVersion, m_data + 4);
		ReadDWord (m_fileSize, m_data + 6);
		ReadWord (m_numObjects, m_data + 10);
		ReadDWord (m_maxRecordSize, m_data + 12);
		ReadWord (m_zero, m_data + 16);
		return verifyVariables ();
	}
	
	bool WMFHeaderGenerated::writeToArray (void)
	{
	CHECK_DEVICE;
	
		WriteWord (m_fieldType, m_data + 0);
		WriteWord (m_headerSize, m_data + 2);
		WriteWord (m_winVersion, m_data + 4);
		WriteDWord (m_fileSize, m_data + 6);
		WriteWord (m_numObjects, m_data + 10);
		WriteDWord (m_maxRecordSize, m_data + 12);
		WriteWord (m_zero, m_data + 16);
		return true;
	}
	
	bool WMFHeaderGenerated::writeToDevice (void)
	{
	CHECK_DEVICE;
	
		// ensure that the variables are in range
		if (!verifyVariables ()) return false;
		
		// write the variables to the array
		if (!writeToArray ()) return false;
		
		// write the data straight to the file
		if (!m_device->writeInternal (m_data, s_size))
			ErrorAndQuit (Error::FileError, "could not write WMFHeaderGenerated data");
		
		return true;
	}
	
	
	// -------------------- BEGIN ImageGenerated --------------------
	
	ImageGenerated::ImageGenerated ()
	{
		// --- set pointer(s) to NULL (prevent segfault with premature exit) ---
		m_bmh = NULL;
		
		// --- allocate memory for embedded structures ---
		m_bmh = new BitmapHeader;	// forward ref to structures*.cpp
		if (!m_bmh) return;
		
		// --- set defaults for variables --
		// no default for m_mappingMode
		// no default for m_MFP_width
		// no default for m_MFP_height
		m_MFP_unknown = (Word) (0);
		m_indent = (Word) (0);
		// no default for m_width
		// no default for m_height
		m_zero = (Word) (0);
		// leaving constructor of m_bmh to set its own defaults
		m_numHeaderBytes = (Word) (s_size);
		// no default for m_numDataBytes
		m_horizontalScalingRel1000 = (Word) (1000);
		m_verticalScalingRel1000 = (Word) (1000);
	}
	
	ImageGenerated::~ImageGenerated ()
	{
		delete m_bmh;
	}
	
	ImageGenerated &ImageGenerated::operator= (const ImageGenerated &rhs)
	{
		if (this == &rhs)
			return *this;
		
		NeedsDevice::operator= (rhs);
		memcpy (m_data, rhs.m_data, s_size);
		
		m_mappingMode = rhs.m_mappingMode;
		m_MFP_width = rhs.m_MFP_width;
		m_MFP_height = rhs.m_MFP_height;
		m_MFP_unknown = rhs.m_MFP_unknown;
		m_indent = rhs.m_indent;
		m_width = rhs.m_width;
		m_height = rhs.m_height;
		m_zero = rhs.m_zero;
		*m_bmh = *(rhs.m_bmh);
		m_numHeaderBytes = rhs.m_numHeaderBytes;
		m_numDataBytes = rhs.m_numDataBytes;
		m_horizontalScalingRel1000 = rhs.m_horizontalScalingRel1000;
		m_verticalScalingRel1000 = rhs.m_verticalScalingRel1000;
		
		return *this;
	}
	
	bool ImageGenerated::verifyVariables (void)
	{
	CHECK_DEVICE;
	
		if (!Verify (Error::InvalidFormat, m_mappingMode != 0xE4, DWord (m_mappingMode))) return false;
		// m_MFP_width will not be checked
		// m_MFP_height will not be checked
		if (!Verify (Error::Warn, m_MFP_unknown==0, DWord (m_MFP_unknown))) return false;
		// m_indent will not be checked
		// m_width will not be checked
		// m_height will not be checked
		// m_zero will not be checked
		if (!m_bmh)	{	ErrorAndQuit (Error::OutOfMemory, "could not allocate memory for bmh in constructor");	}
		if (!Verify (Error::InvalidFormat, m_numHeaderBytes == s_size, DWord (m_numHeaderBytes))) return false;
		// m_numDataBytes will not be checked
		// m_horizontalScalingRel1000 will not be checked
		// m_verticalScalingRel1000 will not be checked
		return true;
	}
	
	bool ImageGenerated::readFromDevice (void)
	{
	CHECK_DEVICE;
	
		// read the data straight from the file
		if (!m_device->readInternal (m_data, s_size))
			ErrorAndQuit (Error::FileError, "could not read ImageGenerated data");
		
		ReadWord (m_mappingMode, m_data + 0);
		ReadWord (m_MFP_width, m_data + 2);
		ReadWord (m_MFP_height, m_data + 4);
		ReadWord (m_MFP_unknown, m_data + 6);
		ReadWord (m_indent, m_data + 8);
		ReadWord (m_width, m_data + 10);
		ReadWord (m_height, m_data + 12);
		ReadWord (m_zero, m_data + 14);
		
		m_device->setCache (m_data + 16);
		m_bmh->setDevice (m_device);
		if (!m_bmh->readFromDevice ()) return false;
		m_device->setCache (NULL);
		
		ReadWord (m_numHeaderBytes, m_data + 30);
		ReadDWord (m_numDataBytes, m_data + 32);
		ReadWord (m_horizontalScalingRel1000, m_data + 36);
		ReadWord (m_verticalScalingRel1000, m_data + 38);
		return verifyVariables ();
	}
	
	bool ImageGenerated::writeToArray (void)
	{
	CHECK_DEVICE;
	
		WriteWord (m_mappingMode, m_data + 0);
		WriteWord (m_MFP_width, m_data + 2);
		WriteWord (m_MFP_height, m_data + 4);
		WriteWord (m_MFP_unknown, m_data + 6);
		WriteWord (m_indent, m_data + 8);
		WriteWord (m_width, m_data + 10);
		WriteWord (m_height, m_data + 12);
		WriteWord (m_zero, m_data + 14);
		
		m_device->setCache (m_data + 16);
		m_bmh->setDevice (m_device);
		if (!m_bmh->writeToDevice ()) return false;
		m_device->setCache (NULL);
		
		WriteWord (m_numHeaderBytes, m_data + 30);
		WriteDWord (m_numDataBytes, m_data + 32);
		WriteWord (m_horizontalScalingRel1000, m_data + 36);
		WriteWord (m_verticalScalingRel1000, m_data + 38);
		return true;
	}
	
	bool ImageGenerated::writeToDevice (void)
	{
	CHECK_DEVICE;
	
		// ensure that the variables are in range
		if (!verifyVariables ()) return false;
		
		// write the variables to the array
		if (!writeToArray ()) return false;
		
		// write the data straight to the file
		if (!m_device->writeInternal (m_data, s_size))
			ErrorAndQuit (Error::FileError, "could not write ImageGenerated data");
		
		return true;
	}
	
	
	// -------------------- BEGIN OLEGenerated --------------------
	
	OLEGenerated::OLEGenerated ()
	{
		// --- set defaults for variables --
		// no default for m_mappingMode
		m_zero = (DWord) (0);
		// no default for m_objectType
		// no default for m_indent
		// no default for m_width
		// no default for m_height
		m_zero2 = (Word) (0);
		// no default for m_numDataBytes
		m_zero3 = (DWord) (0);
		// no default for m_objectName
		m_zero4 = (Word) (0);
		// no default for m_numHeaderBytes
		m_zero5 = (DWord) (0);
		// no default for m_widthScaledRel1000
		// no default for m_heightScaledRel1000
	}
	
	OLEGenerated::~OLEGenerated ()
	{
	}
	
	OLEGenerated &OLEGenerated::operator= (const OLEGenerated &rhs)
	{
		if (this == &rhs)
			return *this;
		
		NeedsDevice::operator= (rhs);
		memcpy (m_data, rhs.m_data, s_size);
		
		m_mappingMode = rhs.m_mappingMode;
		m_zero = rhs.m_zero;
		m_objectType = rhs.m_objectType;
		m_indent = rhs.m_indent;
		m_width = rhs.m_width;
		m_height = rhs.m_height;
		m_zero2 = rhs.m_zero2;
		m_numDataBytes = rhs.m_numDataBytes;
		m_zero3 = rhs.m_zero3;
		m_objectName = rhs.m_objectName;
		m_zero4 = rhs.m_zero4;
		m_numHeaderBytes = rhs.m_numHeaderBytes;
		m_zero5 = rhs.m_zero5;
		m_widthScaledRel1000 = rhs.m_widthScaledRel1000;
		m_heightScaledRel1000 = rhs.m_heightScaledRel1000;
		
		return *this;
	}
	
	bool OLEGenerated::verifyVariables (void)
	{
	CHECK_DEVICE;
	
		if (!Verify (Error::InvalidFormat, m_mappingMode == 0xE4, DWord (m_mappingMode))) return false;
		if (!Verify (Error::Warn, m_zero == 0, DWord (m_zero))) return false;
		if (!Verify (Error::InvalidFormat, m_objectType >= 1 && m_objectType <= 3, DWord (m_objectType))) return false;
		// m_indent will not be checked
		// m_width will not be checked
		// m_height will not be checked
		if (!Verify (Error::Warn, m_zero2 == 0, DWord (m_zero2))) return false;
		// m_numDataBytes will not be checked
		if (!Verify (Error::Warn, m_zero3 == 0, DWord (m_zero3))) return false;
		// m_objectName will not be checked
		if (!Verify (Error::Warn, m_zero4 == 0, DWord (m_zero4))) return false;
		if (!Verify (Error::InvalidFormat, m_numHeaderBytes == s_size, DWord (m_numHeaderBytes))) return false;
		if (!Verify (Error::Warn, m_zero5 == 0, DWord (m_zero5))) return false;
		// m_widthScaledRel1000 will not be checked
		// m_heightScaledRel1000 will not be checked
		return true;
	}
	
	bool OLEGenerated::readFromDevice (void)
	{
	CHECK_DEVICE;
	
		// read the data straight from the file
		if (!m_device->readInternal (m_data, s_size))
			ErrorAndQuit (Error::FileError, "could not read OLEGenerated data");
		
		ReadWord (m_mappingMode, m_data + 0);
		ReadDWord (m_zero, m_data + 2);
		ReadWord (m_objectType, m_data + 6);
		ReadWord (m_indent, m_data + 8);
		ReadWord (m_width, m_data + 10);
		ReadWord (m_height, m_data + 12);
		ReadWord (m_zero2, m_data + 14);
		ReadDWord (m_numDataBytes, m_data + 16);
		ReadDWord (m_zero3, m_data + 20);
		ReadDWord (m_objectName, m_data + 24);
		ReadWord (m_zero4, m_data + 28);
		ReadWord (m_numHeaderBytes, m_data + 30);
		ReadDWord (m_zero5, m_data + 32);
		ReadWord (m_widthScaledRel1000, m_data + 36);
		ReadWord (m_heightScaledRel1000, m_data + 38);
		return verifyVariables ();
	}
	
	bool OLEGenerated::writeToArray (void)
	{
	CHECK_DEVICE;
	
		WriteWord (m_mappingMode, m_data + 0);
		WriteDWord (m_zero, m_data + 2);
		WriteWord (m_objectType, m_data + 6);
		WriteWord (m_indent, m_data + 8);
		WriteWord (m_width, m_data + 10);
		WriteWord (m_height, m_data + 12);
		WriteWord (m_zero2, m_data + 14);
		WriteDWord (m_numDataBytes, m_data + 16);
		WriteDWord (m_zero3, m_data + 20);
		WriteDWord (m_objectName, m_data + 24);
		WriteWord (m_zero4, m_data + 28);
		WriteWord (m_numHeaderBytes, m_data + 30);
		WriteDWord (m_zero5, m_data + 32);
		WriteWord (m_widthScaledRel1000, m_data + 36);
		WriteWord (m_heightScaledRel1000, m_data + 38);
		return true;
	}
	
	bool OLEGenerated::writeToDevice (void)
	{
	CHECK_DEVICE;
	
		// ensure that the variables are in range
		if (!verifyVariables ()) return false;
		
		// write the variables to the array
		if (!writeToArray ()) return false;
		
		// write the data straight to the file
		if (!m_device->writeInternal (m_data, s_size))
			ErrorAndQuit (Error::FileError, "could not write OLEGenerated data");
		
		return true;
	}
	
	
}	// namespace MSWrite	{

// end of structures_generated.cpp
