Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

tokentable.cpp

Go to the documentation of this file.
00001 
00002 #include "xmltk.h"
00003 
00004 
00005 
00006 typedef struct
00007 {
00008     STRPAIR pair;
00009     DWORD dwType;
00010 }
00011 TOKENINFO, *PTOKENINFO;
00012 
00013 typedef vector<TOKENINFO> VTOKENINFO;
00014 
00015 
00016 struct tokeninfo_cmpeq
00017 {
00018     bool operator() (const TOKENINFO &ti1, const TOKENINFO &ti2) const
00019     {
00020         return ti1.dwType == ti2.dwType &&
00021             mystrcmp(ti1.pair.first, ti2.pair.first) == 0 &&
00022             mystrcmp(ti1.pair.second, ti2.pair.second) == 0;
00023     }
00024 };
00025 
00026 inline size_t myhashstr(char const *psz)
00027 {
00028     return psz ? std::hash<char const *>()(psz) : 0;
00029 }
00030 
00031 struct tokeninfo_hash
00032 {
00033     size_t operator() (const TOKENINFO &ti) const
00034     {
00035         return myhashstr(ti.pair.first) + 
00036                 myhashstr(ti.pair.second) + 
00037                 ti.dwType;
00038     }
00039 };
00040 
00041 typedef hash_map<TOKENINFO, unsigned int, tokeninfo_hash, tokeninfo_cmpeq> MAP_TI_INDEX;
00042 
00043 
00044 
00045 class CTokenTable : public ITokenTable
00046 {
00047 public:
00048     // *** IUnknownCL methods ***
00049     CL_STDMETHOD(QueryInterface) (RCLIID riid, void **ppvObj);
00050     CL_STDMETHOD_(ULONG,AddRef) ();
00051     CL_STDMETHOD_(ULONG,Release) ();
00052 
00053     // *** ITokenTable methods ***
00054     CL_STDMETHOD_(char*, StrFromXTOKEN) (XTOKEN xt);
00055     CL_STDMETHOD_(DWORD, TypeFromXTOKEN) (XTOKEN xt);
00056     CL_STDMETHOD_(STRPAIR*, PairFromXTOKEN) (XTOKEN xt);
00057     CL_STDMETHOD_(XTOKEN, XTOKENFromStr)  (char* psz, DWORD dwType);
00058     CL_STDMETHOD_(XTOKEN, XTOKENFromPair) (char *pszFirst, char *pszSecond, DWORD dwType);
00059 
00060     CTokenTable() : m_cRef(1)
00061     {
00062     }
00063     
00064     virtual ~CTokenTable()
00065     {
00066         for (int i = m_vtokeninfo.size() - 1; i >= 0; i--)
00067         {
00068             if (m_vtokeninfo[i].pair.first)
00069                 free(m_vtokeninfo[i].pair.first);
00070             if (m_vtokeninfo[i].pair.second)
00071                 free(m_vtokeninfo[i].pair.second);
00072         }
00073     }
00074 
00075 private:
00076 
00077     unsigned int _XTOKENToIndex(XTOKEN xt)
00078     {
00079         return xt - XT_FIRST;
00080     }
00081 
00082     XTOKEN _IndexToXTOKEN(unsigned int iIndex)
00083     {
00084         return iIndex + XT_FIRST;
00085     }
00086 
00087     ULONG m_cRef;
00088 
00089     VTOKENINFO m_vtokeninfo;        // owns the STRPAIR strings.  indexed directly by XTOKEN (minus offset).
00090     MAP_TI_INDEX m_mapti;           // does not own the STRPAIR strings.  hash index into m_vtokeninfo for
00091                                     // fast string lookup.
00092 };
00093 
00094 // *** IUnknownCL methods ***
00095 bool CTokenTable::QueryInterface(RCLIID riid, void **ppvObj)
00096 {
00097     if (IsEqualCLIID(riid, &IID_IUnknownCL))
00098     {
00099         *ppvObj = (void*)static_cast<IUnknownCL*>(this);
00100     }
00101     else if (IsEqualCLIID(riid, &IID_ITokenTable))
00102     {
00103         *ppvObj = (void*)static_cast<ITokenTable*>(this);
00104     }
00105     else
00106     {
00107         return false;
00108     }
00109     AddRef();
00110     return true;
00111 }
00112 
00113 ULONG CTokenTable::AddRef()
00114 {
00115     return ++m_cRef;
00116 }
00117 
00118 ULONG CTokenTable::Release()
00119 {
00120     --m_cRef;
00121     if (m_cRef > 0)
00122     {
00123         return m_cRef;
00124     }
00125     delete this;
00126     return 0;
00127 }
00128 
00129 
00130 // *** ITokenTable methods ***
00131 char* CTokenTable::StrFromXTOKEN(XTOKEN xt)
00132 {
00133     UINT uIndex = _XTOKENToIndex(xt);
00134     if (uIndex >= 0 && uIndex < m_vtokeninfo.size())
00135     {
00136         return m_vtokeninfo[uIndex].pair.first;
00137     }
00138     return NULL;
00139 }
00140 
00141 DWORD CTokenTable::TypeFromXTOKEN(XTOKEN xt)
00142 {
00143     UINT uIndex = _XTOKENToIndex(xt);
00144     if (uIndex >= 0 && uIndex < m_vtokeninfo.size())
00145     {
00146         return m_vtokeninfo[uIndex].dwType;
00147     }
00148     return 0;
00149 }
00150 
00151 STRPAIR *CTokenTable::PairFromXTOKEN(XTOKEN xt)
00152 {
00153     UINT uIndex = _XTOKENToIndex(xt);
00154     if (uIndex >= 0 && uIndex < m_vtokeninfo.size())
00155     {
00156         return &m_vtokeninfo[uIndex].pair;
00157     }
00158     return NULL;
00159 }
00160 
00161 XTOKEN CTokenTable::XTOKENFromStr(char* psz, DWORD dwType)
00162 {
00163     return XTOKENFromPair(psz, NULL, dwType);
00164 }
00165 
00166 XTOKEN CTokenTable::XTOKENFromPair(char* pszFirst, char *pszSecond, DWORD dwType)
00167 {
00168     TOKENINFO ti;
00169     ti.dwType = dwType;
00170     ti.pair.first = pszFirst;
00171     ti.pair.second = pszSecond;
00172 
00173     MAP_TI_INDEX::const_iterator it = m_mapti.find(ti);
00174     if (it != m_mapti.end())
00175     {
00176         //
00177         // found, map index to XTOKEN and return
00178         //
00179         return _IndexToXTOKEN((*it).second);
00180     }
00181     else
00182     {
00183         //
00184         // not found, let's insert it now.
00185         //
00186         ti.pair.first = mystrdup(ti.pair.first);
00187         ti.pair.second = mystrdup(ti.pair.second);
00188 
00189         UINT iIndex = m_vtokeninfo.size();
00190 
00191         m_vtokeninfo.resize(iIndex+1);
00192         m_vtokeninfo[iIndex] = ti;
00193 
00194         m_mapti.insert(MAP_TI_INDEX::value_type(ti, iIndex));
00195 
00196         return _IndexToXTOKEN(iIndex);
00197     }
00198 }
00199 
00200 ITokenTable *g_ptt = NULL;
00201 
00202 bool GetGlobalTokenTable(RCLIID riid, void** ppv)
00203 {
00204     if (g_ptt)
00205     {
00206         return g_ptt->QueryInterface(riid, ppv);
00207     }
00208 
00209     return false;
00210 }
00211 
00212 void InitGlobalTokenTable()
00213 {
00214     assert (g_ptt == NULL);
00215     CTokenTable *ptt = new CTokenTable();
00216     if (ptt)
00217     {
00218         ptt->QueryInterface(&IID_ITokenTable, (void**)&g_ptt);
00219         ptt->Release();
00220     }
00221 }
00222 
00223 void CleanupGlobalTokenTable()
00224 {
00225     if (g_ptt)
00226     {
00227         g_ptt->Release();
00228         g_ptt = NULL;
00229     }
00230 }

Generated on Sat Dec 22 16:01:52 2001 for XMILLforBinaryFormat by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001