1 // SSItemInfoObject.cpp: implementation of the SSItems class.
3 //////////////////////////////////////////////////////////////////////
8 #include "SSItemInfoObject.h"
9 #include "SSParentFolderObject.h"
10 #include "SSBranchFileObject.h"
12 //---------------------------------------------------------------------------
13 #include "LeakWatcher.h"
18 static char THIS_FILE
[] = __FILE__
;
21 //////////////////////////////////////////////////////////////////////
22 // Construction/Destruction
23 //////////////////////////////////////////////////////////////////////
25 SSItemInfoObject::SSItemInfoObject (SSRecordPtr pRecord
)
26 : SSObject (pRecord
, eItemRecord
)
28 if (pRecord
->GetLen() < sizeof (DH
))
29 throw SSRecordException ("not enough data for info object");
31 memcpy (&m_InfoItem
, pRecord
->GetBuffer(), sizeof (DH
));
34 SSItemInfoObject::~SSItemInfoObject ()
38 SSItemInfoObject
* SSItemInfoObject::MakeItemInfo (SSRecordPtr pRecord
)
40 if (pRecord
->GetLen () < sizeof (DH
))
41 throw SSException ("not enough bytes for DH Header in record");
43 const DH
* pDh
= reinterpret_cast<const DH
*> (pRecord
->GetBuffer ());
45 return new SSProjectItem (pRecord
);
46 else if (pDh
->Type
== 2)
47 return new SSFileItem (pRecord
);
49 throw SSException ("unsupported item type");
51 return (SSItemInfoObject
*) NULL
;
56 SSVersionObject
SSItemInfoObject::GetVersion (int i
)
58 SSFileImpPtr filePtr
= GetFile ();
60 // TODO: Cache versions
61 SSVersionObject
version (filePtr
->GetRecord (GetHistoryOffsetLast ()));
63 while (version
&& version
.GetVersionNumber () != i
)
65 version
= version
.GetPreviousObject();
72 bool SSItemInfoObject::Get (int ver
, const char* dest
)
74 // SSFileImpPtr filePtr = GetFile ();
76 // std::string lastVersion = filePtr->GetFileName () + GetLatestExt ();
77 // char tmrFile[2][255];
78 // char* ptr[2] = {tmrFile[0], (char*)dest};
79 // ptr[0] = tmpnam (ptr[0]);
81 // CopyFile (lastVersion.c_str(), ptr[0]);
83 // SSVersionObject version (filePtr->GetRecord (GetHistoryOffsetLast ()));
85 // while (version && version.GetVersionNumber() > ver)
87 // if (version.GetActionId() == Checked_in)
89 // SSCheckedInAction* pAction = dynamic_cast <SSCheckedInAction*> (version.GetAction());
90 // SSRecordPtr pRecord = pAction->GetFileDelta();
91 // ReverseDelta (ptr[0], pRecord->GetBuffer(), pRecord->GetLen(), ptr[1]);
92 // std::swap (ptr[0], ptr[1]);
95 // version = version.GetPrevious ();
98 // if (0 != strcmp (ptr[0], dest))
100 // CopyFile (ptr[0], dest);
110 bool SSItemInfoObject::Validate()
112 SSFileImpPtr filePtr
= GetFile ();
115 retval
&= warn_if (GetLatestExt() != ".A" && GetLatestExt() != ".B");
116 retval
&= warn_if (GetHistoryOffsetEnd() != filePtr
->Size());
117 retval
&= warn_if (filePtr
->GetRecord (GetHistoryOffsetLast ())->GetType() != eHistoryRecord
);
118 retval
&= warn_if (filePtr
->GetRecord (GetHistoryOffsetBegin ())->GetType() != eHistoryRecord
);
119 retval
&= warn_if (filePtr
->GetRecord (GetHistoryOffsetBegin ())->GetType() != eHistoryRecord
);
122 long offset
= GetHistoryOffsetLast ();
124 SSRecordPtr pRecord
= filePtr
->GetRecord (offset
);
125 retval
&= warn_if (pRecord
->GetType() != eHistoryRecord
);
127 std::auto_ptr
<SSObject
> objectPtr (SSObject::MakeObject(pRecord
));
128 SSVersionObject
* pVersion
= dynamic_cast<SSVersionObject
*> (objectPtr
.get ());
131 SSVersionObject
previous (pVersion
->GetPreviousObject ());
132 offset
= previous
? previous
.GetOffset() : NULL
;
138 } while (offset
!= NULL
/*GetHistoryOffsetBegin ()*/);
140 retval
&= warn_if (nCount
!= GetNumberOfActions ());
144 void SSItemInfoObject::ToXml (XMLNode
* pParent
) const
146 XMLElement
type (pParent
, "Type", GetType());
147 XMLElement
data (pParent
, "DataFileName", GetDataFileName ());
148 XMLElement
ext (pParent
, "LatestExt", GetLatestExt());
149 GetSSName().ToXml (pParent
);
150 XMLElement
noActions (pParent
, "NumberOfActions", GetNumberOfActions());
153 void SSItemInfoObject::Dump (std::ostream
& os
) const
157 SSFileImpPtr filePtr
= GetFile ();
161 switch (m_InfoItem
.Type
)
163 case 1: os
<< "Project" << std::endl
; break;
164 case 2: os
<< "File" << std::endl
; break;
165 default: os
<< "Unknown (" << m_InfoItem
.Type
<< ")" << std::endl
; break;
168 SSName
ssName (GetSSName ());
169 os
<< "Last Name: " << ssName
<< std::endl
;
170 // os << "Number Of Records: " << GetNumberOfRecords () << std::endl;
171 os
<< "LatestExt of last version: " << m_InfoItem
.LatestExt
[0] << m_InfoItem
.LatestExt
[1] << std::endl
;
172 os
<< "Offset to first History record: 0x" << std::hex
<< GetHistoryOffsetBegin()<< std::dec
<< std::endl
;
173 os
<< "Offset to last History record: 0x" << std::hex
<< GetHistoryOffsetLast() << std::dec
<< std::endl
;
174 os
<< "Offset to the end of the file: 0x" << std::hex
<< GetHistoryOffsetEnd() << std::dec
<< std::endl
;
175 os
<< "Size of the file: 0x" << std::hex
<< filePtr
->Size() << std::dec
<< std::endl
;
182 //---------------------------------------------------------------------------
183 SSProjectItem::SSProjectItem (SSRecordPtr pRecord
)
184 : SSItemInfoObject (pRecord
)
186 if (pRecord
->GetLen() < sizeof (DH_PROJECT
))
187 throw SSRecordException ("not enough data for project info object");
190 std::string
SSProjectItem::GetName () const
192 return ("ProjectItem");
194 void SSProjectItem::ToXml (XMLNode
* pParent
) const
196 SSItemInfoObject::ToXml (pParent
);
197 XMLElement
spec (pParent
, "ParentSpec", GetParentSpec ());
198 XMLElement
phys (pParent
, "ParentPhys", GetParentPhys ());
199 XMLElement
noitems (pParent
, "NumberOfItems", GetNumberOfItems ());
200 XMLElement
noProjects (pParent
, "NumberOfProjects", GetNumberOfProjects ());
203 void SSProjectItem::Dump (std::ostream
& os
) const
205 SSItemInfoObject::Dump (os
);
207 // Hexdump (oss, dummy4, 20);
208 os
<< "last parent spec: " << GetParentSpec () << std::endl
;
209 os
<< "parentPhys: " << GetParentPhys () << std::endl
;
210 os
<< "Number of Items: " << GetNumberOfItems () << std::endl
;
211 os
<< "Number of Projects: " << GetNumberOfProjects () << std::endl
;
217 //---------------------------------------------------------------------------
218 SSFileItem::SSFileItem (SSRecordPtr pRecord
)
219 : SSItemInfoObject (pRecord
)
221 if (pRecord
->GetLen() < sizeof (DH_FILE
))
222 throw SSRecordException ("not enough data for file info object");
225 bool SSFileItem::Validate()
227 SSItemInfoObject::Validate ();
229 const DH_FILE
* pFileInfoItem
= GetData();
232 retval
&= warn_if (pFileInfoItem
->NumberOfItems
> 0);
233 retval
&= warn_if (pFileInfoItem
->NumberOfProjects
> 0);
237 0x00, 0x02, 0x04, 0x41, 0x42, 0x20, 0x22
239 for (int i
= 0; i
< countof (knownFlags
); i
++)
240 if (pFileInfoItem
->Flag
== knownFlags
[i
])
242 retval
&= warn_if (i
== countof (knownFlags
));
247 eFileType
SSFileItem::GetFileType () const
249 if ((GetFlag () & 0x02) == 0x02)
250 return eFileTypeBinary
;
252 return eFileTypeText
;
255 bool SSFileItem::GetStoreOnlyLatestRev () const
257 if ((GetFlag () & 0x04) == 0x04)
263 bool SSFileItem::GetCheckedOut () const
265 if ((GetFlag () & 0x41) == 0x41)
271 bool SSFileItem::GetShared () const
273 if ((GetFlag () & 0x20) == 0x20)
279 SSParentFolderObject
* SSFileItem::GetFirstParentFolder ()
281 SSRecordPtr pRecord
= GetFile()->GetRecord(GetOffsetPFRecord ());
282 return new SSParentFolderObject (pRecord
);
285 SSBranchFileObject
* SSFileItem::GetFirstBranchFile ()
287 SSRecordPtr pRecord
= GetFile()->GetRecord(GetOffsetBFRecord ());
288 return new SSBranchFileObject (pRecord
);
291 std::string
SSFileItem::GetName () const
295 void SSFileItem::ToXml (XMLNode
* pParent
) const
297 SSItemInfoObject::ToXml (pParent
);
298 XMLElement
binary (pParent
, "Binary", GetFileType () == eFileTypeBinary
? true : false);
299 XMLElement
store (pParent
, "StoreOnlyLatestRev", GetStoreOnlyLatestRev ());
300 XMLElement
checkedOut (pParent
, "CheckedOut", GetCheckedOut ());
301 XMLElement
shared (pParent
, "Shared", GetShared ());
302 XMLElement
sharedSrc (pParent
, "ShareSrc", GetShareSrcPhys());
303 XMLElement
ref (pParent
, "NumberOfReferences", GetNumberOfReferences());
304 XMLElement
branch (pParent
, "NumberOfBranches", GetNumberOfBranches ());
307 void SSFileItem::Dump (std::ostream
& os
) const
309 SSItemInfoObject::Dump (os
);
311 // Hexdump (oss, dummy4, 20);
313 const DH_FILE
* pFileInfoItem
= GetData ();
314 os
<< "Status: 0x" << std::hex
<< pFileInfoItem
->Flag
<< std::dec
<< " ";
315 if (pFileInfoItem
->Flag
== 0x00)
317 else if (pFileInfoItem
->Flag
== 0x02)
319 else if (pFileInfoItem
->Flag
== 0x04)
320 os
<< "store only latest revision";
321 else if (pFileInfoItem
->Flag
== 0x41)
322 os
<< "checked out, locked";
323 else if (pFileInfoItem
->Flag
== 0x43)
324 os
<< "binary, checked out, locked";
325 else if (pFileInfoItem
->Flag
== 0x20)
327 else if (pFileInfoItem
->Flag
== 0x22)
328 os
<< "binary, shared";
333 os
<< "Share source physical file: " << pFileInfoItem
->ShareSrcSpec
<< std::endl
;
335 os
<< "Offset to first parent record: 0x" << std::hex
<< pFileInfoItem
->OffsetPFRecord
<< std::dec
<< std::endl
;
336 os
<< "Reference count: " << pFileInfoItem
->NumberOfReferences
<< std::endl
;
337 os
<< "Offset to 1st checkout record: 0x" << std::hex
<< pFileInfoItem
->OffsetCFRecord1
<< std::dec
<< std::endl
;
338 os
<< "Offset to 2nd checkout record: 0x" << std::hex
<< pFileInfoItem
->OffsetCFRecord2
<< std::dec
<< std::endl
;
340 os
<< "Number of Items: " << std::hex
<< pFileInfoItem
->NumberOfItems
<< std::dec
<< std::endl
;
341 os
<< "Number of Projects: " << std::hex
<< pFileInfoItem
->NumberOfProjects
<< std::dec
<< std::endl
;