/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* test-msole1.c: test program to dump biff streams
*
* Copyright (C) 2002-2003 Jody Goldberg (jody@gnome.org)
* Michael Meeks (michael@ximian.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2.1 of the GNU Lesser General Public
* License as published by the Free Software Foundation.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*
* Parts of this code are taken from libole2/test/test-ole.c
*/
#include <goffice/ms-compat/go-ms-parser.h>
#include <gsf/gsf-input-stdio.h>
#include <gsf/gsf-input-memory.h>
#include <gsf/gsf-utils.h>
#include <gsf/gsf-infile.h>
#include <gsf/gsf-infile-msole.h>
#include <gsf/gsf-msole-utils.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define INDENT { int i; for (i = 0; i < recursion_depth; i++) { g_print ("\t"); } }
static int recursion_depth;
#define STACK_TOP GO_MS_PARSER_STACK_TOP(stack)
enum {
Unknown = 0,
Document = 1000,
DocumentAtom = 1001,
EndDocument = 1002,
Slide = 1006,
SlideAtom = 1007,
Notes = 1008,
NotesAtom = 1009,
Environment = 1010,
SlidePersistAtom = 1011,
SSlideLayoutAtom = 1015,
MainMaster = 1016,
SSSlideInfoAtom = 1017,
SlideViewInfo = 1018,
GuideAtom = 1019,
ViewInfo = 1020,
ViewInfoAtom = 1021,
SlideViewInfoAtom = 1022,
VBAInfo = 1023,
VBAInfoAtom = 1024,
SSDocInfoAtom = 1025,
Summary = 1026,
DocRoutingSlip = 1030,
OutlineViewInfo = 1031,
SorterViewInfo = 1032,
ExObjList = 1033,
ExObjListAtom = 1034,
PPDrawingGroup = 1035, //FIXME: Office Art File Format Docu
PPDrawing = 1036, //FIXME: Office Art File Format Docu
NamedShows = 1040, // don't know if container
NamedShow = 1041,
NamedShowSlides = 1042, // don't know if container
List = 2000,
FontCollection = 2005,
BookmarkCollection = 2019,
SoundCollAtom = 2021,
Sound = 2022,
SoundData = 2023,
BookmarkSeedAtom = 2025,
ColorSchemeAtom = 2032,
ExObjRefAtom = 3009,
OEShapeAtom = 3009,
OEPlaceholderAtom = 3011,
GPointAtom = 3024,
GRatioAtom = 3031,
OutlineTextRefAtom = 3998,
TextHeaderAtom = 3999,
TextCharsAtom = 4000,
StyleTextPropAtom = 4001,
BaseTextPropAtom = 4002,
TxMasterStyleAtom = 4003,
TxCFStyleAtom = 4004,
TxPFStyleAtom = 4005,
TextRulerAtom = 4006,
TextBookmarkAtom = 4007,
TextBytesAtom = 4008,
TxSIStyleAtom = 4009,
TextSpecInfoAtom = 4010,
DefaultRulerAtom = 4011,
FontEntityAtom = 4023,
FontEmbeddedData = 4024,
CString = 4026,
MetaFile = 4033,
ExOleObjAtom = 4035,
SrKinsoku = 4040,
HandOut = 4041,
ExEmbed = 4044,
ExEmbedAtom = 4045,
ExLink = 4046,
BookmarkEntityAtom = 4048,
ExLinkAtom = 4049,
SrKinsokuAtom = 4050,
ExHyperlinkAtom = 4051,
ExHyperlink = 4055,
SlideNumberMCAtom = 4056,
HeadersFooters = 4057,
HeadersFootersAtom = 4058,
TxInteractiveInfoAtom = 4063,
CharFormatAtom = 4066,
ParaFormatAtom = 4067,
RecolorInfoAtom = 4071,
ExQuickTimeMovie = 4074,
ExQuickTimeMovieData = 4075,
ExControl = 4078,
SlideListWithText = 4080,
InteractiveInfo = 4082,
InteractiveInfoAtom = 4083,
UserEditAtom = 4085,
CurrentUserAtom = 4086,
DateTimeMCAtom = 4087,
GenericDateMCAtom = 4088,
FooterMCAtom = 4090,
ExControlAtom = 4091,
ExMediaAtom = 4100,
ExVideo = 4101,
ExAviMovie = 4102,
ExMCIMovie = 4103,
ExMIDIAudio = 4109,
ExCDAudio = 4110,
ExWAVAudioEmbedded = 4111,
ExWAVAudioLink = 4112,
ExOleObjStg = 4113,
ExCDAudioAtom = 4114,
ExWAVAudioEmbeddedAtom = 4115,
AnimationInfoAtom = 4116,
RTFDateTimeMCAtom = 4117,
ProgTags = 5000, // don't know if container
ProgStringTag = 5001,
ProgBinaryTag = 5002,
BinaryTagData = 5003,
PrintOptions = 6000,
PersistPtrFullBlock = 6001, // don't know if container
PersistPtrIncrementalBlock = 6002, // don't know if container
GScalingAtom = 10001,
GRColorAtom = 10002,
EscherDggContainer = 0xf000, /* Drawing Group Container */
EscherDgg = 0xf006,
EscherCLSID = 0xf016,
EscherOPT = 0xf00b,
EscherBStoreContainer = 0xf001,
EscherBSE = 0xf007,
EscherBlip_START = 0xf018, /* Blip types are between */
EscherBlip_END = 0xf117, /* these two values */
EscherDgContainer = 0xf002, /* Drawing Container */
EscherDg = 0xf008,
EscherRegroupItems = 0xf118,
EscherColorScheme = 0xf120, /* bug in docs */
EscherSpgrContainer = 0xf003,
EscherSpContainer = 0xf004,
EscherSpgr = 0xf009,
EscherSp = 0xf00a,
EscherTextbox = 0xf00c,
EscherClientTextbox = 0xf00d,
EscherAnchor = 0xf00e,
EscherChildAnchor = 0xf00f,
EscherClientAnchor = 0xf010,
EscherClientData = 0xf011,
EscherSolverContainer = 0xf005,
EscherConnectorRule = 0xf012, /* bug in docs */
EscherAlignRule = 0xf013,
EscherArcRule = 0xf014,
EscherClientRule = 0xf015,
EscherCalloutRule = 0xf017,
EscherSelection = 0xf119,
EscherColorMRU = 0xf11a,
EscherDeletedPspl = 0xf11d, /* bug in docs */
EscherSplitMenuColors = 0xf11e,
EscherOleObject = 0xf11f,
EscherUserDefined = 0xf122,
};
static const GOMSParserRecordType types[] =
{
{ Unknown, "Unknown", FALSE, TRUE, -1, -1 },
{ Document, "Document", TRUE, TRUE, -1, -1 },
{ DocumentAtom, "DocumentAtom", FALSE, TRUE, -1, -1 },
{ EndDocument, "EndDocument", FALSE, TRUE, -1, -1 },
{ Slide, "Slide", TRUE, TRUE, -1, -1 },
{ SlideAtom, "SlideAtom", FALSE, TRUE, -1, -1 },
{ Notes, "Notes", TRUE, TRUE, -1, -1 },
{ NotesAtom, "NotesAtom", FALSE, TRUE, -1, -1 },
{ Environment, "Environment", TRUE, TRUE, -1, -1 },
{ SlidePersistAtom, "SlidePersistAtom", FALSE, TRUE, -1, -1 },
{ SSlideLayoutAtom, "SSlideLayoutAtom", FALSE, TRUE, -1, -1 },
{ MainMaster, "MainMaster", TRUE, TRUE, -1, -1 },
{ SSSlideInfoAtom, "SSSlideInfoAtom", FALSE, TRUE, -1, -1 },
{ SlideViewInfo, "SlideViewInfo", TRUE, TRUE, -1, -1 },
{ GuideAtom, "GuideAtom", FALSE, TRUE, -1, -1 },
{ ViewInfo, "ViewInfo", TRUE, TRUE, -1, -1 },
{ ViewInfoAtom, "ViewInfoAtom", FALSE, TRUE, -1, -1 },
{ SlideViewInfoAtom, "SlideViewInfoAtom", FALSE, TRUE, -1, -1 },
{ VBAInfo, "VBAInfo", TRUE, TRUE, -1, -1 },
{ VBAInfoAtom, "VBAInfoAtom", FALSE, TRUE, -1, -1 },
{ SSDocInfoAtom, "SSDocInfoAtom", FALSE, TRUE, -1, -1 },
{ Summary, "Summary", TRUE, TRUE, -1, -1 },
{ DocRoutingSlip, "DocRoutingSlip", FALSE, TRUE, -1, -1 },
{ OutlineViewInfo, "OutlineViewInfo", TRUE, TRUE, -1, -1 },
{ SorterViewInfo, "SorterViewInfo", TRUE, TRUE, -1, -1 },
{ ExObjList, "ExObjList", TRUE, TRUE, -1, -1 },
{ ExObjListAtom, "ExObjListAtom", FALSE, TRUE, -1, -1 },
{ PPDrawingGroup, "PPDrawingGroup", TRUE, TRUE, -1, -1 }, //FIXME: Office Art File Format Docu
{ PPDrawing, "PPDrawing", TRUE, TRUE, -1, -1 }, //FIXME: Office Art File Format Docu
{ NamedShows, "NamedShows", FALSE, TRUE, -1, -1 }, // don't know if container
{ NamedShow, "NamedShow", TRUE, TRUE, -1, -1 },
{ NamedShowSlides, "NamedShowSlides", FALSE, TRUE, -1, -1 }, // don't know if container
{ List, "List", TRUE, TRUE, -1, -1 },
{ FontCollection, "FontCollection", TRUE, TRUE, -1, -1 },
{ BookmarkCollection, "BookmarkCollection", TRUE, TRUE, -1, -1 },
{ SoundCollAtom, "SoundCollAtom", FALSE, TRUE, -1, -1 },
{ Sound, "Sound", TRUE, TRUE, -1, -1 },
{ SoundData, "SoundData", FALSE, TRUE, -1, -1 },
{ BookmarkSeedAtom, "BookmarkSeedAtom", FALSE, TRUE, -1, -1 },
{ ColorSchemeAtom, "ColorSchemeAtom", FALSE, TRUE, -1, -1 },
{ ExObjRefAtom, "ExObjRefAtom", FALSE, TRUE, -1, -1 },
{ OEShapeAtom, "OEShapeAtom", FALSE, TRUE, -1, -1 },
{ OEPlaceholderAtom, "OEPlaceholderAtom", FALSE, TRUE, -1, -1 },
{ GPointAtom, "GPointAtom", FALSE, TRUE, -1, -1 },
{ GRatioAtom, "GRatioAtom", FALSE, TRUE, -1, -1 },
{ OutlineTextRefAtom, "OutlineTextRefAtom", FALSE, TRUE, -1, -1 },
{ TextHeaderAtom, "TextHeaderAtom", FALSE, TRUE, -1, -1 },
{ TextCharsAtom, "TextCharsAtom", FALSE, TRUE, -1, -1 },
{ StyleTextPropAtom, "StyleTextPropAtom", FALSE, TRUE, -1, -1 },
{ BaseTextPropAtom, "BaseTextPropAtom", FALSE, TRUE, -1, -1 },
{ TxMasterStyleAtom, "TxMasterStyleAtom", FALSE, TRUE, -1, -1 },
{ TxCFStyleAtom, "TxCFStyleAtom", FALSE, TRUE, -1, -1 },
{ TxPFStyleAtom, "TxPFStyleAtom", FALSE, TRUE, -1, -1 },
{ TextRulerAtom, "TextRulerAtom", FALSE, TRUE, -1, -1 },
{ TextBookmarkAtom, "TextBookmarkAtom", FALSE, TRUE, -1, -1 },
{ TextBytesAtom, "TextBytesAtom", FALSE, TRUE, -1, -1 },
{ TxSIStyleAtom, "TxSIStyleAtom", FALSE, TRUE, -1, -1 },
{ TextSpecInfoAtom, "TextSpecInfoAtom", FALSE, TRUE, -1, -1 },
{ DefaultRulerAtom, "DefaultRulerAtom", FALSE, TRUE, -1, -1 },
{ FontEntityAtom, "FontEntityAtom", FALSE, TRUE, -1, -1 },
{ FontEmbeddedData, "FontEmbeddedData", FALSE, TRUE, -1, -1 },
{ CString, "CString", FALSE, TRUE, -1, -1 },
{ MetaFile, "MetaFile", FALSE, TRUE, -1, -1 },
{ ExOleObjAtom, "ExOleObjAtom", FALSE, TRUE, -1, -1 },
{ SrKinsoku, "SrKinsoku", TRUE, TRUE, -1, -1 },
{ HandOut, "HandOut", TRUE, TRUE, -1, -1 },
{ ExEmbed, "ExEmbed", TRUE, TRUE, -1, -1 },
{ ExEmbedAtom, "ExEmbedAtom", FALSE, TRUE, -1, -1 },
{ ExLink, "ExLink", TRUE, TRUE, -1, -1 },
{ BookmarkEntityAtom, "BookmarkEntityAtom", FALSE, TRUE, -1, -1 },
{ ExLinkAtom, "ExLinkAtom", FALSE, TRUE, -1, -1 },
{ SrKinsokuAtom, "SrKinsokuAtom", FALSE, TRUE, -1, -1 },
{ ExHyperlinkAtom, "ExHyperlinkAtom", FALSE, TRUE, -1, -1 },
{ ExHyperlink, "ExHyperlink", TRUE, TRUE, -1, -1 },
{ SlideNumberMCAtom, "SlideNumberMCAtom", FALSE, TRUE, -1, -1 },
{ HeadersFooters, "HeadersFooters", TRUE, TRUE, -1, -1 },
{ HeadersFootersAtom, "HeadersFootersAtom", FALSE, TRUE, -1, -1 },
{ TxInteractiveInfoAtom, "TxInteractiveInfoAtom", FALSE, TRUE, -1, -1 },
{ CharFormatAtom, "CharFormatAtom", FALSE, TRUE, -1, -1 },
{ ParaFormatAtom, "ParaFormatAtom", FALSE, TRUE, -1, -1 },
{ RecolorInfoAtom, "RecolorInfoAtom", FALSE, TRUE, -1, -1 },
{ ExQuickTimeMovie, "ExQuickTimeMovie", TRUE, TRUE, -1, -1 },
{ ExQuickTimeMovieData, "ExQuickTimeMovieData", FALSE, TRUE, -1, -1 },
{ ExControl, "ExControl", TRUE, TRUE, -1, -1 },
{ SlideListWithText, "SlideListWithText", TRUE, TRUE, -1, -1 },
{ InteractiveInfo, "InteractiveInfo", TRUE, TRUE, -1, -1 },
{ InteractiveInfoAtom, "InteractiveInfoAtom", FALSE, TRUE, -1, -1 },
{ UserEditAtom, "UserEditAtom", FALSE, TRUE, -1, -1 },
{ CurrentUserAtom, "CurrentUserAtom", FALSE, TRUE, -1, -1 },
{ DateTimeMCAtom, "DateTimeMCAtom", FALSE, TRUE, -1, -1 },
{ GenericDateMCAtom, "GenericDateMCAtom", FALSE, TRUE, -1, -1 },
{ FooterMCAtom, "FooterMCAtom", FALSE, TRUE, -1, -1 },
{ ExControlAtom, "ExControlAtom", FALSE, TRUE, -1, -1 },
{ ExMediaAtom, "ExMediaAtom", FALSE, TRUE, -1, -1 },
{ ExVideo, "ExVideo", TRUE, TRUE, -1, -1 },
{ ExAviMovie, "ExAviMovie", TRUE, TRUE, -1, -1 },
{ ExMCIMovie, "ExMCIMovie", TRUE, TRUE, -1, -1 },
{ ExMIDIAudio, "ExMIDIAudio", TRUE, TRUE, -1, -1 },
{ ExCDAudio, "ExCDAudio", TRUE, TRUE, -1, -1 },
{ ExWAVAudioEmbedded, "ExWAVAudioEmbedded", TRUE, TRUE, -1, -1 },
{ ExWAVAudioLink, "ExWAVAudioLink", TRUE, TRUE, -1, -1 },
{ ExOleObjStg, "ExOleObjStg", FALSE, TRUE, -1, -1 },
{ ExCDAudioAtom, "ExCDAudioAtom", FALSE, TRUE, -1, -1 },
{ ExWAVAudioEmbeddedAtom, "ExWAVAudioEmbeddedAtom", FALSE, TRUE, -1, -1 },
{ AnimationInfoAtom, "AnimationInfoAtom", FALSE, TRUE, -1, -1 },
{ RTFDateTimeMCAtom, "RTFDateTimeMCAtom", FALSE, TRUE, -1, -1 },
{ ProgTags, "ProgTags", FALSE, TRUE, -1, -1 }, // don't know if container
{ ProgStringTag, "ProgStringTag", TRUE, TRUE, -1, -1 },
{ ProgBinaryTag, "ProgBinaryTag", TRUE, TRUE, -1, -1 },
{ BinaryTagData, "BinaryTagData", FALSE, TRUE, -1, -1 },
{ PrintOptions, "PrintOptions", FALSE, TRUE, -1, -1 },
{ PersistPtrFullBlock, "PersistPtrFullBlock", FALSE, TRUE, -1, -1 }, // don't know if container
{ PersistPtrIncrementalBlock, "PersistPtrIncrementalBlock", FALSE, TRUE, -1, -1 },
{ GScalingAtom, "GScalingAtom", FALSE, TRUE, -1, -1 },
{ GRColorAtom, "GRColorAtom", FALSE, TRUE, -1, -1 },
{ EscherDggContainer, "EscherDggContainer", TRUE, TRUE, -1, -1 },
{ EscherDgg, "EscherDgg", FALSE, TRUE, -1, -1 },
{ EscherCLSID, "EscherCLSID", FALSE, TRUE, -1, -1 },
{ EscherOPT, "EscherOPT", FALSE, TRUE, -1, -1 },
{ EscherBStoreContainer, "EscherBStoreContainer", TRUE, TRUE, -1, -1 },
{ EscherBSE, "EscherBSE", FALSE, TRUE, -1, -1 },
{ EscherBlip_START, "EscherBlip_START", FALSE, TRUE, -1, -1 },
{ EscherBlip_END, "EscherBlip_END", FALSE, TRUE, -1, -1 },
{ EscherDgContainer, "EscherDgContainer", TRUE, TRUE, -1, -1 },
{ EscherDg, "EscherDg", FALSE, TRUE, -1, -1 },
{ EscherRegroupItems, "EscherRegroupItems", FALSE, TRUE, -1, -1 },
{ EscherColorScheme, "EscherColorScheme", FALSE, TRUE, -1, -1 },
{ EscherSpgrContainer, "EscherSpgrContainer", TRUE, TRUE, -1, -1 },
{ EscherSpContainer, "EscherSpContainer", TRUE, TRUE, -1, -1 },
{ EscherSpgr, "EscherSpgr", FALSE, TRUE, -1, -1 },
{ EscherSp, "EscherSp", FALSE, TRUE, -1, -1 },
{ EscherTextbox, "EscherTextbox", FALSE, TRUE, -1, -1 },
{ EscherClientTextbox, "EscherClientTextbox", TRUE, TRUE, -1, -1 },
{ EscherAnchor, "EscherAnchor", FALSE, TRUE, -1, -1 },
{ EscherChildAnchor, "EscherChildAnchor", FALSE, TRUE, -1, -1 },
{ EscherClientAnchor, "EscherClientAnchor", FALSE, TRUE, -1, -1 },
{ EscherClientData, "EscherClientData", TRUE, TRUE, -1, -1 },
{ EscherSolverContainer, "EscherSolverContainer", TRUE, TRUE, -1, -1 },
{ EscherConnectorRule, "EscherConnectorRule", FALSE, TRUE, -1, -1 },
{ EscherAlignRule, "EscherAlignRule", FALSE, TRUE, -1, -1 },
{ EscherArcRule, "EscherArcRule", FALSE, TRUE, -1, -1 },
{ EscherClientRule, "EscherClientRule", FALSE, TRUE, -1, -1 },
{ EscherCalloutRule, "EscherCalloutRule", FALSE, TRUE, -1, -1 },
{ EscherSelection, "EscherSelection", FALSE, TRUE, -1, -1 },
{ EscherColorMRU, "EscherColorMRU", FALSE, TRUE, -1, -1 },
{ EscherDeletedPspl, "EscherDeletedPspl", FALSE, TRUE, -1, -1 },
{ EscherSplitMenuColors, "EscherSplitMenuColors", FALSE, TRUE, -1, -1 },
{ EscherOleObject, "EscherOleObject", FALSE, TRUE, -1, -1 },
{ EscherUserDefined, "EscherUserDefined", FALSE, TRUE, -1, -1 },
};
enum {
TEXT_FIELD_PROPERTY_EXISTS_BOLD = 0x00000001,
TEXT_FIELD_PROPERTY_EXISTS_ITALIC = 0x00000002,
TEXT_FIELD_PROPERTY_EXISTS_UNDERLINE = 0x00000004,
TEXT_FIELD_PROPERTY_EXISTS_SHADOW = 0x00000010,
TEXT_FIELD_PROPERTY_EXISTS_STRIKEOUT = 0x00000100,
TEXT_FIELD_PROPERTY_EXISTS_RELIEF = 0x00000200,
TEXT_FIELD_PROPERTY_EXISTS_RESET_NUMBERING = 0x00000400,
TEXT_FIELD_PROPERTY_EXISTS_ENABLE_NUMBERING1 = 0x00000800,
TEXT_FIELD_PROPERTY_EXISTS_ENABLE_NUMBERING2 = 0x00001000,
TEXT_FIELD_PROPERTY_EXISTS_FLAGS = 0x0000ffff,
TEXT_FIELD_PROPERTY_EXISTS_FONT = 0x00010000,
TEXT_FIELD_PROPERTY_EXISTS_FONT_SIZE = 0x00020000,
TEXT_FIELD_PROPERTY_EXISTS_COLOR = 0x00040000,
TEXT_FIELD_PROPERTY_EXISTS_OFFSET = 0x00080000,
TEXT_FIELD_PROPERTY_EXISTS_UNKNOWN1 = 0x00100000,
TEXT_FIELD_PROPERTY_EXISTS_ASIAN_OR_COMPLEX = 0x00200000,
TEXT_FIELD_PROPERTY_EXISTS_UNKNOWN2 = 0x00400000,
TEXT_FIELD_PROPERTY_EXISTS_SYMBOL = 0x00800000,
TEXT_FIELD_PROPERTY_EXISTS_UNKNOWN3 = 0x01000000,
TEXT_FIELD_PROPERTY_EXISTS_UNKNOWN4 = 0x02000000,
TEXT_FIELD_PROPERTY_EXISTS_UNKNOWN5 = 0x04000000,
TEXT_FIELD_PROPERTY_EXISTS_UNKNOWN6 = 0x08000000,
TEXT_FIELD_PROPERTY_EXISTS_UNKNOWN7 = 0x10000000,
TEXT_FIELD_PROPERTY_EXISTS_UNKNOWN8 = 0x20000000,
TEXT_FIELD_PROPERTY_EXISTS_UNKNOWN9 = 0x40000000,
TEXT_FIELD_PROPERTY_EXISTS_UNKNOWN10 = 0x80000000,
} TextFieldPropExists;
enum {
TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_BULLET_FLAGS = 0x0000000f,
TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_BULLET_CHARACTER = 0x00000080,
TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_BULLET_FAMILY = 0x00000010,
TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_BULLET_SIZE = 0x00000040,
TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_BULLET_COLOR = 0x00000020,
TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_ALIGNMENT = 0x00000800,
TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_UNKNOWN_1 = 0x00000400,
TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_UNKNOWN_2 = 0x00000200,
TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_UNKNOWN_3 = 0x00000100,
TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_LINE_FEED = 0x00001000,
TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_SPACING_ABOVE = 0x00002000,
TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_SPACING_BELOW = 0x00004000,
TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_UNKNOWN_4 = 0x00008000,
TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_UNKNOWN_5 = 0x00010000,
TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_ASIAN_UNKNOWN = 0x000e0000,
TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_BIDI = 0x00200000,
} TextFieldParagraphPropExists;
enum {
PARAGRAPH_ALIGNMENT_LEFT = 0,
PARAGRAPH_ALIGNMENT_CENTER = 1,
PARAGRAPH_ALIGNMENT_RIGHT = 2,
PARAGRAPH_ALIGNMENT_JUSTIFY = 3,
} ParagraphAlignment;
static const char *font[0x10000];
static int text_length;
static void
handle_atom (GOMSParserRecord *record, GSList *stack, const guint8 *data, GsfInput *input, GError **err, gpointer user_data)
{
guint pos = gsf_input_tell (input);
int i;
INDENT;
printf ("Atom %5d: %s, length 0x%hx (=%hd) @ pos = 0x%x (=%d) (vers=0x%x, inst=0x%x)\n",
record->opcode, record->type->name,
record->length, record->length, pos, pos, record->vers, record->inst);
// }
if (record->length > 0) {
int remain;
switch (record->opcode) {
case EscherClientAnchor:
g_print ("%d %d %d %d\n", (int) GSF_LE_GET_GUINT16 (data), (int) GSF_LE_GET_GUINT16 (data + 2), (int) GSF_LE_GET_GUINT16 (data + 4), (int) GSF_LE_GET_GUINT16 (data + 6));
break;
case EscherOPT:
{
int i;
guint complex_offset;
complex_offset = 6 * record->inst;
for (i = 0; i < record->inst; i++) {
int id = GSF_LE_GET_GUINT16 (data + i * 6);
gboolean is_bid = id & 0x4000;
gboolean is_complex = id & 0x8000;
guint32 opt_data = GSF_LE_GET_GUINT32 (data + i * 6 + 2);
id &= 0x3fff;
g_print ("Opt Id: %d, is_bid: %s, is_complex: %s, data: %d = 0x%x\n", id, is_bid ? "true" : "false", is_complex ? "true" : "false", opt_data, opt_data);
if (is_complex) {
gsf_mem_dump (data + complex_offset, opt_data);
}
if (is_complex) {
complex_offset += opt_data;
}
}
}
break;
case TextCharsAtom:
data = g_utf16_to_utf8 ((gunichar2 *) data, record->length / 2, NULL, NULL, NULL);
g_print (data);
g_print ("\n");
text_length = g_utf8_strlen (data, -1);
g_free ((char *) data);
break;
case TextBytesAtom:
data = g_convert (data, record->length, "utf8", "latin1", NULL, NULL, NULL);
g_print (data);
g_print ("\n");
text_length = g_utf8_strlen (data, -1);
g_free ((char *) data);
break;
case BaseTextPropAtom:
gsf_mem_dump (data, record->length);
remain = text_length + 1;
i = 0;
while (remain > 0) {
int section_length = GSF_LE_GET_GUINT32 (data + i);
printf ("length: %d\n", section_length);
remain -= section_length;
i += 4;
printf ("depth: %d\n", (guint32) GSF_LE_GET_GUINT16 (data + i));
i += 2;
}
break;
case TxMasterStyleAtom:
{
int indentation_levels;
int indentation_level;
guint i = 0;
guint lasti;
gboolean first = TRUE;
gsf_mem_dump (data, record->length);
indentation_levels = GSF_LE_GET_GUINT16 (data);
i += 2;
lasti = i;
if (record->inst >= 5) {
i += 2;
first = FALSE;
}
for (indentation_level = 0; indentation_level < indentation_levels; indentation_level ++) {
guint32 fields;
/* Paragraph Attributes */
fields = GSF_LE_GET_GUINT32 (data + i);
i += 4;
printf ("level: %d para fields: 0x%04x\n", indentation_level, fields);
if (fields & 0x000f)
printf ("Bullet Flags: 0x%02x Mask: 0x%02x\n", (int) GSF_LE_GET_GUINT16 (data + i), fields & 0x000f);
i += 2; /* Bullet Flags */
if (fields & 0x0080) {
printf ("Bullet Char: u+%x\n", (int) GSF_LE_GET_GUINT16 (data + i));
i += 2; /* Bullet Char */
}
if (fields & 0x0010) {
printf ("Bullet Font: %d=%s\n", (int) GSF_LE_GET_GUINT16 (data + i), font [GSF_LE_GET_GUINT16 (data + i)]);
i += 2; /* Bullet Font */
}
if (fields & 0x0040) {
printf ("Bullet Height: %d\n", (int) GSF_LE_GET_GUINT16 (data + i));
i += 2; /* Bullet Height */
}
if (fields & 0x0020) {
i += 4; /* Bullet Color */
}
if (first) {
if (fields & 0x0f00) {
printf ("Justification: %d\n", (int) (GSF_LE_GET_GUINT16 (data + i) & 3));
i += 2; /* Justification last 2 bits */
}
} else {
if (fields & 0x0800) {
printf ("Justification: %d\n", (int) (GSF_LE_GET_GUINT16 (data + i) & 3));
i += 2; /* Justification last 2 bits */
}
}
if (fields & 0x1000)
i += 2; /* line feed */
if (fields & 0x2000)
i += 2; /* upper dist */
if (fields & 0x4000)
i += 2; /* lower dist */
if (first) {
if (fields & 0x8000) {
printf ("Text Offset: %d\n", (int) GSF_LE_GET_GUINT16 (data + i));
i += 2; /* Text offset */
}
if (fields & 0x00010000) {
printf ("Bullet Offset: %d\n", (int) GSF_LE_GET_GUINT16 (data + i));
i += 2; /* Bullet offset */
}
if (fields & 0x00020000)
i += 2; /* Default tab */
if (fields & 0x00200000) {
guint tab_count = GSF_LE_GET_GUINT16 (data + i);
i += 2 + tab_count * 4; /* Tabs */
}
if (fields & 0x00040000)
i += 2; /* Unknown */
if (fields & 0x00080000)
i += 2; /* Asian Line Break */
if (fields & 0x00100000)
i += 2; /* bidi */
} else {
if (fields & 0x8000)
i += 2; /* Unknown */
if (fields & 0x0100) {
printf ("Text Offset: %d\n", (int) GSF_LE_GET_GUINT16 (data + i));
i += 2; /* Text offset */
}
if (fields & 0x0200)
i += 2; /* Unknown */
if (fields & 0x0400) {
printf ("Bullet Offset: %d\n", (int) GSF_LE_GET_GUINT16 (data + i));
i += 2; /* Bullet offset */
}
if (fields & 0x00010000)
i += 2; /* Unknown */
if (fields & 0x000e0000)
i += 2; /* Asian Line Break some bits. */
if (fields & 0x00100000) {
guint tab_count = GSF_LE_GET_GUINT16 (data + i);
i += 2 + tab_count * 4; /* Tabs */
}
if (fields & 0x00200000) {
i += 2;
}
}
/* Character Attributes */
fields = GSF_LE_GET_GUINT32 (data + i);
printf ("level: %d char fields: 0x%04x\n", indentation_level, fields);
i += 4;
if (fields & 0x0000ffff)
i += 2; /* Bit Field */
if (fields & 0x00010000) {
printf ("Font: %d=%s\n", (int) GSF_LE_GET_GUINT16 (data + i), font [GSF_LE_GET_GUINT16 (data + i)]);
i += 2; /* Font */
}
if (fields & 0x00200000)
i += 2; /* Asian or Complex Font */
if (fields & 0x00400000)
i += 2; /* Unknown */
if (fields & 0x00800000)
i += 2; /* Symbol */
if (fields & 0x00020000) {
printf ("Font size: %d\n", (int) GSF_LE_GET_GUINT16 (data + i));
i += 2;
}
if (fields & 0x00040000)
i += 4; /* Font Color */
if (fields & 0x00080000)
i += 2; /* Escapement */
if (fields & 0x00100000)
i += 2; /* Unknown */
if (i != lasti &&
i <= record->length) {
gsf_mem_dump (data + lasti, i - lasti);
lasti = i;
}
first = FALSE;
}
}
break;
case StyleTextPropAtom:
gsf_mem_dump (data, record->length);
remain = text_length + 1;
i = 0;
while (remain > 0) {
int sublen = 0;
guint fields;
int section_length = GSF_LE_GET_GUINT32 (data + i);
printf ("length: %d\n", section_length);
remain -= section_length;
sublen += 4;
printf ("indent level: %d\n", (int) GSF_LE_GET_GUINT16 (data + i + sublen));
sublen += 2;
fields = GSF_LE_GET_GUINT32 (data + i + sublen);
printf ("para fields: 0x%04x\n", fields);
sublen += 4;
if (fields & TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_BULLET_FLAGS) {
sublen += 2;
}
if (fields & TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_BULLET_CHARACTER) {
sublen += 2;
}
if (fields & TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_BULLET_FAMILY) {
sublen += 2;
}
if (fields & TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_BULLET_SIZE) {
sublen += 2;
}
if (fields & TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_BULLET_COLOR) {
sublen += 4;
}
if (fields & TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_ALIGNMENT) {
printf ("Alignment: ");
switch (GSF_LE_GET_GUINT16 (data + i + sublen)) {
case PARAGRAPH_ALIGNMENT_LEFT:
printf ("Left");
break;
case PARAGRAPH_ALIGNMENT_CENTER:
printf ("Center");
break;
case PARAGRAPH_ALIGNMENT_RIGHT:
printf ("Right");
break;
case PARAGRAPH_ALIGNMENT_JUSTIFY:
printf ("Justify");
break;
}
printf ("\n");
sublen += 2;
}
if (fields & TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_UNKNOWN_1) {
sublen += 2;
}
if (fields & TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_UNKNOWN_2) {
sublen += 2;
}
if (fields & TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_UNKNOWN_3) {
sublen += 2;
}
if (fields & TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_LINE_FEED) {
sublen += 2;
}
if (fields & TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_SPACING_ABOVE) {
int space;
space = GSF_LE_GET_GUINT16 (data + i + sublen);
if (space & 0x8000) {
space = 0x10000 - space;
}
printf ("space_before: %.3f\"\n", space / 576.0);
sublen += 2;
}
if (fields & TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_SPACING_BELOW) {
int space;
space = GSF_LE_GET_GUINT16 (data + i + sublen);
if (space & 0x8000) {
space = 0x10000 - space;
}
printf ("space_after: %.3f\"\n", space / 576.0);
sublen += 2;
}
if (fields & TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_UNKNOWN_4)
sublen += 2;
if (fields & TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_UNKNOWN_5)
sublen += 2;
if (fields & TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_ASIAN_UNKNOWN)
sublen += 2;
if (fields & TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_BIDI)
sublen += 2;
gsf_mem_dump (data + i, sublen);
i += sublen;
}
remain = text_length + 1;
while (remain > 0) {
int sublen = 0;
guint fields;
int section_length = GSF_LE_GET_GUINT32 (data + i);
printf ("length: %d\n", section_length);
remain -= section_length;
sublen += 4;
fields = GSF_LE_GET_GUINT32 (data + i + sublen);
printf ("char fields: 0x%04x\n", fields);
sublen += 4;
if (fields & TEXT_FIELD_PROPERTY_EXISTS_FLAGS) {
guint text_fields = GSF_LE_GET_GUINT16 (data + i + sublen);
if (text_fields & 0x1)
printf ("bold\n");
if (text_fields & 0x2)
printf ("italic\n");
if (text_fields & 0x4)
printf ("underline\n");
if (text_fields & 0x10)
printf ("shadow\n");
if (text_fields & 0x200)
printf ("relief\n");
sublen += 2;
}
if (fields & TEXT_FIELD_PROPERTY_EXISTS_FONT) {
printf ("Font: %d=%s\n", (int) GSF_LE_GET_GUINT16 (data + i + sublen), font [GSF_LE_GET_GUINT16 (data + i + sublen)]);
sublen += 2;
}
if (fields & TEXT_FIELD_PROPERTY_EXISTS_ASIAN_OR_COMPLEX)
sublen += 2;
if (fields & TEXT_FIELD_PROPERTY_EXISTS_UNKNOWN2)
sublen += 2;
if (fields & TEXT_FIELD_PROPERTY_EXISTS_SYMBOL)
sublen += 2;
if (fields & TEXT_FIELD_PROPERTY_EXISTS_FONT_SIZE) {
printf ("Font size: %d\n", GSF_LE_GET_GUINT16 (data + i + sublen));
sublen += 2;
}
if (fields & (TEXT_FIELD_PROPERTY_EXISTS_COLOR)) {
printf ("color: #");
printf ("%02X", data[i + sublen++]);
printf ("%02X", data[i + sublen++]);
printf ("%02X", data[i + sublen++]);
printf ("\n");
sublen ++;
}
if (fields & TEXT_FIELD_PROPERTY_EXISTS_OFFSET) {
int offset = GSF_LE_GET_GUINT16 (data + i + sublen - 2);
if (offset & 0x8000)
offset -= 0x10000;
printf ("offset: %d\n", offset);
sublen += 2;
}
if (fields & TEXT_FIELD_PROPERTY_EXISTS_UNKNOWN1)
sublen += 2;
if (fields & TEXT_FIELD_PROPERTY_EXISTS_UNKNOWN3)
sublen += 2;
if (fields & TEXT_FIELD_PROPERTY_EXISTS_UNKNOWN4)
sublen += 2;
if (fields & TEXT_FIELD_PROPERTY_EXISTS_UNKNOWN5)
sublen += 2;
if (fields & TEXT_FIELD_PROPERTY_EXISTS_UNKNOWN6)
sublen += 2;
if (fields & TEXT_FIELD_PROPERTY_EXISTS_UNKNOWN7)
sublen += 2;
if (fields & TEXT_FIELD_PROPERTY_EXISTS_UNKNOWN8)
sublen += 2;
if (fields & TEXT_FIELD_PROPERTY_EXISTS_UNKNOWN9)
sublen += 2;
if (fields & TEXT_FIELD_PROPERTY_EXISTS_UNKNOWN10)
sublen += 2;
gsf_mem_dump (data + i, sublen);
i += sublen;
}
break;
case FontEntityAtom:
font[record->inst] = g_utf16_to_utf8 ((gunichar2 *) data, record->length / 2, NULL, NULL, NULL);
printf ("Font %d = %s\n", record->inst, font[record->inst]);
break;
case SlideAtom:
if (record->length > 0) {
if (data == NULL) {
data = gsf_input_read (input, record->length, NULL);
}
gsf_mem_dump (data, record->length);
}
printf ("geometry: %d\n", GSF_LE_GET_GINT32 (data));
printf ("PlaceholderIDs: ");
for (i = 0; i < 8; i++) {
printf ("%d ", GSF_LE_GET_GUINT8 (data + 4 + i));
}
printf ("\n");
printf ("masterID: %d\n", GSF_LE_GET_GINT32 (data + 12));
printf ("notesID: %d\n", GSF_LE_GET_GINT32 (data + 16));
printf ("flags: %d\n", GSF_LE_GET_GUINT16 (data + 20));
break;
default:
if (record->length > 0) {
if (data == NULL) {
data = gsf_input_read (input, record->length, NULL);
}
gsf_mem_dump (data, record->length);
}
break;
}
}
}
static void
start_container (GSList *stack, GsfInput *input, GError **err, gpointer user_data)
{
guint pos = gsf_input_tell (input);
INDENT;
printf ("Cont %5d: %s, length 0x%hx (=%hd) @ pos = 0x%x (=%d) (vers=0x%x, inst=0x%x)\n",
STACK_TOP->opcode, STACK_TOP->type->name,
STACK_TOP->length, STACK_TOP->length, pos, pos, STACK_TOP->vers, STACK_TOP->inst);
recursion_depth++;
}
static void
end_container (GSList *stack, GsfInput *input, GError **err, gpointer user_data)
{
recursion_depth--;
}
static GOMSParserCallbacks callbacks = { handle_atom,
start_container,
end_container };
static int
test (unsigned argc, char *argv[])
{
GsfInput *input, *stream;
GsfInfile *infile;
GError *err = NULL;
unsigned i;
for (i = 0; i < 0x10000; i++) {
font[i] = "Unknown";
}
for (i = 1 ; i < argc ; i++) {
g_print ("%s\n",argv[i]);
input = gsf_input_mmap_new (argv[i], &err);
if (input == NULL) {
g_return_val_if_fail (err != NULL, 1);
g_warning ("'%s' error: %s", argv[i], err->message);
g_error_free (err);
continue;
}
input = gsf_input_uncompress (input);
infile = gsf_infile_msole_new (input, &err);
#if 0
stream = gsf_infile_child_by_name (infile, "\01CompObj");
if (stream != NULL) {
gsf_off_t len = gsf_input_size (stream);
guint8 const *data = gsf_input_read (stream, len, NULL);
if (data != NULL)
gsf_mem_dump (data, len);
g_object_unref (G_OBJECT (stream));
}
return 0;
#endif
#if 0
stream = gsf_infile_child_by_name (infile, "\05SummaryInformation");
if (stream != NULL) {
puts ( "SummaryInfo");
gsf_msole_metadata_read (stream, &err);
if (err != NULL)
g_warning ("'%s' error: %s", argv[i], err->message);
g_object_unref (G_OBJECT (stream));
}
stream = gsf_infile_child_by_name (infile, "\05DocumentSummaryInformation");
if (stream != NULL) {
puts ( "DocSummaryInfo");
gsf_msole_metadata_read (stream, &err);
if (err != NULL)
g_warning ("'%s' error: %s", argv[i], err->message);
g_object_unref (G_OBJECT (stream));
}
#endif
stream = gsf_infile_child_by_name (infile, "PowerPoint Document");
if (stream != NULL) {
g_print ("PowerPoint Document\n");
go_ms_parser_read (stream,
gsf_input_remaining (stream),
types,
(sizeof (types) / sizeof (types[0])),
&callbacks,
NULL,
NULL);
g_object_unref (G_OBJECT (stream));
}
stream = gsf_infile_child_by_name (infile, "Pictures");
if (stream != NULL) {
g_print ("Pictures\n");
go_ms_parser_read (stream,
gsf_input_remaining (stream),
types,
(sizeof (types) / sizeof (types[0])),
&callbacks,
NULL,
NULL);
g_object_unref (G_OBJECT (stream));
}
g_object_unref (G_OBJECT (infile));
g_object_unref (G_OBJECT (input));
}
return 0;
}
int
main (int argc, char *argv[])
{
int res;
gsf_init ();
res = test (argc, argv);
gsf_shutdown ();
return res;
}
syntax highlighted by Code2HTML, v. 0.9.1