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 #if B_BEOS_VERSION > B_BEOS_VERSION_4_5 132 void writeAttr( 133 const char* key, 134 int8 value); 135 136 void writeAttr( 137 const char* key, 138 uint8 value); 139 140 void writeAttr( 141 const char* key, 142 int16 value); 143 144 void writeAttr( 145 const char* key, 146 uint16 value); 147 #endif 148 149 void writeAttr( 150 const char* key, 151 int32 value); 152 153 void writeAttr( 154 const char* key, 155 uint32 value); 156 157 void writeAttr( 158 const char* key, 159 int64 value); 160 161 void writeAttr( 162 const char* key, 163 uint64 value); 164 165 void writeAttr( 166 const char* key, 167 const char* value); 168 169 void writeAttr( 170 const char* key, 171 const BString& value); 172 173 void writeAttr( 174 const char* key, 175 float value); 176 177 // writes a child object. 178 // should only be called from IPersistent::xmlExportContent(). 179 // returns B_OK on success, or B_ERROR if an error occurred. 180 status_t writeObject( 181 IPersistent* object); 182 183 // writes an arbitrary string to the stream (calls reportError() 184 // on failure.) 185 status_t writeString( 186 const BString& string); 187 188 status_t writeString( 189 const char* data, 190 ssize_t length); 191 192 public: // *** indentation helpers 193 194 // return a string padded with spaces to the current 195 // indent level 196 const char* indentString() const; 197 198 // return the current indent level 199 uint16 indentLevel() const; 200 201 // decrease the indent level 202 void indentLess(); 203 204 // increase the indent level 205 void indentMore(); 206 207 // +++++ extra formatting controls needed [e.moon 1dec99] 208 // * attrColumn access 209 // * single vs. multi-line element formatting 210 211 212 public: // *** error operations 213 214 // register a fatal error; halts the write process 215 // as soon as possible. 216 void reportError( 217 const char* text); 218 219 // fetch error text 220 const char* errorText() const { return m_error.String(); } 221 222 private: // members 223 224 // * Indentation/formatting 225 226 uint16 m_indentLevel; 227 uint16 m_indentIncrement; 228 229 uint16 m_attrColumn; 230 231 BString m_indentString; 232 233 // * State 234 235 enum state_t { 236 INIT, 237 WRITE_BEGIN, 238 WRITE_ATTRIBUTES, 239 WRITE_CONTENT, 240 WRITE_END, 241 ABORT 242 }; 243 244 state_t m_state; 245 BString m_error; 246 247 // object stack 248 249 struct object_entry { 250 object_entry() : element(0), object(0) {} 251 252 const char* element; 253 IPersistent* object; 254 }; 255 256 typedef std::list<object_entry> object_list; 257 object_list m_objectStack; 258 259 private: 260 void _dumpElementStack( 261 BString& out); 262 }; 263 264 // ExportContext::writeAttr() helper 265 inline BString& _pad_with_spaces( 266 BString& out, 267 const char* text, 268 ExportContext& context, 269 uint16 column) { 270 271 int16 spaces = column - (strlen(text) + context.indentLevel()); 272 if(spaces < 0) spaces = 0; 273 while(spaces--) out << ' '; 274 return out; 275 } 276 277 __END_CORTEX_NAMESPACE 278 279 #endif /*__ExportContext_H__*/ 280