//----------------------------------------------------------------------------
// ObjectWindows
// Copyright (c) 1995, 1996 by Borland International, All Rights Reserved
//
/// \file
/// Reliable platform independent header for common memory and string functions
//
//----------------------------------------------------------------------------
#if !defined(OWL_PRIVATE_MEMORY_H)
#define OWL_PRIVATE_MEMORY_H
#include <owl/private/defs.h>
#if defined(BI_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <tchar.h>
#if defined(BI_COMP_BORLANDC)
# include <mem.h>
#else
# include <memory.h>
#endif
#if !defined(__STRING_H) && !defined(_INC_STRING)
# include <string.h>
#endif
#if !defined(BI_COMP_GNUC)
# include <stdlib.h>
#endif
#include <malloc.h>
#if !defined(BI_COMP_BORLANDC) && !(defined(__GNUC__) && (__GNUC__ >= 3))
# define alloca _alloca
#endif
#if !defined(OWL_PRIVATE_WSYSINC_H)
# include <owl/private/wsysinc.h>
#endif
#if defined(BI_NEED_TCHAR)
# if defined(BI_COMP_BORLANDC)
inline int _tcscmp(const _TCHAR* s1, const _TCHAR* s2)
{return lstrcmp(s1, s2);}
inline int _tcsicmp(const _TCHAR* s1, const _TCHAR* s2)
{return lstrcmpi(s1, s2);}
# endif
# if !defined(strcmpi)
inline int strcmpi(const _TCHAR* s1, const _TCHAR* s2)
{return lstrcmpi(s1, s2);}
# endif //strcmpi
#endif
/// Return the number of bytes of the first character of the passed string
inline UINT CharSize(const _TCHAR* s) {return static_cast<UINT>(sizeof(_TCHAR) * (::CharNext(s) - s));}
inline _TCHAR CharUpper(_TCHAR c) {::CharUpperBuff(&c,1); return c;}
inline _TCHAR CharLower(_TCHAR c) {::CharLowerBuff(&c,1); return c;}
#if defined(_CONVERSION_USES_THREAD_LOCALE)
# define BI_CONVERSION_USES_THREAD_LOCALE
#endif
#if !defined(USES_CONVERSION)
# ifdef BI_CONVERSION_USES_THREAD_LOCALE
# define OWL_USES_CONVERSION_ACP_INIT_ GetACP()
# else
# define OWL_USES_CONVERSION_ACP_INIT_ CP_ACP
# endif
# define USES_CONVERSION\
int _convert = 0; static_cast<void>(_convert);\
UINT _acp = OWL_USES_CONVERSION_ACP_INIT_; static_cast<void>(_acp);\
LPCWSTR _lpw = NULL; static_cast<void>(_lpw);\
LPCSTR _lpa = NULL; static_cast<void>(_lpa)
#endif
// Global UNICODE<>ANSI translation helpers
inline LPWSTR OwlA2WHelper(LPWSTR lpw, LPCSTR lpa, int nChars, unsigned int acp)
{
// verify that no illegal character present
// since lpw was allocated based on the size of lpa
// don't worry about the number of chars
lpw[0] = '\0';
MultiByteToWideChar(acp, 0, lpa, -1, lpw, nChars);
return lpw;
}
inline LPSTR OwlW2AHelper(LPSTR lpa, LPCWSTR lpw, int nChars, unsigned int acp)
{
// verify that no illegal character present
// since lpa was allocated based on the size of lpw
// don't worry about the number of chars
lpa[0] = '\0';
WideCharToMultiByte(acp, 0, lpw, -1, lpa, nChars, NULL, NULL);
return lpa;
}
inline LPWSTR OwlA2WHelper(LPWSTR lpw, LPCSTR lpa, int nChars)
{
return OwlA2WHelper(lpw, lpa, nChars, CP_ACP);
}
inline LPSTR OwlW2AHelper(LPSTR lpa, LPCWSTR lpw, int nChars)
{
return OwlW2AHelper(lpa, lpw, nChars, CP_ACP);
}
# ifdef BI_CONVERSION_USES_THREAD_LOCALE
# ifdef OWLA2WHELPER
# undef OWLA2WHELPER
# undef OWLW2AHELPER
# endif
# define OWLA2WHELPER OwlA2WHelper
# define OWLW2AHELPER OwlW2AHelper
# else
# ifndef OWLA2WHELPER
# define OWLA2WHELPER OwlA2WHelper
# define OWLW2AHELPER OwlW2AHelper
# endif
# endif
# if defined(BI_CONVERSION_USES_THREAD_LOCALE)
# if !defined(A2W)
# define A2W(lpa) (\
((_lpa = lpa) == NULL) ? NULL : (\
_convert = (lstrlenA(_lpa)+1),\
OWLA2WHELPER((LPWSTR) alloca(_convert*2), _lpa, _convert, _acp)))
# endif
# if !defined(A2WB)
# define A2WB(lpa,buf) (\
((_lpa = lpa) == NULL) ? NULL : (\
_convert = (lstrlenA(_lpa)+1),\
OWLA2WHELPER((LPWSTR) buf, _lpa, _convert, _acp)))
# endif
# else
# if !defined(A2W)
# define A2W(lpa) (\
((_lpa = lpa) == NULL) ? NULL : (\
_convert = (lstrlenA(_lpa)+1),\
OWLA2WHELPER((LPWSTR) alloca(_convert*2), _lpa, _convert)))
# endif
# if !defined(A2WB)
# define A2WB(lpa,buf) (\
((_lpa = lpa) == NULL) ? NULL : (\
_convert = (lstrlenA(_lpa)+1),\
OWLA2WHELPER((LPWSTR) buf, _lpa, _convert)))
# endif
# endif
# ifdef BI_CONVERSION_USES_THREAD_LOCALE
# if !defined(W2A)
# define W2A(lpw) (\
((_lpw = lpw) == NULL) ? NULL : (\
_convert = (lstrlenW(_lpw)+1)*2,\
OWLW2AHELPER((LPSTR) alloca(_convert), _lpw, _convert, _acp)))
# endif
# if !defined(W2AB)
# define W2AB(lpw,buf) (\
((_lpw = lpw) == NULL) ? NULL : (\
_convert = (lstrlenW(_lpw)+1)*2,\
OWLW2AHELPER((LPSTR) buf, _lpw, _convert, _acp)))
# endif
# else
# if !defined(W2A)
# define W2A(lpw) (\
((_lpw = lpw) == NULL) ? NULL : (\
_convert = (lstrlenW(_lpw)+1)*2,\
OWLW2AHELPER((LPSTR) alloca(_convert), _lpw, _convert)))
# endif
# if !defined(W2AB)
# define W2AB(lpw,buf) (\
((_lpw = lpw) == NULL) ? NULL : (\
_convert = (lstrlenW(_lpw)+1)*2,\
OWLW2AHELPER((LPSTR) buf, _lpw, _convert)))
# endif
# endif
# if !defined(A2CW)
# define A2CW(lpa) ((LPCWSTR)A2W(lpa))
# endif
# if !defined(W2CA)
# define W2CA(lpw) ((LPCSTR)W2A(lpw))
# endif
# if !defined(A2CWB)
# define A2CWB(lpa,buf) ((LPCWSTR)A2WB(lpa,buf))
# endif
# if !defined(W2CAB)
# define W2CAB(lpw,buf) ((LPCSTR)W2AB(lpw,buf))
# endif
//////////////////////////////
// Usefull macros
// _USES_CONVERSION -> set variables if UNICODE
// _USES_CONVERSION_A -> set variables if not UNICODE
// _W2A(lpw) -> W to A convert if UNICODE
// _A2W(lpw) -> A to W convert if UNICODE
// _W2AB(lpw,buf) -> W to A convert if UNICODE using buffer
// _A2WB(lpw,buf) -> A to W convert if UNICODE using buffer
// _W2A_A(lpw) -> W to A convert if not UNICODE
// _A2W_A(lpw) -> A to W convert if not UNICODE
// _W2A_AB(lpw,buf) -> W to A convert if not UNICODE using buffer
// _A2W_AB(lpw,buf) -> A to W convert if not UNICODE using buffer
#if defined(UNICODE)
# define _USES_CONVERSION USES_CONVERSION
# define _USES_CONVERSION_A
# define _W2A(lpw) W2A(lpw)
# define _A2W(lpw) A2W(lpw)
# define _W2AB(lpw,buf) W2AB(lpw,buf)
# define _A2WB(lpw,buf) A2WB(lpw,buf)
# define _W2A_A(lpw) lpw
# define _A2W_A(lpw) lpw
# define _W2A_AB(lpw,buf) lpw
# define _A2W_AB(lpw,buf) lpw
#else
# define _USES_CONVERSION
# define _USES_CONVERSION_A USES_CONVERSION
# define _W2A(lpw) lpw
# define _A2W(lpw) lpw
# define _W2AB(lpw,buf) lpw
# define _A2WB(lpw,buf) lpw
# define _W2A_A(lpw) W2A(lpw)
# define _A2W_A(lpw) A2W(lpw)
# define _W2A_AB(lpw,buf) W2AB(lpw,buf)
# define _A2W_AB(lpw,buf) A2WB(lpw,buf)
#endif
namespace owl {
/// \cond NoSuppressDoxygenWarning
#include <owl/preclass.h>
/// \endcond
/// \addtogroup utility_group
/// @{
//
/// \class TCharIterator
// ~~~~~ ~~~~~~~~~~~~~
//
template<class T> class TCharIterator {
public:
TCharIterator(T* p);
T* Next() const;
T* Current() const;
T* operator ++(); // prefix
T* operator ++(int); // postfix
operator T*() const;
protected:
T* P;
};
//
/// \class TBidirCharIterator
// ~~~~~ ~~~~~~~~~~~~~~~~~~
//
template<class T> class TBidirCharIterator : public TCharIterator<T> {
public:
TBidirCharIterator(T* begin, T* p);
T* Prev() const;
T* operator --(); // prefix
T* operator --(int); // postfix
private:
T* Begin;
};
//
/// \class TTmpBufferBase
// ~~~~~ ~~~~~~~~~~~~~~
/// Static temporary fixed buffer, provides fast temporary buffer, for use in functions
//
/// For example:
/// \code
/// TTmpBuffer<_TCHAR> buffer(MAX_PATH);
/// GetWindowDirectory(buffer,MAX_PATH);
/// \endcode
//
class _OWLCLASS TTmpBufferBase {
protected:
TTmpBufferBase(int size);
~TTmpBufferBase();
protected:
void* Buffer;
int Index;
private:
TTmpBufferBase(const TTmpBufferBase& buff);
TTmpBufferBase& operator=(const TTmpBufferBase& buff);
void* operator new(size_t) noexcept; // prohibit use of new
};
//
template<class T> class TTmpBuffer: public TTmpBufferBase {
public:
TTmpBuffer(int size) : TTmpBufferBase(size*sizeof(T)){}
T& operator *() {return *(T*)Buffer;}
operator T*() {return (T*)Buffer;}
const bool operator !() const {return Buffer==0;}
T& operator[](int i) {return ((T*)Buffer)[i];}
};
/// @}
/// \cond NoSuppressDoxygenWarning
#include <owl/posclass.h>
/// \endcond
//
template<class T> inline TCharIterator<T>::TCharIterator(T* p)
: P(p)
{
}
//
template<class T> inline T* TCharIterator<T>::Next() const
{
#if defined(BI_DBCS_SUPPORT)
return *P ? ::AnsiNext(P) : P + 1;
#else
return P + 1;
#endif
}
//
template<class T> inline T* TCharIterator<T>::Current() const
{
return P;
}
//
template<class T> inline T* TCharIterator<T>::operator ++()
{
return P = Next();
}
//
template<class T> inline T* TCharIterator<T>::operator ++(int)
{
T* p = P;
P = Next();
return p;
}
//
template<class T> inline TCharIterator<T>::operator T*() const
{
return P;
}
//
template<class T> inline TBidirCharIterator<T>::TBidirCharIterator(T* begin, T* p)
:
TCharIterator<T>(p), Begin(begin)
{
}
//
template<class T> inline T* TBidirCharIterator<T>::Prev() const
{
#if defined(BI_DBCS_SUPPORT)
return ::AnsiPrev(Begin, this->P);
#else
return this->P > Begin ? this->P - 1 : this->P;
#endif
}
//
template<class T> inline T* TBidirCharIterator<T>::operator --() // prefix
{
return this->P = Prev();
}
//
template<class T> inline T* TBidirCharIterator<T>::operator --(int) // postfix
{
T* p = this->P;
this->P = Prev();
return p;
}
} // OWL namespace
//
// Type overloaded version of Window's huge mem copy (hmemcpy) for flat memory
// models.
//
// inline void hmemcpy(void* d, const void* s, long n) {memcpy(d, s, n);}
//
// A C++ version of strdup(), strnewdup(). Uses new char[], to allow duplicated
// strings to be deleted[].
// Also a string version of atol for near data models
//
_OWLFUNC(char*) strnewdup(const char* s, size_t minAllocSize = 0);
# define nstrnewdup strnewdup
# if !defined(_WCHAR_T_DEFINED)
typedef unsigned short wchar_t;
# define _WCHAR_T_DEFINED
# endif
_OWLFUNC(wchar_t*) strnewdup(const wchar_t* s, size_t minAllocSize = 0);
#endif // OWL_PRIVATE_MEMORY_H
↑ V302 Member operator[] of 'TTmpBuffer' class has a 32-bit type argument. Use memsize-type here.
↑ V1062 The 'TTmpBufferBase' class defines a custom 'new' operator. The 'delete' operator must also be defined.