00001
00037 #include "DAGDBFile.h"
00038 #include "ShockGraph.h"
00039 #include "GestureGraph.h"
00040 #include "Exceptions.h"
00041
00042 #define UNK_GRAPH 0
00043 #define SHOCK_GRAPH 1
00044 #define GESTURE_GRAPH 2
00045
00046
00047 int DAGDBFile::GetClassID(const String& strClassName) const
00048 {
00049 if (strClassName == "ShockGraph")
00050 return SHOCK_GRAPH;
00051 else if (strClassName == "GestureGraph")
00052 return GESTURE_GRAPH;
00053
00054 DBG_MSG1("Warning: Unknown graph class", strClassName);
00055 return UNK_GRAPH;
00056 }
00057
00058 DAG* DAGDBFile::CreateDAGObj(int nClassID) const
00059 {
00060 switch (nClassID)
00061 {
00062 case SHOCK_GRAPH:
00063 return new ShockGraph;
00064 case GESTURE_GRAPH:
00065 return new GestureGraph;
00066 }
00067
00068 DBG_MSG1("Warning: Unknown class ID", nClassID);
00069 return NULL;
00070 }
00071
00073 void DAGDBFile::open(const char* szName, ios_base::openmode nMode)
00074 {
00075 ASSERT(!IsDBModified());
00076
00077
00078
00079 if (nMode & ios_base::app)
00080 {
00081 nMode &= ~ios_base::app;
00082 nMode |= ios_base::out;
00083 }
00084
00085 nMode |= ios_base::in;
00086
00087 m_strFileName = szName;
00088 fstream::open(szName, nMode);
00089
00090 if (!fail())
00091 {
00092 if (!ReadTailInfo())
00093 {
00094 if (!(nMode & ios_base::out))
00095 {
00096 fstream::close();
00097 nMode |= ios_base::out;
00098 fstream::open(szName, nMode);
00099 }
00100
00101 DBG_MSG("Warning: DB tail info has to be rebuilt.");
00102
00103 if (!RebuildTailInfo())
00104 THROW_EXCEPTION("Cannot read database info.");
00105 }
00106 }
00107 }
00108
00110 void DAGDBFile::close()
00111 {
00112 if (IsDBModified())
00113 WriteTailInfo();
00114
00115 m_nDBSize = 0;
00116 SetDBModified(false);
00117 m_strFileName.Clear();
00118 DBInfo().Clear();
00119 m_dagInfo.Clear();
00120
00121 fstream::close();
00122 }
00123
00124 bool DAGDBFile::ReadTailInfo()
00125 {
00126 ASSERT(is_open());
00127 ASSERT(!IsDBModified());
00128
00129 MoveToEnd();
00130 m_nDBSize = tellg();
00131
00132 if (m_nDBSize > 0)
00133 {
00134 MoveTo(m_nDBSize - sizeof(DBINFO));
00135
00136 read((char*) m_pDBInfo, sizeof(DBINFO));
00137
00138 ASSERT(gcount() == sizeof(DBINFO));
00139
00140 if (!DBInfo().IsValid())
00141 return false;
00142
00143 MoveTo(DBInfo().m_nTailOffset);
00144 m_dagInfo.Read(*this);
00145 }
00146
00147 return true;
00148 }
00149
00150 void DAGDBFile::WriteTailInfo()
00151 {
00152 seekp(DBInfo().m_nTailOffset);
00153
00154 DBInfo().MakeValid();
00155
00156 m_dagInfo.Write(*this);
00157
00158 write((char*) m_pDBInfo, sizeof(DBINFO));
00159 flush();
00160
00161 SetDBModified(false);
00162 }
00163
00164 DAGPtr DAGDBFile::ReadDAG(int nDagId, bool bOnlyDataForMatching )
00165 {
00166 ASSERT(nDagId < m_dagInfo.GetSize());
00167
00168 DAGPtr ptrDag;
00169 DAGINFO info = m_dagInfo[nDagId];
00170
00171 ASSERT(info.nOffset < DBInfo().m_nTailOffset);
00172 MoveTo(info.nOffset);
00173
00174 ptrDag = CreateDAGObj(info.nType);
00175 ASSERT(!ptrDag.IsNull());
00176
00177 try {
00178 ptrDag->Read(*this, bOnlyDataForMatching);
00179 }
00180 catch(ExceptionInfo e)
00181 {
00182 e.Print();
00183 return (DAG*)NULL;
00184 }
00185
00186 ptrDag->SetDAGId(nDagId);
00187
00188 return ptrDag;
00189 }
00190
00191 DAGPtr DAGDBFile::ReadDAG(streamoff nDagOffset, const String& strClassName)
00192 {
00193 DAGPtr ptrDag;
00194
00195 ptrDag = CreateDAGObj(GetClassID(strClassName));
00196
00197 if (!ptrDag.IsNull())
00198 {
00199 ASSERT(nDagOffset < DBInfo().m_nTailOffset);
00200 MoveTo(nDagOffset);
00201
00202 try {
00203 ptrDag->Read(*this);
00204 }
00205 catch(ExceptionInfo e)
00206 {
00207 e.Print();
00208 return (DAG*)NULL;
00209 }
00210 }
00211
00212 return ptrDag;
00213 }
00214
00215 bool DAGDBFile::AddDAG(const DAG* pDag, bool bReadSaveTailInfo)
00216 {
00217 DAGINFO info;
00218
00219 if (bReadSaveTailInfo)
00220 ReadTailInfo();
00221
00222 info.nType = GetClassID(pDag->ClassName());
00223 ASSERT(info.nType != UNK_GRAPH);
00224
00225 info.nOffset = DBInfo().m_nTailOffset;
00226 seekp(DBInfo().m_nTailOffset);
00227
00228 pDag->Write(*this);
00229 DBInfo().m_nTailOffset = tellp();
00230
00231 m_dagInfo.AddTail(info);
00232
00233 if (pDag->GetMaxTSVDimension() > DBInfo().m_nMaxTSVDimension)
00234 DBInfo().m_nMaxTSVDimension = pDag->GetMaxTSVDimension();
00235
00236 SetDBModified(true);
00237 flush();
00238
00239 if (bReadSaveTailInfo)
00240 WriteTailInfo();
00241
00242 return true;
00243 }
00244
00245 bool DAGDBFile::RebuildTailInfo()
00246 {
00247 String strClassName;
00248 streampos pos;
00249 DAGPtr ptrDag;
00250 DAGINFO dagInfo;
00251
00252 MoveToEnd();
00253 DBInfo().m_nTailOffset = tellg();
00254 DBInfo().m_nMaxTSVDimension = 0;
00255
00256 MoveToBeg();
00257
00258 while(!fail())
00259 {
00260 pos = tellg();
00261 strClassName.Read(*this);
00262
00263 ptrDag = ReadDAG(pos, strClassName);
00264
00265 if (ptrDag.IsNull())
00266 break;
00267
00268 dagInfo.nOffset = pos;
00269 dagInfo.nType = GetClassID(strClassName);
00270
00271 m_dagInfo.AddTail(dagInfo);
00272
00273 if (ptrDag->GetMaxTSVDimension() > DBInfo().m_nMaxTSVDimension)
00274 DBInfo().m_nMaxTSVDimension = ptrDag->GetMaxTSVDimension();
00275 }
00276
00277 return SetDBModified(m_dagInfo.GetSize() > 0);
00278 }
00279