1/*
2 * Copyright 2004-2005, Axel D��rfler, axeld@pinc-software.de. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef RTF_H
6#define RTF_H
7
8
9#include "Stack.h"
10
11#include <List.h>
12#include <String.h>
13#include <GraphicsDefs.h>
14#include <BufferIO.h>
15
16
17namespace RTF {
18
19class Group;
20class Header;
21class Command;
22
23static const size_t kCommandLength = 32;
24
25enum group_destination {
26	TEXT_DESTINATION,
27	COMMENT_DESTINATION,
28	OTHER_DESTINATION,
29
30	ALL_DESTINATIONS = 255
31};
32
33
34class Parser {
35	public:
36		Parser(BPositionIO &stream);
37
38		status_t Identify();
39		status_t Parse(RTF::Header &header);
40
41	private:
42		BBufferIO	fStream;
43		bool		fIdentified;
44};
45
46
47class Element {
48	public:
49		Element();
50		virtual ~Element();
51
52		void SetParent(Group *parent);
53		Group *Parent() const;
54
55		virtual bool IsDefinitionDelimiter();
56		virtual void Parse(char first, BDataIO &stream, char &last) = 0;
57		virtual void PrintToStream(int32 level = 0);
58
59	private:
60		Group	*fParent;
61};
62
63
64class Group : public Element {
65	public:
66		Group();
67		virtual ~Group();
68
69		status_t AddElement(RTF::Element *element);
70		uint32 CountElements() const;
71		Element *ElementAt(uint32 index) const;
72
73		Element *FindDefinitionStart(int32 index, int32 *_startIndex = NULL) const;
74		Command *FindDefinition(const char *name, int32 index = 0) const;
75		Group *FindGroup(const char *name) const;
76
77		const char *Name() const;
78
79		void DetermineDestination();
80		group_destination Destination() const;
81
82		virtual void Parse(char first, BDataIO &stream, char &last);
83
84	protected:
85		BList				fElements;
86		group_destination	fDestination;
87};
88
89class Header : public Group {
90	public:
91		Header();
92		virtual ~Header();
93
94		int32 Version() const;
95		const char *Charset() const;
96
97		rgb_color Color(int32 index);
98
99		virtual void Parse(char first, BDataIO &stream, char &last);
100
101	private:
102		int32				fVersion;
103
104};
105
106class Text : public Element {
107	public:
108		Text();
109		virtual ~Text();
110
111		status_t SetTo(const char *text);
112		const char *String() const;
113		uint32 Length() const;
114
115		virtual bool IsDefinitionDelimiter();
116		virtual void Parse(char first, BDataIO &stream, char &last);
117
118	private:
119		BString				fText;
120};
121
122class Command : public Element {
123	public:
124		Command();
125		virtual ~Command();
126
127		status_t SetName(const char *name);
128		const char *Name();
129
130		void UnsetOption();
131		void SetOption(int32 option);
132		bool HasOption() const;
133		int32 Option() const;
134
135		virtual void Parse(char first, BDataIO &stream, char &last);
136
137	private:
138		BString				fName;
139		bool				fHasOption;
140		int32				fOption;
141};
142
143//---------------------------------
144
145class Iterator {
146	public:
147		Iterator(Element &start, group_destination destination = ALL_DESTINATIONS);
148
149		void SetTo(Element &start, group_destination destination = ALL_DESTINATIONS);
150		void Rewind();
151
152		bool HasNext() const;
153		Element *Next();
154
155	private:
156		Element				*fStart;
157		Stack<Element *>	fStack;
158		group_destination	fDestination;
159};
160
161class Worker {
162	public:
163		Worker(RTF::Header &start);
164		virtual ~Worker();
165
166		void Work();
167
168	protected:
169		virtual void Group(RTF::Group *group);
170		virtual void GroupEnd(RTF::Group *group);
171		virtual void Command(RTF::Command *command);
172		virtual void Text(RTF::Text *text);
173
174		RTF::Header &Start();
175		void Skip();
176		void Abort(status_t status);
177
178	private:
179		void Dispatch(RTF::Element *element);
180
181		RTF::Header	&fStart;
182		bool		fSkip;
183};
184
185}	// namespace RTF
186
187#endif	/* RTF_H */
188