Index: src/libchcore/TPath.cpp
===================================================================
diff -u -N -rb42450e5a25470c399e04cfbb7a368519aa455f2 -r69b48f0b4d7fad78f95854e95fca166014311474
--- src/libchcore/TPath.cpp	(.../TPath.cpp)	(revision b42450e5a25470c399e04cfbb7a368519aa455f2)
+++ src/libchcore/TPath.cpp	(.../TPath.cpp)	(revision 69b48f0b4d7fad78f95854e95fca166014311474)
@@ -17,11 +17,15 @@
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
 #include "stdafx.h"
+#include <boost/serialization/serialization.hpp>
 #include "TPath.h"
 #include <boost/algorithm/string.hpp>
+#include "../libicpf/exception.h"
 
 BEGIN_CHCORE_NAMESPACE
 
+#define DEFAULT_PATH_SEPARATOR _T("\\")
+
 // ============================================================================
 /// TPath::TPath
 /// @date 2009/11/29
@@ -124,36 +128,6 @@
 /// TSmartPath::TSmartPath
 /// @date 2009/11/29
 ///
-/// @brief     Constructs path from stl string object.
-/// @param[in] strPath - string containing a path.
-// ============================================================================
-TSmartPath::TSmartPath(const tstring_t& strPath) :
-	m_pPath(NULL)
-{
-	m_pPath = TPath::New();
-	if(m_pPath)
-		m_pPath->m_strPath = strPath;
-}
-
-// ============================================================================
-/// TSmartPath::TSmartPath
-/// @date 2009/11/29
-///
-/// @brief     Constructs a path object from string.
-/// @param[in] pszPath - string with path.
-// ============================================================================
-TSmartPath::TSmartPath(const wchar_t* pszPath) :
-	m_pPath(NULL)
-{
-	m_pPath = TPath::New();
-	if(m_pPath)
-		m_pPath->m_strPath = pszPath;
-}
-
-// ============================================================================
-/// TSmartPath::TSmartPath
-/// @date 2009/11/29
-///
 /// @brief     Constructs path object from another path object.
 /// @param[in] spPath - reference to another path object.
 // ============================================================================
@@ -195,38 +169,6 @@
 /// TSmartPath::operator=
 /// @date 2009/11/29
 ///
-/// @brief     Assigns a path from string.
-/// @param[in] strPath - string containing a path.
-/// @return    Reference to this object.
-// ============================================================================
-TSmartPath& TSmartPath::operator=(const tstring_t& strPath)
-{
-	PrepareToWrite();
-	m_pPath->m_strPath = strPath;
-
-	return *this;
-}
-
-// ============================================================================
-/// TSmartPath::operator=
-/// @date 2009/11/29
-///
-/// @brief     Assigns a path from string.
-/// @param[in] strPath - string containing a path.
-/// @return    Reference to this object.
-// ============================================================================
-TSmartPath& TSmartPath::operator=(const wchar_t* pszPath)
-{
-	PrepareToWrite();
-	m_pPath->m_strPath = pszPath;
-
-	return *this;
-}
-
-// ============================================================================
-/// TSmartPath::operator=
-/// @date 2009/11/29
-///
 /// @brief     Assigns a path from other path object.
 /// @param[in] spPath - path object from which we want to get path.
 /// @return    Reference to this object.
@@ -309,7 +251,10 @@
 {
 	TSmartPath spNewPath(*this);
 	if(rPath.m_pPath)
-		spNewPath += rPath.m_pPath->m_strPath;
+	{
+		spNewPath.PrepareToWrite();
+		spNewPath.m_pPath->m_strPath += rPath.m_pPath->m_strPath;
+	}
 
 	return spNewPath;
 }
@@ -335,19 +280,61 @@
 }
 
 // ============================================================================
-/// TSmartPath::operator const tstring_t
-/// @date 2009/11/29
+/// chcore::TSmartPath::FromString
+/// @date 2010/10/12
 ///
-/// @brief     Casts this path object to string
-/// @return    String with path.
+/// @brief     Initializes this path object with path contained in string.
+/// @param[in] pszPath - string containing path.
 // ============================================================================
-TSmartPath::operator const tstring_t() const
+void TSmartPath::FromString(const wchar_t* pszPath)
 {
-	tstring_t strPath;
+	if(!pszPath)
+		THROW(_T("Invalid pointer"), 0, 0, 0);
+
+	PrepareToWrite();
+	m_pPath->m_strPath = pszPath;
+}
+
+// ============================================================================
+/// chcore::TSmartPath::FromString
+/// @date 2010/10/12
+///
+/// @brief     Initializes this path object with path contained in string.
+/// @param[in] strPath - string containing path.
+// ============================================================================
+void TSmartPath::FromString(const std::wstring& strPath)
+{
+	PrepareToWrite();
+	m_pPath->m_strPath = strPath;
+}
+
+// ============================================================================
+/// chcore::TSmartPath::ToString
+/// @date 2010/10/12
+///
+/// @brief     Retrieves the pointer to a string containing path.
+/// @return    Pointer to the string containing path.
+// ============================================================================
+const wchar_t* TSmartPath::ToString() const
+{
 	if(m_pPath)
-		strPath = m_pPath->m_strPath;
+		return m_pPath->m_strPath.c_str();
+	return _T("");
+}
 
-	return strPath;
+// ============================================================================
+/// chcore::TSmartPath::ToString
+/// @date 2010/10/12
+///
+/// @brief     Retrieves the string containing path.
+/// @return    String containing path.
+// ============================================================================
+std::wstring TSmartPath::ToWString() const
+{
+	std::wstring wstrPath;
+	if(m_pPath)
+		wstrPath = m_pPath->m_strPath;
+	return wstrPath;
 }
 
 // ============================================================================
