Add Dirk Luetjen's ssphys libraries and command-line tool
[vss2svn.git] / ssphys / SSPhys / Formatter.cpp
blob60b1ab7a7c9a185092fc91ad7b308e8898baa09c
1 // IFormatter.cpp: implementation of the IFormatter class.
2 //
3 //////////////////////////////////////////////////////////////////////
5 #include "stdafx.h"
6 #include "Formatter.h"
8 #include <boost\lexical_cast.hpp>
10 #include <SSPhysLib\SSFiles.h>
11 #include <SSPhysLib\SSCheckoutObject.h>
12 #include <SSPhysLib\SSNameObject.h>
13 #include <SSPhysLib\SSItemInfoObject.h>
14 #include <SSPhysLib\SSProjectObject.h>
15 #include <SSPhysLib\SSParentFolderObject.h>
16 #include <SSPhysLib\SSBranchFileObject.h>
18 class CSSObjectVisitor : public ISSObjectVisitor
20 virtual void Apply(const SSVersionObject& object, const ISSContext* pCtx) { Apply ((SSObject&) object, pCtx); }
21 virtual void Apply(const SSCheckOutObject& object, const ISSContext* pCtx) { Apply ((SSObject&) object, pCtx); }
22 virtual void Apply(const SSNameObject& object, const ISSContext* pCtx) { Apply ((SSObject&) object, pCtx); }
23 virtual void Apply(const SSCommentObject& object, const ISSContext* pCtx) { Apply ((SSObject&) object, pCtx); }
24 virtual void Apply(const SSProjectObject& object, const ISSContext* pCtx) { Apply ((SSObject&) object, pCtx); }
25 virtual void Apply(const SSParentFolderObject& object, const ISSContext* pCtx) { Apply ((SSObject&) object, pCtx); }
26 virtual void Apply(const SSBranchFileObject& object, const ISSContext* pCtx) { Apply ((SSObject&) object, pCtx); }
28 virtual void Apply(const SSFileItem& object, const ISSContext* pCtx) { Apply ((SSItemInfoObject&) object, pCtx); }
29 virtual void Apply(const SSProjectItem& object, const ISSContext* pCtx) { Apply ((SSItemInfoObject&) object, pCtx); }
31 protected:
32 virtual void Apply(const SSItemInfoObject& object, const ISSContext* pCtx) { Apply ((SSObject&) object, pCtx); }
33 virtual void Apply(const SSObject& object, const ISSContext* pCtx) = 0;
36 /////////////////////////////////////////////////////////////////////
37 class CPhysFormatter : public CFormatter
39 public:
40 virtual bool SetOption (const COption& option)
42 return false;
45 void Format (const SSObject& object, const ISSContext* pCtx)
47 object.Dump (std::cout);
50 protected:
54 //////////////////////////////////////////////////////////////////////
55 class CXMLFormatter : public CFormatter
57 public:
58 CXMLFormatter ()
59 : m_pXMLNode (NULL)
62 ~CXMLFormatter ()
64 delete m_pXMLNode;
66 void SetFileName (std::string fileName)
68 AttribMap map;
69 map ["Name"]=fileName;
70 m_pXMLNode = new XMLNode (NULL, "File", map);
73 virtual bool SetOption (const COption& option)
75 return false;
78 void Format (const SSObject& object, const ISSContext* pCtx)
80 AttribMap map;
81 map ["offset"] = boost::lexical_cast<std::string>(object.GetOffset ());
82 XMLNode node (m_pXMLNode, object.GetName (), map);
83 object.ToXml (&node);
86 protected:
87 XMLNode* m_pXMLNode;
90 //////////////////////////////////////////////////////////////////////
91 void hexdump( const unsigned char *buffer, int size )
93 int i = 0;
95 while( i < size )
97 int j = 0;
98 char str[256];
99 char* p = str;
101 for( j = 0; j < 16 && i + j < size; j++ )
102 p += sprintf (p, "%02x ", buffer[i + j]);
104 //if not entire line
105 for( ; j < 16; j++ )
106 p += sprintf (p, " " );
108 p += sprintf (p, " | " );
110 for( j = 0; j < 16 && i + j < size; j++ )
111 p += sprintf (p, "%c", buffer[i + j] < ' ' || buffer[i + j] >= 127 ? '.' : buffer[i + j] );
113 //filler
114 for( ; j < 16; j++ )
115 p += sprintf (p, " " );
117 p += sprintf (p, " |\n" );
119 i += 16;
121 std::cout << str;
126 class CBinaryFormatter : public CFormatter
128 public:
129 CBinaryFormatter (tristate value)
130 : m_Value (value)
134 virtual bool SetOption (const COption& option)
136 return false;
139 void Format (const SSObject& object, const ISSContext* pCtx)
141 const SSRecordPtr pRecord = object.GetRecord ();
142 std::cout << "Offset: " << pRecord->GetOffset ();
143 std::cout << " Type: " << SSRecord::TypeToString(pRecord->GetType());
144 std::cout << " Len: " << pRecord->GetLen();
146 if (m_Value == set)
148 std::cout << std::endl;
149 hexdump (object.GetRecord()->GetBuffer(), object.GetRecord()->GetLen());
153 private:
154 tristate m_Value;
158 //////////////////////////////////////////////////////////////////////
159 class CVssFormatter : public CFormatter, public CSSObjectVisitor
161 public:
162 CVssFormatter ()
163 : n_bPhysicalID (true)
166 virtual void Apply (const SSVersionObject& object, const ISSContext* pCtx);
167 virtual void Apply (const SSFileItem& object, const ISSContext* pCtx);
168 virtual void Apply (const SSProjectItem& object, const ISSContext* pCtx);
169 virtual void Apply (const SSProjectObject& object, const ISSContext* pCtx);
170 virtual void Apply (const SSCommentObject& object, const ISSContext* pCtx);
171 virtual void Apply (const SSNameObject& object, const ISSContext* pCtx);
173 virtual bool SetOption (const COption& option)
175 return false;
178 void Format (const SSObject& object, const ISSContext* pCtx)
180 object.Accept (*this, pCtx);
182 protected:
183 virtual void Apply(const class SSObject &object, const ISSContext* pCtx)
185 std::cout << "not implemented" << std::endl;
188 bool n_bPhysicalID;
191 void CVssFormatter::Apply (const SSVersionObject& rObject, const ISSContext* pCtx)
193 // ***************** Version 1 *****************
194 // User: Admin Date: 21.11.94 Time: 18:59
195 // Created
196 const char* format1 = "***************** Version %d *****************";
197 const char* format2 = "User: %-12s Date: %-8s Time: %s";
199 char line1[60]; _snprintf (line1, 60, format1, rObject.GetVersionNumber ());
200 char date[12];
201 char time[12];
202 time_t versionDate = rObject.GetDate ();
203 const tm* ttm = gmtime (&versionDate);//localtime (&versionDate);
204 strftime (date, countof (date), "%x", ttm);
205 strftime (time, countof (time), "%X", ttm);
206 char line2[60]; _snprintf (line2, 60, format2, rObject.GetUsername ().c_str (), date, time);
208 std::cout << line1 << std::endl;
209 if (rObject.GetActionID() == Labeled)
210 std::cout << "Label: \"" << rObject.GetLabel() << "\"" << std::endl;
211 std::cout << line2 << std::endl;
212 std::cout << rObject.GetActionString() << std::endl;
214 if (n_bPhysicalID)
216 ISSItemAction* pAction = dynamic_cast<ISSItemAction*> (rObject.GetAction());
217 if (pAction)
218 std::cout << "Physical: " << pAction->GetPhysical() << std::endl;
221 if (!rObject.GetComment ().empty())
222 std::cout << rObject.GetComment () << std::endl;
223 if (rObject.GetActionID() == Labeled)
224 std::cout << "Label Comment: " << rObject.GetLabelComment () << std::endl;
226 std::cout << std::endl;
229 void CVssFormatter::Apply (const SSFileItem& object, const ISSContext* pCtx)
231 const IFormattingContext* pFormattingContext = dynamic_cast<const IFormattingContext*> (pCtx);
232 if (pFormattingContext && pFormattingContext->GetExtendedOutput ())
234 //File: $/Modules/bin/z.dll
235 //Type: Binary
236 //Size: 92160 bytes
237 //Store only latest version: No
238 //Latest: Last Label: 1.9.3
239 // Version: 1 Version: 178
240 // Date: 8.11.02 17:03 Date: 15.11.04 17:13
241 //Comment: doxygen and graphviz
243 // TODO: output the parent, but which?
244 std::cout << "File: " << object.GetName () << std::endl;
245 std::string type = object.GetFileType () == eFileTypeBinary ? "Binary" : "Text";
246 std::cout << "Type: " << type << std::endl;
247 // TODO: calculate the size, is it in the record??
248 std::cout << "Size: " << "???" << std::endl;
249 // TODO:
250 std::cout << "Store only latest version: " << "???" << std::endl;
251 std::cout << "Latest: Last Label: " << "???" << std::endl;
252 // std::cout << " Version: " << object.GetVersion () << " Version: ???" << std::endl;
253 // std::cout << " Date: " << object.GetDate () << " Date: ???" << std::endl;
255 else
257 std::string type = object.GetFileType () == eFileTypeBinary ? "Binary" : "Text";
258 std::cout << object.GetName () << "\t" << type << std::endl;
262 void CVssFormatter::Apply (const SSProjectItem& object, const ISSContext* pCtx)
264 const IFormattingContext* pFormattingContext = dynamic_cast<const IFormattingContext*> (pCtx);
265 if (pFormattingContext && pFormattingContext->GetExtendedOutput ())
267 //Project: $/Modules/bin
268 //Contains:
269 // 98 Files ( +2 deleted )
270 // 0 Subproject(s)
271 //Latest: Last Label: 1.9.3
272 // Version: 113 Version: 178
273 // Date: 8.10.04 16:10 Date: 15.11.04 17:13
274 //Comment:
276 else
278 std::cout << "$" << object.GetName () << "\tProject" << std::endl;
283 void CVssFormatter::Apply(const SSProjectObject& object, const ISSContext* pCtx)
285 std::string type;
286 if (object.GetType () == SSITEM_FILE)
287 type = object.GetFileType () == eFileTypeBinary ? "Binary" : "Text";
288 else
289 type = "Project";
291 std::cout << object.GetName () << "\t" << type << std::endl;
294 void CVssFormatter::Apply (const SSCommentObject& object, const ISSContext* pCtx)
296 std::cout << object.GetComment () << std::endl;
299 void CVssFormatter::Apply (const SSNameObject& object, const ISSContext* pCtx)
301 std::cout << "Entries: " << object.size () << std::endl;
303 SSNameObject::const_iterator iter = object.begin ();
304 for (; iter != object.end (); ++iter)
306 std::cout << "id(" << (*iter).first << ") "/*, offset (" << pEntry->offset << ")*/ "= " << (*iter).second <<std::endl;
310 //////////////////////////////////////////////////////////////////////
311 std::auto_ptr<CFormatter> CFormatterFactory::MakeFormatter (eStyle style, tristate value)
313 if (style == eBinary)
314 return new CBinaryFormatter (value);
315 if (style == eXML)
316 return new CXMLFormatter ();
317 if (style == eVSS)
318 return new CVssFormatter ();
319 if (style == eDump)
320 return new CPhysFormatter ();
322 return NULL;