|
MythTV
0.26-pre
|
00001 /* BaseClasses.h 00002 00003 Copyright (C) David C. J. Matthews 2004 dm at prolingua.co.uk 00004 00005 This program is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU General Public License 00007 as published by the Free Software Foundation; either version 2 00008 of the License, or (at your option) any later version. 00009 00010 This program is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License 00016 along with this program; if not, write to the Free Software 00017 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00018 Or, point your browser to http://www.gnu.org/copyleft/gpl.html 00019 00020 */ 00021 00022 #if !defined(BASECLASSES_H) 00023 #define BASECLASSES_H 00024 00025 #include "config.h" 00026 #if HAVE_MALLOC_H 00027 #include <malloc.h> 00028 #endif 00029 00030 #include <QString> 00031 00032 #include "Logging.h" // For MHASSERT 00033 00034 class MHEngine; 00035 00036 // These templates should really be obtained from a library. They are defined here to 00037 // allow easy porting to a variety of libraries. 00038 00039 // Simple sequence class. 00040 template <class BASE> class MHSequence { 00041 public: 00042 MHSequence(){ m_VecSize = 0; m_Values = 0; } 00043 // The destructor frees the vector but not the elements. 00044 ~MHSequence() { free(m_Values); } 00045 // Get the current size. 00046 int Size() const { return m_VecSize; } 00047 // Get an element at a particular index. 00048 BASE GetAt(int i) const { MHASSERT(i >= 0 && i < m_VecSize); return m_Values[i]; } 00049 BASE operator[](int i) const { return GetAt(i); } 00050 // Add a new element at position n and move the existing element at that position 00051 // and anything above it up one place. 00052 void InsertAt(BASE b, int n) { 00053 MHASSERT(n >= 0 && n <= m_VecSize); 00054 BASE *ptr = (BASE*)realloc(m_Values, (m_VecSize+1) * sizeof(BASE)); 00055 if (ptr == NULL) throw "Out of Memory"; 00056 m_Values = ptr; 00057 for (int i = m_VecSize; i > n; i--) m_Values[i] = m_Values[i-1]; 00058 m_Values[n] = b; 00059 m_VecSize++; 00060 } 00061 // Add an element to the end of the sequence. 00062 void Append(BASE b) { InsertAt(b, m_VecSize); } 00063 // Remove an element and shift all the others down. 00064 void RemoveAt(int i) { 00065 MHASSERT(i >= 0 && i < m_VecSize); 00066 for (int j = i+1; j < m_VecSize; j++) m_Values[j-1] = m_Values[j]; 00067 m_VecSize--; 00068 } 00069 protected: 00070 int m_VecSize; 00071 BASE *m_Values; 00072 }; 00073 00074 // As above, but it deletes the pointers when the sequence is destroyed. 00075 template <class BASE> class MHOwnPtrSequence: public MHSequence<BASE*> { 00076 public: 00077 ~MHOwnPtrSequence() { for(int i = 0; i < MHSequence<BASE*>::m_VecSize; i++) delete(MHSequence<BASE*>::GetAt(i)); } 00078 }; 00079 00080 00081 // Simple stack. 00082 template <class BASE> class MHStack: protected MHSequence<BASE> { 00083 public: 00084 // Test for empty 00085 bool Empty() const { return Size() == 0; } 00086 // Pop an item from the stack. 00087 BASE Pop() { 00088 MHASSERT(MHSequence<BASE>::m_VecSize > 0); 00089 return MHSequence<BASE>::m_Values[--MHSequence<BASE>::m_VecSize]; 00090 } 00091 // Push an element on the stack. 00092 void Push(BASE b) { this->Append(b); } 00093 // Return the top of the stack. 00094 BASE Top() { 00095 MHASSERT(MHSequence<BASE>::m_VecSize > 0); 00096 return MHSequence<BASE>::m_Values[MHSequence<BASE>::m_VecSize-1]; 00097 } 00098 int Size() const { return MHSequence<BASE>::Size(); } 00099 }; 00100 00101 class MHParseNode; 00102 00103 // An MHEG octet string is a sequence of bytes which can include nulls. MHEG, or at least UK MHEG, indexes 00104 // strings from 1. We use 0 indexing in calls to these functions. 00105 class MHOctetString 00106 { 00107 public: 00108 MHOctetString(); 00109 MHOctetString(const char *str, int nLen = -1); // From character string 00110 MHOctetString(const unsigned char *str, int nLen); // From byte vector 00111 MHOctetString(const MHOctetString &str, int nOffset=0, int nLen=-1); // Substring 00112 virtual ~MHOctetString(); 00113 00114 void Copy(const MHOctetString &str); 00115 int Size() const { return m_nLength; } 00116 // Comparison - returns <0, =0, >0 depending on the ordering. 00117 int Compare(const MHOctetString &str) const; 00118 bool Equal(const MHOctetString &str) const { return Compare(str) == 0; } 00119 unsigned char GetAt(int i) const { MHASSERT(i >= 0 && i < Size()); return m_pChars[i]; } 00120 const unsigned char *Bytes() const { return m_pChars; } // Read-only pointer to the buffer. 00121 void Append(const MHOctetString &str); // Add text to the end of the string. 00122 00123 QString Printable() const { return QString::fromAscii((const char*)m_pChars, m_nLength); } 00124 00125 void PrintMe(FILE *fd, int nTabs) const; 00126 00127 protected: 00128 int m_nLength; 00129 unsigned char *m_pChars; 00130 }; 00131 00132 // A colour is encoded as a string or the index into a palette. 00133 // Palettes aren't defined in UK MHEG so the palette index isn't really relevant. 00134 class MHColour { 00135 public: 00136 MHColour(): m_nColIndex(-1) {} 00137 void Initialise(MHParseNode *p, MHEngine *engine); 00138 void PrintMe(FILE *fd, int nTabs) const; 00139 bool IsSet() const { return m_nColIndex >= 0 || m_ColStr.Size() != 0; } 00140 void SetFromString(const char *str, int nLen); 00141 void Copy(const MHColour &col); 00142 MHOctetString m_ColStr; 00143 int m_nColIndex; 00144 }; 00145 00146 // An object reference is used to identify and refer to an object. 00147 // Internal objects have the m_pGroupId field empty. 00148 class MHObjectRef 00149 { 00150 public: 00151 MHObjectRef() { m_nObjectNo = 0; } 00152 void Initialise(MHParseNode *p, MHEngine *engine); 00153 void Copy(const MHObjectRef &objr); 00154 static MHObjectRef Null; 00155 00156 // Sometimes the object reference is optional. This tests if it has been set 00157 bool IsSet() const { return (m_nObjectNo != 0 || m_GroupId.Size() != 0); } 00158 void PrintMe(FILE *fd, int nTabs) const; 00159 bool Equal(const MHObjectRef &objr, MHEngine *engine) const; 00160 QString Printable() const; 00161 00162 int m_nObjectNo; 00163 MHOctetString m_GroupId; 00164 }; 00165 00166 // A content reference gives the location (e.g. file name) to find the content. 00167 class MHContentRef 00168 { 00169 public: 00170 MHContentRef() {} 00171 void Initialise(MHParseNode *p, MHEngine *engine); 00172 void PrintMe(FILE *fd, int nTabs) const { m_ContentRef.PrintMe(fd, nTabs); } 00173 void Copy(const MHContentRef &cr) { m_ContentRef.Copy(cr.m_ContentRef); } 00174 bool IsSet() const { return m_ContentRef.Size() != 0; } 00175 bool Equal(const MHContentRef &cr, MHEngine *engine) const; 00176 static MHContentRef Null; 00177 QString Printable() const { return m_ContentRef.Printable(); } 00178 00179 MHOctetString m_ContentRef; 00180 }; 00181 00182 // "Generic" versions of int, bool etc can be either the value or an indirect reference. 00183 class MHGenericBase 00184 { 00185 public: 00186 MHObjectRef *GetReference(); // Return the indirect reference or fail if it's direct 00187 protected: 00188 bool m_fIsDirect; 00189 MHObjectRef m_Indirect; 00190 }; 00191 00192 class MHGenericBoolean: public MHGenericBase 00193 { 00194 public: 00195 MHGenericBoolean() : m_fDirect(false) {} 00196 void Initialise(MHParseNode *p, MHEngine *engine); 00197 void PrintMe(FILE *fd, int nTabs) const; 00198 bool GetValue(MHEngine *engine) const; // Return the value, looking up any indirect ref. 00199 protected: 00200 bool m_fDirect; 00201 }; 00202 00203 class MHGenericInteger: public MHGenericBase 00204 { 00205 public: 00206 MHGenericInteger() : m_nDirect(-1) {} 00207 void Initialise(MHParseNode *p, MHEngine *engine); 00208 void PrintMe(FILE *fd, int nTabs) const; 00209 int GetValue(MHEngine *engine) const; // Return the value, looking up any indirect ref. 00210 protected: 00211 int m_nDirect; 00212 }; 00213 00214 class MHGenericOctetString: public MHGenericBase 00215 { 00216 public: 00217 MHGenericOctetString() {} 00218 void Initialise(MHParseNode *p, MHEngine *engine); 00219 void PrintMe(FILE *fd, int nTabs) const; 00220 void GetValue(MHOctetString &str, MHEngine *engine) const; // Return the value, looking up any indirect ref. 00221 protected: 00222 MHOctetString m_Direct; 00223 }; 00224 00225 class MHGenericObjectRef: public MHGenericBase 00226 { 00227 public: 00228 MHGenericObjectRef() {} 00229 void Initialise(MHParseNode *p, MHEngine *engine); 00230 void PrintMe(FILE *fd, int nTabs) const; 00231 void GetValue(MHObjectRef &ref, MHEngine *engine) const; // Return the value, looking up any indirect ref. 00232 protected: 00233 MHObjectRef m_ObjRef; 00234 }; 00235 00236 class MHGenericContentRef: public MHGenericBase 00237 { 00238 public: 00239 MHGenericContentRef() {} 00240 void Initialise(MHParseNode *p, MHEngine *engine); 00241 void PrintMe(FILE *fd, int nTabs) const; 00242 void GetValue(MHContentRef &ref, MHEngine *engine) const; // Return the value, looking up any indirect ref. 00243 protected: 00244 MHContentRef m_Direct; 00245 }; 00246 00247 // In certain cases (e.g. parameters to Call) we have values which are the union of the base types. 00248 class MHParameter 00249 { 00250 public: 00251 MHParameter(): m_Type(P_Null) {} 00252 void Initialise(MHParseNode *p, MHEngine *engine); 00253 void PrintMe(FILE *fd, int nTabs) const; 00254 MHObjectRef *GetReference(); // Get an indirect reference. 00255 00256 enum ParamTypes { P_Int, P_Bool, P_String, P_ObjRef, P_ContentRef, P_Null } m_Type; // Null is used when this is optional 00257 00258 MHGenericInteger m_IntVal; 00259 MHGenericBoolean m_BoolVal; 00260 MHGenericOctetString m_StrVal; 00261 MHGenericObjectRef m_ObjRefVal; 00262 MHGenericContentRef m_ContentRefVal; 00263 }; 00264 00265 // A union type. Returned when a parameter is evaluated. 00266 class MHUnion 00267 { 00268 public: 00269 MHUnion() { m_Type = U_None; } 00270 MHUnion(int nVal) { m_Type = U_Int; m_nIntVal = nVal; } 00271 MHUnion(bool fVal) { m_Type = U_Bool; m_fBoolVal = fVal; } 00272 MHUnion(const MHOctetString &strVal) { m_Type = U_String; m_StrVal.Copy(strVal); } 00273 MHUnion(const MHObjectRef &objVal) { m_Type = U_ObjRef; m_ObjRefVal.Copy(objVal); }; 00274 MHUnion(const MHContentRef &cnVal) { m_Type = U_ContentRef; m_ContentRefVal.Copy(cnVal); } 00275 00276 void GetValueFrom(const MHParameter &value, MHEngine *engine); // Copies the argument, getting the value of an indirect args. 00277 00278 enum UnionTypes { U_Int, U_Bool, U_String, U_ObjRef, U_ContentRef, U_None } m_Type; 00279 void CheckType (enum UnionTypes) const; // Check a type and fail if it doesn't match. 00280 static const char *GetAsString(enum UnionTypes t); 00281 00282 int m_nIntVal; 00283 bool m_fBoolVal; 00284 MHOctetString m_StrVal; 00285 MHObjectRef m_ObjRefVal; 00286 MHContentRef m_ContentRefVal; 00287 }; 00288 00289 class MHFontBody { 00290 // A font body can either be a string or an object reference 00291 public: 00292 MHFontBody() {} 00293 void Initialise(MHParseNode *p, MHEngine *engine); 00294 void PrintMe(FILE *fd, int nTabs) const; 00295 bool IsSet() const { return m_DirFont.Size() != 0 || m_IndirFont.IsSet(); } 00296 void Copy(const MHFontBody &fb); 00297 protected: 00298 MHOctetString m_DirFont; 00299 MHObjectRef m_IndirFont; 00300 }; 00301 00302 // This is used only in DynamicLineArt 00303 class MHPointArg { 00304 public: 00305 MHPointArg() {} 00306 void Initialise(MHParseNode *p, MHEngine *engine); 00307 void PrintMe(FILE *fd, int nTabs) const; 00308 MHGenericInteger x, y; 00309 }; 00310 00311 #endif
1.7.6.1