@@ -393,6 +380,35 @@
 }
 
 // ============================================================================
+/// chcore::TSmartPath::MakeRelativePath
+/// @date 2010/10/12
+///
+/// @brief     Converts this path to be relative to the reference, base path.
+/// @param[in] rReferenceBasePath - Path which will be base path to this relative path.
+/// @param[in] bCaseSensitive - Compare path with case sensitivity on/off.
+/// @return    True if conversion to relative path succeeded, false otherwise.
+// ============================================================================
+void TSmartPath::MakeRelativePath(const TSmartPath& rReferenceBasePath, bool bCaseSensitive)
+{
+	if(!m_pPath || !rReferenceBasePath.m_pPath)
+		return;		// nothing to do; in this case we might as well treat the path as relative one
+
+	bool bStartsWith = false;
+	if(bCaseSensitive)
+		bStartsWith = boost::starts_with(m_pPath->m_strPath, rReferenceBasePath.m_pPath->m_strPath);
+	else
+		bStartsWith = boost::istarts_with(m_pPath->m_strPath, rReferenceBasePath.m_pPath->m_strPath);
+
+	if(bStartsWith)
+	{
+		PrepareToWrite();
+		m_pPath->m_strPath.erase(m_pPath->m_strPath.begin(), m_pPath->m_strPath.begin() + rReferenceBasePath.m_pPath->m_strPath.length());
+	}
+	else
+		THROW(_T("Incompatible paths"), 0, 0, 0);
+}
+
+// ============================================================================
 /// TSmartPath::AppendIfNotExists
 /// @date 2009/11/29
 ///
@@ -444,24 +460,49 @@
 	}
 }
 
-TSmartPath TSmartPath::GetLastComponent(const wchar_t* pszSeparator, bool bCaseSensitive)
+// ============================================================================
+/// chcore::TSmartPath::GetLastComponent
+/// @date 2010/10/12
+///
+/// @brief     Retrieves the last component of path (i.e. test.txt for c:\test\test.txt)
+/// @return    Sub-path with the last component.
+// ============================================================================
+TSmartPath TSmartPath::GetLastComponent()
 {
 	if(!m_pPath)
 		return TSmartPath();
 
 	boost::iterator_range<std::wstring::iterator> rangeIter;
-	if(bCaseSensitive)
-		rangeIter = boost::find_last(m_pPath->m_strPath, pszSeparator);
-	else
-		rangeIter = boost::ifind_last(m_pPath->m_strPath, pszSeparator);
+	rangeIter = boost::find_last(m_pPath->m_strPath, DEFAULT_PATH_SEPARATOR);
 
 	std::wstring wstrData;
 	wstrData.insert(wstrData.end(), rangeIter.end(), m_pPath->m_strPath.end());
 
-	return TSmartPath(wstrData);
+	return PathFromString(wstrData);
 }
 
 // ============================================================================
+/// chcore::TSmartPath::DeleteLastComponent
+/// @date 2010/10/12
+///
+/// @brief     Removes the last component of a path (i.e. test.txt for c:\test\test.txt)
+// ============================================================================
+void TSmartPath::DeleteLastComponent()
+{
+	if(m_pPath)
+	{
+		boost::iterator_range<std::wstring::iterator> rangeIter = boost::find_last(m_pPath->m_strPath, DEFAULT_PATH_SEPARATOR);
+
+		if(rangeIter.end() != m_pPath->m_strPath.end())
+		{
+			size_t stOffset = std::distance(m_pPath->m_strPath.begin(), rangeIter.end());
+			PrepareToWrite();
+			m_pPath->m_strPath.erase(m_pPath->m_strPath.begin() + stOffset, m_pPath->m_strPath.end());
+		}
+	}
+}
+
+// ============================================================================
 /// TSmartPath::IsEmpty
 /// @date 2010/10/07
 ///
@@ -493,6 +534,39 @@
 }
 
 // ============================================================================
+/// chcore::PathFromString
+/// @date 2010/10/12
+///
+/// @brief     Creates a path object from string.
+/// @param[in] pszPath - string containing path.
+/// @return    New path object.
+// ============================================================================
+TSmartPath PathFromString(const wchar_t* pszPath)
+{
+	if(!pszPath)
+		THROW(_T("Invalid pointer"), 0, 0, 0);
+
+	TSmartPath spPath;
+	spPath.FromString(pszPath);
+	return spPath;
+}
+
+// ============================================================================
+/// chcore::PathFromString
+/// @date 2010/10/12
+///
+/// @brief     Creates a path object from string.
+/// @param[in] pszPath - string containing path.
+/// @return    New path object.
+// ============================================================================
+TSmartPath PathFromString(const std::wstring& strPath)
+{
+	TSmartPath spPath;
+	spPath.FromString(strPath);
+	return spPath;
+}
+
+// ============================================================================
 /// TPathContainer::TPathContainer
 /// @date 2009/11/30
 ///
@@ -639,4 +713,16 @@
 	return m_vPaths.size();
 }
 
+// ============================================================================
+/// chcore::TPathContainer::GetCount
+/// @date 2010/10/12
+///
+/// @brief     Retrieves info if this container is empty.
+/// @return    True if empty, false otherwise.
+// ============================================================================
+bool TPathContainer::IsEmpty() const
+{
+	return m_vPaths.empty();
+}
+
 END_CHCORE_NAMESPACE