1 // SSRecord.cpp: implementation of the SSRecord class.
3 //////////////////////////////////////////////////////////////////////
10 //---------------------------------------------------------------------------
11 #include "LeakWatcher.h"
16 static char THIS_FILE
[] = __FILE__
;
19 //////////////////////////////////////////////////////////////////////
20 // Construction/Destruction
21 //////////////////////////////////////////////////////////////////////
29 TypeMap g_TypeMap
[] = {
31 {"MC", eCommentRecord
},
32 {"EL", eHistoryRecord
},
33 {"CF", eCheckOutRecord
},
34 {"PF", eParentFolder
},
37 {"SN", eNameCacheEntry
},
38 {"JP", eProjectEntry
},
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
;
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);
69 bool SSRecord::IsValid () const
71 // TODO: check checksum
72 return m_pBuffer
!= NULL
;
75 eType
SSRecord::GetType () const
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");
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);
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 ()