xref: /haiku/src/apps/cortex/Persistence/ExportContext.h (revision e81a954787e50e56a7f06f72705b7859b6ab06d1)
1 /*
2  * Copyright (c) 1999-2000, Eric Moon.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions, and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions, and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * 3. The name of the author may not be used to endorse or promote products
17  *    derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21  * OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
23  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
27  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 
32 // ExportContext.h
33 // * PURPOSE
34 //   Describe the state of a serialization ('save') operation.
35 //   The 'load' equivalent is ImportContext.
36 //
37 // * HISTORY
38 //   e.moon		28jun99		Begun
39 
40 #ifndef __ExportContext_H__
41 #define __ExportContext_H__
42 
43 #include <Debug.h>
44 
45 #include <String.h>
46 #include <iostream>
47 
48 #include <list>
49 #include <utility>
50 
51 #include "cortex_defs.h"
52 __BEGIN_CORTEX_NAMESPACE
53 
54 class BDataIO;
55 class IPersistent;
56 class ExportContext;
57 
58 // writeAttr() helper
59 inline BString& _pad_with_spaces(BString& out, const char* text,
60 	ExportContext& context, uint16 column);
61 
62 
63 class ExportContext {
64 public:
65 	ExportContext();
66 	ExportContext(BDataIO* stream);
67 	virtual ~ExportContext();
68 
69 	// the output stream
70 	BDataIO* stream;
71 
72 	// the element stack
73 	struct element_entry {
74 		element_entry() : hasAttributes(false), hasContent(false) {}
75 
76 		BString	name;
77 		bool	hasAttributes;
78 		bool	hasContent;
79 	};
80 
81 	typedef std::list<element_entry> element_list;
82 	element_list m_elementStack;
83 
84 public:													// *** XML formatting helpers
85 
86 	// writes a start tag.  should be called from
87 	// IPersistent::xmlExportBegin()
88 	// (or xmlExportContent(), if you're writing nested elements)
89 
90 	void beginElement(const char* name);
91 
92 	// writes an end tag corresponding to the current element.
93 	// should only be called from IPersistent::xmlExportEnd() or
94 	// xmlExportContent().
95 	void endElement();
96 
97 	// indicates that content follows (writes the end of the
98 	// current element's start tag.)
99 	void beginContent();
100 
101 //	// writes an attribute.
102 //	// should only be called from IPersistent::xmlExportAttributes().
103 //	template <class T>
104 //	void writeAttr(
105 //		const char*									key,
106 //		T														value) {
107 //
108 //		if(!m_objectStack.size()) {
109 //			reportError("writeAttr(): no object being written.\n");
110 //			return;
111 //		}
112 //		ASSERT(m_elementStack.size());
113 //		if(m_state != WRITE_ATTRIBUTES &&
114 //			m_state != WRITE_CONTENT) {
115 //			reportError("writeAttr(): not allowed (state mismatch).\n");
116 //			return;
117 //		}
118 //
119 //		m_elementStack.back().hasAttributes = true;
120 //
121 //		BString out;
122 //		out << "\n" << indentString() << key;
123 //		_pad_with_spaces(out, key, *this, m_attrColumn) << " = '" << value << '\'';
124 //
125 //		writeString(out);
126 //	}
127 
128 	// [e.moon 22dec99]
129 	// non-template forms of writeAttr()
130 
131 	void writeAttr(
132 		const char*									key,
133 		int8												value);
134 
135 	void writeAttr(
136 		const char*									key,
137 		uint8												value);
138 
139 	void writeAttr(
140 		const char*									key,
141 		int16												value);
142 
143 	void writeAttr(
144 		const char*									key,
145 		uint16											value);
146 
147 	void writeAttr(
148 		const char*									key,
149 		int32												value);
150 
151 	void writeAttr(
152 		const char*									key,
153 		uint32											value);
154 
155 	void writeAttr(
156 		const char*									key,
157 		int64												value);
158 
159 	void writeAttr(
160 		const char*									key,
161 		uint64											value);
162 
163 	void writeAttr(
164 		const char*									key,
165 		const char*									value);
166 
167 	void writeAttr(
168 		const char*									key,
169 		const BString&							value);
170 
171 	void writeAttr(
172 		const char*									key,
173 		float												value);
174 
175 	// writes a child object.
176 	// should only be called from IPersistent::xmlExportContent().
177 	// returns B_OK on success, or B_ERROR if an error occurred.
178 	status_t writeObject(
179 		IPersistent*								object);
180 
181 	// writes an arbitrary string to the stream (calls reportError()
182 	// on failure.)
183 	status_t writeString(
184 		const BString&							string);
185 
186 	status_t writeString(
187 		const char*									data,
188 		ssize_t											length);
189 
190 public:													// *** indentation helpers
191 
192 	// return a string padded with spaces to the current
193 	// indent level
194 	const char* indentString() const;
195 
196 	// return the current indent level
197 	uint16 indentLevel() const;
198 
199 	// decrease the indent level
200 	void indentLess();
201 
202 	// increase the indent level
203 	void indentMore();
204 
205 	// +++++ extra formatting controls needed [e.moon 1dec99]
206 	// * attrColumn access
207 	// * single vs. multi-line element formatting
208 
209 
210 public:													// *** error operations
211 
212 	// register a fatal error; halts the write process
213 	// as soon as possible.
214 	void reportError(
215 		const char*									text);
216 
217 	// fetch error text
218 	const char* errorText() const { return m_error.String(); }
219 
220 private:				// members
221 
222 	// * Indentation/formatting
223 
224 	uint16												m_indentLevel;
225 	uint16												m_indentIncrement;
226 
227 	uint16												m_attrColumn;
228 
229 	BString												m_indentString;
230 
231 	// * State
232 
233 	enum state_t {
234 		INIT,
235 		WRITE_BEGIN,
236 		WRITE_ATTRIBUTES,
237 		WRITE_CONTENT,
238 		WRITE_END,
239 		ABORT
240 	};
241 
242 	state_t												m_state;
243 	BString												m_error;
244 
245 	// object stack
246 
247 	struct object_entry {
248 		object_entry() : element(0), object(0) {}
249 
250 		const char*		element;
251 		IPersistent*	object;
252 	};
253 
254 	typedef std::list<object_entry> object_list;
255 	object_list										m_objectStack;
256 
257 private:
258 	void _dumpElementStack(
259 		BString&										out);
260 };
261 
262 // ExportContext::writeAttr() helper
263 inline BString& _pad_with_spaces(
264 	BString&											out,
265 	const char*										text,
266 	ExportContext&								context,
267 	uint16												column) {
268 
269 	int16 spaces = column - (strlen(text) + context.indentLevel());
270 	if(spaces < 0) spaces = 0;
271 	while(spaces--) out << ' ';
272 	return out;
273 }
274 
275 __END_CORTEX_NAMESPACE
276 
277 #endif /*__ExportContext_H__*/
278