home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 1997 April
/
Chip_1997-04_cd.bin
/
prezent
/
cb
/
data.z
/
DSTRING.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1997-01-16
|
25KB
|
871 lines
//---------------------------------------------------------------------------
// dstring.cpp - support for delphi strings in cpp
//---------------------------------------------------------------------------
// $Revision: 1.32 $
//-------------------------------------------------------------------------
// copyright (c) 1996 Borland International
//----------------------------------------------------------------------------
#pragma inline
// PRONTO_NAMESPACES must be defined when .HPP headers were generated
// with namespace enabled.. //!BB
//
// #define PRONTO_NAMESPACES
#include <windows.hpp>
#include <sysutils.hpp>
#include <string.h>
#include <stdlib.h>
#include <dstring.h>
#ifdef near
#undef near
#endif
#if defined(PRONTO_NAMESPACES)
namespace System
{
#endif
//---------------------------------------------------------------------------
__fastcall AnsiString::AnsiString(const char*)
{
asm
{
#if defined(PRONTO_NAMESPACES)
extrn @System@@LStrFromPChar$qqrv:near
#else
extrn @@LStrFromPChar$qqrv:near
#endif
xor ecx,ecx
mov eax, this
mov [eax], ecx
#if defined(PRONTO_NAMESPACES)
call @System@@LStrFromPChar$qqrv
#else
call @@LStrFromPChar$qqrv
#endif
}
}
//---------------------------------------------------------------------------
__fastcall AnsiString::AnsiString(const AnsiString&)
{
asm
{
#if defined(PRONTO_NAMESPACES)
extrn @System@@LStrAsg$qqrv:near
#else
extrn @@LStrAsg$qqrv:near
#endif
mov edx,[edx] //!JK Do this first, Peter is relying on this!
xor ecx,ecx
mov eax, this
mov [eax],ecx
#if defined(PRONTO_NAMESPACES)
call @System@@LStrAsg$qqrv
#else
call @@LStrAsg$qqrv
#endif
}
}
//---------------------------------------------------------------------------
__fastcall AnsiString::AnsiString(const char*, unsigned char len)
{
asm
{
#if defined(PRONTO_NAMESPACES)
extrn @System@@LStrFromArray$qqrv:near
#else
extrn @@LStrFromArray$qqrv:near
#endif
xor ecx,ecx
mov eax, this
mov [eax],ecx
mov cl, len
#if defined(PRONTO_NAMESPACES)
call @System@@LStrFromArray$qqrv
#else
call @@LStrFromArray$qqrv
#endif
}
}
//---------------------------------------------------------------------------
__fastcall AnsiString::AnsiString(const wchar_t* src)
{
int len = WideCharToMultiByte(CP_ACP, 0, const_cast<wchar_t*>(src), -1, 0,
0, 0, 0);
if (len == 1)
Data = 0;
else
{
char* buffer = new char[len];
len = WideCharToMultiByte(CP_ACP, 0, const_cast<wchar_t*>(src), -1,
buffer, len, 0, 0);
asm
{
#if defined(PRONTO_NAMESPACES)
extrn @System@@LStrFromArray$qqrv:near
#else
extrn @@LStrFromArray$qqrv:near
#endif
mov eax, this
xor ecx,ecx
mov [eax],ecx
mov ecx, len
mov edx, buffer
#if defined(PRONTO_NAMESPACES)
call @System@@LStrFromArray$qqrv
#else
call @@LStrFromArray$qqrv
#endif
}
//!JK redo this routine, don't mess with the stack (with C++ in between)
asm push eax
delete[] buffer;
asm pop eax
}
}
//---------------------------------------------------------------------------
__fastcall AnsiString::AnsiString(char src)
{
char s[2];
char* sptr = s;
s[0] = src;
s[1] = 0;
asm
{
#if defined(PRONTO_NAMESPACES)
extrn @System@@LStrFromPChar$qqrv:near
#else
extrn @@LStrFromPChar$qqrv:near
#endif
xor ecx,ecx
mov eax, this
mov [eax], ecx
mov edx, sptr
#if defined(PRONTO_NAMESPACES)
call @System@@LStrFromPChar$qqrv
#else
call @@LStrFromPChar$qqrv
#endif
}
}
//---------------------------------------------------------------------------
__fastcall AnsiString::AnsiString(int src)
{
Data = 0;
#if defined(PRONTO_NAMESPACES)
*this = Sysutils::IntToStr(src);
#else
*this = ::IntToStr(src);
#endif
}
//---------------------------------------------------------------------------
__fastcall AnsiString::AnsiString(double src)
{
Data = 0;
#if defined(PRONTO_NAMESPACES)
*this = Sysutils::FloatToStr(src);
#else
*this = ::FloatToStr(src);
#endif
}
//---------------------------------------------------------------------------
__fastcall AnsiString::~AnsiString()
{
asm
{
#if defined(PRONTO_NAMESPACES)
extrn @System@@LStrClr$qqrv:near
#else
extrn @@LStrClr$qqrv:near
#endif
//!JK don't even think of removing the mov eax, this line
//!JK apparently, the this ptr is not in eax on destructors
mov eax,this
#if defined(PRONTO_NAMESPACES)
call @System@@LStrClr$qqrv
#else
call @@LStrClr$qqrv
#endif
}
}
//---------------------------------------------------------------------------
AnsiString& __fastcall AnsiString::operator=(const AnsiString&)
{
asm
{
#if defined(PRONTO_NAMESPACES)
extrn @System@@LStrAsg$qqrv:near
#else
extrn @@LStrAsg$qqrv:near
#endif
mov edx,[edx]
#if defined(PRONTO_NAMESPACES)
call @System@@LStrAsg$qqrv
#else
call @@LStrAsg$qqrv
#endif
}
return *this;
}
//---------------------------------------------------------------------------
AnsiString& __fastcall AnsiString::operator+=(const AnsiString&)
{
asm
{
#if defined(PRONTO_NAMESPACES)
extrn @System@@LStrCat$qqrv:near
#else
extrn @@LStrCat$qqrv:near
#endif
mov edx,[edx]
#if defined(PRONTO_NAMESPACES)
call @System@@LStrCat$qqrv
#else
call @@LStrCat$qqrv
#endif
}
return *this;
}
//---------------------------------------------------------------------------
AnsiString __fastcall AnsiString::operator+(const AnsiString& rhs) const
{
//!JK Per Peter S., change to push 0 onto the stack
//!JK and use as the first parm
//!JK need to take out double contruction (return tmp)
AnsiString tmp;
AnsiString* ptmp = &tmp;
asm
{
#if defined(PRONTO_NAMESPACES)
extrn @System@@LStrCat3$qqrv:near
#else
extrn @@LStrCat3$qqrv:near
#endif
mov edx, this
mov edx, [edx]
mov eax, ptmp
mov ecx, rhs
mov ecx, [ecx]
#if defined(PRONTO_NAMESPACES)
call @System@@LStrCat3$qqrv
#else
call @@LStrCat3$qqrv
#endif
}
return tmp;
}
//---------------------------------------------------------------------------
bool __fastcall AnsiString::operator==(const AnsiString&) const
{
asm
{
#if defined(PRONTO_NAMESPACES)
extrn @System@@LStrCmp$qqrv:near
#else
extrn @@LStrCmp$qqrv:near
#endif
mov eax, [eax]
mov edx, [edx]
#if defined(PRONTO_NAMESPACES)
call @System@@LStrCmp$qqrv
#else
call @@LStrCmp$qqrv
#endif
sete al
and eax, 1
}
}
//---------------------------------------------------------------------------
bool __fastcall AnsiString::operator!=(const AnsiString&) const
{
asm
{
#if defined(PRONTO_NAMESPACES)
extrn @System@@LStrCmp$qqrv:near
#else
extrn @@LStrCmp$qqrv:near
#endif
mov eax, [eax]
mov edx, [edx]
#if defined(PRONTO_NAMESPACES)
call @System@@LStrCmp$qqrv
#else
call @@LStrCmp$qqrv
#endif
setne al
and eax, 1
}
}
//---------------------------------------------------------------------------
bool __fastcall AnsiString::operator<(const AnsiString&) const
{
asm
{
#if defined(PRONTO_NAMESPACES)
extrn @System@@LStrCmp$qqrv:near
#else
extrn @@LStrCmp$qqrv:near
#endif
mov eax, [eax]
mov edx, [edx]
#if defined(PRONTO_NAMESPACES)
call @System@@LStrCmp$qqrv
#else
call @@LStrCmp$qqrv
#endif
setb al
and eax, 1
}
}
//---------------------------------------------------------------------------
bool __fastcall AnsiString::operator>(const AnsiString&) const
{
asm
{
#if defined(PRONTO_NAMESPACES)
extrn @System@@LStrCmp$qqrv:near
#else
extrn @@LStrCmp$qqrv:near
#endif
mov eax, [eax]
mov edx, [edx]
#if defined(PRONTO_NAMESPACES)
call @System@@LStrCmp$qqrv
#else
call @@LStrCmp$qqrv
#endif
seta al
and eax, 1
}
}
//---------------------------------------------------------------------------
bool __fastcall AnsiString::operator<=(const AnsiString& rhs) const
{
return !operator>(rhs);
}
//---------------------------------------------------------------------------
bool __fastcall AnsiString::operator >=(const AnsiString& rhs) const
{
return !operator<(rhs);
}
//---------------------------------------------------------------------------
int __fastcall AnsiString::AnsiCompare(const AnsiString& rhs) const
{
#if defined(PRONTO_NAMESPACES)
return Sysutils::AnsiCompareStr(*this, rhs);
#else
return ::AnsiCompareStr(*this, rhs);
#endif
}
//---------------------------------------------------------------------------
int __fastcall AnsiString::AnsiCompareIC(const AnsiString& rhs) const
{
#if defined(PRONTO_NAMESPACES)
return Sysutils::AnsiCompareText(*this, rhs);
#else
return ::AnsiCompareText(*this, rhs);
#endif
}
//---------------------------------------------------------------------------
int __fastcall AnsiString::Length() const
{
asm
{
#if defined(PRONTO_NAMESPACES)
extrn @System@@LStrLen$qqrv:near
#else
extrn @@LStrLen$qqrv:near
#endif
mov eax, [eax]
#if defined(PRONTO_NAMESPACES)
call @System@@LStrLen$qqrv
#else
call @@LStrLen$qqrv
#endif
}
}
//---------------------------------------------------------------------------
bool __fastcall AnsiString::IsEmpty() const
{
asm
{
mov eax, [eax]
test eax, eax
sete al
and eax, 1
}
}
//---------------------------------------------------------------------------
// Return AnsiString of count chars of value ch
AnsiString __fastcall AnsiString::StringOfChar(char ch, int count)
{
char* s = new char[count+1];
for (int i = 0; i < count; i++)
s[i] = ch;
s[count] = 0;
AnsiString tmp(s);
delete [] s;
return tmp;
}
//---------------------------------------------------------------------------
AnsiString __fastcall AnsiString::LoadStr(int ident)
{
#if defined(PRONTO_NAMESPACES)
return Sysutils::LoadStr(ident);
#else
return ::LoadStr(ident);
#endif
}
//---------------------------------------------------------------------------
AnsiString __fastcall AnsiString::FmtLoadStr(int ident, const TVarRec* args,
int size)
{
#if defined(PRONTO_NAMESPACES)
return Sysutils::FmtLoadStr(ident, args, size);
#else
return ::FmtLoadStr(ident, args, size);
#endif
}
//---------------------------------------------------------------------------
AnsiString __fastcall AnsiString::Format(const AnsiString& format,
const TVarRec *args, int size)
{
#if defined(PRONTO_NAMESPACES)
return Sysutils::Format(format, args, size);
#else
return ::Format(format, args, size);
#endif
}
//---------------------------------------------------------------------------
AnsiString __fastcall AnsiString::FormatFloat(const AnsiString& format,
const long double& value)
{
#if defined(PRONTO_NAMESPACES)
return Sysutils::FormatFloat(format, value);
#else
return ::FormatFloat(format, value);
#endif
}
//---------------------------------------------------------------------------
AnsiString __fastcall AnsiString::FloatToStrF(long double value,
TStringFloatFormat format, int precision, int digits)
{
//!JK this code requires TStringFloatFormat and TFloatFormat to be identical
#if defined(PRONTO_NAMESPACES)
return Sysutils::FloatToStrF(value, TFloatFormat(format), precision, digits);
#else
return ::FloatToStrF(value, TFloatFormat(format), precision, digits);
#endif
}
//---------------------------------------------------------------------------
AnsiString __fastcall AnsiString::IntToHex(int value, int digits)
{
#if defined(PRONTO_NAMESPACES)
return Sysutils::IntToHex(value, digits);
#else
return ::IntToHex(value, digits);
#endif
}
//---------------------------------------------------------------------------
AnsiString __fastcall AnsiString::CurrToStr(Currency value)
{
#if !defined(PRONTO_NAMESPACES)
return ::CurrToStr(value);
#else
return Sysutils::CurrToStr(value);
#endif
}
//---------------------------------------------------------------------------
AnsiString __fastcall AnsiString::CurrToStrF(Currency value,
TStringFloatFormat format, int digits)
{
//!JK this code requires TStringFloatFormat and TFloatFormat to be identical
#if !defined(PRONTO_NAMESPACES)
return ::CurrToStrF(value, TFloatFormat(format), digits);
#else
return Sysutils::CurrToStrF(value, TFloatFormat(format), digits);
#endif
}
//---------------------------------------------------------------------------
int __fastcall AnsiString::WideCharBufSize() const
{
// return size of buffer required to call WideChar()
return MultiByteToWideChar(CP_ACP,0,(Data)? Data: (const PChar)"", -1, 0,0);
}
//---------------------------------------------------------------------------
//Convert to Unicode
wchar_t* __fastcall AnsiString::WideChar(wchar_t* dest, int destSize) const
{
MultiByteToWideChar(CP_ACP,0,(Data)?Data: (const PChar)"",-1,dest,destSize);
return dest;
}
//---------------------------------------------------------------------------
void __fastcall AnsiString::Unique()
{
#if defined(PRONTO_NAMESPACES)
System::UniqueString(*this);
#else
::UniqueString(*this);
#endif
}
//---------------------------------------------------------------------------
void __fastcall AnsiString::Insert(const String& source, int index)
{
asm
{
#if defined(PRONTO_NAMESPACES)
extrn @System@@LStrInsert$qqrv:near
#else
extrn @@LStrInsert$qqrv:near
#endif
//!JK edx must be a pointer to the characters
mov edx, this
//!JK eax must be the characters themselves!
mov eax, source
mov eax, [eax]
mov ecx, index
#if defined(PRONTO_NAMESPACES)
call @System@@LStrInsert$qqrv
#else
call @@LStrInsert$qqrv
#endif
}
}
//---------------------------------------------------------------------------
void __fastcall AnsiString::Delete(int index, int count)
{
asm
{
#if defined(PRONTO_NAMESPACES)
extrn @System@@LStrDelete$qqrv:near
#else
extrn @@LStrDelete$qqrv:near
#endif
//!JK eax must be a pointer to the characters
mov eax, this
mov edx, index
mov ecx, count
#if defined(PRONTO_NAMESPACES)
call @System@@LStrDelete$qqrv
#else
call @@LStrDelete$qqrv
#endif
}
}
//---------------------------------------------------------------------------
void __fastcall AnsiString::SetLength(int newLength)
{
asm
{
#if defined(PRONTO_NAMESPACES)
extrn @System@@LStrSetLength$qqrv:near
#else
extrn @@LStrSetLength$qqrv:near
#endif
//!JK eax must be a pointer to the characters
mov eax, this
mov edx, newLength
#if defined(PRONTO_NAMESPACES)
call @System@@LStrSetLength$qqrv
#else
call @@LStrSetLength$qqrv
#endif
}
}
//---------------------------------------------------------------------------
int __fastcall AnsiString::Pos(const AnsiString& subStr) const
{
asm
{
#if defined(PRONTO_NAMESPACES)
extrn @System@@LStrPos$qqrv:near
#else
extrn @@LStrPos$qqrv:near
#endif
//!JK edx must be the characters themselves!
mov edx, this
mov edx, [edx]
//!JK eax must be the characters themselves!
mov eax, subStr
mov eax, [eax]
#if defined(PRONTO_NAMESPACES)
call @System@@LStrPos$qqrv
#else
call @@LStrPos$qqrv
#endif
//Result left in eax
}
}
//---------------------------------------------------------------------------
AnsiString __fastcall AnsiString::LowerCase() const
{
#if defined(PRONTO_NAMESPACES)
return Sysutils::AnsiLowerCase(*this);
#else
return ::AnsiLowerCase(*this);
#endif
}
//---------------------------------------------------------------------------
AnsiString __fastcall AnsiString::UpperCase() const
{
#if defined(PRONTO_NAMESPACES)
return Sysutils::AnsiUpperCase(*this);
#else
return ::AnsiUpperCase(*this);
#endif
}
//---------------------------------------------------------------------------
AnsiString __fastcall AnsiString::Trim() const
{
#if defined(PRONTO_NAMESPACES)
return Sysutils::Trim(*this);
#else
return ::Trim(*this);
#endif
}
//---------------------------------------------------------------------------
AnsiString __fastcall AnsiString::TrimLeft() const
{
#if defined(PRONTO_NAMESPACES)
return Sysutils::TrimLeft(*this);
#else
return ::TrimLeft(*this);
#endif
}
//---------------------------------------------------------------------------
AnsiString __fastcall AnsiString::TrimRight() const
{
#if defined(PRONTO_NAMESPACES)
return Sysutils::TrimRight(*this);
#else
return ::TrimRight(*this);
#endif
}
//---------------------------------------------------------------------------
AnsiString __fastcall AnsiString::SubString(int index, int count) const
{
AnsiString tmp;
AnsiString* ptmp = &tmp;
asm
{
#if defined(PRONTO_NAMESPACES)
extrn @System@@LStrCopy$qqrv:near
#else
extrn @@LStrCopy$qqrv:near
#endif
//!JK eax must be a pointer to the characters
mov eax, ptmp
push eax
mov ecx, count
mov edx, index
//!JK eax must be the characters themselves
mov eax, this
mov eax, [eax]
#if defined(PRONTO_NAMESPACES)
call @System@@LStrCopy$qqrv
#else
call @@LStrCopy$qqrv
#endif
}
return tmp;
}
//---------------------------------------------------------------------------
int __fastcall AnsiString::ToInt() const
{
#if defined(PRONTO_NAMESPACES)
return Sysutils::StrToInt(*this);
#else
return ::StrToInt(*this);
#endif
}
//---------------------------------------------------------------------------
int __fastcall AnsiString::ToIntDef(int defaultValue) const
{
#if defined(PRONTO_NAMESPACES)
return Sysutils::StrToIntDef(*this, defaultValue);
#else
return ::StrToIntDef(*this, defaultValue);
#endif
}
//---------------------------------------------------------------------------
double __fastcall AnsiString::ToDouble() const
{
//!JK change this to return a long double when the compiler properly
//!JK promotes/demotes long doubles/doubles
#if defined(PRONTO_NAMESPACES)
return Sysutils::StrToFloat(*this);
#else
return ::StrToFloat(*this);
#endif
}
#if defined(MBCS)
//---------------------------------------------------------------------------
bool __fastcall AnsiString::IsDelimiter(const AnsiString& delimiters, int index) const
{
#if defined(PRONTO_NAMESPACES)
return Sysutils::IsDelimiter(delimiters, *this, index);
#else
return ::IsDelimiter(delimiters, *this, index);
#endif
}
//---------------------------------------------------------------------------
int __fastcall AnsiString::AnsiPos(const AnsiString& subStr) const
{
#if defined(PRONTO_NAMESPACES)
return Sysutils::AnsiPos(subStr, *this);
#else
return ::AnsiPos(subStr, *this);
#endif
}
//---------------------------------------------------------------------------
bool __fastcall AnsiString::IsPathDelimiter(int index) const
{
#if defined(PRONTO_NAMESPACES)
return Sysutils::IsPathDelimiter(*this, index);
#else
return ::IsPathDelimiter(*this, index);
#endif
}
//---------------------------------------------------------------------------
int __fastcall AnsiString::LastDelimiter(const AnsiString& delimiters) const
{
#if defined(PRONTO_NAMESPACES)
return Sysutils::LastDelimiter(delimiters, *this);
#else
return ::LastDelimiter(delimiters, *this);
#endif
}
//---------------------------------------------------------------------------
AnsiString::TStringMbcsByteType __fastcall AnsiString::ByteType(int index) const
{
//!GCD this code requires TStringMbcsByteType and TMbcsByteType to be identical
#if defined(PRONTO_NAMESPACES)
return TStringMbcsByteType(Sysutils::ByteType(*this, index));
#else
return TStringMbcsByteType(::ByteType(*this, index));
#endif
}
//---------------------------------------------------------------------------
bool __fastcall AnsiString::IsLeadByte(int index) const
{
return ByteType(index) == mbLeadByte;
}
//---------------------------------------------------------------------------
bool __fastcall AnsiString::IsTrailByte(int index) const
{
return ByteType(index) == mbTrailByte;
}
//---------------------------------------------------------------------------
char* __fastcall AnsiString::AnsiLastChar() const
{
#if defined(PRONTO_NAMESPACES)
return Sysutils::AnsiLastChar(*this);
#else
return ::AnsiLastChar(*this);
#endif
}
#endif
//---------------------------------------------------------------------------
AnsiString __fastcall operator+(const char* lhs, const AnsiString& rhs)
{
AnsiString tmp(lhs);
AnsiString* ptmp = &tmp;
asm
{
#if defined(PRONTO_NAMESPACES)
extrn @System@@LStrCat$qqrv:near
#else
extrn @@LStrCat$qqrv:near
#endif
mov eax,ptmp
mov edx,rhs
mov edx,[edx]
#if defined(PRONTO_NAMESPACES)
call @System@@LStrCat$qqrv
#else
call @@LStrCat$qqrv
#endif
}
return tmp;
}
//---------------------------------------------------------------------------
static void read_to_delim(istream& strm, char delim, AnsiString& str);
istream& operator >>(istream& is, AnsiString& arg)
{read_to_delim(is, 0, arg);}
//---------------------------------------------------------------------------
static void read_to_delim(istream& strm, char delim, AnsiString& str)
{
char ch;
int nchars = 0;
char array[4096];
int capacity = sizeof array;
while ( 1 )
{
// Read as many characters as we can, up to the delimitor:
strm.get( array+nchars, capacity-nchars+1, delim );
// This is the new string length:
nchars += strlen( array+nchars );
// What stopped us? An EOF?
if( !strm.good() )
break; // EOF encountered (or worse!)
// Nope. Was it the delimiter?
strm.get(ch);
if(ch==delim)
break; // Yup. We're done. Don't put it back on the stream.
else
strm.putback(ch); // Nope, Put it back and keep going.
}
str = array;
}
//---------------------------------------------------------------------------
void __fastcall InitExe()
{
asm
{
#if defined(PRONTO_NAMESPACES)
extrn @System@@InitExe$qqrv:near
call @System@@InitExe$qqrv
#else
extrn @@InitExe$qqrv:near
call @@InitExe$qqrv
#endif
}
}
//---------------------------------------------------------------------
#if defined(PRONTO_NAMESPACES)
}
#endif
//---------------------------------------------------------------------
//!BB The following is a hack that should be moved somewhere else - like
//!BB the startup code. Currently it's not a problem since dstring.obj
//!BB pulled in by the RTL/StartupCode anyway.
//---------------------------------------------------------------------
extern HINSTANCE _hInstance;
extern char __isDLL;
extern char __isGUI;
void InitVCL()
{
VclInit(__isDLL, long(_hInstance), __isGUI);
}
#pragma startup InitVCL 0
void ExitVCL()
{
VclExit();
}
#pragma exit ExitVCL 31