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