/*********************************************************************
Copyright 2001 Alexander Berthold, alexander-berthold@web.de.
-- This file is part of ctkCommon --
"ctkCommon" is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or any later version.
"ctkCommon" is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with "ctkCommon"; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
---------------------------------------------------------------
If you find any bugs or if you make other corrections/
enhancements, i'd appreciate if you'd let me know about
that. My email is
alexander-berthold@web.de
If you share this code, do not remove this text.
---------------------------------------------------------------
Class: ctkMisc
Author: Alexander Berthold
Copyright: Alexander Berthold
Date: 2001/06/05
Version: 0.1.01
Purpose: Provides some helper methods used by cxTokenizer
and cxAnalyzer.
Version history:
- 2001/06/05
Current source labeled version 0.1.01
*********************************************************************/
// ctkMisc.h: interface for the ctkMisc class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_CTKMISC_H__02DB3E9E_00AB_4FC7_9F58_E01EECC31A91__INCLUDED_)
#define AFX_CTKMISC_H__02DB3E9E_00AB_4FC7_9F58_E01EECC31A91__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "tkCommon.h"
class ctkMisc
{
// Purely static helper class
public:
static bool fStripOffBraces(std::tstring& strTarget)
{
int nLen = (int)strTarget.length();
if(nLen<2)
return false;
if(nLen==2)
return false;
if(strTarget[0]!='{' || strTarget[nLen-1]!='}')
return false;
strTarget =strTarget.substr(1,strTarget.length()-2);
return true;
}
static std::tstring strStripOffSpaces(const std::tstring& strTarget)
{
std::tstring::const_iterator sit;
std::tstring::const_reverse_iterator eit;
std::tstring res;
int nPos = 0;
for(sit=strTarget.begin();sit!=strTarget.end();sit++)
if( (*sit)!=' ' && (*sit)!='\t' && (*sit)!='\n' && (*sit)!='\r') break;
if(sit==strTarget.end()) return std::tstring();
for(eit=strTarget.rbegin();eit!=strTarget.rend();eit++)
if( (*eit)!=' ' && (*eit)!='\t' && (*eit)!='\n' && (*eit)!='\r')
{ eit--; break; }
res.insert(res.begin(),&(*sit),&(*eit));
return res;
}
static std::tstring strParseEscapeCharacters(const std::tstring& strSource)
{
std::tstring strDest;
int nLen = (int)strSource.length();
int i;
bool fEscapeNext = false;
for(i=0;i<nLen;i++)
{
TCHAR tcTemp = strSource[i];
if(fEscapeNext)
{
bool fOk = false;
if(tcTemp==_T('n'))
fOk = true, strDest+="\n";
if(tcTemp==_T('r'))
fOk = true, strDest+="\r";
if(tcTemp==_T('\\'))
fOk = true, strDest+="\\";
if(tcTemp==_T('x') && ((i+2)<nLen))
{
TCHAR szHex[3];
szHex[0] =strSource[i+1];
szHex[1] =strSource[i+2];
szHex[2] ='\0';
strDest+=(TCHAR)(_tcstoul(szHex,NULL,16));
fOk = true;
}
if(!fOk)
strDest+=tcTemp;
fEscapeNext = false;
continue;
}
if(tcTemp=='\\')
{
fEscapeNext = true;
continue;
}
strDest+=tcTemp;
}
return strDest;
}
static std::tstring strEscapeBraces(const std::tstring& strSource)
{
std::tstring strDest;
int nLen = (int)strSource.length();
int i;
TCHAR tcBefore,tcTemp;
bool fSkip;
if(nLen==0)
return strSource;
tcBefore =_T('\0');
for(i=0;i<nLen;i++)
{
fSkip =false;
tcTemp =strSource[i];
if(tcBefore!=_T('\\') && tcTemp==_T('{'))
strDest+=_T("{{"), fSkip=true;
if(tcBefore!=_T('\\') && tcTemp==_T('}'))
strDest+=_T("}}"), fSkip=true;
if(!fSkip)
strDest+=tcTemp;
tcBefore =tcTemp;
}
return strDest;
}
static std::tstring strUnescapeBraces(const std::tstring& strSource)
{
std::tstring strDest;
int nLen = (int)strSource.length();
int i;
TCHAR tcTemp;
bool fSkip;
if(nLen==0)
return strSource;
for(i=0;i<nLen-1;i++)
{
fSkip =false;
tcTemp =strSource[i];
if(tcTemp=='\\' && strSource[i+1]=='{')
{
strDest +=_T("\\{");
fSkip=true;
i++;
}
if(tcTemp=='\\' && strSource[i+1]=='}')
{
strDest +=_T("\\}");
fSkip=true;
i++;
}
if(!fSkip)
strDest +=tcTemp;
}
if(i<nLen)
strDest+=strSource[i];
return strDest;
}
};
class ctkExceptionBase
{
// Construction/Destruction
public:
ctkExceptionBase(HRESULT hr, LPCTSTR lpszCause=NULL, DWORD dwData = 0)
{ m_hr=hr; m_dwData=dwData;
if(lpszCause)
{
m_pszCause = new TCHAR[_tcslen(lpszCause)+1];
_tcscpy(m_pszCause,lpszCause);
}
else
m_pszCause = NULL;
};
ctkExceptionBase(const ctkExceptionBase& other)
{
m_hr =other.m_hr;
m_dwData=other.m_dwData;
if(other.m_pszCause)
{
m_pszCause = new TCHAR[_tcslen(other.m_pszCause)+1];
_tcscpy(m_pszCause, other.m_pszCause);
}
else
m_pszCause = NULL;
}
virtual ~ctkExceptionBase()
{ delete[] m_pszCause; };
// Attributes
protected:
HRESULT m_hr;
TCHAR *m_pszCause;
DWORD m_dwData;
// Operatoins
public:
HRESULT Error() const
{ return m_hr; };
LPCTSTR ErrorString() const
{ return m_pszCause; };
LPCTSTR ErrorCode() const
{ return LookupError(m_hr)->lpszDesc; };
void SetErrorString(LPCTSTR lpszString)
{ delete[] m_pszCause;
if(lpszString)
{
m_pszCause = new TCHAR[_tcslen(lpszString)+1];
_tcscpy(m_pszCause, lpszString);
}
else
m_pszCause = NULL;
};
DWORD GetData() const
{ return m_dwData; };
void SetData(DWORD dwData)
{ m_dwData = dwData; };
};
template<class _value_type, class _Pr >
class key_comp : public std::binary_function<const _value_type&,const _value_type::first_type&, bool>
{
public:
typedef _value_type first_argument_type;
typedef _value_type::first_type second_argument_type;
_Pr pred;
bool operator() (const _value_type& e1, const _value_type::first_type& e2) const
{
return pred(e1.first,e2 );
}
};
template<class _value_type, class _Pr >
class key_comp_rev : public std::binary_function<const _value_type::first_type&,const _value_type&, bool>
{
public:
typedef _value_type::first_type first_argument_type;
typedef _value_type second_argument_type;
_Pr pred;
bool operator() (const _value_type::first_type& e1, const _value_type& e2) const
{
return pred(e1,e2.first );
}
};
template<class _value_type, class _Pr >
class sort_comp : public std::binary_function<const _value_type&,const _value_type&, bool>
{
public:
typedef _value_type first_argument_type;
typedef _value_type second_argument_type;
_Pr pred;
bool operator() (const _value_type& e1, const _value_type& e2) const
{
return pred(e1.first, e2.first );
}
};
template<class _K, class _Ty, class _Pr = std::less<_K> >
class ctkMultiMap : public std::vector< std::pair<_K,_Ty> >
{
// Construction/Destruction
public:
ctkMultiMap()
: eState(state_initialization)
{};
virtual ~ctkMultiMap() {};
// Typedefs
public:
typedef std::pair<_K,_Ty> value_type;
typedef _K key_type;
typedef _Ty data_type;
typedef _Ty mapped_type;
typedef _Pr key_compare;
enum estate
{
state_initialization,
state_query
};
// Attributes
protected:
key_comp<value_type, _Pr> k;
key_comp_rev<value_type, _Pr> kr;
sort_comp<value_type, _Pr> s;
estate eState;
// Operations
public:
// Sets or resets status to initialization stage (clears all content)
void vSetInitStage() { clear(); eState = state_initialization; };
// Sets status to query stage
void vSetQueryStage();
// "Multimap" operations multimap
public:
void insert(const value_type& _Val);
void insert(iterator /*where*/, const value_type& _Val) { insert(_Val); };
void erase(iterator) { ASSERT(FALSE); };
void erase(iterator,iterator) { ASSERT(FALSE); };
void erase(const key_type& key) { ASSERT(FALSE); };
iterator find(const key_type& key);
const_iterator find(const key_type& key) const;
};
template<class _K, class _Ty, class _Pr>
void ctkMultiMap<_K,_Ty,_Pr>::vSetQueryStage()
{
eState = state_query;
if(empty()) return;
std::stable_sort(begin(),end(),s);
}
template<class _K, class _Ty, class _Pr>
void ctkMultiMap<_K,_Ty,_Pr>::insert(const value_type& _Val)
{
ASSERT(eState==state_initialization);
push_back(_Val);
}
template<class _K, class _Ty, class _Pr>
ctkMultiMap<_K,_Ty,_Pr>::iterator ctkMultiMap<_K,_Ty,_Pr>::find(const key_type& key)
{
if(eState==state_initialization)
{
if(empty()) return end();
for(iterator it=begin();it!=end();it++)
{
if( !k( (*it), key ) && !kr( key, (*it) ) )
return it;
}
return end();
}
else
{
if(empty()) return end();
ASSERT(eState==state_query);
iterator it = std::lower_bound(begin(),end(),key,k );
if(it!=end() && it->first!=key)
return end();
else
return it;
}
}
template<class _K, class _Ty, class _Pr>
ctkMultiMap<_K,_Ty,_Pr>::const_iterator ctkMultiMap<_K,_Ty,_Pr>::find(const key_type& key) const
{
if(eState==state_initialization)
{
if(empty()) return end();
for(const_iterator it=begin();it!=end();it++)
{
if( !k( (*it), key ) && !kr( key, (*it) ) )
return it;
}
return end();
}
else
{
ASSERT(eState==state_query);
if(empty()) return end();
return std::lower_bound(begin(),end(),key,k );
}
}
template<class _K, class _Ty>
class ctkTableMap : public std::vector< std::pair<_K,_Ty> >
{
// Construction/Destruction
public:
ctkTableMap()
{
ASSERT(sizeof(_K)==1);
vSetInitStage();
};
virtual ~ctkTableMap() {};
// Typedefs
public:
typedef std::pair<_K,_Ty> value_type;
typedef _K key_type;
typedef _Ty data_type;
typedef _Ty mapped_type;
// Operations
public:
// Sets or resets status to initialization stage (clears all content)
void vSetInitStage();
// Sets status to query stage
void vSetQueryStage() {};
// "Multimap" operations multimap
public:
void insert(const value_type& _Val);
void insert(iterator /*where*/, const value_type& _Val) { insert(_Val); };
void erase(iterator) { ASSERT(FALSE); };
void erase(iterator,iterator) { ASSERT(FALSE); };
void erase(const key_type& key) { ASSERT(FALSE); };
iterator find(const key_type& key);
const_iterator find(const key_type& key) const;
};
template<class _K, class _Ty>
void ctkTableMap<_K,_Ty>::vSetInitStage()
{
int bound = 1<<(sizeof(_K)*8);
clear();
resize(bound);
for(iterator it=begin();it!=end();it++) it->first = bound-1;
}
template<class _K, class _Ty>
void ctkTableMap<_K,_Ty>::insert(const value_type& val)
{
if(val.first==0)
push_back(val);
else
{
ASSERT(at(val.first).first==-1 );
at(val.first) = val;
}
}
template<class _K, class _Ty>
ctkTableMap<_K,_Ty>::iterator ctkTableMap<_K,_Ty>::find(const key_type& key)
{
if( key==0 )
return begin()+(1<<(sizeof(_K)*8));
if( at(key).first==-1 )
return end();
return begin()+key;
}
template<class _K, class _Ty>
ctkTableMap<_K,_Ty>::const_iterator ctkTableMap<_K,_Ty>::find(const key_type& key) const
{
if( at(key).first==-1 )
return end();
return begin()+key;
}
#endif // !defined(AFX_CTKMISC_H__02DB3E9E_00AB_4FC7_9F58_E01EECC31A91__INCLUDED_)