Test to see if auto_props and label_mapper files are readable.
[vss2svn.git] / ssphys / SSPhysLib / SSRecord.cpp
blob5391df2e0aa02eae88407387f6a0b89c0836c4a6
1 // SSRecord.cpp: implementation of the SSRecord class.
2 //
3 //////////////////////////////////////////////////////////////////////
5 #include "StdAfx.h"
6 #include "SSRecord.h"
7 #include "SSFiles.h"
8 #include "crc.h"
10 //---------------------------------------------------------------------------
11 #include "LeakWatcher.h"
13 #ifdef _DEBUG
14 #define new DEBUG_NEW
15 #undef THIS_FILE
16 static char THIS_FILE[] = __FILE__;
17 #endif
19 //////////////////////////////////////////////////////////////////////
20 // Construction/Destruction
21 //////////////////////////////////////////////////////////////////////
24 struct TypeMap {
25 char _string[3];
26 eType _eType;
29 TypeMap g_TypeMap[] = {
30 {"DH", eItemRecord},
31 {"MC", eCommentRecord},
32 {"EL", eHistoryRecord},
33 {"CF", eCheckOutRecord},
34 {"PF", eParentFolder},
35 {"FD", eFileDelta},
36 {"HN", eNamesCache},
37 {"SN", eNameCacheEntry},
38 {"JP", eProjectEntry},
39 {"HU", eUsersHeader},
40 {"UU", eUser},
41 {"BF", eBranchFile},
44 eType SSRecord::StringToType (const char type[2])
46 for (int i = 0; i< countof(g_TypeMap); ++i)
48 if (0 == memcmp (type, g_TypeMap[i]._string, 2))
49 return g_TypeMap[i]._eType;
52 return eUnknown;
55 std::string SSRecord::TypeToString (eType type)
57 for (int i = 0; i< countof(g_TypeMap); ++i)
59 if (type == g_TypeMap[i]._eType)
60 return std::string (g_TypeMap[i]._string, 2);
63 if (type == eNone)
64 return "none";
66 return "unknown";
69 bool SSRecord::IsValid () const
71 // TODO: check checksum
72 return m_pBuffer != NULL;
75 eType SSRecord::GetType () const
77 if (!m_pBuffer)
78 return eNone;
79 return SSRecord::StringToType (m_Header.type);
82 SSRecord::SSRecord (SSFileImpPtr filePtr, long offset)
83 : m_FileImpPtr (filePtr), m_Offset(offset), m_pBuffer(NULL), m_Len (0)
85 int fileLength = m_FileImpPtr->Size ();
87 if (!m_FileImpPtr->Read (offset, &m_Header, sizeof(m_Header)))
88 throw SSException ("could not read record header");
90 // OPTIMIZE: We do not nead to read all the record payload in advance (esp. for FD records)
91 if (m_Header.size > 0)
93 if (offset + sizeof(m_Header) + m_Header.size > fileLength)
94 throw SSRecordException ("bad header: length variable exceeds file size");
96 m_pBuffer = new byte[m_Header.size];
97 if (!m_FileImpPtr->Read (/*offset + sizeof(m_Header), */ m_pBuffer, m_Header.size))
98 throw SSException ("could not read record data");
100 short crc = calc_crc16 (m_pBuffer, m_Header.size);
101 if (m_Header.checksum != (short)crc && m_Header.checksum != 0)
103 SSRecordException ex("wrong checksum");
104 Warning (ex.what());
105 _RAISE (ex);
109 m_Len = m_Header.size;
112 SSRecord::SSRecord (eType type, const void* buffer, int len)
113 : m_Offset(0), m_pBuffer(NULL), m_Len (0)
115 m_Header.checksum = calc_crc16 (buffer, len);
116 strncpy (m_Header.type, TypeToString (type).c_str(), 2);
117 m_Header.size = len;
119 // OPTIMIZE: We do not nead to read all the record payload in advance (esp. for FD records)
120 if (m_Header.size > 0)
122 m_pBuffer = new byte[m_Header.size];
123 memcpy (m_pBuffer, buffer, m_Header.size);
126 m_Len = m_Header.size;
129 void SSRecord::Dump (std::ostream& os) const
131 os << "Offset: " << GetOffset ();
132 os << " Type: " << GetRecordType ();
133 os << " Len: " << GetLen();
134 std::string validity = IsValid() ? "valid" : "invalid";
135 os << " crc: " << m_Header.checksum << " -> " << validity << std::endl;
138 SSRecord::~SSRecord ()
140 delete [] m_pBuffer;