1 // ExportContext.h 2 // * PURPOSE 3 // Describe the state of a serialization ('save') operation. 4 // The 'load' equivalent is ImportContext. 5 // 6 // * HISTORY 7 // e.moon 28jun99 Begun 8 9 #ifndef __ExportContext_H__ 10 #define __ExportContext_H__ 11 12 #include <Debug.h> 13 14 #include <String.h> 15 #include <ostream.h> 16 17 #include <list> 18 #include <utility> 19 20 #include "cortex_defs.h" 21 __BEGIN_CORTEX_NAMESPACE 22 23 class BDataIO; 24 class IPersistent; 25 class ExportContext; 26 27 // writeAttr() helper 28 inline BString& _pad_with_spaces(BString& out, const char* text, 29 ExportContext& context, uint16 column); 30 31 32 class ExportContext { 33 public: 34 ExportContext(); 35 ExportContext(BDataIO* stream); 36 virtual ~ExportContext(); 37 38 // the output stream 39 BDataIO* stream; 40 41 // the element stack 42 struct element_entry { 43 element_entry() : hasAttributes(false), hasContent(false) {} 44 45 BString name; 46 bool hasAttributes; 47 bool hasContent; 48 }; 49 50 typedef std::list<element_entry> element_list; 51 element_list m_elementStack; 52 53 public: // *** XML formatting helpers 54 55 // writes a start tag. should be called from 56 // IPersistent::xmlExportBegin() 57 // (or xmlExportContent(), if you're writing nested elements) 58 59 void beginElement(const char* name); 60 61 // writes an end tag corresponding to the current element. 62 // should only be called from IPersistent::xmlExportEnd() or 63 // xmlExportContent(). 64 void endElement(); 65 66 // indicates that content follows (writes the end of the 67 // current element's start tag.) 68 void beginContent(); 69 70 // // writes an attribute. 71 // // should only be called from IPersistent::xmlExportAttributes(). 72 // template <class T> 73 // void writeAttr( 74 // const char* key, 75 // T value) { 76 // 77 // if(!m_objectStack.size()) { 78 // reportError("writeAttr(): no object being written.\n"); 79 // return; 80 // } 81 // ASSERT(m_elementStack.size()); 82 // if(m_state != WRITE_ATTRIBUTES && 83 // m_state != WRITE_CONTENT) { 84 // reportError("writeAttr(): not allowed (state mismatch).\n"); 85 // return; 86 // } 87 // 88 // m_elementStack.back().hasAttributes = true; 89 // 90 // BString out; 91 // out << "\n" << indentString() << key; 92 // _pad_with_spaces(out, key, *this, m_attrColumn) << " = '" << value << '\''; 93 // 94 // writeString(out); 95 // } 96 97 // [e.moon 22dec99] 98 // non-template forms of writeAttr() 99 100 #if B_BEOS_VERSION > B_BEOS_VERSION_4_5 101 void writeAttr( 102 const char* key, 103 int8 value); 104 105 void writeAttr( 106 const char* key, 107 uint8 value); 108 109 void writeAttr( 110 const char* key, 111 int16 value); 112 113 void writeAttr( 114 const char* key, 115 uint16 value); 116 #endif 117 118 void writeAttr( 119 const char* key, 120 int32 value); 121 122 void writeAttr( 123 const char* key, 124 uint32 value); 125 126 void writeAttr( 127 const char* key, 128 int64 value); 129 130 void writeAttr( 131 const char* key, 132 uint64 value); 133 134 void writeAttr( 135 const char* key, 136 const char* value); 137 138 void writeAttr( 139 const char* key, 140 const BString& value); 141 142 void writeAttr( 143 const char* key, 144 float value); 145 146 // writes a child object. 147 // should only be called from IPersistent::xmlExportContent(). 148 // returns B_OK on success, or B_ERROR if an error occurred. 149 status_t writeObject( 150 IPersistent* object); 151 152 // writes an arbitrary string to the stream (calls reportError() 153 // on failure.) 154 status_t writeString( 155 const BString& string); 156 157 status_t writeString( 158 const char* data, 159 ssize_t length); 160 161 public: // *** indentation helpers 162 163 // return a string padded with spaces to the current 164 // indent level 165 const char* indentString() const; 166 167 // return the current indent level 168 uint16 indentLevel() const; 169 170 // decrease the indent level 171 void indentLess(); 172 173 // increase the indent level 174 void indentMore(); 175 176 // +++++ extra formatting controls needed [e.moon 1dec99] 177 // * attrColumn access 178 // * single vs. multi-line element formatting 179 180 181 public: // *** error operations 182 183 // register a fatal error; halts the write process 184 // as soon as possible. 185 void reportError( 186 const char* text); 187 188 // fetch error text 189 const char* errorText() const { return m_error.String(); } 190 191 private: // members 192 193 // * Indentation/formatting 194 195 uint16 m_indentLevel; 196 uint16 m_indentIncrement; 197 198 uint16 m_attrColumn; 199 200 BString m_indentString; 201 202 // * State 203 204 enum state_t { 205 INIT, 206 WRITE_BEGIN, 207 WRITE_ATTRIBUTES, 208 WRITE_CONTENT, 209 WRITE_END, 210 ABORT 211 }; 212 213 state_t m_state; 214 BString m_error; 215 216 // object stack 217 218 struct object_entry { 219 object_entry() : element(0), object(0) {} 220 221 const char* element; 222 IPersistent* object; 223 }; 224 225 typedef std::list<object_entry> object_list; 226 object_list m_objectStack; 227 228 private: 229 void _dumpElementStack( 230 BString& out); 231 }; 232 233 // ExportContext::writeAttr() helper 234 inline BString& _pad_with_spaces( 235 BString& out, 236 const char* text, 237 ExportContext& context, 238 uint16 column) { 239 240 int16 spaces = column - (strlen(text) + context.indentLevel()); 241 if(spaces < 0) spaces = 0; 242 while(spaces--) out << ' '; 243 return out; 244 } 245 246 __END_CORTEX_NAMESPACE 247 248 #endif /*__ExportContext_H__*/ 249