bool read_wri_struct (wri_struct *w, GsfInput *f)
{
	int i, size;
	unsigned char *blob;
	bool result;

	// first we need to calculate the size
	i = size = 0;

	while (w[i].name) size += w[i++].size;

	// got the size, read the blob
	blob = static_cast<unsigned char *>(malloc(size));

	if (!blob)
	{
		UT_WARNINGMSG(("read_wri_struct: Out of memory!\n"));
		return false;
	}

	if (!gsf_input_read(f, size, blob))
	{
		UT_WARNINGMSG(("read_wri_struct: File not big enough!\n"));
		return false;
	}

	result = read_wri_struct_mem(w, blob);
	free(blob);

	return result;
}
int wri_struct_value (const wri_struct *w, const char *name)
{
	for (int i = 0; w[i].name; i++)
		if (strcmp(w[i].name, name) == 0) return w[i].value;

	/* This should never happen! */
	UT_WARNINGMSG(("wri_struct_value: Internal error, '%s' not found!\n", name));
	exit(1);
	return 0;
}
Example #3
0
static void _png_read(png_structp png_ptr, png_bytep data, png_size_t length)
{
	struct _bb* p = static_cast<struct _bb*>(png_get_io_ptr(png_ptr));
	const UT_Byte* pBytes = p->pBB->getPointer(0);

	// make sure that we don't read outside of pBytes
	if (p->iCurPos >= p->pBB->getLength() - length) {
		UT_WARNINGMSG(("PNG: Reading past buffer bounds. cur = %u, buflen = %u, length = %lu\n",
					   p->iCurPos, p->pBB->getLength(), length));
		length = p->pBB->getLength() - p->iCurPos;
		if (length == 0) {
			UT_WARNINGMSG(("PNG: Truncating to ZERO length.\n"));
			png_error(png_ptr, "Premature end of buffer");
			return;
		} else {
			UT_WARNINGMSG(("PNG: Truncating to %lu.\n", length));
		}
	}
	memcpy(data, pBytes + p->iCurPos, length);
	p->iCurPos += length;
}
Example #4
0
// The error-handler we will use when calling the psiconv library
void psion_error_handler (int kind, psiconv_u32 /*off*/, const char *message)
{
	switch(kind) {
		case PSICONV_VERB_FATAL:
		case PSICONV_VERB_ERROR:
			UT_WARNINGMSG(("%s\n",message));
			break;
                                                                                
		//case PSICONV_VERB_DEBUG:
		//case PSICONV_VERB_WARN:
		//case PSICONV_VERB_PROGRESS:
		default:
			UT_DEBUGMSG(("PSION: %s\n",message));
	}
}
// This should be removed at some time.
void XAP_UnixApp::migrate (const char *oldName, const char *newName, const char *path) const
{
	if (path && newName && oldName && (*oldName == '/'))
	{
		char *old = new char[strlen(path) - strlen(newName) + strlen(oldName)];
     
		if (old)
		{
			size_t len = strrchr(path, '/') - path;       
			strncpy(old, path, len);
			old[len] = 0;
			strcat(old, oldName);

			if (g_access(old, F_OK) == 0) 
			{
				UT_WARNINGMSG(("Renaming: %s -> %s\n", old, path));
				g_rename(old, path);
			}
                     
			delete[] old;
		}         
	}
}
bool read_wri_struct_mem (wri_struct *w, unsigned char *blob)
{
	int n;

	for (int i = 0; w[i].name; i++)
	{
		switch (w[i].type)
		{
			case CT_VALUE:
				n = w[i].size;
				w[i].value = 0;

				while (n--) w[i].value = (w[i].value * 256) + blob[n];

				break;

			case CT_BLOB:
				w[i].data = static_cast<char *>(malloc(w[i].size));

				if (!w[i].data)
				{
					UT_WARNINGMSG(("read_wri_struct_mem: Out of memory!\n"));
					return false;
				}

				memcpy(w[i].data, blob, w[i].size);
				break;

			case CT_IGNORE:
				break;
		}

		blob += w[i].size;
	}

	return true;
}
bool IE_Imp_MSWrite::read_txt (int from, int to)
{
	static const char *currcp;
	int fcMac, pnChar, fcFirst, cfod, fc, fcLim;
	unsigned char page[0x80];
	UT_String properties, tmp;
	int dataLen = static_cast<UT_sint32>(mData.getLength());

	UT_DEBUGMSG(("    TXT:\n"));
	UT_DEBUGMSG(("     from = %d\n", from));
	UT_DEBUGMSG(("     to   = %d\n", to));

	fcMac = wri_struct_value(wri_file_header, "fcMac");
	pnChar = (fcMac + 127) / 128;

	fcFirst = 0x80;

	while (true)
	{
		gsf_input_seek(mFile, pnChar++ * 0x80, G_SEEK_SET);
		gsf_input_read(mFile, 0x80, page);

		fc = READ_DWORD(page);
		cfod = page[0x7f];

		UT_DEBUGMSG(("      fcFirst = %d\n", fc));
		UT_DEBUGMSG(("      cfod    = %d\n", cfod));

		if (fc != fcFirst) UT_WARNINGMSG(("read_txt: fcFirst wrong.\n"));

		// read all FODs (format descriptors)
		for (int fod = 0; fod < cfod; fod++)
		{
			int bfprop, cch, ftc, hps, fBold, fItalic, fUline, hpsPos;

			UT_DEBUGMSG(("       CHP-FOD #%02d:\n", fod + 1));

			// read a FOD (format descriptor)
			fcLim = READ_DWORD(page + 4 + fod * 6);
			bfprop = READ_WORD(page + 8 + fod * 6);

			UT_DEBUGMSG(("        fcLim  = %d\n", fcLim));
			UT_DEBUGMSG((bfprop == 0xffff ? "        bfprop = 0x%04X\n" : "        bfprop = %d\n", bfprop));

			// default CHP values
			ftc = 0;
			hps = 24;
			fBold = fItalic = fUline = hpsPos = 0;

			// if the CHP FPROPs (formatting properties) differ from the defaults, get them
			if (bfprop != 0xffff && bfprop + (cch = page[bfprop + 4]) < 0x80)
			{
				UT_DEBUGMSG(("         cch = %d\n", cch));

				if (cch >= 2) ftc = page[bfprop + 6] >> 2;
				if (cch >= 5) ftc |= (page[bfprop + 9] & 3) << 6;
				if (cch >= 3) hps = page[bfprop + 7];
				if (cch >= 2) fBold = page[bfprop + 6] & 1;
				if (cch >= 2) fItalic = page[bfprop + 6] & 2;
				if (cch >= 4) fUline = page[bfprop + 8] & 1;
				if (cch >= 6) hpsPos = page[bfprop + 10];
			}

			UT_DEBUGMSG(("         ftc           = %d\n", ftc));
			UT_DEBUGMSG(("         hps           = %d\n", hps));
			UT_DEBUGMSG(("         fBold         = %d\n", fBold));
			UT_DEBUGMSG(("         fItalic       = %d\n", fItalic));
			UT_DEBUGMSG(("         fUline        = %d\n", fUline));
			UT_DEBUGMSG(("         hpsPos        = %d\n", hpsPos));

			if (ftc >= wri_fonts_count)
			{
				UT_WARNINGMSG(("read_txt: Wrong font code.\n"));
				ftc = wri_fonts_count - 1;
			}

			if (from < fcLim && to >= fcFirst)
			{
				UT_LocaleTransactor lt(LC_NUMERIC, "C");
				UT_String_sprintf(properties, "font-weight:%s",
				                              fBold ? "bold" : "normal");

				if (hps != 24)
				{
					UT_String_sprintf(tmp, "; font-size:%dpt", hps / 2);
					properties += tmp;
				}

				if (fItalic) properties += "; font-style:italic";
				if (fUline) properties += "; text-decoration:underline";

				if (hpsPos)
				{
					UT_String_sprintf(tmp, "; text-position:%s",
					                       hpsPos < 128 ? "superscript" : "subscript");
					properties += tmp;
				}

				if (wri_fonts_count)
				{
					UT_String_sprintf(tmp, "; font-family:%s", wri_fonts[ftc].name);
					properties += tmp;
				}

				if (wri_fonts[ftc].codepage != currcp /*sic!*/)
				{
					set_codepage(wri_fonts[ftc].codepage);
					currcp = wri_fonts[ftc].codepage;
				}

				mText.clear();
				UT_DEBUGMSG(("         Text: "));

				while (fcFirst <= from && from < fcLim && from <= to && from - 0x80 < dataLen)
					translate_char(*mData.getPointer(from++ - 0x80), mText);

				UT_DEBUGMSG(("\n"));

				// new attributes, only if there was text
				if (mText.size() > 0)
				{
					const gchar *attributes[5];
					const UT_UCS4Char *text = mText.ucs4_str(), *p = text;
					size_t txtLen;

					UT_DEBUGMSG(("         Conv: %s\n", mText.utf8_str()));

					attributes[0] = PT_PROPS_ATTRIBUTE_NAME;
					attributes[1] = properties.c_str();
					attributes[2] = NULL;

					appendFmt(attributes);

					// check for page number (should only be in header or footer)
					while (*p && *p != (UT_UCS4Char) 0x01) p++;

					if (*p)
					{
						if (p - text) appendSpan(text, p - text);

						attributes[2] = PT_TYPE_ATTRIBUTE_NAME;
						attributes[3] = "page_number";
						attributes[4] = NULL;

						appendObject(PTO_Field, attributes);

						txtLen = mText.size() - (p - text) - 1;
						p++;
					}
					else
					{
						txtLen = mText.size();
						p = text;
					}

					if (txtLen) appendSpan(p, txtLen);
				}
			}

			fcFirst = fcLim;

			if (fcLim >= fcMac || fcFirst > to)
			{
				UT_DEBUGMSG(("       CHP-FODs end, fcLim (%d) >= fcMac (%d) or fcFirst (%d) > to (%d)\n", fcLim, fcMac, fcFirst, to));
				return true;
			}
		}
	}
bool IE_Imp_MSWrite::read_pap (pap_t process)
{
	static const char *text_align[] = {"left", "center", "right", "justify"};
	int fcMac, pnPara, fcFirst, cfod, fc, fcLim;
	unsigned char page[0x80];
	UT_String properties, tmp, lastprops;

	if (process == All) { UT_DEBUGMSG(("PAP:\n")); }

	fcMac = wri_struct_value(wri_file_header, "fcMac");
	pnPara = wri_struct_value(wri_file_header, "pnPara");

	fcFirst = 0x80;

	while (true)
	{
		gsf_input_seek(mFile, pnPara++ * 0x80, G_SEEK_SET);
		gsf_input_read(mFile, 0x80, page);

		fc = READ_DWORD(page);
		cfod = page[0x7f];

		if (process == All)
		{
			UT_DEBUGMSG((" fcFirst = %d\n", fc));
			UT_DEBUGMSG((" cfod    = %d\n", cfod));
		}

		if (fc != fcFirst) UT_WARNINGMSG(("read_pap: fcFirst wrong.\n"));

		// read all FODs (format descriptors)
		for (int fod = 0; fod < cfod; fod++)
		{
			int bfprop, cch;
			int jc, dxaRight, dxaLeft, dxaLeft1, dyaLine, fGraphics;
			int rhcPage, rHeaderFooter, rhcFirst;
			int tabs, dxaTab[14], jcTab[14];

			if (process == All) { UT_DEBUGMSG(("  PAP-FOD #%02d:\n", fod + 1)); }

			// read a FOD (format descriptor)
			fcLim = READ_DWORD(page + 4 + fod * 6);
			bfprop = READ_WORD(page + 8 + fod * 6);

			if (process == All)
			{
				UT_DEBUGMSG(("   fcLim  = %d\n", fcLim));
				UT_DEBUGMSG((bfprop == 0xffff ? "   bfprop = 0x%04X\n" : "   bfprop = %d\n", bfprop));
			}

			// default PAP values
			jc = 0;
			dxaRight = dxaLeft = dxaLeft1 = 0;
			dyaLine = 240;
			rhcPage = rHeaderFooter = rhcFirst = 0;
			fGraphics = 0;
			tabs = 0;

			// if the PAP FPROPs (formatting properties) differ from the defaults, get them
			if (bfprop != 0xffff && bfprop + (cch = page[bfprop + 4]) < 0x80)
			{
				if (process == All) { UT_DEBUGMSG(("    cch = %d\n", cch)); }

				if (cch >= 2) jc = page[bfprop + 6] & 3;
				if (cch >= 6) dxaRight = READ_WORD(page + bfprop + 9);
				if (cch >= 8) dxaLeft = READ_WORD(page + bfprop + 11);
				if (cch >= 10) dxaLeft1 = READ_WORD(page + bfprop + 13);
				if (cch >= 12) dyaLine = READ_WORD(page + bfprop + 15);

				if (cch >= 17)
				{
					rhcPage = page[bfprop + 21] & 1;
					rHeaderFooter = page[bfprop + 21] & 6;
					rhcFirst = page[bfprop + 21] & 8;
					fGraphics = page[bfprop + 21] & 0x10;
				}

				for (int n = 0; n < 14; n++)
				{
					if (cch >= 4 * (n + 1) + 26)
					{
						dxaTab[tabs] = READ_WORD(page + bfprop + n * 4 + 27);
						jcTab[tabs] = page[bfprop + n * 4 + 29] & 3;
						tabs++;
					}
				}

				if (dxaRight & 0x8000) dxaRight = -0x10000 + dxaRight;
				if (dxaLeft & 0x8000) dxaLeft = -0x10000 + dxaLeft;
				if (dxaLeft1 & 0x8000) dxaLeft1 = -0x10000 + dxaLeft1;
				if (dyaLine < 240) dyaLine = 240;

				if (process == All && rHeaderFooter)
				{
					if (rhcPage)
					{
						if (!hasFooter)
						{
							hasFooter = true;
							page1Footer = rhcFirst;
						}
					}
					else
					{
						if (!hasHeader)
						{
							hasHeader = true;
							page1Header = rhcFirst;
						}
					}
				}
			}

			if ((process == All && !rHeaderFooter) ||
			    (rHeaderFooter && ((process == Header && !rhcPage) ||
			                       (process == Footer && rhcPage))))
			{
				UT_DEBUGMSG(("    jc            = %d\n", jc));
				UT_DEBUGMSG(("    dxaRight      = %d\n", dxaRight));
				UT_DEBUGMSG(("    dxaLeft       = %d\n", dxaLeft));
				UT_DEBUGMSG(("    dxaLeft1      = %d\n", dxaLeft1));
				UT_DEBUGMSG(("    dyaLine       = %d\n", dyaLine));
				UT_DEBUGMSG(("    rhcPage       = %d\n", rhcPage));
				UT_DEBUGMSG(("    rHeaderFooter = %d\n", rHeaderFooter));
				UT_DEBUGMSG(("    rhcFirst      = %d\n", rhcFirst));
				UT_DEBUGMSG(("    fGraphics     = %d\n", fGraphics));

				UT_LocaleTransactor lt(LC_NUMERIC, "C");
				UT_String_sprintf(properties, "text-align:%s; line-height:%.1f",
				                              text_align[jc],
				                              static_cast<float>(dyaLine) / 240.0);

				if (tabs)
				{
					properties += "; tabstops:";
					UT_DEBUGMSG(("    Tabs:\n"));

					for (int n = 0; n < tabs; n++)
					{
						UT_String_sprintf(tmp, "%.4fin/%c0",
						                       static_cast<float>(dxaTab[n]) / 1440.0,
						                       jcTab[n] ? 'D' : 'L');
						properties += tmp;
						UT_DEBUGMSG(("     #%02d dxa = %d, jcTab = %d\n", n + 1, dxaTab[n], jcTab[n]));

						if (n != tabs - 1) properties += ",";
					}
				}

				if (process == Header || process == Footer)
				{
					// For reasons unknown, the left and right margins from the paper
					// are included in the indents of the headers and footers.
					dxaLeft -= xaLeft;
					dxaRight -= xaRight;
				}

				if (dxaLeft1)
				{
					UT_String_sprintf(tmp, "; text-indent:%.4fin",
					                       static_cast<float>(dxaLeft1) / 1440.0);
					properties += tmp;
				}

				if (dxaLeft)
				{
					UT_String_sprintf(tmp, "; margin-left:%.4fin",
					                       static_cast<float>(dxaLeft) / 1440.0);
					properties += tmp;
				}

				if (dxaRight)
				{
					UT_String_sprintf(tmp, "; margin-right:%.4fin",
					                       static_cast<float>(dxaRight) / 1440.0);
					properties += tmp;
				}

				// new attributes, only if there was a line feed or FPROPs have changed
				if (lf || strcmp(properties.c_str(), lastprops.c_str()) != 0)
				{
					const gchar *attributes[3];

					attributes[0] = PT_PROPS_ATTRIBUTE_NAME;
					attributes[1] = properties.c_str();
					attributes[2] = NULL;

					appendStrux(PTX_Block, attributes);

					lastprops = properties;
				}

				if (fGraphics) read_pic(fcFirst, fcLim - fcFirst);
				else read_txt(fcFirst, fcLim - 1);
			}

			fcFirst = fcLim;

			if (fcLim >= fcMac)
			{
				UT_DEBUGMSG(("  PAP-FODs end, fcLim (%d) >= fcMac (%d)\n", fcLim, fcMac));
				return true;
			}
		}
	}
}
bool IE_Imp_MSWrite::read_ffntb ()
{
	int pnFfntb, pnMac, fonts_count = 0, cbFfn, fflen;
	unsigned char buf[2], ffid;
	wri_font *fonts;
	char *ffn;

	UT_DEBUGMSG(("Fonts:\n"));

	pnFfntb = wri_struct_value(wri_file_header, "pnFfntb");
	pnMac = wri_struct_value(wri_file_header, "pnMac");

	// if pnFfntb is the same as pnMac, there are no fonts
	if (pnFfntb == pnMac)
	{
		UT_DEBUGMSG((" (none)\n"));
		return true;
	}

	if (gsf_input_seek(mFile, pnFfntb++ * 0x80, G_SEEK_SET))
	{
		UT_WARNINGMSG(("read_ffntb: Can't seek FFNTB!\n"));
		return false;
	}

	// the first two bytes are the number of fonts
	if (!gsf_input_read(mFile, 2, buf))
	{
		UT_WARNINGMSG(("read_ffntb: Can't read FFNTB!\n"));
		return false;
	}

	wri_fonts_count = READ_WORD(buf);
	UT_DEBUGMSG((" reported: %d\n", wri_fonts_count));

	while (true)
	{
		if (!gsf_input_read(mFile, 2, buf))
		{
			UT_WARNINGMSG(("read_ffntb: Can't read cbFfn!\n"));
			wri_fonts_count = fonts_count;
			free_ffntb();
			return false;
		}

		cbFfn = READ_WORD(buf);

		if (cbFfn == 0) break;

		if (cbFfn == 0xffff)
		{
			if (gsf_input_seek(mFile, pnFfntb++ * 0x80, G_SEEK_SET))
			{
				UT_WARNINGMSG(("read_ffntb: Can't seek next FFNTB!\n"));
				wri_fonts_count = fonts_count;
				free_ffntb();
				return false;
			}

			continue;
		}

		// add one more font
		fonts = (wri_font *) realloc(wri_fonts, (fonts_count + 1) * sizeof(wri_font));

		if (!fonts)
		{
			UT_WARNINGMSG(("read_ffntb: Out of memory!\n"));
			wri_fonts_count = fonts_count;
			free_ffntb();
			return false;
		}

		wri_fonts = fonts;

		// This is the font family identifier. It can either be FF_DONTCARE,
		// FF_ROMAN, FF_SWISS, FF_MODERN, FF_SCRIPT or FF_DECORATIVE. These
		// are defined in <windows.h>, but I don't know what to do with them.
		if (!gsf_input_read(mFile, 1, &ffid))
		{
			UT_WARNINGMSG(("read_ffntb: Can't read ffid!\n"));
			wri_fonts_count = fonts_count;
			free_ffntb();
			return false;
		}

		wri_fonts[fonts_count].ffid = ffid;

		cbFfn--;   // we've already read ffid

		ffn = static_cast<char *>(malloc(cbFfn));

		if (!ffn)
		{
			UT_WARNINGMSG(("read_ffntb: Out of memory!\n"));
			wri_fonts_count = fonts_count;
			free_ffntb();
			return false;
		}

		if (!gsf_input_read(mFile, cbFfn, (guint8 *) ffn))
		{
			UT_WARNINGMSG(("read_ffntb: Can't read szFfn!\n"));
			wri_fonts_count = fonts_count + 1;
			free_ffntb();
			return false;
		}

		wri_fonts[fonts_count].codepage = get_codepage(ffn, &fflen);

		ffn[fflen] = 0;
		wri_fonts[fonts_count].name = ffn;

		UT_DEBUGMSG(("  %2d: %s (%s)\n", fonts_count, wri_fonts[fonts_count].name, wri_fonts[fonts_count].codepage));
		fonts_count++;
	}

	if (fonts_count != wri_fonts_count)
	{
		wri_fonts_count = fonts_count;
		UT_WARNINGMSG(("read_ffntb: Wrong number of fonts.\n"));
	}

	return true;
}
UT_Error IE_Imp_MSWrite::parse_file ()
{
	int id, size;
	UT_Byte *thetext;

	if (!read_wri_struct(wri_file_header, mFile)) return UT_ERROR;

	UT_DEBUGMSG(("File Header:\n"));
	DEBUG_WRI_STRUCT(wri_file_header);

	id = wri_struct_value(wri_file_header, "wIdent");

	if (id == 0137062)
	{
		// okay, but expect OLE objects
	}
	else if (id != 0137061)
	{
		UT_WARNINGMSG(("parse_file: Not a write file!\n"));
		return UT_ERROR;
	}

	if (wri_struct_value(wri_file_header, "wTool") != 0125400)
	{
		UT_WARNINGMSG(("parse_file: Not a write file!\n"));
		return UT_ERROR;
	}

	size = wri_struct_value(wri_file_header, "fcMac") - 0x80;
	thetext = static_cast<UT_Byte *>(malloc(size));

	if (!thetext)
	{
		UT_WARNINGMSG(("parse_file: Out of memory!\n"));
		return UT_ERROR;
	}

	if (gsf_input_seek(mFile, 0x80, G_SEEK_SET))
	{
		UT_WARNINGMSG(("parse_file: Can't seek data!\n"));
		return UT_ERROR;
	}

	gsf_input_read(mFile, size, thetext);

	if (!read_ffntb())
	{
		free(thetext);
		return UT_ERROR;
	}

	mData.truncate(0);
	mData.append(thetext, size);
	free(thetext);

	read_sep();
	read_pap(All);

	UT_DEBUGMSG(("Header: %d, on first page: %d\n", hasHeader, page1Header));

	if (hasHeader)
	{
		_append_hdrftr(header);
		read_pap(Header);

		if (!page1Header) _append_hdrftr(headerfirst);   // an empty one

	}

	UT_DEBUGMSG(("Footer: %d, on first page: %d\n", hasFooter, page1Footer));

	if (hasFooter)
	{
		_append_hdrftr(footer);
		read_pap(Footer);

		if (!page1Footer) _append_hdrftr(footerfirst);   // an empty one

	}

	free_ffntb();

	return UT_OK;
}