|
yast2-core
|
00001 /*---------------------------------------------------------------------\ 00002 | | 00003 | __ __ ____ _____ ____ | 00004 | \ \ / /_ _/ ___|_ _|___ \ | 00005 | \ V / _` \___ \ | | __) | | 00006 | | | (_| |___) || | / __/ | 00007 | |_|\__,_|____/ |_| |_____| | 00008 | | 00009 | core system | 00010 | (C) SuSE GmbH | 00011 \----------------------------------------------------------------------/ 00012 00013 File: YCPElement.h 00014 00015 Author: Mathias Kettner <kettner@suse.de> 00016 Maintainer: Klaus Kaempf <kkaempf@suse.de> 00017 00018 /-*/ 00019 // -*- c++ -*- 00020 00021 #ifndef YCPElement_h 00022 #define YCPElement_h 00023 00024 // MemUsage.h defines/undefines D_MEMUSAGE 00025 #include <y2util/MemUsage.h> 00026 00027 // include only forward declarations of iostream 00028 #include <iosfwd> 00029 #include <string> 00030 #include <vector> 00031 #include <map> 00032 00033 using std::string; 00034 using std::vector; 00035 using std::map; 00036 using std::pair; 00037 00038 #include "toString.h" 00039 00040 // forward declarations 00041 00042 class YCPElement; 00043 class YCPValue; 00044 class YCPVoid; 00045 class YCPBoolean; 00046 class YCPInteger; 00047 class YCPFloat; 00048 class YCPString; 00049 class YCPByteblock; 00050 class YCPPath; 00051 class YCPSymbol; 00052 class YCPLocale; 00053 class YCPList; 00054 class YCPTerm; 00055 class YCPMap; 00056 class YCPBuiltin; 00057 class YCPCode; 00058 class YCPEntry; 00059 class YCPReference; 00060 class YCPExternal; 00061 00062 00063 #define DEF_OPS(name) \ 00064 public: \ 00065 const YCP##name##Rep *operator ->() const { \ 00066 return static_cast<const YCP##name##Rep *>(element); } \ 00067 YCP##name##Rep *operator ->() { \ 00068 return const_cast<YCP##name##Rep *>( \ 00069 static_cast<const YCP##name##Rep *>(element)); } \ 00070 private: \ 00071 int operator !() const; \ 00072 int operator ==(const YCPElement &) const; 00073 00074 00075 #ifdef D_MEMUSAGE 00076 #define DEF_MEMSIZE(name) \ 00077 virtual size_t mem_size () const { return sizeof (YCP##name); } 00078 #else 00079 #define DEF_MEMSIZE(name) 00080 #endif 00081 00082 #define DEF_COMMON(name, base) \ 00083 DEF_OPS(name) \ 00084 friend class YCP##base##Rep; \ 00085 public: \ 00086 DEF_MEMSIZE(name) \ 00087 YCP##name(const YCPNull &n) : YCP##base(n) {} \ 00088 protected: \ 00089 YCP##name (const YCP##name##Rep *x) : YCP##base(x) {} 00090 00091 00092 #define DEF_COW_OPS(name) \ 00093 public: \ 00094 const YCP##name *operator ->() const { \ 00095 return static_cast<const YCP##name *>(this); } \ 00096 YCP##name *operator ->() { \ 00097 return const_cast<YCP##name *>( \ 00098 static_cast<const YCP##name *>(this)); } \ 00099 private: \ 00100 int operator !() const; \ 00101 int operator ==(const YCPElement &) const; 00102 00103 #define DEF_COW_COMMON(name, base) \ 00104 friend class YCP##base##Rep; \ 00105 DEF_COW_OPS(name) \ 00106 public: \ 00107 YCP##name(const YCPNull &n) : YCP##base(n) {} \ 00108 protected: \ 00109 YCP##name (const YCP##name##Rep *x) : YCP##base(x) {} \ 00110 public: \ 00111 YCPOrder compare(const YCP##name x) const { \ 00112 return (static_cast<const YCP##name##Rep*>(element))->compare(x); \ 00113 } \ 00114 string toString () const { return element->toString (); } \ 00115 std::ostream & toStream (std::ostream & str ) const { \ 00116 return element->toStream (str); \ 00117 } \ 00118 std::ostream & toXml (std::ostream & str, int indent ) const { \ 00119 return element->toXml( str, indent ); \ 00120 } \ 00121 YCPValueType valuetype () const { return (static_cast<const YCP##name##Rep*>(element))->valuetype (); } 00122 00123 00124 class YCPNull {}; 00125 00126 /*** 00127 * <h2>The YCP Datastructures</h2> 00128 * 00129 * <p>YCP is both a scripting language and a communication protocol. 00130 * A YCP value is a data structure. It has currently two possible 00131 * representations. One ist an ASCII representation, the other is 00132 * a representation a network of C++ objects. The class framework 00133 * for this object representation is laid in this library. Furthermore 00134 * It contains the @ref Parser, that transforms an ASCII representation 00135 * of YCP values into the object-representation. 00136 * 00137 * <h2>YCP Data management</h2> 00138 * 00139 * <p>YCP data are managed via "smart pointers". This means that an application 00140 * instantiates an object from a class in a conventional way but does not get 00141 * the object itself. The result is a wrapper object that "points" to the real 00142 * object which is automatically created on instantiation. This real object 00143 * (the representation of the actual data) holds a reference counter and 00144 * therefore "knows" who is using it. After all references to this object have 00145 * diminished (e.g. auto variables get out of scope) the real object is 00146 * automatically destroyed. This way it is neither necessary nor allowed 00147 * to "new" or "delete" YCP data objects. Furthermore all members of the 00148 * object must be accessed using pointer notation. 00149 * 00150 * <p>So all YCP data objects do exist in two flavours: 00151 * <ul> 00152 * <li>Class name without "Rep" is the usable object, e.g. @ref YCPInteger.</li> 00153 * <li>Class name with "Rep" is the real Object, e.g. @ref YCPIntegerRep.</li> 00154 * </ul> 00155 * 00156 * <p>Important: Applications <i>never</i> use "Rep" classes directly! 00157 * 00158 * <p>Example: 00159 * <pre> 00160 * { 00161 * YCPInteger a (18); // here a YCPIntegerRep is created automatically 00162 * YCPInteger b = a; // b points to the same YCPIntegerRep as a 00163 * 00164 * cout << b->toString (); // use pointer notation to access members 00165 * cout << b->value () - 18; // a and b out of scope, last reference lost, YCPIntegerRep is destroyed automatically 00166 * } 00167 * </pre> 00168 */ 00169 00221 class YCPElementRep 00222 #ifdef D_MEMUSAGE 00223 : public MemUsage 00224 #endif 00225 { 00230 YCPElementRep& operator=(const YCPElementRep&); 00231 00236 YCPElementRep(const YCPElementRep&); 00237 00244 mutable int reference_counter; 00245 00246 protected: 00247 00248 friend class YCPElement; 00249 00253 YCPElementRep(); 00254 00260 virtual ~YCPElementRep(); 00261 00262 public: 00266 YCPValue asValue() const; 00267 00274 virtual string toString() const = 0; 00275 00279 virtual std::ostream & toStream (std::ostream & str) const = 0; 00280 virtual std::ostream & toXml (std::ostream & str, int indent ) const = 0; 00281 00286 virtual const YCPElementRep* shallowCopy() const { return this; } 00287 00288 private: 00299 void destroy() const; 00300 00307 const YCPElementRep *clone() const; 00308 }; 00309 00316 class YCPElement 00317 #ifdef D_MEMUSAGE 00318 : public MemUsage 00319 #endif 00320 { 00321 DEF_OPS(Element); 00322 protected: 00323 const YCPElementRep *element; 00324 00329 const YCPElementRep *writeCopy() { 00330 if (element->reference_counter == 1 ) return element; 00331 00332 const YCPElementRep* old = element; 00333 element = element->shallowCopy (); 00334 element->clone (); 00335 old->destroy (); 00336 return element; 00337 } 00338 00339 public: 00340 YCPElement(); 00341 YCPElement(const YCPNull&); 00342 YCPElement(const YCPElementRep *e); 00343 YCPElement(const YCPElement &e); 00344 ~YCPElement(); 00345 const YCPElement& operator=(const YCPElement& e); 00346 bool isNull() const { return element == 0; } 00347 bool refersToSameElementAs(const YCPElement& e) const { return element == e.element; } 00348 }; 00349 00350 #endif // YCPElement_h
1.7.3