MythTV  0.26-pre
BaseClasses.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends