Files
RepoMain/ZCppMain/ZtCStringEx.H
sauron f7636ecc5d commit 2025-08-16 34:34
git add ZCppMain/ZMainHead.H
git add ZCppMain/ZtCArray.H
git add ZCppMain/ZtCObjList.H
git add ZCppMain/ZMainAVL.H
git add ZCppMain/ZMainHeadEx.H
git add ZCppMain/ZMainXhtml.H
git add ZCppMain/ZtCLoadDataBlock.H
git add ZCppMain/ZtCMainChars.H
git add ZCppMain/ZtCObjAVL.H
git add ZCppMain/ZtCStringEx.H
git add ZCppMain/ZtCTreeData.H
2025-08-16 23:35:44 +09:00

8277 lines
313 KiB
C++

#ifndef __ZCPPMAIIN__ZTCSTRINGEX_H__
#define __ZCPPMAIIN__ZTCSTRINGEX_H__
#include <cstdarg>
#include <cstdio>
#include <string>
#include <iostream>
#include "ZCppMain/ZMainHead.H"
#include "ZCppMain/ZMainHeadEx.H"
#include "ZCppMain/ZMainXhtml.H"
#include "ZCppMain/ZtCMainChars.H"
#include "ZCppMain/ZtCObjList.H"
using namespace std ;
using namespace ZNsMain;
namespace ZNsMain
{
/*#######################################################################################################
■ 아래 WriteFileRaw() 함수는 원래, ZtCStringBase<> 의 멤버 함수로 WriteFile() 라는 정적 멤버 함수였으나
이미 같은 이름의 비정적 멤버 함수가 있다 보니, 두 개 함수를 사용했을 때, g++ 4.4.7 에서 경고가 발생했
었다.
[sauron@localhost Donut_CPP]$ g++ -g -D_DEBUG -D_REENTRANT DonutTopCheck.cpp -o DonutTopCheck_D.exe -lpthread -I../../../my_CPP/CPP_Std/ -I../../../my_CPP/CPP_Net/ -I../../../my_CPP/CPP_Main/
DonutTopCheck.cpp: In static member function 'static void std::CSngtChecker::Exec()::HandleLine::Exec(CStringData&)':
DonutTopCheck.cpp:235: warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second:
Donut.H:23376: note: candidate 1: static bool std::ZtCStringBase<TTypCh, TAlloc, TAllocSize, TTypeString>::WriteFile(const TTypCh*, const typename TTypeString::ZCTypeChars::TypeChar*, typename TTypeString::ZCTypeChars::TypeLength, bool, int) [with TTypCh = char, TAlloc = std::ZtCAllocClass<char>, TAllocSize = std::ZtCAllocMemSize<char>, TTypeString = std::ZNsType::ZtCTypeStringBase<char, std::ZtCAllocClass<char>, std::ZtCAllocMemSize<char>, long int>]
Donut.H:23318: note: candidate 2: bool std::ZtCStringBase<TTypCh, TAlloc, TAllocSize, TTypeString>::WriteFile(const TTypCh*, bool, int) const [with TTypCh = char, TAlloc = std::ZtCAllocClass<char>, TAllocSize = std::ZtCAllocMemSize<char>, TTypeString = std::ZNsType::ZtCTypeStringBase<char, std::ZtCAllocClass<char>, std::ZtCAllocMemSize<char>, long int>]
DonutTopCheck.cpp:235: warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second:
Donut.H:23376: note: candidate 1: static bool std::ZtCStringBase<TTypCh, TAlloc, TAllocSize, TTypeString>::WriteFile(const TTypCh*, const typename TTypeString::ZCTypeChars::TypeChar*, typename TTypeString::ZCTypeChars::TypeLength, bool, int) [with TTypCh = char, TAlloc = std::ZtCAllocClass<char>, TAllocSize = std::ZtCAllocMemSize<char>, TTypeString = std::ZNsType::ZtCTypeStringBase<char, std::ZtCAllocClass<char>, std::ZtCAllocMemSize<char>, long int>]
Donut.H:23318: note: candidate 2: bool std::ZtCStringBase<TTypCh, TAlloc, TAllocSize, TTypeString>::WriteFile(const TTypCh*, bool, int) const [with TTypCh = char, TAlloc = std::ZtCAllocClass<char>, TAllocSize = std::ZtCAllocMemSize<char>, TTypeString = std::ZNsType::ZtCTypeStringBase<char, std::ZtCAllocClass<char>, std::ZtCAllocMemSize<char>, long int>]
그래서 WriteFileRaw() 로 이름을 바꾸고, std 의 전역 함수로 뺀 것이다. -- 2015-09-25 20:15:00
■ ZfWriteFileRaw() 로 이름을 바꾸었다. -- 2025-08-11 10:52
#######################################################################################################*/
static bool ZfWriteFileRaw /*##########################################################################*/
(
ZTypCPCh APC_FileName , ZTypCPCh APC_Content ,
ZTypLength AL_ContentLen, bool AB_DoAppend=true, int AI_RightMode=-1
)
/*#####################################################################################################*/
{
// int AI_RightMode = -1 은 리눅스에서만 쓴다.
#ifdef _WIN
HANDLE VH_File = ::CreateFileA(
APC_FileName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL,NULL);
if(VH_File==INVALID_HANDLE_VALUE) return false;
if(AB_DoAppend==true)
::SetFilePointer(VH_File, 0, NULL, FILE_END); // 덧붙이는 경우라면 파일 포인터를 맨 끝으로 옮긴다.
else ::SetEndOfFile (VH_File ); // 덧붙이는 경우가 아니면 기존 내용을 지운다.
DWORD NumberOfBytesWritten = 0 ;
if(::WriteFile(VH_File, APC_Content, AL_ContentLen, &NumberOfBytesWritten, NULL)==FALSE)
{
::CloseHandle(VH_File); return false;
}/*
if(::WriteFile(VH_File, APC_Content, AL_ContentLen, &NumberOfBytesWritten, NULL)==FALSE)*/
return ::CloseHandle(VH_File)==TRUE ;
#else // !defined(_WIN)
// 리눅스의 경우
using ZNsConst::ZNsLlioMode::AppendMake ;
using ZNsConst::ZNsLlioMode::WriteMakeCut;
const int CI_FileOpenTag=(AI_RightMode<0 ? S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP : AI_RightMode ) ;
const int CI_FileOpenErr=-1;
int AH_FileDesc = CI_FileOpenErr ;
if(AB_DoAppend==true)
{
const bool CB_IsError = ////////////////////////////////////
(
(
AH_FileDesc = ::open
( APC_FileName, AppendMake, CI_FileOpenTag )
)==CI_FileOpenErr
);
////////////////////////////////////////////////////////////
if(CB_IsError) return false; ///////////////////////////////
}
else
{
const bool CB_IsError = ////////////////////////////////////
(
(
AH_FileDesc = ::open
( APC_FileName, WriteMakeCut, CI_FileOpenTag )
)==CI_FileOpenErr
);
//////////////////////////////////////////////////////////////
if(CB_IsError) return false; /////////////////////////////////
}/*
else*/
if(::write(AH_FileDesc, APC_Content, AL_ContentLen)<AL_ContentLen)
{
::close(AH_FileDesc); return false;
}/*
if(::write(AH_FileDesc, APC_Content, AL_ContentLen)<AL_ContentLen)*/
return ::close(AH_FileDesc)==0 ;
#endif //!defined(_WIN)
}/*
static bool ZfWriteFileRaw( #############################################################################
(
ZTypCPCh APC_FileName , ZTypCPCh APC_Content ,
ZTypLength AL_ContentLen, bool AB_DoAppend=true, int AI_RightMode=-1
)
/*#####################################################################################################*/
/*//////////////////////////////////////////////////////////////////////////
■ 문자열을 편하게 다루기 위해서 ZtCStringBase 클래스 템플릿을 설계하였는데
이 클래스 템플릿은 동적으로 생성된 문자열만 다루고 있으므로, 정적 문자열을
다룰 수 있는 class ZtCCharPtr 템플릿을 설계한다. 단 정적 문자열의 길이는
맨 끝에 널문자를 위해, 필요한 길이 + 1 이 됨을 명심할 것.
//////////////////////////////////////////////////////////////////////////*/
template<typename TTypCh> class ZtCCharPtr
{
public :
typedef long TypeLength;
typedef TTypCh TypeChar ;
typedef const TTypCh TypeCharC ;
typedef const TTypCh* TypeCharCP;
typedef const TTypCh* TypeCPChar;
private:
TypeChar* mpc_Buff ;
TypeLength ml_Length; // mpc_Buff 에서 사용되는 문자길이
TypeLength ml_AllLen; // mpc_Buff 에 할당된 메모리크기
public :
ZtCCharPtr()
{
mpc_Buff =0;
ml_Length=0;
ml_AllLen=0;
}/*
ZtCCharPtr()*/
ZtCCharPtr(TypeChar* APC_ArgBuf, TypeLength AL_ArgAllLen)
{
// AL_ArgAllLen 는 맨 끝에 널 문자를 위한 1 개의 공간을 뺀 길이다.
mpc_Buff =APC_ArgBuf ;
ml_Length=0 ;
ml_AllLen=AL_ArgAllLen;
}/*
ZtCCharPtr(TypeChar* APC_ArgBuf, TypeLength AL_ArgAllLen)*/
ZtCCharPtr<TypeChar>& SetCharSet(TypeChar* APC_ArgBuf, TypeLength AL_ArgAllLen)
{
// AL_ArgAllLen 는 맨 끝에 널 문자를 위한 1 개의 공간을 뺀 길이다.
mpc_Buff =APC_ArgBuf ;
ml_Length=0 ;
ml_AllLen=AL_ArgAllLen;
return *this;
}/*
ZtCCharPtr<TypeChar>& SetCharSet(TypeChar* APC_ArgBuf, TypeLength AL_ArgAllLen)*/
ZtCCharPtr<TypeChar>& Add(TypeChar* APC_ArgChar, TypeLength AL_ArgLength)
{
// AL_ArgAllLen 는 맨 끝에 널 문자를 위한 1 개의 공간을 뺀 길이다.
if(AL_ArgLength<1) return *this;
TypeLength VUL_MaxIndex =
( (ml_Length +AL_ArgLength >= ml_AllLen) ? ml_AllLen : ml_Length +AL_ArgLength) ;
for(TypeLength i=ml_Length; i<VUL_MaxIndex; ++i)
{
mpc_Buff[i]=APC_ArgChar[i-ml_Length] ;
}/*
for(TypeLength i=ml_Length; i<VUL_MaxIndex; ++i)*/
mpc_Buff[ml_Length=VUL_MaxIndex]=0; return *this;
}/*
ZtCCharPtr<TypeChar>& Add(TypeChar* APC_ArgChar, TypeLength AL_ArgLength)*/
ZtCCharPtr<TypeChar>& Add(TypeChar* APC_ArgChar)
{
return Add(APC_ArgChar, ZNsMain::ZftGetLengthType<TypeLength, TypeChar>(APC_ArgChar));
}/*
ZtCCharPtr<TypeChar>& Add(TypeChar* APC_ArgChar)*/
operator TypeChar*()
{
return mpc_Buff ;
}/*
operator TypeChar*()*/
operator TypeCharC*() const
{
return mpc_Buff ;
}/*
operator TypeCharC*() const*/
TypeChar* data()
{
return mpc_Buff ;
}/*
TypeChar* data()*/
TypeCharC* data() const
{
return mpc_Buff ;
}/*
TypeCharC* data() const*/
TypeLength size() const
{
return ml_Length;
}/*
TypeLength size() const*/
public:
};/*
template< typename TTypCh
>
class ZtCCharPtr ////////*/
typedef ZtCCharPtr<char> CCharPtr ;
typedef ZtCCharPtr<char> CCharPtrA;
typedef ZtCCharPtr<wchar_t> CCharPtrW;
template< typename TTypCh , /*######*/
typename TAlloc ,
typename TAllocSize ,
typename TTypeString
>
class ZtCStringBase; /*###################*/
namespace ZNsType
{
template< typename TTypCh ,
typename TAlloc =ZNsMain::ZtCAllocClass <TTypCh>,
typename TAllocSize=ZNsMain::ZtCAllocMemSize<TTypCh>,
typename TLength =ZNsMain::ZTypLength
>
class ZtCTypeStringBase /////////////////////////////////////////
{
public:
typedef TLength TypeLong ;
typedef TLength TypeLength;
typedef TTypCh TypeChar ;
public:
typedef ZNsMain::ZNsChars::ZNsType::
ZtCTypeChars<TTypCh, TypeLength> ZCTypeChars;
typedef ZNsMain::ZNsChars::
ZtCMainChars<ZCTypeChars > ZCMainChars;
public:
typedef typename ZCTypeChars::ZCChars ZCChars ;
public:
template<typename TDeriveString> class ZtCHelpBase
{
public:
typedef ZNsMain::ZtCObjList< //////////////////
TDeriveString ,
const TDeriveString&,
TAlloc
/*/////////*/ > ZCStringList; /////////////////
public:
};/*
template<typename TDeriveString>class ZtCHelpBase*/
class ZCSearchInfo
{
protected:
template< typename TypeCh2 , ////////////
typename TypeAlloc2 ,
typename TypeAllocSize2,
typename TypeHelp2
>
friend class ZNsMain::ZtCStringBase; ////////////
protected:
TypeChar* mp_Char;
TypeLength ml_Len ;
TypeLength ml_Pos ;
public :
ZCSearchInfo()
{
mp_Char=0;
ml_Pos =0;
ml_Len =0;
}/*
ZCSearchInfo()*/
inline TypeLength GetPos() const{return ml_Pos ;}
inline TypeLength size () const{return ml_Len ;}
inline TypeChar* data () {return mp_Char;}
inline const TypeChar* data () const{return mp_Char;}
public:
};/*
class ZCSearchInfo*/
typedef ZNsMain::ZtCObjList /////////////////////
<
ZCSearchInfo, const ZCSearchInfo&, TAlloc
>
ZCSearchInfoList; ///////////////////////////////
public:
};/*
template< typename TTypCh ,
typename TAlloc =ZNsMain::ZtCAllocClass <TTypCh>,
typename TAllocSize=ZNsMain::ZtCAllocMemSize<TTypCh>,
typename TLength =ZNsMain::ZTypLength
>
class ZtCTypeStringBase ///////////////////////////////////////*/
}/*
namespace ZNsType*/
template<typename TTypCh, typename TAlloc> class ZtCHString;
/*/////////////////////////////////////////////////////////////////
■ stl 의 string 클래스는 문자열 처리가 PHP 에 비해 다소 불편하므로
별도의 문자열 클래스 템플릿 class ZtCStringBase<> 을 설계한다.
■ 파일입출력 및 몇몇 멤버함수에 관련해서
class ZtCStringBase<wchar_t> 클래스를 별도로 설계할 필요가 있다.
/////////////////////////////////////////////////////////////////*/
template< typename TTypCh,
typename TAlloc =ZNsMain::ZtCAllocClass <TTypCh>,
typename TAllocSize =ZNsMain::ZtCAllocMemSize<TTypCh>,
typename TTypeString=ZNsMain::ZNsType::ZtCTypeStringBase
<
TTypCh, TAlloc, TAllocSize
>
>
class ZtCStringBase : /////////////////////////////////////////
public TAlloc ,
protected TAllocSize ,
public TTypeString::template ZtCHelpBase
<
ZtCStringBase
<
TTypCh, TAlloc, TAllocSize, TTypeString
>
/*//////////*/ > /////////////////////////////////////////////
{
public:
typedef typename TTypeString::template ZtCHelpBase< ///////
ZtCStringBase
<
TTypCh, TAlloc, TAllocSize, TTypeString
>
/*////////*/ > TypeHelpBase; /////////////////////////////
typedef typename TypeHelpBase::ZCStringList ZCStringList ;
public:
typedef TAlloc ZCAllocator ;
typedef const TTypCh TypeCharC ;
typedef const TTypCh* TypeCharCP ;
typedef const TTypCh* TypeCPChar ;
typedef TTypeString ZCTypeString;
typedef ZtCStringBase ZCStringBase;
public:
typedef typename ZCTypeString::ZCSearchInfo ZCSearchInfo ;
typedef typename ZCTypeString::ZCSearchInfoList ZCSearchInfoList ;
typedef typename ZCTypeString::ZCTypeChars ZCTypeChars ;
typedef typename ZCTypeString::ZCMainChars ZCMainChars ;
typedef typename ZCTypeString::TypeLong TypeLong ;
typedef typename ZCTypeString::TypeLong TypeLength ;
public:
typedef typename ZCTypeChars ::TypeChar TypeChar ; // TTypCh 과 같은 형이어야 한다.
typedef typename ZCTypeChars ::TypeLength TypeLength;
typedef typename ZCTypeChars ::ZCChars ZCChars ;
public:
typedef TypeChar TypeData ;
public:
typedef TAlloc TypeAlloc ;
typedef ZCStringList TypeList ;
public:
friend class ZtCHString<TTypCh, TAlloc>;
public:
enum EWriteFile // WriteFile() 에서 사용한다.
{
EWriteFile_Append , // 데이타를 파일에 덧붙인다.
EWriteFile_OverWrite // 기존 파일의 내용을 지우고 데이타를 파일에 쓴다.
};/*
enum EWriteFile*/
public:
template<typename TSearchInfoList> void MakeInfoList
(
TypeCharC* APC_Search ,
TypeLength AL_SearchLen,
TypeLength AL_StartPos ,
TSearchInfoList& ARR_InfoList
)
////////////////////////////////////////////////////
{
typedef typename
TSearchInfoList::TypeData ZCSearchInfo;
if(ml_UseLen<1 || AL_SearchLen<1) return ;
if(AL_StartPos<0) AL_StartPos=0;
TypeLength VL_Loop =ml_UseLen-AL_SearchLen ;
ZCSearchInfo* VP_CSearchInfo=0 ;
TypeChar* VP_Origin =mpc_Data ;
TypeLength i =AL_StartPos;
while(i<=VL_Loop)
{
TypeLength j;
for(j=0; j<AL_SearchLen; ++j)
{
if(VP_Origin[i+j]!=APC_Search[j]) break;
}/*
for(j=0; j<AL_SearchLen; ++j)*/
if(j==AL_SearchLen)
{
/* VP_CSearchInfo=&ARR_InfoList.AddTailDefault()->GetData();
위 코드처럼 하면 ARR_InfoList 를 일반화 하기가 어렵다. */
VP_CSearchInfo=&(ZCSearchInfo&)ARR_InfoList;
VP_CSearchInfo->mp_Char=VP_Origin+i ;
VP_CSearchInfo->ml_Pos =i ;
VP_CSearchInfo->ml_Len =AL_SearchLen ;
i += AL_SearchLen ;
}
else // j!=AL_SearchLen
{
++i;
}/*
else // j!=AL_SearchLen*/
}/*
while(i<=VL_Loop)*/
}/*
template<typename TSearchInfoList> void MakeInfoList
(
TypeCharC* APC_Search ,
TypeLength AL_SearchLen,
TypeLength AL_StartPos ,
TSearchInfoList& ARR_InfoList
)
//////////////////////////////////////////////////*/
template<typename TSearchInfoList> void MakeSplitInfoList
(
TypeCharC* APC_Search ,
TypeLength AL_SearchLen,
TypeLength AL_StartPos ,
TSearchInfoList& ARR_InfoList
)
/////////////////////////////////////////////////////////
{
typedef typename
TSearchInfoList::TypeData ZCSearchInfo;
/* void MakeInfoList 함수와는 달리 APC_Search 문자열로
나뉘어지는 각 구간의 문자열 정보리스트를 얻는다. */
if(ml_UseLen<1 || AL_SearchLen<1) return ;
if(AL_StartPos<0) AL_StartPos=0;
TypeLength VL_Loop =ml_UseLen-AL_SearchLen ;
ZCSearchInfo* VP_CSearchInfo=0 ;
TypeChar* VP_Origin =mpc_Data ;
TypeLength i =AL_StartPos;
TypeLength VL_PrevPos =AL_StartPos;
while(i<=VL_Loop)
{
TypeLength j=0;
for(j=0; j<AL_SearchLen; ++j)
{
if(VP_Origin[i+j]!=APC_Search[j]) break;
}/*
for(j=0; j<AL_SearchLen; ++j)*/
if(j==AL_SearchLen)
{
if(i-VL_PrevPos>0)
{
VP_CSearchInfo=&(ZCSearchInfo&)ARR_InfoList ;
VP_CSearchInfo->mp_Char=VP_Origin+VL_PrevPos;
VP_CSearchInfo->ml_Pos =VL_PrevPos ;
VP_CSearchInfo->ml_Len =i-VL_PrevPos ;
}/*
if(i-VL_PrevPos>0)*/
VL_PrevPos = i += AL_SearchLen ;
}
else // j==AL_SearchLen
{
++i;
}/*
else // j==AL_SearchLen*/
}/*
while(i<=VL_Loop)*/
if(VL_PrevPos<ml_UseLen)
{
VP_CSearchInfo=&(ZCSearchInfo&)ARR_InfoList ;
VP_CSearchInfo->mp_Char=VP_Origin+VL_PrevPos ;
VP_CSearchInfo->ml_Pos =VL_PrevPos ;
VP_CSearchInfo->ml_Len =ml_UseLen-VL_PrevPos ;
}/*
if(VL_PrevPos<ml_UseLen)*/
}/*
template<typename TSearchInfoList> void MakeSplitInfoList
(
TypeCharC* APC_Search ,
TypeLength AL_SearchLen,
TypeLength AL_StartPos ,
TSearchInfoList& ARR_InfoList
)
///////////////////////////////////////////////////////*/
/*public :*/
protected:
TypeLength ml_AllLen;
TypeLength ml_UseLen;
TypeChar* mpc_Data ;
/*protected:*/
public :
ZtCStringBase()
{
ml_AllLen=0;
ml_UseLen=0;
mpc_Data =0;
}/*
ZtCStringBase()*/
ZtCStringBase(TypeCharC* APC_Data)
{
ml_AllLen=0;
ml_UseLen=0;
mpc_Data =0;
if(APC_Data==0 || APC_Data[0]==0) return;
MakeWord
(
APC_Data, ZNsMain::ZftGetLengthType
< TypeLength, TypeChar >( APC_Data )
);
////////
}/*
ZtCStringBase(TypeCharC* APC_Data)*/
ZtCStringBase(TypeCharC* APC_Data, TypeLength AL_Length)
{
ml_AllLen=0;
ml_UseLen=0;
mpc_Data =0;
if(AL_Length<1) return;
MakeWord(APC_Data, AL_Length);
}/*
ZtCStringBase(TypeCharC* APC_Data, TypeLength AL_Length)*/
ZtCStringBase(const ZtCStringBase& rhs)
{
ml_AllLen=0;
ml_UseLen=0;
mpc_Data =0;
MakeWord(rhs.mpc_Data, rhs.ml_UseLen);
}/*
ZtCStringBase(const ZtCStringBase& rhs)*/
ZtCStringBase(TypeLength AL_Long)
{
ml_AllLen=0;
ml_UseLen=0;
mpc_Data =0;
(*this)(AL_Long);
}/*
ZtCStringBase(TypeLength AL_Long)*/
~ZtCStringBase()
{
if(ml_AllLen>0) this->DeleteMem(mpc_Data);
}/*
~ZtCStringBase()*/
TypeLength GetAllLength () const{return ml_AllLen ;}
TypeLength GetUseLength () const{return ml_UseLen ;}
TypeLength GetNotUseLength() const{return ml_AllLen-ml_UseLen;}
TypeChar* GetChars() {return mpc_Data;}
TypeCharC* GetChars() const{return mpc_Data;}
bool IsAnsi() const
{
return ZCTypeChars::IsAnsiChars(mpc_Data, ml_UseLen);
}/*
bool IsAnsi() const*/
void Delete()
{
if(ml_AllLen>0)
{
this->DeleteMem(mpc_Data);
ml_AllLen=0;
ml_UseLen=0;
mpc_Data =0;
}/*
if(ml_AllLen>0)*/
}/*
void Delete()*/
void ReAlloc(TypeLength AL_AllocSize, bool AB_DoKeepString=false)
{
if(AL_AllocSize<1) return;
TypeLength VL_NewAllocSize = this->
TAllocSize::GetNewAllocSize(AL_AllocSize, ml_AllLen);
if(ml_AllLen>=VL_NewAllocSize) return;
if(AB_DoKeepString==false)
{
this->DeleteMem(mpc_Data);
mpc_Data =this->NewMem((VL_NewAllocSize+1)*sizeof(TypeChar));
ml_AllLen =VL_NewAllocSize ;
ml_UseLen =0 ;
mpc_Data[0]=0 ;
mpc_Data[VL_NewAllocSize]=0 ;
}
else //AB_DoKeepString==true
{
// 문자열을 유지하는 경우
TypeChar* VPC_NewChar =
this->NewMem((VL_NewAllocSize+1)*sizeof(TypeChar));
if(ml_UseLen>0) ::memcpy(
VPC_NewChar, mpc_Data, ml_UseLen*sizeof(TypeChar));
ml_AllLen =VL_NewAllocSize;
VPC_NewChar[ml_UseLen]=0 ;
this->DeleteMem(mpc_Data);
mpc_Data=VPC_NewChar;
}/*
else //AB_DoKeepString==true*/
}/*
void ReAlloc(TypeLength AL_AllocSize, bool AB_DoKeepString=false)*/
void ReAllocKeep(TypeLength AL_AllocSize)
{
ReAlloc(AL_AllocSize, true);
}/*
void ReAllocKeep(TypeLength AL_AllocSize)*/
void ReAllocAdd(TypeLength AL_AddSize, bool AB_DoKeepString=false)
{
ReAlloc(ml_UseLen+AL_AddSize, AB_DoKeepString) ;
}/*
void ReAllocAdd(TypeLength AL_AddSize, bool AB_DoKeepString=false)*/
void ReAllocAddKeep(TypeLength AL_AddSize)
{
ReAlloc(ml_UseLen+AL_AddSize, true) ;
}/*
void ReAllocAddKeep(TypeLength AL_AddSize)*/
operator TypeChar* () {return mpc_Data ;}
operator TypeCharC*() const{return mpc_Data ;}
operator int () const{return GetInt ();}
operator ZTypLong () const{return GetLong ();}
operator ZTypLLong () const{return GetLLong();}
void FreeAlloc()
{
if(ml_AllLen>0)
{
this->DeleteMem(mpc_Data) ;
mpc_Data = 0 ;
ml_AllLen = ml_UseLen =0;
}/*
if(ml_AllLen>0)*/
}/*
void FreeAlloc()*/
// 아래 몇 멤버는 STL 의 string 멤버 함수와 이름을 맞추기 위한 것.
TypeChar* data (){return mpc_Data;}
TypeChar* c_str(){return mpc_Data;}
TypeCharC* data () const{return mpc_Data;}
TypeCharC* c_str() const{return mpc_Data;}
void reserve(TypeLength AL_AllocSize)
{
// 이전 문자열을 유지한다.
ReAllocKeep(AL_AllocSize);
}/*
void reserve(TypeLength AL_AllocSize)*/
ZCStringBase& resize(TypeLength AL_NewSize, TypeChar AC_FillChar=' ')
{
// AL_NewSize>ml_UseLen 이면 추가되는 부분은 AC_FillChar 로 채운다.
if(AL_NewSize<=ml_UseLen) return Invalidate(AL_NewSize);
TypeLength VL_PrevSize=ml_UseLen; ReAllocKeep(AL_NewSize);
for(TypeLength i=VL_PrevSize; i<AL_NewSize; ++i)
{ mpc_Data[i]=AC_FillChar ; }
////////////////////////////////////////////////
mpc_Data[ml_UseLen = AL_NewSize]=0; return *this;
}/*
ZCStringBase& resize(TypeLength AL_NewSize=0, TypeChar AC_FillChar=' ')*/
void erase()
{
Delete(); //if(ml_AllLen>0) mpc_Data[ml_UseLen=0]=0;
}/*
void erase();*/
void clear()
{
Delete(); //if(ml_AllLen>0) mpc_Data[ml_UseLen=0]=0;
}/*
void clear()*/
TypeLength size () const{return ml_UseLen ;}
TypeLength length () const{return ml_UseLen ;}
TypeLength capacity() const{return ml_AllLen ;}
bool empty () const{return ml_UseLen<=0;}
ZCStringBase& append(TypeCharC* APC_Data)
{
return (*this)(APC_Data);
}/*
ZCStringBase& append(TypeCharC* APC_Data)*/
ZCStringBase& append(TypeChar CharParam, TypeLength AL_Count)
{
// 문자 CharParam 을 AL_Count 개 붙인다.
return (*this)(CharParam,AL_Count);
}/*
ZCStringBase& append(TypeChar CharParam, TypeLength AL_Count)*/
ZCStringBase& append(TypeCharC* APC_Data, TypeLength AL_Length)
{
return (*this)(APC_Data, AL_Length);
}/*
ZCStringBase& append(TypeCharC* APC_Data, TypeLength AL_Length)*/
ZCStringBase& append(TypeCharC* APC_Data, TypeLength AL_Length, TypeLength AL_LoopCnt)
{
// APC_Data 를 AL_LoopCnt 번 더한다.
for(TypeLength i=1;i<=AL_LoopCnt;++i) (*this)(APC_Data,AL_Length); return *this;
}/*
ZCStringBase& append(TypeCharC* APC_Data, TypeLength AL_Length, TypeLength AL_LoopCnt)*/
ZCStringBase& append(const ZCStringBase& rhs){return (*this)(rhs);}
ZCStringBase& append(const ZCStringBase& rhs, TypeLength AL_LoopCnt)
{
// rhs 를 AL_LoopCnt 번 더한다.
__for1(TypeLength, i, AL_LoopCnt) (*this)(rhs); return *this;
}/*
ZCStringBase& append(const ZCStringBase& rhs, TypeLength AL_LoopCnt)*/
// STL 의 string 멤버함수와 이름을 맞추기 위한 함수 끝
TypeLength MemCopy /*##########################################################*/
(
TypeChar* APC_Buff, TypeLength AL_BuffSize, bool AB_DoEndNull=true
)
const
/*#############################################################################*/
{
/* 문자열을 APC_Buff 로 복사한다. 복사된 문자열 길이를 반환한다.
AB_DoEndNull==true 인 경우, APC_Buff 의 크기는 AL_BuffSize+1 이어야 한다. */
if(ml_UseLen<1 || AL_BuffSize<1) return 0;
TypeLength VL_LoopCnt =
ml_UseLen<AL_BuffSize ? ml_UseLen : AL_BuffSize ;
for(TypeLength i=0;i<VL_LoopCnt;++i)
{ APC_Buff[i]=mpc_Data[i]; }
if(AB_DoEndNull==true)
{ APC_Buff[VL_LoopCnt]=0 ; }
return VL_LoopCnt;
}/*
TypeLength MemCopy #############################################################
(
TypeChar* APC_Buff, TypeLength AL_BuffSize, bool AB_DoEndNull=true
)
const
/*#############################################################################*/
ZCStringBase& Invalidate(TypeLength AL_Index=0)
{
if(AL_Index>=0 && AL_Index<ml_UseLen) mpc_Data[ml_UseLen=AL_Index]=0; return *this;
}/*
ZCStringBase& Invalidate(TypeLength AL_Index=0)*/
ZCStringBase& Invalid(TypeLength AL_Index=0)
{
if(AL_Index>=0 && AL_Index<ml_UseLen) mpc_Data[ml_UseLen=AL_Index]=0; return *this;
}/*
ZCStringBase& Invalid(TypeLength AL_Index=0)*/
ZCStringBase& Invalid(TypeLength AL_Index1, TypeLength AL_Index2)
{
// AL_Index1 부터 AL_Index2 까지의 문자열을 제거한다.
if(AL_Index1<0 || AL_Index1>AL_Index2 || AL_Index2>=ml_UseLen)
{
return *this; /*########################################*/
}/*
if(AL_Index1<0 || AL_Index1>AL_Index2 || AL_Index2>=ml_UseLen)*/
if(AL_Index2-1==ml_UseLen) return Invalid(AL_Index1);
::memmove( mpc_Data +AL_Index1 ,
mpc_Data +AL_Index2+1,
ml_UseLen-AL_Index2-1
/*////*/ );
mpc_Data[ml_UseLen-=(AL_Index2-AL_Index1+1)]=0; return *this;
}/*
ZCStringBase& Invalid(TypeLength AL_Index1, TypeLength AL_Index2)*/
ZCStringBase& InvalidByForce(TypeLength AL_Index=0)
{
// Invalidate() 와의 차이에 주의
const bool CB_IsOK =
(AL_Index>=0 && AL_Index<=ml_AllLen && ml_AllLen>0);
if(CB_IsOK) mpc_Data[ml_UseLen=AL_Index]=0; return *this;
}/*
ZCStringBase& InvalidByForce(TypeLength AL_Index=0)*/
ZCStringBase& InvalidateSearch(
TypeCharC* APC_Search, TypeLength AL_SearchLen, TypeLength AL_Index=0)
{
// APC_Search 를 찾아서 그 부분을 무효화시킨다.
TypeLength VL_Pos =
FindPos(APC_Search, AL_SearchLen ,AL_Index);
if(VL_Pos>=0) mpc_Data[ml_UseLen=VL_Pos]=0; return *this;
}/*
ZCStringBase& InvalidateSearch(
TypeCharC* APC_Search, TypeLength AL_SearchLen, TypeLength AL_Index=0)*/
ZCStringBase& InvalidateSearchFromEnd(
TypeCharC* APC_Search, TypeLength AL_SearchLen, TypeLength AL_StartPos)
{
// APC_Search 를 뒤로부터 찾아서 그 부분을 무효화시킨다.
TypeLength VL_Pos =
FindPosFromEnd(APC_Search, AL_SearchLen, AL_StartPos);
if(VL_Pos>=0) mpc_Data[ml_UseLen=VL_Pos]=0; return *this;
}/*
ZCStringBase& InvalidateSearchFromEnd(
TypeCharC* APC_Search, TypeLength AL_SearchLen, TypeLength AL_StartPos)*/
ZCStringBase& InvalidateSearchFromEnd(TypeCharC* APC_Search, TypeLength AL_SearchLen)
{
// APC_Search 를 뒤로부터 찾아서 그 부분을 무효화시킨다.
if(ml_UseLen<1) return *this;
return InvalidateSearchFromEnd(
APC_Search, AL_SearchLen, ml_UseLen-1);
}/*
ZCStringBase& InvalidateSearchFromEnd(TypeCharC* APC_Search, TypeLength AL_SearchLen)*/
ZCStringBase& InvalidHead(TypeCharC* APC_Search, TypeLength AL_SearchLen)
{
// APC_Search 를 앞에서 찾아서 있다면 그 부분을 무효화시킨다.
if(ml_UseLen<1 || AL_SearchLen<1) return *this;
const bool CB_IsOK = this->DoStart(APC_Search, AL_SearchLen);
if(CB_IsOK) MoveFirst(AL_SearchLen); return *this;
}/*
ZCStringBase& InvalidHead(TypeCharC* APC_Search, TypeLength AL_SearchLen)*/
ZCStringBase& InvalidHead(TypeCharC* APC_Search)
{
return InvalidHead
(
APC_Search, ZNsMain::ZftGetLengthType
< TypeLength, TypeChar >( APC_Search )
);
//////////////////
}/*
ZCStringBase& InvalidHead(TypeCharC* APC_Search)*/
/*////////////////////////////////////////////
// 가끔 오류가 나는 경우가 있어서 주석처리한다.
ZCStringBase* operator->()
{
// 이 멤버를 호출하면 어떤 경우에도
// 문자열 포인터는 NULL 이 아니다.
static char SA_Char[1]="";
if(ml_AllLen<1)
mpc_Data=SA_Char;
return this;
}
////////////////////////////////////////////*/
ZCStringBase& operator=(const ZCStringBase& rhs)
{
if(this==&rhs) return *this;
if(rhs.ml_UseLen<1)
{
Invalidate(); return *this;
}/*
if(rhs.ml_UseLen<1)*/
ReAlloc(rhs.ml_UseLen); ::memcpy
(
mpc_Data, rhs.mpc_Data, rhs.ml_UseLen*sizeof(TypeChar)
);
/////////////////////////////////
mpc_Data[ml_UseLen=rhs.ml_UseLen]=0; return *this;
}/*
ZCStringBase& operator=(const ZCStringBase& rhs)*/
ZCStringBase& operator=(TypeCharC* APC_Data)
{
if(mpc_Data==APC_Data) return *this;
return MakeWord
(
APC_Data, ZNsMain::ZftGetLengthType
< TypeLength, TypeChar >( APC_Data )
);
///////////////
}/*
ZCStringBase& operator=(TypeCharC* APC_Data)*/
ZCStringBase& operator=(const ZCChars& AR_CChars)
{
Invalidate(); return (*this)(AR_CChars.data(), AR_CChars.size());
}/*
ZCStringBase& operator=(const ZCChars& AR_CChars)*/
ZCStringBase& operator=(int AI_Int ){Invalidate(); return (*this)(AI_Int );}
ZCStringBase& operator=(long AL_Long ){Invalidate(); return (*this)(AL_Long );}
ZCStringBase& operator=(double AD_Double){Invalidate(); return (*this)(AD_Double);}
ZCStringBase& operator=(const std::string& AR_CString)
{
return this->MakeWord(AR_CString.c_str(), AR_CString.size());
}/*
ZCStringBase& operator=(const std::string& AR_CString)*/
bool operator==(TypeCharC* APC_Data) const{return Minus(APC_Data)==0 ;}
bool operator!=(TypeCharC* APC_Data) const{return Minus(APC_Data)!=0 ;}
bool operator> (TypeCharC* APC_Data) const{return Minus(APC_Data)> 0 ;}
bool operator>=(TypeCharC* APC_Data) const{return Minus(APC_Data)>=0 ;}
bool operator<=(TypeCharC* APC_Data) const{return Minus(APC_Data)<=0 ;}
bool operator< (TypeCharC* APC_Data) const{return Minus(APC_Data)< 0 ;}
bool operator==(const ZCStringBase& rhs) const{return Minus(rhs.data(), rhs.GetUseLength())==0 ;}
bool operator!=(const ZCStringBase& rhs) const{return Minus(rhs.data(), rhs.GetUseLength())!=0 ;}
bool operator> (const ZCStringBase& rhs) const{return Minus(rhs)> 0;}
bool operator>=(const ZCStringBase& rhs) const{return Minus(rhs)>=0;}
bool operator< (const ZCStringBase& rhs) const{return Minus(rhs)< 0;}
bool operator<=(const ZCStringBase& rhs) const{return Minus(rhs)<=0;}
bool operator==(const ZCChars& AR_CChars) const{return Minus(AR_CChars.data(), AR_CChars.size())==0 ;}
bool operator!=(const ZCChars& AR_CChars) const{return Minus(AR_CChars.data(), AR_CChars.size())!=0 ;}
bool operator> (const ZCChars& AR_CChars) const{return Minus(AR_CChars.data(), AR_CChars.size())> 0 ;}
bool operator>=(const ZCChars& AR_CChars) const{return Minus(AR_CChars.data(), AR_CChars.size())>=0 ;}
bool operator< (const ZCChars& AR_CChars) const{return Minus(AR_CChars.data(), AR_CChars.size())< 0 ;}
bool operator<=(const ZCChars& AR_CChars) const{return Minus(AR_CChars.data(), AR_CChars.size())<=0 ;}
ZCStringBase operator+(TypeCharC* APC_Data)
{
if(APC_Data==0 || APC_Data[0]+=0) return *this;
ZCStringBase VO_CStringTemp;
TypeLength VL_ArgLen = ZNsMain::
ZftGetLengthType<TypeLength, TypeChar>(APC_Data);
VO_CStringTemp.ReAlloc(ml_UseLen+VL_ArgLen);
VO_CStringTemp(*this)(APC_Data, VL_ArgLen );
return VO_CStringTemp;
}/*
ZCStringBase operator+(TypeCharC* APC_Data)*/
ZCStringBase& operator+=(TypeCharC* APC_Data)
{
return (*this)(APC_Data);
}/*
ZCStringBase& operator+=(TypeCharC* APC_Data)*/
ZCStringBase& operator+=(const ZCStringBase& rhs)
{
return (*this)(rhs.mpc_Data, rhs.ml_UseLen);
}/*
ZCStringBase& operator+=(const ZCStringBase& rhs)*/
TypeChar& operator[](TypeLength AL_Index)
{
return mpc_Data[AL_Index] ;
}/*
TypeChar& operator[](TypeLength AL_Index)*/
const TypeChar& operator[](TypeLength AL_Index) const
{
return mpc_Data[AL_Index] ;
}/*
const TypeChar& operator[](TypeLength AL_Index) const*/
ZCStringBase& operator-(const ZCStringBase& rhs)
{
if(this->DoStart(rhs.c_str(), rhs.size())==true)
MoveFirst(rhs.size());
return *this; //////////////////////////////////
}/*
ZCStringBase& operator-(const ZCStringBase& rhs)*/
ZCStringBase& operator-(TypeCharC* APC_Data)
{
TypeLength VL_Length = ZNsMain::
ZftGetLengthType<TypeLength, TypeChar>(APC_Data);
if(this->DoStart(APC_Data, VL_Length)==true)
MoveFirst(VL_Length);
return *this; //////////////////////////////
}/*
ZCStringBase& operator-(TypeCharC* APC_Data)*/
ZCStringBase& operator-=(TypeCharC* APC_Data)
{
TypeLength VL_Length = ZNsMain::
ZftGetLengthType<TypeLength, TypeChar>(APC_Data);
if(this->DoStart(APC_Data, VL_Length)==true)
MoveFirst(VL_Length);
return *this; //////////////////////////////
}/*
ZCStringBase& operator-=(TypeCharC* APC_Data)*/
bool IsEqual(TypeCharC* APC_Data, TypeLength AL_Length) const
{
return Minus(data(), APC_Data,size(), AL_Length)==0;
}/*
bool IsEqual(TypeCharC* APC_Data, TypeLength AL_Length) const*/
ZCStringBase& Minus(TypeCharC* APC_Data, TypeLength AL_Length)
{
if(this->DoStart(APC_Data, AL_Length)==true) MoveFirst(AL_Length);
return *this; /*################################################*/
}/*
ZCStringBase& Minus(TypeCharC* APC_Data, TypeLength AL_Length)*/
ZCStringBase& Reverse()
{
/* 문자열의 순서를 뒤집는다. 문자열의 길이가 2 이상이어야 한다. */
if(ml_UseLen<2) return *this;
TypeLength i =0 ;
TypeLength j =ml_UseLen-1;
TypeChar VC_TempChar;
TypeChar* VPC_TempHead=mpc_Data ;
TypeChar* VPC_TempTail=mpc_Data+j;
while(i<j)
{
VC_TempChar =*VPC_TempHead ;
*VPC_TempHead++ =*VPC_TempTail ;
*VPC_TempTail-- = VC_TempChar ;
(++i,--j);
}/*
while(i<j)*/
return *this;
}/*
ZCStringBase& Reverse()*/
ZCStringBase& MakeWord(TypeCharC* APC_Data, TypeLength AL_Length)
{
if(AL_Length<1)
{
Invalidate(); return *this;
}/*
if(AL_Length<1)*/
ReAlloc(AL_Length); ::memcpy(
mpc_Data, APC_Data, AL_Length*sizeof(TypeChar));
mpc_Data[ml_UseLen=AL_Length]=0; return *this;
}/*
ZCStringBase& MakeWord(TypeCharC* APC_Data, TypeLength AL_Length)*/
ZCStringBase& operator()(TypeCharC* APC_Data, TypeLength AL_Length)
{
if(mpc_Data==APC_Data || AL_Length<1) return *this;
ReAllocKeep(ml_UseLen+AL_Length);
::memcpy(
mpc_Data+ml_UseLen, APC_Data, AL_Length*sizeof(TypeChar));
mpc_Data[ml_UseLen+=AL_Length]=0; return *this;
}/*
ZCStringBase& operator()(TypeCharC* APC_Data, TypeLength AL_Length)*/
ZCStringBase& operator()(TypeCharC* APC_Data)
{
return (*this)(APC_Data, ZNsMain::ZftGetLengthType<TypeLength, TypeChar>(APC_Data));
}/*
ZCStringBase& operator()(TypeCharC* APC_Data)*/
ZCStringBase& operator()(TypeChar AC_CharParam, TypeLength AL_Count)
{
// 문자 CharParam 를 AL_Count 개 덧붙인다.
if(AL_Count<1) return *this;
ReAllocKeep(ml_UseLen+AL_Count);
__for0(TypeLength, i, AL_Count)
mpc_Data[ml_UseLen+i]=AC_CharParam;
ml_UseLen += AL_Count ;
mpc_Data[ml_UseLen]=0 ; return *this;
}/*
ZCStringBase& operator()(TypeChar CharParam, TypeLength AL_Count)*/
ZCStringBase& operator()(TypeChar AC_CharParam)
{
// 문자 CharParam 를 덧붙인다.
ReAllocKeep(ml_UseLen+1);
mpc_Data[ml_UseLen++]=AC_CharParam;
mpc_Data[ml_UseLen ]=0 ; return *this;
}/*
ZCStringBase& operator()(TypeChar AC_CharParam)*/
ZCStringBase& operator()(const ZCStringBase& rhs)
{
return (*this)(rhs.mpc_Data, rhs.ml_UseLen);
}/*
ZCStringBase& operator()(const ZCStringBase& rhs)*/
ZCStringBase& operator()(const ZCChars& AR_CChars)
{
return (*this)(AR_CChars.data(), AR_CChars.size());
}/*
ZCStringBase& operator()(const ZCChars& AR_CChars)*/
ZCStringBase& operator()(int AI_IntParam)
{
const int CI_BuffSize=21; char VCA_BuffParam[CI_BuffSize];
int VI_ResultSize=::sprintf(VCA_BuffParam, "%d", AI_IntParam);
return (*this)(VCA_BuffParam, VI_ResultSize);
}/*
ZCStringBase& operator()(int AI_IntParam)*/
ZCStringBase& operator()(ZTypUInt AUI_UIntParam)
{
const int CI_BuffSize=21; char VCA_BuffParam[CI_BuffSize];
int VI_ResultSize=::sprintf(VCA_BuffParam, "%u", AUI_UIntParam);
return (*this)(VCA_BuffParam, VI_ResultSize);
}/*
ZCStringBase& operator()(ZTypUInt AUI_UIntParam)*/
ZCStringBase& operator()(long AL_LongParam)
{
const int CI_BuffSize=31; char VCA_BuffParam[CI_BuffSize];
int VI_ResultSize=::sprintf(VCA_BuffParam, "%ld", AL_LongParam);
return (*this)(VCA_BuffParam, VI_ResultSize);
}/*
ZCStringBase& operator()(long AL_LongParam)*/
ZCStringBase& operator()(ZTypULong AUL_ULongParam)
{
const int CI_BuffSize=31; char VCA_BuffParam[CI_BuffSize];
int VI_ResultSize = ::sprintf(VCA_BuffParam, "%lu", AUL_ULongParam);
return (*this)(VCA_BuffParam, VI_ResultSize);
}/*
ZCStringBase& operator()(ZTypULong AUL_ULongParam)*/
ZCStringBase& operator()(ZTypLLong ALL_LLongParam)
{
const int CI_BuffSize=41; char VCA_BuffParam[CI_BuffSize];
#ifdef _WIN
int VI_ResultSize=::sprintf(VCA_BuffParam, "%I64d", ALL_LLongParam);
#else
int VI_ResultSize=::sprintf(VCA_BuffParam, "%lld" , ALL_LLongParam);
#endif
return (*this)(VCA_BuffParam, VI_ResultSize);
}/*
ZCStringBase& operator()(ZTypLLong ALL_LLongParam)*/
ZCStringBase& operator()(ZTypULLong AULL_LLongParam)
{
const int CI_BuffSize=41; char VCA_BuffParam[CI_BuffSize];
#ifdef _WIN
int VI_ResultSize=::sprintf(VCA_BuffParam, "%I64u", AULL_LLongParam);
#else
int VI_ResultSize=::sprintf(VCA_BuffParam, "%llu" , AULL_LLongParam);
#endif
return (*this)(VCA_BuffParam, VI_ResultSize);
}/*
ZCStringBase& operator()(ZTypULLong AULL_LLongParam)*/
ZCStringBase& operator()(double AD_DoubleParam)
{
const int CI_BuffSize=51 ;
char VCA_BuffParam[CI_BuffSize];
int VI_ResultSize=::sprintf(VCA_BuffParam, "%f", AD_DoubleParam);
TrimDecimalZero(VCA_BuffParam, VI_ResultSize); return (*this)(VCA_BuffParam);
}/*
ZCStringBase& operator()(double AD_DoubleParam)*/
ZCStringBase& operator()(
TypeLength AL_AddSize, TypeCharC* APC_Format, ...)
{
if(AL_AddSize<1) return *this;
ReAllocKeep(ml_UseLen+AL_AddSize);
// ml_UseLen+AL_AddSize 의 크기가 가변인수 문자열을 담을 만큼 커야한다.
va_list VP_VarParam;
va_start( VP_VarParam, APC_Format);
vsprintf(mpc_Data+ml_UseLen, APC_Format, VP_VarParam);
CorrectLength(ml_UseLen); return *this;
}/*
ZCStringBase& operator()(
TypeLength AL_AddSize, TypeCharC* APC_Format, ...)*/
ZCStringBase& AddInt4Byte(ZNsMain::ZTypLong AUL_LongType)
{
/*////////////////////////////////////////////////////////////////////////////////////////
■ ULongType 을 4 바이트의 비트 그대로 붙인다. 붙일때 big endian 으로 한다. big endian 이
인간의 표현과 일치한다. 즉 주소가 증가하는 순서로 메모리에 저장된다.
little endian 의 경우 4 바이트 정수형의 주소를 p 라 하면 p[3],p[2],p[1],p[0] 의 순서다.
■ AddInt~Byte 류의 멤버함수는 최적화의 여지가 있다.
////////////////////////////////////////////////////////////////////////////////////////*/
const int CI_AddSize =4;
const int CI_BitOfByte=8;
const int CI_LongByte =sizeof(ZNsMain::ZTypLong);
const bool CB_DoKeepString= true; ReAllocAdd
( CI_AddSize, CB_DoKeepString );
////////////////////////////////////////////
TypeChar* VPC_Start=mpc_Data+ml_UseLen;
int i=CI_AddSize; /////////////////////
while(i>CI_LongByte)
{
*VPC_Start++ = 0 ; --i; // CI_AddSize>sizeof(TypeLength) 일 때는 대비.
}/*
while(i>CI_LongByte)*/
while(i>=1)
{
*VPC_Start++ =
( ( AUL_LongType << ((CI_LongByte-i)*CI_BitOfByte) ) >> ((CI_LongByte-1)*CI_BitOfByte) ) ;
--i;
}/*
while(i>=1)*/
*VPC_Start=0; ml_UseLen += CI_AddSize ; return *this;
}/*
ZCStringBase& AddInt4Byte(ZNsMain::ZTypLong AUL_LongType)*/
ZCStringBase& AddInt8Byte(ZNsMain::ZTypLLong ALL_LLongType)
{
// ULongType 을 8 바이트의 비트 그대로 붙인다.
// 붙일 때 big endian 으로 한다.
const int CI_AddSize =8;
const int CI_BitOfByte =8;
const int CI_LLongByte =sizeof(ZNsMain::ZTypLLong);
ReAllocAdd(CI_AddSize, true); /*>>>>>>>>>>>>>>>>>>>>>>>>*/
TypeChar* VPC_Start=mpc_Data+ml_UseLen; int i=CI_AddSize;
while(i>CI_LLongByte)
{
*VPC_Start++ = 0 ; --i;
}/*
while(i>CI_LLongByte)*/
while(i>=1)
{
*VPC_Start++ =
( ( ALL_LLongType << ((CI_LLongByte-i)*CI_BitOfByte) ) >> ((CI_LLongByte-1)*CI_BitOfByte) ) ;
--i;
}/*
while(i>=1)*/
*VPC_Start=0; ml_UseLen += CI_AddSize; return *this;
}/*
ZCStringBase& AddInt8Byte(TypeLength ALL_LLongType)*/
ZCStringBase& AddInt2Byte(ZNsMain::ZTypInt AI_IntType)
{
const int CI_AddSize =2;
const int CI_BitOfByte=8;
const int CI_IntByte =sizeof(ZNsMain::ZTypInt);
ReAllocAdd(CI_AddSize,true);
TypeChar* VPC_Start=mpc_Data+ml_UseLen;
*VPC_Start++ = ( ( AI_IntType << ((CI_IntByte-2)*CI_BitOfByte) ) >> ((CI_IntByte-1)*CI_BitOfByte) ) ;
*VPC_Start++ = ( ( AI_IntType << ((CI_IntByte-1)*CI_BitOfByte) ) >> ((CI_IntByte-1)*CI_BitOfByte) ) ;
*VPC_Start=0; ml_UseLen += CI_AddSize; return *this;
}/*
ZCStringBase& AddInt2Byte(ZNsMain::ZTypInt AI_IntType)*/
template<typename TObject> ZCStringBase& AddObject(TObject& AR_CObject)
{
return (*this)((TypeCharC*)&AR_CObject, sizeof(AR_CObject));
}/*
template<typename TObject> ZCStringBase& AddObject(TObject& AR_CObject) */
ZCStringBase& CorrectLength(TypeLength AL_StartPos=0)
{
if(AL_StartPos<0 ) AL_StartPos=0;
if(AL_StartPos>=ml_AllLen) return *this ;
do ////
{
if(mpc_Data[AL_StartPos++]==0) break;
}
while(true);
ml_UseLen=AL_StartPos-1; return *this;
}/*
ZCStringBase& CorrectLength(TypeLength AL_StartPos=0)*/
TypeChar* c_str_FromEnd(TypeLength AL_DistanceFromEnd)
{
// 뒤에서 DistanceFromEnd 개 문자열을 읽는다.
if(AL_DistanceFromEnd<=ml_UseLen && AL_DistanceFromEnd>0)
return mpc_Data+(ml_UseLen-AL_DistanceFromEnd) ;
else
return 0;
//else
}/*
TypeChar* c_str_FromEnd(TypeLength AL_DistanceFromEnd)*/
const TypeChar* c_str_FromEnd(TypeLength AL_DistanceFromEnd) const
{
// 뒤에서 DistanceFromEnd 개 문자열을 읽는다.
if(AL_DistanceFromEnd<=ml_UseLen && AL_DistanceFromEnd>0)
return mpc_Data+(ml_UseLen-AL_DistanceFromEnd) ;
else
return 0;
//else
}/*
const TypeChar* c_str_FromEnd(TypeLength AL_DistanceFromEnd) const*/
TypeLength ReadLongFromIndex(TypeLength AL_Index1, TypeLength AL_Index2)
{
// 이 함수는 약간의 속도를 위해 에러처리를 하지 않는 것에 주의
// Index1 번째 문자부터 VL_Index2 번째 문자까지 정수로 읽는다.
TypeChar* VP_Char=
this->NewMem(AL_Index2-AL_Index1+1+1/*Null Char*/);
if(VP_Char==0)
{
return 0; // Add Codes For Memory Over
}/*
if(VP_Char==0)*/
int i;
for(i=0;i<=AL_Index2-AL_Index1;++i)
{
VP_Char[i]=mpc_Data[AL_Index1+i];
}/*
for(i=0;i<=AL_Index2-AL_Index1;++i)*/
VP_Char[i]=0; TypeLength VB_Return=ZNsMain::ATOL(VP_Char);
this->DeleteMem(VP_Char); return VB_Return;
}/*
TypeLength ReadLongFromIndex(TypeLength AL_Index1, TypeLength AL_Index2)*/
TypeLength ReadLong(TypeLength AL_Index1, TypeLength AL_Index2)
{
// Index1 번째 문자부터 VL_Index2 번째 문자까지 정수로 읽는다.
if(AL_Index2>=ml_UseLen) AL_Index2=ml_UseLen-1 ;
if(ml_UseLen<1 || AL_Index1<0 || AL_Index2<0 || AL_Index1>AL_Index2)
return 0;
//endif
return ReadLongFromIndex(AL_Index1, AL_Index2);
}/*
TypeLength ReadLong(TypeLength AL_Index1, TypeLength AL_Index2)*/
TypeLength ReadLong(TypeLength AL_Index)
{
return ReadLong(AL_Index, ml_UseLen-1);
}/*
TypeLength ReadLong(TypeLength AL_Index)*/
TypeLength ReadLong(
TypeLength AL_Index, TypeCharC* APC_Search, TypeLength AL_SearchLen)
{
// VL_Index 부터 APC_Search 을 찾아서 그 앞에까지만 정수로 읽는다.
if(ml_UseLen<1 || AL_Index>=ml_UseLen) return 0;
TypeLength VL_Pos = FindPos
(APC_Search, AL_SearchLen, AL_Index);
if(VL_Pos==AL_Index) return 0;
if(VL_Pos<0) VL_Pos=ml_UseLen-1;
return ReadLongFromIndex(AL_Index,VL_Pos-1);
}/*
TypeLength ReadLong(
TypeLength AL_Index, TypeCharC* APC_Search, TypeLength AL_SearchLen)*/
ZCStringBase& ReadString(
ZCStringBase& ARR_CString, TypeLength AL_Index1, TypeLength AL_Index2)
{
// Index1 번째 문자부터 VL_Index2 문자까지를 ARR_CString 에 전달한다.
return ARR_CString(mpc_Data+AL_Index1, AL_Index2-AL_Index1+1);
}/*
ZCStringBase& ReadString(
ZCStringBase& ARR_CString, TypeLength AL_Index1, TypeLength AL_Index2)*/
ZCStringBase& ReadString_E(
ZCStringBase& ARR_CString, TypeLength AL_Index1, TypeLength AL_Index2)
{
// Index1 번째 문자부터 VL_Index2 문자까지를 ARR_CString 에 전달한다.
// ReadString 과는 달리 에러검사를 한다.
const bool CB_IsTrue = /*////////////////////////*/
(
ml_UseLen<1 ||
AL_Index1<0 || AL_Index2<0 ||
AL_Index1>AL_Index2 || AL_Index2>=ml_UseLen
);
/*///////////////////////////////////////////////*/
if(CB_IsTrue) return ARR_CString; return
ARR_CString( mpc_Data+AL_Index1, AL_Index2-AL_Index1+1 );
}/*
ZCStringBase& ReadString_E(
ZCStringBase& ARR_CString, TypeLength AL_Index1, TypeLength AL_Index2)*/
ZCStringBase& ReadString( ////////////////////////////////////////
ZCStringBase& ARR_CString,
TypeLength AL_Index ,
TypeCharC* APC_Search ,
TypeLength AL_SearchLen
/*/////////*/ ) /*/////////////////////////////////////////////*/
{
// AL_Index 번째 문자부터 APC_Search 문자를 찾아서 그 앞부분까지 ARR_CString 에 전달한다.
if(AL_Index>=ml_UseLen) return ARR_CString;
TypeLength VL_Pos =
FindPos(APC_Search, AL_SearchLen, AL_Index);
if(VL_Pos==AL_Index) return ARR_CString;
if(VL_Pos<0)
VL_Pos=ml_UseLen-1;
else
VL_Pos--;
//else
return ReadString(ARR_CString, AL_Index, VL_Pos);
}/*
ZCStringBase& ReadString( ////////////////////////////////////////
ZCStringBase& ARR_CString,
TypeLength AL_Index ,
TypeCharC* APC_Search ,
TypeLength AL_SearchLen
///////////// ) ///////////////////////////////////////////////*/
// AL_Index 번째 부터 끝문자까지의 데이타를 가져온다.
ZCStringBase& ReadStrToEnd(ZCStringBase& ARR_CString, TypeLength AL_Index)
{
return ReadString(RR(ARR_CString), AL_Index, ml_UseLen-1);
}/*
ZCStringBase& ReadStrToEnd(ZCStringBase& ARR_CString, TypeLength AL_Index)*/
bool IsEmpty() const
{
return ml_UseLen<1;
}/*
bool IsEmpty() const*/
int GetInt () const{return ZNsMain::ATOI (mpc_Data);}
ZTypLong GetLong () const{return ZNsMain::ATOL (mpc_Data);}
ZTypLLong GetLongLong() const{return ZNsMain::ATOLL(mpc_Data);}
ZTypLLong GetLLong () const{return ZNsMain::ATOLL(mpc_Data);}
double GetDouble () const{return ZNsMain::ATOD (mpc_Data);}
ZCStringBase& ConvertLLong()
{
ZNsMain::ZTypLLong LLongValue=ZNsMain::ATOLL(mpc_Data);
this->Invalidate(); return (*this)(LLongValue);
}/*
ZCStringBase& ConvertLLong()*/
ZCStringBase& ConvertLong()
{
ZNsMain::ZTypLLong LongValue=ZNsMain::ATOL(mpc_Data);
this->Invalidate(); return (*this)(LongValue);
}/*
ZCStringBase& ConvertLong()*/
ZCStringBase& Format(TypeCharC* APC_Format, ...)
{
// 이 함수 수행전에 적당한 문자열 메모리가 할당되어 있어야 한다.
va_list VP_VarParam;
va_start(VP_VarParam, APC_Format);
vsprintf(mpc_Data, APC_Format, VP_VarParam);
CorrectLength(); return *this;
}/*
ZCStringBase& Format(TypeCharC* APC_Format, ...)*/
ZCStringBase& FormatAdd(TypeLength AL_FormatSize, TypeCharC* APC_Format, ...)
{
if(AL_FormatSize<0) AL_FormatSize=0;
ReAllocKeep(ml_UseLen+AL_FormatSize);
va_list VP_VarParam;
va_start( VP_VarParam, APC_Format);
vsprintf(mpc_Data+ml_UseLen, APC_Format, VP_VarParam);
CorrectLength(ml_UseLen); return *this;
}/*
ZCStringBase& FormatAdd(TypeLength AL_FormatSize, TypeCharC* APC_Format, ...)*/
ZCStringBase& ReplaceChar(
TypeChar AC_SearchChar, TypeChar AC_ReplaceChar, TypeLength AI_StartPos=0)
{
for(TypeLength i=AI_StartPos;i<ml_UseLen;++i)
{
if(mpc_Data[i]==AC_SearchChar) mpc_Data[i]=AC_ReplaceChar;
}/*
for(TypeLength i=AI_StartPos;i<ml_UseLen;++i)*/
return *this;
}/*
ZCStringBase& ReplaceChar(
TypeChar AC_SearchChar, TypeChar AC_ReplaceChar, TypeLength AI_StartPos=0)*/
ZCStringBase& ReplaceOnce
(
TypeCharC* APC_Search , TypeCharC* APC_Replace ,
TypeLength AL_SearchLen, TypeLength AL_ReplaceLen, TypeLength AL_StartPos=0
)
/*#####################*/
{
TypeLength VL_PosFind =
FindPos(APC_Search, AL_SearchLen, AL_StartPos);
if(VL_PosFind<0) return *this;
return ReplaceSection(
VL_PosFind, AL_SearchLen, APC_Replace, AL_ReplaceLen);
}/*
ZCStringBase& ReplaceOnce
(
TypeCharC* APC_Search , TypeCharC* APC_Replace ,
TypeLength AL_SearchLen, TypeLength AL_ReplaceLen, TypeLength AL_StartPos=0
)
#######################*/
ZCStringBase& ReplaceOnce(
TypeCharC* APC_Search, TypeCharC* APC_Replace, TypeLength AL_StartPos=0)
{
using ZNsMain::ZftGetLengthType ;
return ReplaceOnce( /////////////////////////////////////////////////
APC_Search ,
APC_Replace ,
ZftGetLengthType<TypeLength, TypeChar>(APC_Search) ,
ZftGetLengthType<TypeLength, TypeChar>(APC_Replace) ,
AL_StartPos
/*/////////*/ ); ////////////////////////////////////////////////////
}/*
ZCStringBase& ReplaceOnce(
TypeCharC* APC_Search, TypeCharC* APC_Replace, TypeLength AL_StartPos=0)*/
ZCStringBase& Replace /*##############*/
(
TypeCharC* APC_Search ,
TypeCharC* APC_Replace ,
TypeLength AL_SearchLen ,
TypeLength AL_ReplaceLen ,
TypeLength AL_StartPos=0
)
/*####################################*/
{
if(ml_UseLen<1) return *this;
ZCSearchInfoList VO_CSearchInfoList;
MakeInfoList
(
APC_Search , AL_SearchLen,
AL_StartPos, RR(VO_CSearchInfoList)
);
TypeLength VL_InfoEntrySize =
VO_CSearchInfoList.GetSize() ;
if(VL_InfoEntrySize<1) return *this;
TypeLength VL_PrevSize =ml_UseLen;
TypeLength VL_NewSize =0 ;
IterEasyID VI_IterEasyID=
VO_CSearchInfoList.GetHeadIterEasyID();
VL_NewSize = ml_UseLen +
VL_InfoEntrySize*(AL_ReplaceLen-AL_SearchLen );
if(VL_NewSize>VL_PrevSize) ReAllocKeep(VL_NewSize);
TypeChar* VP_Origin=mpc_Data; TypeLength VL_Index=0;
/* AL_ReplaceLen==AL_SearchLen 나
AL_ReplaceLen> AL_SearchLen 나
AL_ReplaceLen< AL_SearchLen 각 경우에
Replace 방식이 조금 틀리다. */
if(AL_ReplaceLen==AL_SearchLen)
{
__for0(TypeLength, i, VL_InfoEntrySize)
{
VL_Index = VO_CSearchInfoList.
ItD(VI_IterEasyID).ml_Pos ;
__for0(TypeLength, j, AL_ReplaceLen)
{ VP_Origin[VL_Index+j] =APC_Replace[j] ; }
VO_CSearchInfoList.MoveNextIter(VI_IterEasyID);
}/*
__for0(TypeLength, i, VL_InfoEntrySize)*/
}
else if(AL_ReplaceLen<AL_SearchLen)
{
VL_Index=VO_CSearchInfoList.GetHeadData().ml_Pos;
for(TypeLength i=1; i<=VL_InfoEntrySize; ++i)
{
for(TypeLength j=0; j<AL_ReplaceLen; ++j)
{ VP_Origin[VL_Index++]=APC_Replace[j] ; }
if(i!=VL_InfoEntrySize)
{
// 마지막 링크가 아닐 경우
TypeLength VL_IndexHead =
VO_CSearchInfoList.ItD(VI_IterEasyID ).ml_Pos+AL_SearchLen;
TypeLength VL_IndexTail =
VO_CSearchInfoList.ItD(VI_IterEasyID, 1).ml_Pos-1 ;
for(TypeLength k=VL_IndexHead; k<=VL_IndexTail; ++k)
{ VP_Origin[VL_Index++] = VP_Origin[k] ; }
}
else // i==VL_InfoEntrySize
{
TypeLength VL_IndexTail = VL_PrevSize-1 ;
TypeLength VL_IndexHead =
VO_CSearchInfoList.ItD(VI_IterEasyID).ml_Pos+AL_SearchLen;
for(TypeLength k=VL_IndexHead; k<=VL_IndexTail; ++k)
{
VP_Origin[VL_Index++] = VP_Origin[k] ;
}/*
for(TypeLength k=VL_IndexHead; k<=VL_IndexTail; ++k)*/
}/*
else // i==VL_InfoEntrySize*/
VO_CSearchInfoList.MoveNextIter(VI_IterEasyID);
}/*
for(TypeLength i=1;i<=VL_InfoEntrySize;++i)*/
}/*
else if(AL_ReplaceLen<AL_SearchLen)*/
else // AL_ReplaceLen>AL_SearchLen
{
// 뒤부터 채워 나간다.
VP_Origin[VL_NewSize]=0;
VL_Index = VL_NewSize-1 ;
VI_IterEasyID =
VO_CSearchInfoList.GetTailIterEasyID() ;
TypeLength VL_IndexTail = VL_PrevSize-1 ;
TypeLength VL_IndexHead =
VO_CSearchInfoList.ItD(VI_IterEasyID).ml_Pos+AL_SearchLen;
for(TypeLength i=VL_IndexTail; i>=VL_IndexHead; --i)
{
VP_Origin[VL_Index--] = VP_Origin[i];
}/*
for(TypeLength i=VL_IndexTail; i>=VL_IndexHead; --i)*/
for(TypeLength j=VL_InfoEntrySize ;j>=2; --j)
{
TypeLength k=0;
for(k=AL_ReplaceLen-1; k>=0; --k)
{ VP_Origin[VL_Index--]=APC_Replace[k]; }
VL_IndexHead=VO_CSearchInfoList.ItD(VI_IterEasyID, -1).ml_Pos+AL_SearchLen ;
VL_IndexTail=VO_CSearchInfoList.ItD(VI_IterEasyID ).ml_Pos-1 ;
for(k=VL_IndexTail; k>=VL_IndexHead; --k)
{ VP_Origin[VL_Index--]=VP_Origin[k] ; }
VO_CSearchInfoList.MovePrevIter(VI_IterEasyID);
}/*
for(TypeLength j=VL_InfoEntrySize; j>=2; --j)*/
for(TypeLength k=AL_ReplaceLen-1; k>=0; --k)
{
VP_Origin[VL_Index--] = APC_Replace[k];
}/*
for(TypeLength k=AL_ReplaceLen-1; k>=0; --k)*/
}/*
else // AL_ReplaceLen>AL_SearchLen*/
VP_Origin[ml_UseLen=VL_NewSize]=0; return *this;
}/*
ZCStringBase& Replace //////////////////////
(
TypeCharC* APC_Search ,
TypeCharC* APC_Replace ,
TypeLength AL_SearchLen ,
TypeLength AL_ReplaceLen ,
TypeLength AL_StartPos=0
)
//////////////////////////////////////////*/
template<typename TSearchInfoList> ZCStringBase& ReplaceType
(
TypeCharC* APC_Search , TypeCharC* APC_Replace ,
TypeLength AL_SearchLen , TypeLength AL_ReplaceLen,
TypeLength AL_StartPos=0
)
/*########################################################*/
{
// 내부 연결리스트로 TSearchInfoList 를 사용한다.
if(ml_UseLen<1) return *this;
TSearchInfoList VO_CSearchInfoList; MakeInfoList
(
APC_Search , AL_SearchLen,
AL_StartPos, RR(VO_CSearchInfoList)
);
////////////////////////////////////////////////
TypeLength VL_InfoEntrySize =
VO_CSearchInfoList.GetSize() ;
if(VL_InfoEntrySize<1) return *this ;
TypeLength VL_PrevSize = ml_UseLen ;
TypeLength VL_NewSize = 0 ;
IterEasyID VI_IterEasyID =
VO_CSearchInfoList.GetHeadIterEasyID();
VL_NewSize = ml_UseLen +
VL_InfoEntrySize * (AL_ReplaceLen-AL_SearchLen);
if(VL_NewSize>VL_PrevSize) ReAllocKeep(VL_NewSize);
TypeChar* VP_Origin=mpc_Data;
TypeLength VL_Index =0 ;
// AL_ReplaceLen==AL_SearchLen 나
// AL_ReplaceLen> AL_SearchLen 나
// AL_ReplaceLen< AL_SearchLen 각 경우에
// Replace 방식이 조금 틀리다.
if(AL_ReplaceLen==AL_SearchLen)
{
for(TypeLength i=0; i<VL_InfoEntrySize; ++i)
{
VL_Index=VO_CSearchInfoList.ItD(VI_IterEasyID).ml_Pos ;
for(TypeLength j=0; j<AL_ReplaceLen; ++j)
{ VP_Origin[VL_Index+j]=APC_Replace[j]; }
VO_CSearchInfoList.MoveNextIter(VI_IterEasyID);
}/*
for(TypeLength i=0; i<VL_InfoEntrySize; ++i)*/
}
else if(AL_ReplaceLen<AL_SearchLen)
{
VL_Index=VO_CSearchInfoList.GetHeadData().ml_Pos;
for(TypeLength i=1;i<=VL_InfoEntrySize;++i)
{
for(TypeLength j=0; j<AL_ReplaceLen; ++j)
{
VP_Origin[VL_Index++]=APC_Replace[j] ;
}/*
for(TypeLength j=0; j<AL_ReplaceLen; ++j)*/
if(i!=VL_InfoEntrySize)
{
// 마지막 링크가 아닐 경우
TypeLength VL_IndexHead=VO_CSearchInfoList.ItD(VI_IterEasyID ).ml_Pos+AL_SearchLen;
TypeLength VL_IndexTail=VO_CSearchInfoList.ItD(VI_IterEasyID, 1).ml_Pos-1;
for(TypeLength k=VL_IndexHead; k<=VL_IndexTail; ++k)
{
VP_Origin[VL_Index++] = VP_Origin[k] ;
}/*
for(TypeLength k=VL_IndexHead; k<=VL_IndexTail; ++k)*/
}
else // i==VL_InfoEntrySize
{
TypeLength VL_IndexTail=VL_PrevSize-1 ;
TypeLength VL_IndexHead=VO_CSearchInfoList.
ItD(VI_IterEasyID).ml_Pos + AL_SearchLen ;
for(TypeLength k=VL_IndexHead; k<=VL_IndexTail; ++k)
{
VP_Origin[VL_Index++] = VP_Origin[k] ;
}/*
for(TypeLength k=VL_IndexHead; k<=VL_IndexTail; ++k)*/
}/*
else // i==VL_InfoEntrySize*/
VO_CSearchInfoList.MoveNextIter(VI_IterEasyID);
}/*
for(TypeLength i=1; i<=VL_InfoEntrySize; ++i)*/
}
else // AL_ReplaceLen>AL_SearchLen
{
// 뒤부터 채워 나간다.
VP_Origin[VL_NewSize]=0;
VL_Index = VL_NewSize-1 ;
VI_IterEasyID =
VO_CSearchInfoList.GetTailIterEasyID();
TypeLength VL_IndexTail=VL_PrevSize-1;
TypeLength VL_IndexHead=VO_CSearchInfoList.
ItD(VI_IterEasyID).ml_Pos + AL_SearchLen ;
for(TypeLength i=VL_IndexTail; i>=VL_IndexHead; --i)
{
VP_Origin[VL_Index--]=VP_Origin[i];
}/*
for(TypeLength i=VL_IndexTail; i>=VL_IndexHead; --i)*/
for(TypeLength j=VL_InfoEntrySize; j>=2; --j)
{
TypeLength k;
for(k=AL_ReplaceLen-1; k>=0; --k)
{
VP_Origin[VL_Index--]=APC_Replace[k];
}/*
for(k=AL_ReplaceLen-1; k>=0; --k)*/
VL_IndexHead=VO_CSearchInfoList.ItD(VI_IterEasyID, -1).ml_Pos+AL_SearchLen;
VL_IndexTail=VO_CSearchInfoList.ItD(VI_IterEasyID ).ml_Pos-1 ;
for(k=VL_IndexTail; k>=VL_IndexHead; --k)
{ VP_Origin[VL_Index--]=VP_Origin[k]; }
VO_CSearchInfoList.MovePrevIter(VI_IterEasyID);
}/*
for(TypeLength j=VL_InfoEntrySize; j>=2; --j)*/
for(TypeLength k=AL_ReplaceLen-1; k>=0 ;--k)
{
VP_Origin[VL_Index--]=APC_Replace[k];
}/*
for(TypeLength k=AL_ReplaceLen-1; k>=0; --k)*/
}/*
else // AL_ReplaceLen>AL_SearchLen*/
VP_Origin[ml_UseLen=VL_NewSize]=0; return *this;
}/*
tempalte<typename TSearchInfoList> ZCStringBase& ReplaceType
(
TypeCharC* APC_Search , TypeCharC* APC_Replace ,
TypeLength AL_SearchLen , TypeLength AL_ReplaceLen,
TypeLength AL_StartPos=0
)
###########################################################*/
ZCStringBase& Replace(TypeCharC* APC_Search, TypeCharC* APC_Replace, TypeLength AL_StartPos=0)
{
using ZNsMain::ZftGetLengthType ;
return Replace /////////////////////////////////////////////
(
APC_Search ,
APC_Replace ,
ZftGetLengthType<TypeLength, TypeChar>(APC_Search ),
ZftGetLengthType<TypeLength, TypeChar>(APC_Replace),
AL_StartPos
);
////////////////////////////////////////////////////////////
}/*
ZCStringBase& Replace(TypeCharC* APC_Search, TypeCharC* APC_Replace, TypeLength AL_StartPos=0)*/
template<typename TSearchInfoList> ZCStringBase&
ReplaceType(TypeCharC* APC_Search, TypeCharC* APC_Replace, TypeLength AL_StartPos=0)
{
using ZNsMain::ZftGetLengthType ;
return ReplaceType<TSearchInfoList>
(
APC_Search ,
APC_Replace ,
ZftGetLengthType<TypeLength, TypeChar>(APC_Search) ,
ZftGetLengthType<TypeLength, TypeChar>(APC_Replace) ,
AL_StartPos
);
///////////////////////////////////
}/*
template<typename TSearchInfoList> ZCStringBase&
ReplaceType(TypeCharC* APC_Search, TypeCharC* APC_Replace, TypeLength AL_StartPos=0) */
ZCStringBase& Replace(
const ZCStringBase& AR_CStrSearch, const ZCStringBase& AR_CStrReplace, TypeLength AL_StartPos=0)
{
return Replace( AR_CStrSearch. data(), //////
AR_CStrReplace.data(),
AR_CStrSearch. size(),
AR_CStrReplace.size(),
AL_StartPos
/*/////////*/ ); ////////////////////////////
}/*
ZCStringBase& Replace(
const ZCStringBase& AR_CStrSearch, const ZCStringBase& AR_CStrReplace, TypeLength AL_StartPos=0) */
template<typename TSearchInfoList> ZCStringBase& ReplaceType(
const ZCStringBase& AR_CStrSearch ,
const ZCStringBase& AR_CStrReplace,
TypeLength AL_StartPos=0
/*/////////*/ ) ////////////////////////////////////////////
{
return ReplaceType<TSearchInfoList>( ///////
AR_CStrSearch. data(),
AR_CStrReplace.data(),
AR_CStrSearch. size(),
AR_CStrReplace.size(),
AL_StartPos
/*/////////*/ ); ///////////////////////////
}/*
template<typename TSearchInfoList> ZCStringBase& ReplaceType(
const ZCStringBase& AR_CStrSearch ,
const ZCStringBase& AR_CStrReplace,
TypeLength AL_StartPos=0
///////////// ) //////////////////////////////////////////*/
static ZCStringBase& ReplaceSection /*#########################################*/
(
ZCStringBase& ARR_Saver ,
TypeCharC* APC_Origin ,
TypeLength AL_SectPos , // APC_Origin 의 특정위치
TypeLength AL_SectLen ,
TypeCharC* APC_Replace ,
TypeLength AL_OriginLen ,
TypeLength AL_ReplaceLen
)
/*#############################################################################*/
{
// APC_Origin 의 AL_SectPos 부터 AL_SectLen 개의 문자를
// APC_Replace 로 바꾸어서 ARR_Saver 에 저장한다.
if(AL_SectLen<1 || AL_OriginLen<1)
{ return ARR_Saver; }
if(AL_ReplaceLen<0)
{ AL_ReplaceLen=0 ; }
TypeLength VL_AllMemSize=0;
// 아래 if 문에 대해서는 ReplaceFromInfoList() 를 참고
if(ARR_Saver.data()==APC_Origin)
{
ARR_Saver.ReAllocKeep(
VL_AllMemSize=AL_OriginLen+AL_ReplaceLen-AL_SectLen);
TypeChar* VPC_Origin2=ARR_Saver.data();
if(AL_ReplaceLen<AL_SectLen)
{
TypeChar* VPC_Dest=ARR_Saver.data() + AL_SectPos ;
for(int i=0;i<AL_ReplaceLen;++i)
{
*VPC_Dest++ = APC_Replace[i] ;
}/*
for(int i=0;i<AL_ReplaceLen;++i)*/
for(int j=AL_SectPos+AL_SectLen; j<AL_OriginLen; ++j)
{
*VPC_Dest++ = VPC_Origin2[j] ;
}/*
for(int j=AL_SectPos+AL_SectLen; j<AL_OriginLen; ++j)*/
ARR_Saver.data()[VL_AllMemSize]=0;
ARR_Saver.CorrectLength(VL_AllMemSize-1);
return ARR_Saver;
}
else // AL_ReplaceLen>=AL_SectLen
{
TypeLength VL_NowIndex=AL_OriginLen-1 ;
TypeChar* VPC_Dest =ARR_Saver.data()+VL_AllMemSize-1;
while(VL_NowIndex>=AL_SectPos+AL_SectLen)
{
*VPC_Dest-- = VPC_Origin2[VL_NowIndex--] ;
}/*
while(VL_NowIndex>=AL_SectPos+AL_SectLen)*/
for(int i=AL_ReplaceLen-1; i>=0; --i)
{
*VPC_Dest-- = APC_Replace[i] ;
}/*
for(int i=AL_ReplaceLen-1; i>=0; --i)*/
ARR_Saver.data()[VL_AllMemSize]=0;
ARR_Saver.CorrectLength(VL_AllMemSize-1);
return ARR_Saver;
}/*
else // AL_ReplaceLen>=AL_SectLen*/
}/*
if(ARR_Saver.data()==APC_Origin)*/
ARR_Saver.ReAllocKeep
(
VL_AllMemSize += ARR_Saver.size() +
AL_OriginLen + AL_ReplaceLen - AL_SectLen
);
/////////////////////
TypeLength VL_NowIndex=AL_OriginLen-1 ;
TypeChar* VPC_Dest =ARR_Saver.data()+VL_AllMemSize-1;
while(VL_NowIndex>=AL_SectPos+AL_SectLen)
{
*VPC_Dest-- = APC_Origin[VL_NowIndex--] ;
}/*
while(VL_NowIndex>=AL_SectPos+AL_SectLen)*/
for(int i=AL_ReplaceLen-1; i>=0; --i)
{
*VPC_Dest-- = APC_Replace[i] ;
}/*
for(int i=AL_ReplaceLen-1; i>=0; --i)*/
for(int j=AL_SectPos-1; j>=0; --j)
{
*VPC_Dest-- = APC_Origin[j] ;
}/*
for(int j=AL_SectPos-1; j>=0; --j)*/
ARR_Saver.data()[VL_AllMemSize]=0;
ARR_Saver.CorrectLength(VL_AllMemSize-1);
return ARR_Saver;
}/*
static ZCStringBase& ReplaceSection #############################################
(
ZCStringBase& ARR_Saver ,
TypeCharC* APC_Origin ,
TypeLength AL_SectPos ,
TypeLength AL_SectLen ,
TypeCharC* APC_Replace ,
TypeLength AL_OriginLen ,
TypeLength AL_ReplaceLen
)
###############################################################################*/
static ZCStringBase& ReplaceSection( ////////////////////////////////////////////
ZCStringBase& ARR_Saver ,
TypeCharC* APC_Origin ,
TypeLength AL_SectPos , // APC_Origin의 특정위치
TypeLength AL_SectLen ,
TypeCharC* APC_Replace
/*/////////*/ ) ////////////////////////////////////////////////////////////////
{
using ZNsMain::ZftGetLengthType;
return ReplaceSection( ARR_Saver , //////////////////////////////////////
APC_Origin ,
AL_SectPos ,
AL_SectLen ,
APC_Replace ,
ZftGetLengthType<TypeLength, TypeChar>(APC_Origin ),
ZftGetLengthType<TypeLength, TypeChar>(APC_Replace)
/*////////////////*/ ) ;
}/*
static ZCStringBase& ReplaceSection( ////////////////////////////////////////////
ZCStringBase& ARR_Saver ,
TypeCharC* APC_Origin,
TypeLength AL_SectPos, // APC_Origin의 특정위치
TypeLength AL_SectLen,
TypeCharC* APC_Replace
///////////// ) /////////////////////////////////////////////////////////////*/
// TSearchInfoList 은 class ZCSearchInfo 의 리스트
template<typename TSearchInfoList> ZCStringBase& ReplaceFromInfoList /*########*/
(
TSearchInfoList& AR_InfoList ,
TypeCharC* APC_Origin ,
TypeCharC* APC_Replace ,
TypeLength AL_OriginLen ,
TypeLength AL_ReplaceLen
)
/*#############################################################################*/
{
// APC_Origin문자열을 어떤 기준에 적합한 부문자열 정보가 AR_InfoList
// 에 있고, 이 정보를 토대로 부문자열을 APC_Replace로 바꾼다.
IterEasyID VI_InfoIter =AR_InfoList.GetTailIterEasyID();
TypeLength VL_NeedMemory=
GetNeedMemoryForReplace
(AR_InfoList, AL_ReplaceLen, AL_OriginLen);
TypeLength VL_InfoSize =AR_InfoList.GetSize() ;
TypeLength VL_NowIndex =AL_OriginLen-1 ;
TypeLength VL_AllMemCnt =ml_UseLen+VL_NeedMemory ;
/*///////////////////////////////////////////////////////////////////////////////////////////////
■ this 의 내부버퍼가 APC_Origin일 때 수행할 수 있게 한다. 만일
APC_Origin==ARR_StringReplace.c_str()
인 경우에, ARR_StringReplace 이 새로운 메모리를 할당하면서 APC_Origin의 값이 바뀔 수 있으므로
다시 초기화하는 코드가 필요하다. 이때 ZtCStringBase::ReplaceSection() 함수와는 달리, 메모리를
추가해야 한다. ZCStringBase object.ReplaceSection(0,10,"MyTest",6) 라고 할 때 ZCStringBase object
의 메모리는 변하지 않는다. 그러나 지금 함수 Replace() 는 반드시 메모리를 추가 할당한다.
///////////////////////////////////////////////////////////////////////////////////////////////*/
if(APC_Origin==mpc_Data)
{
ReAllocKeep(VL_AllMemCnt); APC_Origin=mpc_Data; // APC_Origin 다시 초기화
}
else
ReAllocKeep(VL_AllMemCnt);
//else
TypeChar* VPC_CharDest = mpc_Data + (VL_AllMemCnt-1);
// ARR_StringReplace 의 내부 버퍼가 APC_Origin 일 때 수행할
// 수 있게 한다. 그러자면 뒤부터 채워오는 것이 안전하다.
TypeLength VL_InnerPos=0;
for(TypeLength i=0; i<VL_InfoSize; ++i)
{
VL_InnerPos =
AR_InfoList.ItD(VI_InfoIter).ml_Pos +
AR_InfoList.ItD(VI_InfoIter).ml_Len ;
while(VL_NowIndex>=VL_InnerPos)
{
*VPC_CharDest-- = APC_Origin[VL_NowIndex--];
}/*
while(VL_NowIndex>=VL_InnerPos)*/
for(int p=AL_ReplaceLen-1; p>=0; --p)
{
*VPC_CharDest--=APC_Replace[p];
}/*
for(int p=AL_ReplaceLen-1; p>=0; --p)*/
VL_NowIndex=AR_InfoList.ItD(VI_InfoIter).ml_Pos-1;
AR_InfoList.MovePrevIter(VI_InfoIter);
}/*
for(TypeLength i=0; i<VL_InfoSize; ++i)*/
if(VL_NowIndex>=0)
{
while(VL_NowIndex>=0)
{
*VPC_CharDest-- = APC_Origin[VL_NowIndex--];
}/*
while(VL_NowIndex>=0)*/
}/*
if(VL_NowIndex>=0)*/
mpc_Data[ml_UseLen=VL_AllMemCnt]=0; return *this;
}/*
template<typename TSearchInfoList> ZCStringBase& ReplaceFromInfoList ###########
(
TSearchInfoList& AR_InfoList ,
TypeCharC* APC_Origin ,
TypeCharC* APC_Replace ,
TypeLength AL_OriginLen ,
TypeLength AL_ReplaceLen
)
###############################################################################*/
ZCStringBase& ReplaceSection( //////////////////////////////////////
TypeLength AL_SectPos ,
TypeLength AL_SectLen ,
TypeCharC* APC_Replace,
TypeLength AL_ReplaceLen
/*/////////*/ ) ////////////////////////////////////////////////////
{
return ReplaceSection( /////////////////////
*this ,
mpc_Data ,
AL_SectPos ,
AL_SectLen ,
APC_Replace ,
ml_UseLen ,
AL_ReplaceLen
/*//////////*/ ); //////////////////////////
}/*
ZCStringBase& ReplaceSection( //////////////////////////////////////
TypeLength AL_SectPos ,
TypeLength AL_SectLen ,
TypeCharC* APC_Replace,
TypeLength AL_ReplaceLen
///////////// ) ////////////////////////////////////////////////*/
ZCStringBase& ReplaceRange /*##################################################*/
(
TypeCharC* APC_Search1 ,
TypeCharC* APC_Search2 ,
TypeCharC* APC_Replace ,
bool AB_DoKeepSearch,
TypeLength AL_StartPos ,
TypeLength AL_SearchLen1 ,
TypeLength AL_SearchLen2 ,
TypeLength AL_ReplaceLen ,
bool AB_IsExactTwo=true
)
/*#############################################################################*/
{
/*/////////////////////////////////////////////////////////////////
■ APC_Search1 부터 APC_Search2까지의 문자열을 APC_Replace 로 바꾼다.
■ bool AB_DoKeepSearch==true 이면 APC_Search1, APC_Search2 는 바뀌
지 않고, 그 사이에 있는 문자열만 바꾼다.
■ FindPos() 수행 중에 ml_UseLen<1 일 때의 경우를 검사한다.
/////////////////////////////////////////////////////////////////*/
if(AL_SearchLen1<1 || AL_SearchLen2<1) return *this;
TypeLength VL_SearchPos1; TypeLength VL_SearchPos2;
const bool CB_IsSearched = (
(VL_SearchPos1 = FindPos(mpc_Data, APC_Search1, ml_UseLen, AL_SearchLen1, AL_StartPos ))>=0 &&
(VL_SearchPos2 = FindPos(mpc_Data, APC_Search2, ml_UseLen, AL_SearchLen2, VL_SearchPos1+AL_SearchLen1))>=0 );
if(CB_IsSearched)
{
if(AB_DoKeepSearch==true)
{
if(VL_SearchPos2-VL_SearchPos1-AL_SearchLen1<1)
{
return *this; // 찾은 두 문자열 사이에 문자가 없을 때
}/*
if(VL_SearchPos2-VL_SearchPos1-AL_SearchLen1<1)*/
return ReplaceSection
(
VL_SearchPos1+AL_SearchLen1 ,
VL_SearchPos2-VL_SearchPos1-AL_SearchLen1,
APC_Replace ,
AL_ReplaceLen
);
/////////////////////
}
else // AB_DoKeepSearch!=true
{
return ReplaceSection
(
VL_SearchPos1, VL_SearchPos2-VL_SearchPos1+AL_SearchLen2,
APC_Replace , AL_ReplaceLen
);
/////////////////////
}/*
else // AB_DoKeepSearch!=true*/
}
else if(AB_IsExactTwo==false && VL_SearchPos1>=0 && VL_SearchPos2<0)
{
if(AB_DoKeepSearch==true) Invalidate(VL_SearchPos1+AL_SearchLen1);
else Invalidate(VL_SearchPos1);
}/*
else if(AB_IsExactTwo==false && VL_SearchPos1>=0 && VL_SearchPos2<0)*/
return *this;
}/*
ZCStringBase& ReplaceRange( #####################################################
(
TypeCharC* APC_Search1 ,
TypeCharC* APC_Search2 ,
TypeCharC* APC_Replace ,
bool AB_DoKeepSearch,
TypeLength AL_StartPos ,
TypeLength AL_SearchLen1 ,
TypeLength AL_SearchLen2 ,
TypeLength AL_ReplaceLen ,
bool AB_IsExactTwo=true
)
###############################################################################*/
ZCStringBase& ReplaceRange( //////////////////////////////////
const ZCStringBase& AR_CStrSearch1,
const ZCStringBase& AR_CStrSearch2,
const ZCStringBase& AR_CStrReplace,
bool AB_DoKeepSearch=false,
TypeLength AL_StartPos =0 ,
bool AB_IsExactTwo =true
/*//////////*/ ) /////////////////////////////////////////////
{
return ReplaceRange( /////////////////////////////////////
AR_CStrSearch1.data(),
AR_CStrSearch2.data(),
AR_CStrReplace.data(),
AB_DoKeepSearch ,
AL_StartPos ,
AR_CStrSearch1.size(),
AR_CStrSearch2.size(),
AR_CStrReplace.size(),
AB_IsExactTwo
/*//////////*/ ); ////////////////////////////////////////
}/*
ZCStringBase& ReplaceRange( //////////////////////////////////
const ZCStringBase& AR_CStrSearch1,
const ZCStringBase& AR_CStrSearch2,
const ZCStringBase& AR_CStrReplace,
bool AB_DoKeepSearch=false,
TypeLength AL_StartPos =0 ,
bool AB_IsExactTwo =true
///////////// ) ////////////////////////////////////////////*/
ZCStringBase& ReplaceRange( ///////////////////////////////////
TypeCharC* APC_Search1 ,
TypeCharC* APC_Search2 ,
TypeCharC* APC_Replace ,
bool AB_DoKeepSearch=false,
TypeLength AL_StartPos =0 ,
bool AB_IsExactTwo =true
/*/////////*/ ) ///////////////////////////////////////////////
{
using ZNsMain::ZftGetLengthType ;
return ReplaceRange( ////////////////////////////////////////////////
APC_Search1 ,
APC_Search2 ,
APC_Replace ,
AB_DoKeepSearch ,
AL_StartPos ,
ZftGetLengthType<TypeLength, TypeChar>(APC_Search1),
ZftGetLengthType<TypeLength, TypeChar>(APC_Search2),
ZftGetLengthType<TypeLength, TypeChar>(APC_Replace),
AB_IsExactTwo
/*//////////*/ ); ///////////////////////////////////////////////////
}/*
ZCStringBase& ReplaceRange( ///////////////////////////////////
TypeCharC* APC_Search1 ,
TypeCharC* APC_Search2 ,
TypeCharC* APC_Replace ,
bool AB_DoKeepSearch=false,
TypeLength AL_StartPos =0 ,
bool AB_IsExactTwo =true
//////////// ) /////////////////////////////////////////////*/
ZCStringBase& ReplaceAllRange( ///////////////////////////////
TypeCharC* APC_Search1 ,
TypeCharC* APC_Search2 ,
TypeCharC* APC_Replace ,
bool AB_DoKeepSearch ,
TypeLength AL_StartPos ,
TypeLength AL_SearchLen1 ,
TypeLength AL_SearchLen2 ,
TypeLength AL_ReplaceLen
/*/////////*/ ) //////////////////////////////////////////////
{
if(AL_SearchLen1<1 || AL_SearchLen2<1 || AL_ReplaceLen<0)
{ return *this; }
/////////////////////////////////////////////////////////
TypeLength VL_SearchPos1= AL_StartPos;
TypeLength VL_SearchPos2= -1 ;
while(VL_SearchPos1<ml_UseLen)
{
const bool CB_IsSearched = (
(VL_SearchPos1=FindPos(mpc_Data, APC_Search1, ml_UseLen, AL_SearchLen1, VL_SearchPos1 ))>=0 &&
(VL_SearchPos2=FindPos(mpc_Data, APC_Search2, ml_UseLen, AL_SearchLen2, VL_SearchPos1+AL_SearchLen1))>=0 );
if(CB_IsSearched)
{
if(AB_DoKeepSearch==true)
{
// 찾은 두 문자열 사이에 문자가 없을 때
if(VL_SearchPos2-VL_SearchPos1-AL_SearchLen1<1)
{
VL_SearchPos1 = VL_SearchPos2 + AL_SearchLen2 ; continue;
}/*
if(VL_SearchPos2-VL_SearchPos1-AL_SearchLen1<1)*/
ReplaceSection( VL_SearchPos1+AL_SearchLen1,
VL_SearchPos2-VL_SearchPos1-AL_SearchLen1,
APC_Replace,
AL_ReplaceLen
/*/////////*/ ); /////////////////////////////////////////
VL_SearchPos1 += AL_SearchLen1 + AL_ReplaceLen + AL_SearchLen2 ;
}
else //AB_DoKeepSearch!=true
{
ReplaceSection /////////////////////
(
VL_SearchPos1 ,
VL_SearchPos2-VL_SearchPos1+AL_SearchLen2,
APC_Replace ,
AL_ReplaceLen
);
/////////////////////////////////////
VL_SearchPos1 += AL_ReplaceLen ;
}/*
else //AB_DoKeepSearch!=true*/
continue;
}/*
if(CB_IsSearched)*/
return *this;
}/*
while(VL_SearchPos1<ml_UseLen)*/
return *this;
}/*
ZCStringBase& ReplaceAllRange( ////////////////////////////////
TypeCharC* APC_Search1 ,
TypeCharC* APC_Search2 ,
TypeCharC* APC_Replace ,
bool AB_DoKeepSearch ,
TypeLength AL_StartPos ,
TypeLength AL_SearchLen1 ,
TypeLength AL_SearchLen2 ,
TypeLength AL_ReplaceLen
///////////// ) //////////////////////////////////////////./*/
ZCStringBase& ReplaceAllRange( ////////////////////////////////
const ZCStringBase& AR_CStrSearch1,
const ZCStringBase& AR_CStrSearch2,
const ZCStringBase& AR_CStrReplace,
bool AB_DoKeepSearch=false,
TypeLength AL_StartPos =0
/*/////////*/ ) ///////////////////////////////////////////////
{
return ReplaceAllRange( ///////////////////////////////////
AR_CStrSearch1.data(),
AR_CStrSearch2.data(),
AR_CStrReplace.data(),
AB_DoKeepSearch ,
AL_StartPos ,
AR_CStrSearch1.size(),
AR_CStrSearch2.size(),
AR_CStrReplace.size()
/*/////////*/ ); //////////////////////////////////////////
}/*
ZCStringBase& ReplaceAllRange( ////////////////////////////////
const ZCStringBase& AR_CStrSearch1,
const ZCStringBase& AR_CStrSearch2,
const ZCStringBase& AR_CStrReplace,
bool AB_DoKeepSearch=false,
TypeLength AL_StartPos =0
//////////// ) ////////////////////////////////////////////*/
ZCStringBase& ReplaceAllRange( ////////////////////////////////
TypeCharC* APC_Search1 ,
TypeCharC* APC_Search2 ,
TypeCharC* APC_Replace ,
bool AB_DoKeepSearch=false,
TypeLength AL_StartPos =0
/*/////////*/ ) ///////////////////////////////////////////////
{
using ZNsMain::ZftGetLengthType ;
return ReplaceAllRange( ////////////////////////////////////////////
APC_Search1 ,
APC_Search2 ,
APC_Replace ,
AB_DoKeepSearch ,
AL_StartPos ,
ZftGetLengthType<TypeLength, TypeChar>(APC_Search1),
ZftGetLengthType<TypeLength, TypeChar>(APC_Search2),
ZftGetLengthType<TypeLength, TypeChar>(APC_Replace)
/*/////////*/ );
}/*
ZCStringBase& ReplaceAllRange( ////////////////////////////////
TypeCharC* APC_Search1 ,
TypeCharC* APC_Search2 ,
TypeCharC* APC_Replace ,
bool AB_DoKeepSearch=false ,
TypeLength AL_StartPos =0
//////////// ) ////////////////////////////////////////////*/
// TSearchInfoList 은 class ZCSearchInfo 의 리스트
template<typename TSearchInfoList> /*#########################################*/
static TypeLength GetNeedMemoryForReplace
(
TSearchInfoList& AR_InfoList ,
TypeLength AL_ReplaceLen ,
TypeLength AL_OriginLen
)
/*#############################################################################*/
{
// 정규식 등으로 찾아진, 길이가 제각각인 문자열을 다른 문자열로 치환할 때
// 찾아진 문자열 정보를 가지고 있는 AR_InfoList 로부터
// 필요한 문자열의 총길이를 구할 때 이 함수가 필요하다.
TypeLength VL_NeedMemory = 0 ;
IterEasyID VI_SearchIter =
AR_InfoList.GetHeadIterEasyID();
const TypeLength CL_MaxLoop=AR_InfoList.GetSize();
__for1(TypeLength, i, CL_MaxLoop)
{
VL_NeedMemory +=
AL_ReplaceLen-AR_InfoList.ItD(VI_SearchIter).size() ;
AR_InfoList.MoveNextIter(VI_SearchIter);
}/*
__for1(TypeLength, i, CL_MaxLoop)*/
return VL_NeedMemory+AL_OriginLen ;
}/*
template<typename TSearchInfoList> #############################################
static TypeLength GetNeedMemoryForReplace
(
TSearchInfoList& AR_InfoList ,
TypeLength AL_ReplaceLen ,
TypeLength AL_OriginLen
)
###############################################################################*/
ZCStringBase& Insert /*########################################################*/
(
TypeLength AL_InsertPos ,
TypeCharC* APC_Insert ,
TypeLength AL_InsertLen
)
/*#############################################################################*/
{
// AL_InsertPos<0 이어서는 안된다.
if(ml_UseLen<1)
{ return MakeWord(APC_Insert, AL_InsertLen); }
ReAllocAdd(AL_InsertLen, true);
int VL_NowIndex= ml_UseLen-1 ;
TypeChar* VPC_Dest = mpc_Data+ml_UseLen+AL_InsertLen-1 ;
while(VL_NowIndex>=AL_InsertPos)
{ *VPC_Dest-- = mpc_Data[VL_NowIndex--] ; }
for(int i=AL_InsertLen-1;i>=0;--i)
{ *VPC_Dest-- = APC_Insert[i] ; }
mpc_Data[ml_UseLen+=AL_InsertLen]=0; return *this;
}/*
ZCStringBase& Insert /*##########################################################
(
TypeLength AL_InsertPos ,
TypeCharC* APC_Insert ,
TypeLength AL_InsertLen
)
###############################################################################*/
ZCStringBase& Insert(TypeLength AL_InsertPos, const ZCStringBase& AR_CStrInsert)
{
if(this==&AR_CStrInsert) return *this;
return Insert(
AL_InsertPos, AR_CStrInsert.data(), AR_CStrInsert.size());
}/*
ZCStringBase& Insert(TypeLength AL_InsertPos, const ZCStringBase& AR_CStrInsert)*/
ZCStringBase& Insert_E(
TypeLength AL_InsertPos, TypeCharC* APC_Insert, TypeLength AL_InsertLen)
{
if(AL_InsertLen<1) return *this;
if (AL_InsertPos<0 ) { AL_InsertPos=0 ; }
else if(AL_InsertPos>ml_UseLen) { AL_InsertPos=ml_UseLen; }
return Insert_E(AL_InsertPos, APC_Insert, AL_InsertLen) ;
}/*
ZCStringBase& Insert_E(
TypeLength AL_InsertPos, TypeCharC* APC_Insert, TypeLength AL_InsertLen)*/
ZCStringBase& Insert_E(TypeLength AL_InsertPos, TypeCharC* APC_Insert)
{
return Insert_E
(
AL_InsertPos, APC_Insert, ZNsMain::
ZftGetLengthType<TypeLength, TypeChar>(APC_Insert)
) ;
///////////////
}/*
ZCStringBase& Insert_E(TypeLength AL_InsertPos, TypeCharC* APC_Insert)*/
ZCStringBase& GetSubString(
TypeLength AL_Index, TypeLength AL_Count, ZCStringBase& ARR_CString)
{
if(AL_Index<0 || AL_Count<1) return ARR_CString;
#ifdef _DEBUG
if(AL_Index+AL_Count>ml_UseLen)
{
std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app);
fileout<<std::endl<<"File : "<<__FILE__<<std::endl<<"Line : "<<__LINE__<<std::endl;
fileout<<"Error In 'ZCStringBase& GetSubString(TypeLength AL_Index,TypeLength AL_Count,ZCStringBase& ARR_CString)"<<std::endl;
fileout<<" Parameter are not valid(AL_Index="<<AL_Index<<", AL_Count="<<AL_Count<<", ml_UseLen="<<ml_UseLen<<std::endl;
fileout.close();
//exit(1);
}/*
if(AL_Index+AL_Count>ml_UseLen)*/
#endif // _DEBUG
ARR_CString.ReAllocAdd(AL_Count,true); ::memcpy ////////
(
ARR_CString.mpc_Data+ARR_CString.ml_UseLen,
mpc_Data+AL_Index, AL_Count*sizeof(TypeChar)
);
//////////////////////////////////////////////////////////
ARR_CString.
mpc_Data[ARR_CString.ml_UseLen+=AL_Count]=0;
return ARR_CString;
}/*
ZCStringBase& GetSubString(
TypeLength AL_Index, TypeLength AL_Count, ZCStringBase& ARR_CString)*/
static ZCStringBase& GetSubSearch /*##########################################*/
(
TypeCharC* APC_Origin ,
TypeCharC* APC_Find1 ,
TypeCharC* APC_Find2 ,
TypeLength AL_OriginLen ,
TypeLength AL_Find1Len ,
TypeLength AL_Find2Len ,
TypeLength& ARRL_StartPos ,
ZCStringBase& ARR_CStringSave,
bool AB_IsExactTwo=false
)
/*#############################################################################*/
{
/*/////////////////////////////////////////////////////////////////////////////////////////////
■ APC_Find1 와 APC_Find2 사이에 있는 문자열을 가져온다. 두번째로 찾는 문자열 APC_Find2 을
발견했으면, ARRL_StartPos 를 APC_Find2 이후로 이동시켜 다음 문자열을 찾을 준비를 하게 하자.
■ AB_IsExactTwo==true 이면 APC_Find1 과 APC_Find2 을 다 찾아야만 부문자열을 가져온다.
AB_IsExactTwo==false 이면 APC_Find1 만 찾을 경우 그곳부터 끝까지의 부문자열을 가져온다.
/////////////////////////////////////////////////////////////////////////////////////////////*/
if(AL_OriginLen<1 || ARRL_StartPos>=AL_OriginLen)
{
ARRL_StartPos=-1; return ARR_CStringSave;
}/*
if(AL_OriginLen<1 || ARRL_StartPos>=AL_OriginLen)*/
TypeLength VL_Pos1 = FindPos
(
APC_Origin , APC_Find1 ,
AL_OriginLen, AL_Find1Len, ARRL_StartPos
);
////////////////////////////
if(VL_Pos1<0)
{
ARRL_StartPos=-1; return ARR_CStringSave;
}/*
if(VL_Pos1<0)*/
VL_Pos1 += AL_Find1Len ; TypeLength
VL_Pos2 = FindPos
(
APC_Origin , APC_Find2 ,
AL_OriginLen, AL_Find2Len, VL_Pos1
);
///////////////////////////////////
if(VL_Pos2<0)
{
if(AB_IsExactTwo==true)
{
ARRL_StartPos=-1; return ARR_CStringSave;
}/*
if(AB_IsExactTwo==true)*/
ARRL_StartPos=AL_OriginLen;
ARR_CStringSave.MakeWord(
APC_Origin+VL_Pos1, AL_OriginLen-VL_Pos1);
return ARR_CStringSave;
}/*
if(VL_Pos2<0)*/
ARR_CStringSave.MakeWord(
APC_Origin+VL_Pos1, VL_Pos2-VL_Pos1 );
ARRL_StartPos = VL_Pos2+AL_Find2Len ;
return ARR_CStringSave;
}/*
static ZCStringBase& GetSubSearch ##############################################
(
TypeCharC* APC_Origin ,
TypeCharC* APC_Find1 ,
TypeCharC* APC_Find2 ,
TypeLength AL_OriginLen ,
TypeLength AL_Find1Len ,
TypeLength AL_Find2Len ,
TypeLength& ARRL_StartPos ,
ZCStringBase& ARR_CStringSave,
bool AB_IsExactTwo=false
)
###############################################################################*/
ZCStringBase& GetSubSearch( /*###################################*/
TypeCharC* APC_Find1 ,
TypeCharC* APC_Find2 ,
TypeLength AL_Find1Len ,
TypeLength AL_Find2Len ,
TypeLength& ARRL_StartPos ,
ZCStringBase& ARR_CStringSave ,
bool AB_IsExactTwo=false
/*#########*/ ) const /*########################################*/
{
return GetSubSearch( ////////////////////////
mpc_Data ,
APC_Find1 ,
APC_Find2 ,
ml_UseLen ,
AL_Find1Len ,
AL_Find2Len ,
RR(ARRL_StartPos) ,
RR(ARR_CStringSave) ,
AB_IsExactTwo
/*//////////*/ ); ///////////////////////////
}/*
ZCStringBase& GetSubSearch( #######################################
TypeCharC* APC_Find1 ,
TypeCharC* APC_Find2 ,
TypeLength AL_Find1Len ,
TypeLength AL_Find2Len ,
TypeLength& ARRL_StartPos ,
ZCStringBase& ARR_CStringSave ,
bool AB_IsExactTwo=false
############# ) const ##########################################*/
ZCStringBase& GetSubSearch( /*###################################*/
TypeCharC* APC_Find1 ,
TypeCharC* APC_Find2 ,
TypeLength AL_Find1Len ,
TypeLength AL_Find2Len ,
ZCStringBase& ARR_CString ,
bool AB_IsExactTwo=false
/*#########*/ ) const /*########################################*/
{
TypeLength VL_StartPos=0;
return GetSubSearch( ////////////////////
mpc_Data ,
APC_Find1 ,
APC_Find2 ,
ml_UseLen ,
AL_Find1Len ,
AL_Find2Len ,
RR(VL_StartPos) ,
RR(ARR_CString) ,
AB_IsExactTwo
/*/////////*/ ); ////////////////////////
}/*
ZCStringBase& GetSubSearch( #######################################
TypeCharC* APC_Find1 ,
TypeCharC* APC_Find2 ,
TypeLength AL_Find1Len ,
TypeLength AL_Find2Len ,
ZCStringBase& ARR_CString ,
bool AB_IsExactTwo=false
############# ) const ##########################################*/
ZCStringBase& GetSubSearch( /*###################################*/
TypeCharC* APC_Find1 ,
TypeCharC* APC_Find2 ,
TypeLength& ARRL_StartPos,
ZCStringBase& ARR_CString ,
bool AB_IsExactTwo=false
/*#########*/ ) const /*########################################*/
{
using ZNsMain::ZftGetLengthType ;
return GetSubSearch( //////////////////////////////////////////////
mpc_Data ,
APC_Find1 ,
APC_Find2 ,
ml_UseLen ,
ZftGetLengthType<TypeLength, TypeChar>(APC_Find1),
ZftGetLengthType<TypeLength, TypeChar>(APC_Find2),
RR(ARRL_StartPos),
RR(ARR_CString) ,
AB_IsExactTwo
/*/////////*/ ); //////////////////////////////////////////////////
}/*
ZCStringBase& GetSubSearch( #######################################
TypeCharC* APC_Find1 ,
TypeCharC* APC_Find2 ,
TypeLength& ARRL_StartPos,
ZCStringBase& ARR_CString ,
bool AB_IsExactTwo=false
############# ) const ##########################################*/
ZCStringBase& GetSubSearch( /*###################################*/
TypeCharC* APC_Find1 ,
TypeCharC* APC_Find2 ,
ZCStringBase& ARR_CString ,
bool AB_IsExactTwo=false
/*#########*/ ) const /*########################################*/
{
TypeLength VL_StartPos=0;
using ZNsMain::ZftGetLengthType ;
return GetSubSearch( //////////////////////////////////////////////
mpc_Data ,
APC_Find1 ,
APC_Find2 ,
ml_UseLen ,
ZftGetLengthType<TypeLength, TypeChar>(APC_Find1),
ZftGetLengthType<TypeLength, TypeChar>(APC_Find2),
RR(VL_StartPos) ,
RR(ARR_CString) ,
AB_IsExactTwo
/*/////////*/ ); //////////////////////////////////////////////////
}/*
ZCStringBase& GetSubSearch( #######################################
TypeCharC* APC_Find1 ,
TypeCharC* APC_Find2 ,
ZCStringBase& ARR_CString ,
bool AB_IsExactTwo=false
############# ) const ##########################################*/
static ZCStringBase& GetSubSearch( /*############################*/
const ZCStringBase& AR_CStringOrigin,
const ZCStringBase& AR_CStringFind1 ,
const ZCStringBase& AR_CStringFind2 ,
TypeLength& ARRL_StartPos ,
ZCStringBase& ARR_CStringSave ,
bool AB_IsExactTwo=false
/*#########*/ ) /*##############################################*/
{
return GetSubSearch( ///////////////////////////
AR_CStringOrigin.data(),
AR_CStringFind1. data(),
AR_CStringFind2. data(),
AR_CStringOrigin.size(),
AR_CStringFind1. size(),
AR_CStringFind2. size(),
RR(ARRL_StartPos) ,
RR(ARR_CStringSave) ,
AB_IsExactTwo
/*//////////*/ ); //////////////////////////////
}/*
static ZCStringBase& GetSubSearch( ################################
const ZCStringBase& AR_CStringOrigin,
const ZCStringBase& AR_CStringFind1 ,
const ZCStringBase& AR_CStringFind2 ,
TypeLength& ARRL_StartPos ,
ZCStringBase& ARR_CStringSave ,
bool AB_IsExactTwo=false
############# ) ################################################*/
ZCStringBase& GetSubSearch( /*###################################*/
const ZCStringBase& AR_CStringFind1,
const ZCStringBase& AR_CStringFind2,
TypeLength& ARRL_StartPos ,
ZCStringBase& ARR_CStringSave,
bool AB_IsExactTwo=false
/*#########*/ ) const /*########################################*/
{
return GetSubSearch( //////////////////////////
mpc_Data ,
AR_CStringFind1.data(),
AR_CStringFind2.data(),
ml_UseLen ,
AR_CStringFind1.size(),
AR_CStringFind2.size(),
RR(ARRL_StartPos) ,
RR(ARR_CStringSave) ,
AB_IsExactTwo
/*//////////*/ ); /////////////////////////////
}/*
ZCStringBase& GetSubSearch( #######################################
const ZCStringBase& AR_CStringFind1,
const ZCStringBase& AR_CStringFind2,
TypeLength& ARRL_StartPos ,
ZCStringBase& ARR_CStringSave,
bool AB_IsExactTwo=false
############# ) const ##########################################*/
ZCStringBase& GetSubSearch( /*###################################*/
const ZCStringBase& AR_CStringFind1,
const ZCStringBase& AR_CStringFind2,
ZCStringBase& ARR_CStringSave,
bool AB_IsExactTwo=false
/*#########*/ ) const /*########################################*/
{
TypeLength VL_StartPos=0;
return GetSubSearch( //////////////////////////
mpc_Data ,
AR_CStringFind1.data(),
AR_CStringFind2.data(),
ml_UseLen ,
AR_CStringFind1.size(),
AR_CStringFind2.size(),
RR(VL_StartPos) ,
RR(ARR_CStringSave) ,
AB_IsExactTwo
/*//////////*/ ); /////////////////////////////
}/*
ZCStringBase& GetSubSearch( #######################################
const ZCStringBase& AR_CStringFind1,
const ZCStringBase& AR_CStringFind2,
ZCStringBase& ARR_CStringSave,
bool AB_IsExactTwo=false
############# ) const ##########################################*/
ZCStringBase GetSubSearch( /*####################################*/
const ZCStringBase& AR_CStringFind1,
const ZCStringBase& AR_CStringFind2,
bool AB_IsExactTwo=false
/*#########*/ ) const /*########################################*/
{
ZCStringBase VO_SaveCStr; return GetSubSearch(
AR_CStringFind1, AR_CStringFind2, RR(VO_SaveCStr), AB_IsExactTwo);
}/*
ZCStringBase GetSubSearch( #######################################
const ZCStringBase& AR_CStringFind1,
const ZCStringBase& AR_CStringFind2,
ZCStringBase& ARR_CStringSave,
bool AB_IsExactTwo=false
############# ) const ##########################################*/
// TStringList 은 현재 클래스(ZtCStringBase)의 container 이어야 한다.
template<typename TStringList> static ZCStringBase& GetSubSearchEx
(
TypeCharC* APC_Origin ,
TStringList AR_FindList1 ,
TStringList AR_FindList2 ,
TypeLength AL_OriginLen ,
TypeLength& ARRL_StartPos ,
ZCStringBase& ARR_CString ,
bool AB_IsExactTwo=false
)
/*##############################################################*/
{
TypeLength VL_MatchLen= 0 ;
TypeLength VL_Pos1 = FindPosType
(
APC_Origin , AR_FindList1 ,
AL_OriginLen, RR(VL_MatchLen), ARRL_StartPos
);
///////////////////////////////////
if(VL_Pos1<0){ return ARR_CString; }
VL_Pos1 += VL_MatchLen ;
TypeLength VL_Pos2=FindPosType //////////////
(
APC_Origin , AR_FindList2 ,
AL_OriginLen, RR(VL_MatchLen), VL_Pos1
);
//////////////////////////////////////////////
if(VL_Pos2<0)
{
if(AB_IsExactTwo==true)
{
ARRL_StartPos=-1; return ARR_CString;
}/*
if(AB_IsExactTwo==true)*/
ARRL_StartPos=AL_OriginLen;
ARR_CString.MakeWord(
APC_Origin+VL_Pos1, AL_OriginLen-VL_Pos1);
return ARR_CString;
}/*
if(VL_Pos2<0)*/
ARRL_StartPos = VL_Pos2+VL_MatchLen ;
ARR_CString.MakeWord
(APC_Origin+VL_Pos1, VL_Pos2-VL_Pos1);
return ARR_CString;
}/*
template<typename TStringList> static ZCStringBase& GetSubSearchEx
(
TypeCharC* APC_Origin ,
TStringList AR_FindList1 ,
TStringList AR_FindList2 ,
TypeLength AL_OriginLen ,
TypeLength& ARRL_StartPos ,
ZCStringBase& ARR_CString ,
bool AB_IsExactTwo=false
)
################################################################*/
template<typename TStringList> static ZCStringBase& GetSubSearchEx(
TypeCharC* APC_Origin ,
TStringList AR_FindList1 ,
TStringList AR_FindList2 ,
TypeLength& ARRL_StartPos ,
ZCStringBase& ARR_CString ,
bool AB_IsExactTwo=false
/*//////////*/ ) //////////////////////////////////////////////////
{
using ZNsMain::ZftGetLengthType ;
return GetSubSearchEx( /////////////////////////////////////////////
APC_Origin ,
AR_FindList1 ,
AR_FindList2 ,
ZftGetLengthType<TypeLength, TypeChar>(APC_Origin),
ARRL_StartPos ,
ARR_CString ,
AB_IsExactTwo
/*//////////*/ ); //////////////////////////////////////////////////
}/*
template<typename TStringList> static ZCStringBase& GetSubSearchEx(
TypeCharC* APC_Origin ,
TStringList AR_FindList1 ,
TStringList AR_FindList2 ,
TypeLength& ARRL_StartPos,
ZCStringBase& ARR_CString ,
bool AB_IsExactTwo=false
//////////// ) ////////////////////////////////////////////////*/
template<typename TStringList> ZCStringBase& GetSubSearchEx( //////
TStringList AR_FindList1 ,
TStringList AR_FindList2 ,
TypeLength& ARRL_StartPos,
ZCStringBase& ARR_CString ,
bool AB_IsExactTwo=false
/*//////////*/ ) //////////////////////////////////////////////////
{
return GetSubSearchEx( ///////////////////
mpc_Data ,
AR_FindList1 ,
AR_FindList2 ,
ml_UseLen ,
RR(ARRL_StartPos),
RR(ARR_CString) ,
AB_IsExactTwo
/*/////////*/ ); /////////////////////////
}/*
template<typename TStringList> ZCStringBase& GetSubSearchEx( //////
TStringList AR_FindList1 ,
TStringList AR_FindList2 ,
TypeLength& ARRL_StartPos,
ZCStringBase& ARR_CString ,
bool AB_IsExactTwo=false
/*/////////// ) /////////////////////////////////////////////////*/
template<typename TStringList> ZCStringBase& GetSubSearchEx( //////
TStringList AR_FindList1,
TStringList AR_FindList2,
ZCStringBase& ARR_CString ,
bool AB_IsExactTwo=false
/*/////////*/ ) ///////////////////////////////////////////////////
{
TypeLength VL_StartPos=0;
return GetSubSearchEx( //////////////////
mpc_Data ,
AR_FindList1 ,
AR_FindList2 ,
ml_UseLen ,
RR(VL_StartPos) ,
RR(ARR_CString) ,
AB_IsExactTwo
/*/////////*/ ); ////////////////////////
}/*
template<typename TStringList> ZCStringBase& GetSubSearchEx( //////
TStringList AR_FindList1,
TStringList AR_FindList2,
ZCStringBase& ARR_CString ,
bool AB_IsExactTwo=false
//////////// ) /////////////////////////////////////////////////*/
template<typename TFunctor> static void Split /*#################*/
(
TFunctor AR_TFunctor ,
TypeCharC* APC_OriginChar,
TypeCharC* APC_SearchChar,
TypeLength AL_OriginLen ,
TypeLength AL_SearchLen
)
/*###############################################################*/
{
ZCStringList VO_CStringList;
/*/////////////////////////////////////////////////////////////////////////////////////
■ 이 함수는 찾아낸 문자열을 복사해서 VO_CStringList 에 담는데, 펑크터는 구분 문자열로
나뉜 문자가 없을 경우 (즉 찾아낸 문자열을 별도로 할당할 필요가 없을 경우) 원래 문자
열 APC_OriginChar을 인수로 받고, 그 외에는 VO_CStringList 참조를 인수로 받는다. 따라
서 펑크터는 TypeChar* 과 VO_CStringList 을 인수로 받는 () 연산자를 가져야 한다.
/////////////////////////////////////////////////////////////////////////////////////*/
if(AL_OriginLen<1) return;
if(AL_SearchLen<1)
{
AR_TFunctor(APC_OriginChar, AL_OriginLen); return;
}/*
if(AL_SearchLen<1)*/
TypeLength VL_Loop =AL_OriginLen-AL_SearchLen;
TypeLength VL_CopyStartPos=0 ;
TypeLength VL_Index =0 ;
while(VL_Index<=VL_Loop)
{
TypeLength j;
for(j=0; j<AL_SearchLen; ++j)
{
if(APC_OriginChar[VL_Index+j]!=APC_SearchChar[j]) break;
}/*
for(j=0; j<AL_SearchLen; ++j)*/
if(j!=AL_SearchLen) // 못찾은 경우
{
++VL_Index; continue;
}/*
if(j!=AL_SearchLen)*/
// 찾은 경우
if(VL_Index>VL_CopyStartPos)
{
((ZCStringBase&)VO_CStringList).append
(
APC_OriginChar+VL_CopyStartPos, VL_Index-VL_CopyStartPos
) ;
//////////////////////////////////////
}/*
if(VL_Index>VL_CopyStartPos)*/
VL_CopyStartPos=VL_Index+=AL_SearchLen;
}/*
while(VL_Index<=VL_Loop)*/
if(VL_CopyStartPos>=AL_OriginLen)
{
AR_TFunctor(RR(VO_CStringList)); return;
}/*
if(VL_CopyStartPos>=AL_OriginLen)*/
if(VO_CStringList.IsEmpty() && VL_CopyStartPos==0)
{
AR_TFunctor(APC_OriginChar, AL_OriginLen) ;
}
else
{
((ZCStringBase&)VO_CStringList).append
(
APC_OriginChar+VL_CopyStartPos, AL_OriginLen-VL_CopyStartPos
) ;
//////////////////////////////////////
AR_TFunctor(RR(VO_CStringList)) ;
}/*
else*/
}/*
template<typename TFunctor> static void Split ####################
(
TFunctor AR_TFunctor ,
TypeCharC* APC_OriginChar,
TypeCharC* APC_SearchChar,
TypeLength AL_OriginLen ,
TypeLength AL_SearchLen
)
/*###############################################################*/
template<typename TFunctor> void Split( //////////////////////////
TFunctor AR_TFunctor ,
TypeCharC* APC_Search ,
TypeLength AL_SearchLen ,
TypeLength AL_StartPos=0
/*//////////*/ ) /////////////////////////////////////////////////
{
Split(AR_TFunctor, mpc_Data+AL_StartPos, APC_Search, ml_UseLen, AL_SearchLen);
}/*
template<typename TFunctor> void Split( //////////////////////////
TFunctor AR_TFunctor ,
TypeCharC* APC_Search ,
TypeLength AL_SearchLen,
TypeLength AL_StartPos=0
///////// ) ////////////////////////////////////////////////////*/
template<typename TFunctor, typename TSplitList> static void SplitEx
(
TFunctor AR_TFunctor ,
TypeCharC* APC_OriginChar ,
TypeCharC* APC_SearchChar ,
TypeLength AL_OriginLen ,
TypeLength AL_SearchLen
)
/*################################################################*/
{
typedef typename TSplitList::TypeData CString; TSplitList VO_CStringList;
/*/////////////////////////////////////////////////////////////////////////////////////
■ 이 함수는 찾아낸 문자열을 복사해서 VO_CStringList 에 담는데, 펑크터는 구분 문자열로
나뉜 문자가 없을 경우 (즉 찾아낸 문자열을 별도로 할당할 필요가 없을 경우) 원래 문자
열 APC_OriginChar을 인수로 받고 그 외에는 VO_CStringList 참조를 인수로 받는다. 따라
서 펑크터는 TypeChar* 과 VO_CStringList 을 인수로 받는 () 연산자를 가져야 한다.
/////////////////////////////////////////////////////////////////////////////////////*/
if(AL_OriginLen<1) return;
if(AL_SearchLen<1)
{
AR_TFunctor(APC_OriginChar, AL_OriginLen); return;
}/*
if(AL_SearchLen<1)*/
TypeLength VL_Loop =AL_OriginLen-AL_SearchLen;
TypeLength VL_CopyStartPos=0 ;
TypeLength VL_Index =0 ;
while(VL_Index<=VL_Loop)
{
TypeLength j;
for(j=0; j<AL_SearchLen; ++j)
{
if(APC_OriginChar[VL_Index+j]!=APC_SearchChar[j]) break;
}/*
for(j=0; j<AL_SearchLen; ++j)*/
if(j!=AL_SearchLen) // 못찾은 경우
{
++VL_Index; continue;
}/*
if(j!=AL_SearchLen)*/
if(VL_Index>VL_CopyStartPos)
{
((CString&)VO_CStringList).append
(
APC_OriginChar+VL_CopyStartPos,
VL_Index -VL_CopyStartPos
) ;
/////////////////////////////////
}/*
if(VL_Index>VL_CopyStartPos)*/
VL_CopyStartPos=VL_Index+=AL_SearchLen;
}/*
while(VL_Index<=VL_Loop)*/
if(VL_CopyStartPos>=AL_OriginLen)
{
AR_TFunctor(RR(VO_CStringList)); return;
}/*
if(VL_CopyStartPos>=AL_OriginLen)*/
if(VO_CStringList.IsEmpty() && VL_CopyStartPos==0)
{
AR_TFunctor(APC_OriginChar,AL_OriginLen) ;
}
else
{
((ZCStringBase&)VO_CStringList).append
(
APC_OriginChar+VL_CopyStartPos,
AL_OriginLen -VL_CopyStartPos
) ;
///////////////////////////////////////
AR_TFunctor(RR(VO_CStringList)) ;
}/*
else*/
}/*
template<typename TFunctor, typename TSplitList> static void SplitEx
(
TFunctor AR_TFunctor ,
TypeCharC* APC_OriginChar,
TypeCharC* APC_SearchChar,
TypeLength AL_OriginLen ,
TypeLength AL_SearchLen
)
##################################################################*/
template<typename TFunctor, typename TSplitList> /////////////////
void SplitEx( TFunctor AR_TFunctor ,
TypeCharC* APC_SearchChar,
TypeLength AL_SearchLen ,
TypeLength AL_StartPos=0
/*///////*/ ) ////////////////////////////////////////////////////
{
SplitEx<TFunctor, TSplitList>( ///////////////
AR_TFunctor ,
mpc_Data+AL_StartPos,
APC_SearchChar ,
ml_UseLen ,
AL_SearchLen
/*//////////*/ ); ////////////////////////////
}/*
template<typename TFunctor, typename TSplitList> /////////////////
void SplitEx( TFunctor AR_TFunctor ,
TypeCharC* APC_SearchChar,
TypeLength AL_SearchLen ,
TypeLength AL_StartPos=0
/////////// ) /////////////////////////////////////////////////*/
template<typename TFunctor> static void SplitEach /*############*/
(
TFunctor AR_TFunctor ,
TypeCharC* APC_OriginChar ,
TypeCharC* APC_SearchChar ,
TypeLength AL_OriginLen ,
TypeLength AL_SearchLen ,
bool AB_DoExecNull =true
)
/*##############################################################*/
{
/* bool AB_DoExecNull 이 true 이면 구분 문자로 잘린 문자열 길이
가 0 인 경우에도 AR_TFunctor 를 수행한다. */
if(AL_OriginLen<1) return; int VL_SearchCount=0; /*####################*/
if(AL_SearchLen<1)
{
AR_TFunctor( APC_OriginChar, AL_OriginLen , ++VL_SearchCount); return;
}/*
if(AL_SearchLen<1)*/
TypeLength VL_Loop =AL_OriginLen-AL_SearchLen;
TypeLength VL_CopyStartPos=0 ;
TypeLength VL_Index =0 ;
while(VL_Index<=VL_Loop)
{
TypeLength j=0;
for(j=0; j<AL_SearchLen; ++j)
{
if(APC_OriginChar[VL_Index+j]!=APC_SearchChar[j]) break;
}/*
for(j=0; j<AL_SearchLen; ++j)*/
if(j!=AL_SearchLen) // 못찾은 경우
{
++VL_Index; continue;
}/*
if(j!=AL_SearchLen)*/
// 찾은 경우
if(VL_Index>VL_CopyStartPos)
{
AR_TFunctor
(
APC_OriginChar+VL_CopyStartPos,
VL_Index -VL_CopyStartPos,
++VL_SearchCount
) ;
///////////
}
else if(AB_DoExecNull==true)
{
AR_TFunctor(0, 0, ++VL_SearchCount) ;
}/*
else if(AB_DoExecNull==true)*/
VL_CopyStartPos=VL_Index+=AL_SearchLen;
}/*
while(VL_Index<=VL_Loop)*/
if(VL_CopyStartPos>=AL_OriginLen) return;
if(VL_SearchCount==0 && VL_CopyStartPos==0)
{
AR_TFunctor ////////
(
APC_OriginChar, AL_OriginLen, ++VL_SearchCount
) ;
////////////////////
}
else
{
AR_TFunctor ////////
(
APC_OriginChar+VL_CopyStartPos,
AL_OriginLen -VL_CopyStartPos,
++VL_SearchCount
) ;
////////////////////
}
}/*
template<typename TFunctor> static void SplitEach ################
(
TFunctor AR_TFunctor ,
TypeCharC* APC_OriginChar ,
TypeCharC* APC_SearchChar ,
TypeLength AL_OriginLen ,
TypeLength AL_SearchLen ,
bool AB_DoExecNull =true
)
/*##############################################################*/
template<typename TFunctor> void SplitEach( /*##################*/
TFunctor AR_TFunctor ,
TypeCharC* APC_SearchChar,
TypeLength AL_SearchLen ,
TypeLength AL_StartPos=0 ,
bool AB_DoExecNull=true
/*#########*/ ) /*##############################################*/
{
SplitEach<TFunctor>( /*####################*/
AR_TFunctor ,
mpc_Data+AL_StartPos,
APC_SearchChar ,
ml_UseLen ,
AL_SearchLen ,
AB_DoExecNull
/*########*/ ); /*########################*/
}/*
template<typename TFunctor> void SplitEach( #####################
TFunctor AR_TFunctor ,
TypeCharC* APC_SearchChar,
TypeLength AL_SearchLen ,
TypeLength AL_StartPos=0 ,
bool AB_DoExecNull=true
########### ) ###############################################*/
// cf) TStringList=ZNsMain::CDoubleList<ZCStringBase>
template<typename TStringList> /*##############################*/
static TStringList& SplitToList
(
TStringList& ARR_SaveList ,
TypeCharC* APC_OriginChar ,
TypeCharC* APC_SearchChar ,
TypeLength AL_OriginLen ,
TypeLength AL_SearchLen ,
bool AB_DoEndWhenNoMatch=true ,
bool AB_DoAppendEachLink=false,
bool AB_DoAppendEmpty =false
)
/*#############################################################*/
{
/*/////////////////////////////////////////////////////////////////////
■ AB_DoEndWhenNoMatch==false 이면, APC_SearchChar 를 찾지 못한 경우에
APC_OriginChar 을 ARR_SaveList 에 입력한다.
■ AB_DoAppendEachLink 는 ARR_SaveList 에 추가된 링크가 어떤 링크 풀에
이어서, 그 링크의 데이타가 아직 초기화되지 않았을 경우에, 의미가 있
는데, AB_DoAppendEachLink 이 false 이면 초기화를 하고, 찾을 데이타를
입력한다.
/////////////////////////////////////////////////////////////////////*/
typedef typename TStringList::TypeData CString;
if(AL_OriginLen<1) return ARR_SaveList;
TypeLength VL_PrevListSize=ARR_SaveList.GetSize() ;
TypeLength VL_Loop =AL_OriginLen-AL_SearchLen;
TypeLength VL_CopyStartPos=0 ;
TypeLength VL_Index =0 ;
while(VL_Index<=VL_Loop)
{
TypeLength j;
for(j=0; j<AL_SearchLen; ++j)
{
if(APC_OriginChar[VL_Index+j]!=APC_SearchChar[j]) break;
}/*
for(j=0; j<AL_SearchLen; ++j)*/
if(j!=AL_SearchLen) // 못찾은 경우
{
++VL_Index; continue;
}/*
if(j!=AL_SearchLen)*/
// 찾은 경우
if(VL_Index>VL_CopyStartPos)
{
if(AB_DoAppendEachLink==true)
{
((CString&)ARR_SaveList).append
(
APC_OriginChar+VL_CopyStartPos, VL_Index-VL_CopyStartPos
) ;
///////////////////////////////
}
else
{
((CString&)ARR_SaveList).Invalidate().append
(
APC_OriginChar+VL_CopyStartPos, VL_Index-VL_CopyStartPos
) ;
////////////////////////////////////////////
}/*
else*/
}
else if(AB_DoAppendEmpty==true)
{
(CString&)ARR_SaveList;
}/*
else if(AB_DoAppendEmpty==true)*/
VL_CopyStartPos=VL_Index+=AL_SearchLen;
}/*
while(VL_Index<=VL_Loop)*/
if(VL_CopyStartPos>=AL_OriginLen)
{
return ARR_SaveList;
}
if(VL_PrevListSize<ARR_SaveList.size() || AB_DoEndWhenNoMatch==false)
{
if(AB_DoAppendEachLink==true)
{ ((ZCStringBase&)ARR_SaveList).
append( APC_OriginChar+VL_CopyStartPos, AL_OriginLen-VL_CopyStartPos ) ;
}else
{ ((ZCStringBase&)ARR_SaveList).Invalidate().
append( APC_OriginChar+VL_CopyStartPos, AL_OriginLen-VL_CopyStartPos ) ;
}
}/*
if(VL_PrevListSize<ARR_SaveList.size() || AB_DoEndWhenNoMatch==false)*/
return ARR_SaveList;
}/*
template<typename TStringList> #################################
static TStringList& SplitToList
(
TStringList& ARR_SaveList ,
TypeCharC* APC_OriginChar,
TypeCharC* APC_SearchChar,
TypeLength AL_OriginLen ,
TypeLength AL_SearchLen ,
bool AB_DoEndWhenNoMatch=true ,
bool AB_DoAppendEachLink=false,
bool AB_DoAppendEmpty =false
)
/*#############################################################*/
template<typename TStringList>
static TStringList& SplitToList( /*#########################*/
TStringList& ARR_SaveList ,
const ZCChars& AR_CCharsOrigin ,
const ZCChars& AR_CCharsSearch ,
bool AB_DoEndWhenNoMatch=true ,
bool AB_DoAppendEachLink=false,
bool AB_DoAppendEmpty =false
/*#########*/ ) /*##############################################*/
{
return SplitToList(
RR(ARR_SaveList) , AR_CCharsOrigin.data(),
AR_CCharsSearch.data(), AR_CCharsOrigin.size(),
AR_CCharsSearch.size(), AB_DoEndWhenNoMatch ,
AB_DoAppendEachLink , AB_DoAppendEmpty );
}/*
template<typename TStringList>
static TStringList& SplitToList( ############################/
TStringList& ARR_SaveList ,
const ZCChars& AR_CCharsOrigin ,
const ZCChars& AR_CCharsSearch ,
bool AB_DoEndWhenNoMatch=true ,
bool AB_DoAppendEachLink=false,
bool AB_DoAppendEmpty =false
############# ) ################################################*/
template<typename TStringList> /*###############################*/
static TStringList& SplitToList(
TStringList& ARR_SaveList ,
const ZCStringBase& AR_CStrOrigin,
const ZCStringBase& AR_CStrSearch,
bool AB_DoEndWhenNoMatch=true ,
bool AB_DoAppendEachLink=false,
bool AB_DoAppendEmpty =false
/*#########*/ ) /*##############################################*/
{
return SplitToList( /*#####################*/
RR(ARR_SaveList) ,
AR_CStrOrigin.data(),
AR_CStrSearch.data(),
AR_CStrOrigin.size(),
AR_CStrSearch.size(),
AB_DoEndWhenNoMatch ,
AB_DoAppendEachLink ,
AB_DoAppendEmpty
/*########*/ ); /*#########################*/
}/*
template<typename TStringList> ###################################
static TStringList& SplitToList(
TStringList& ARR_SaveList ,
const ZCStringBase& AR_CStrOrigin,
const ZCStringBase& AR_CStrSearch,
bool AB_DoEndWhenNoMatch=true ,
bool AB_DoAppendEachLink=false,
bool AB_DoAppendEmpty =false
############# ) ################################################*/
// cf) TStringList=CDoubleList<ZtCStringBase>
template<typename TStringList> TStringList& SplitToList( /////////
TStringList& ARR_SaveList ,
TypeCharC* APC_SearchChar ,
TypeLength AL_SearchLen ,
bool AB_DoEndWhenNoMatch=true ,
bool AB_DoAppendEachLink=false,
bool AB_DoAppendEmpty =false
/*#########*/ ) const /*########################################*/
{
return SplitToList<TStringList>( /*########*/
ARR_SaveList ,
mpc_Data ,
APC_SearchChar ,
ml_UseLen ,
AL_SearchLen ,
AB_DoEndWhenNoMatch ,
AB_DoAppendEachLink ,
AB_DoAppendEmpty
/*########*/ ); /*#########################*/
}/*
template<typename TStringList> TStringList& SplitToList( #########
TStringList& ARR_SaveList ,
TypeCharC* APC_SearchChar,
TypeLength AL_SearchLen ,
bool AB_DoEndWhenNoMatch=true ,
bool AB_DoAppendEachLink=false,
bool AB_DoAppendEmpty =false
############ ) const ##########################################*/
template<typename TStringList> TStringList& SplitToList( /*#####*/
TStringList& ARR_SaveList ,
ZCChars& AR_CCharsSearch ,
bool AB_DoEndWhenNoMatch=true ,
bool AB_DoAppendEachLink=false,
bool AB_DoAppendEmpty =false
/*#########*/ ) /*##############################################*/
{
return SplitToList
(
RR(ARR_SaveList) , this->mpc_Data ,
AR_CCharsSearch.data(), this->ml_UseLen ,
AR_CCharsSearch.size(), AB_DoEndWhenNoMatch ,
AB_DoAppendEachLink , AB_DoAppendEmpty
);
//////////////////
}/*
template<typename TStringList> TStringList& SplitToList( #########
TStringList& ARR_SaveList ,
ZCChars& AR_CCharsOrigin ,
ZCChars& AR_CCharsSearch ,
bool AB_DoEndWhenNoMatch=true ,
bool AB_DoAppendEachLink=false,
bool AB_DoAppendEmpty =false
############# ) ################################################*/
template<typename TStringList> TStringList& SplitToList( /*#####*/
TStringList& ARR_SaveList ,
TypeCharC* APC_SearchChar ,
bool AB_DoEndWhenNoMatch=true ,
bool AB_DoAppendEachLink=false,
bool AB_DoAppendEmpty =false
/*#########*/ ) const /*########################################*/
{
return SplitToList<TStringList>( /*################################################*/
ARR_SaveList ,
mpc_Data ,
APC_SearchChar ,
ml_UseLen ,
TypeLength(ZNsMain::ZftGetLengthType
<TypeLength, TypeChar>(APC_SearchChar)),
AB_DoEndWhenNoMatch ,
AB_DoAppendEachLink ,
AB_DoAppendEmpty
/*##########*/ ); /*###############################################################*/
}/*
template<typename TStringList> TStringList& SplitToList( #########
TStringList& ARR_SaveList ,
TypeCharC* APC_SearchChar,
bool AB_DoEndWhenNoMatch=true ,
bool AB_DoAppendEachLink=false,
bool AB_DoAppendEmpty =false
############ ) const ##########################################*/
template<typename TStringList> TStringList& SplitToList( /*#####*/
TStringList& ARR_SaveList ,
const ZCStringBase& AR_CStrSearch ,
bool AB_DoEndWhenNoMatch=true ,
bool AB_DoAppendEachLink=false,
bool AB_DoAppendEmpty =false
/*#########*/ ) const /*########################################*/
{
return SplitToList<TStringList>( /*########*/
ARR_SaveList ,
mpc_Data ,
AR_CStrSearch.data(),
ml_UseLen ,
AR_CStrSearch.size(),
AB_DoEndWhenNoMatch ,
AB_DoAppendEachLink ,
AB_DoAppendEmpty
/*##########*/ ); /*#######################*/
}/*
template<typename TStringList> TStringList& SplitToList( #########
TStringList& ARR_SaveList ,
const ZCStringBase& AR_CStrSearch ,
bool AB_DoEndWhenNoMatch=true ,
bool AB_DoAppendEachLink=false,
bool AB_DoAppendEmpty =false
############ ) const ##########################################*/
template<typename TSaveList>
static TSaveList& SplitToListType( /*#######################*/
TSaveList& ARR_SaveList ,
TypeCharC* APC_OriginChar ,
TypeCharC* APC_SearchChar ,
TypeLength AL_OriginLen ,
TypeLength AL_SearchLen ,
bool AB_DoEndWhenNoMatch=true,
bool AB_DoAppendEmpty =false
/*#########*/ ) /*##############################################*/
{
// ARR_SaveList 의 각 원소들은 문자열 object 이어야 한다.
typedef typename TSaveList::TypeData CString;
if(AL_OriginLen<1 || AL_SearchLen<1) return ARR_SaveList;
TypeLength VL_PrevListSize=ARR_SaveList.size() ;
TypeLength VL_CopyStartPos=0 ;
TypeLength VL_Loop =AL_OriginLen-AL_SearchLen;
TypeLength VL_Index =0 ;
CString VO_CStringTemp ;
while(VL_Index<=VL_Loop)
{
TypeLength j;
for(j=0; j<AL_SearchLen; ++j)
{
if(APC_OriginChar[VL_Index+j]!=APC_SearchChar[j]) break;
}/*
for(j=0; j<AL_SearchLen; ++j)*/
if(j!=AL_SearchLen) // 못찾은 경우
{
++VL_Index; continue;
}/*
if(j!=AL_SearchLen)*/
// 찾은 경우
if(VL_Index>VL_CopyStartPos)
{
VO_CStringTemp.Invalidate();
ARR_SaveList.push_back ////////////////////
(
VO_CStringTemp
(
APC_OriginChar+VL_CopyStartPos,
VL_Index -VL_CopyStartPos
)
);
///////////////////////////////////////////
}
else if(AB_DoAppendEmpty==true)
{
ARR_SaveList.push_back(VO_CStringTemp="");
}/*
else if(AB_DoAppendEmpty==true)*/
VL_CopyStartPos=VL_Index+=AL_SearchLen;
}/*
while(VL_Index<=VL_Loop)*/
if(VL_CopyStartPos>=AL_OriginLen)
{
return ARR_SaveList;
}/*
if(VL_CopyStartPos>=AL_OriginLen)*/
if(VL_PrevListSize<ARR_SaveList.size() || AB_DoEndWhenNoMatch==false)
{
/* VL_PrevListSize==ARR_SaveList.size() 인 경우는, 분리 문자열을
찾을 수 없는 경우다. 이때는 아무짓도 하지 말자. */
VO_CStringTemp.Invalidate();
ARR_SaveList.push_back ////////
(
VO_CStringTemp
(
APC_OriginChar+VL_CopyStartPos, AL_OriginLen-VL_CopyStartPos
)
);
///////////////////////////////
}/*
if(VL_PrevListSize<ARR_SaveList.size() || AB_DoEndWhenNoMatch==false)*/
return ARR_SaveList;
}/*
template<typename TSaveList>
static TSaveList& SplitToListType( ###########################
TSaveList& ARR_SaveList ,
TypeCharC* APC_OriginChar ,
TypeCharC* APC_SearchChar ,
TypeLength AL_OriginLen ,
TypeLength AL_SearchLen ,
bool AB_DoEndWhenNoMatch=true,
bool AB_DoAppendEmpty =false
########### ) ################################################*/
template<typename TSaveList> TSaveList& SplitToListType( /*#####*/
TSaveList& ARR_SaveList ,
TypeCharC* APC_SearchChar ,
TypeLength AL_SearchLen ,
bool AB_DoEndWhenNoMatch=true,
bool AB_DoAppendEmpty =false
/*#########*/ ) const /*########################################*/
{
return SplitToListType<TSaveList>( /*######*/
ARR_SaveList ,
mpc_Data ,
APC_SearchChar ,
ml_UseLen ,
AL_SearchLen ,
AB_DoEndWhenNoMatch ,
AB_DoAppendEmpty
/*########*/ ); /*#########################*/
}/*
template<typename TSaveList> TSaveList& SplitToListType( #########
TSaveList& ARR_SaveList ,
TypeCharC* APC_SearchChar ,
TypeLength AL_SearchLen ,
bool AB_DoEndWhenNoMatch=true,
bool AB_DoAppendEmpty =false
############ ) const ##########################################*/
/* cf)
ZNsMain::ZtCStringBase<char> myc;
myc="Z,'A,,'B,C,'D,,,''E'ET,";
myc.SplitToListWrap(l1, ",", "'", "'", (TypeLength)1,(TypeLength)1,(TypeLength)1);
*/
template<typename TStringList> TStringList& SplitToListWrap( /////
TStringList& ARR_SaveList ,
const TypeChar* APC_SearchChar ,
const TypeChar* APC_WrapStart ,
const TypeChar* APC_WrapClose ,
TypeLength AL_SearchLen ,
TypeLength AL_WrapStartLen ,
TypeLength AL_WrapCloseLen ,
bool AB_DoEndWhenNoMatch=true ,
bool AB_DoAppendEachLink=false
/*/////////*/ ) const ////////////////////////////////////////////
{
return ZCMainChars::SplitToListWrap( /////////
RR(ARR_SaveList) ,
mpc_Data ,
APC_SearchChar ,
APC_WrapStart ,
APC_WrapClose ,
ml_UseLen ,
AL_SearchLen ,
AL_WrapStartLen ,
AL_WrapCloseLen ,
AB_DoEndWhenNoMatch ,
AB_DoAppendEachLink
/*//////////*/ ); ///////////////////////////
}/*
template<typename TStringList> TStringList& SplitToListWrap( /////
TStringList& ARR_SaveList ,
const TypeChar* APC_SearchChar ,
const TypeChar* APC_WrapStart ,
const TypeChar* APC_WrapClose ,
TypeLength AL_SearchLen ,
TypeLength AL_WrapStartLen ,
TypeLength AL_WrapCloseLen ,
bool AB_DoEndWhenNoMatch=true ,
bool AB_DoAppendEachLink=false
///////////// ) const //////////////////////////////////////////*/
template<typename TStringList> TStringList& SplitToListWrap( /////
TStringList& ARR_SaveList ,
const TypeChar* APC_SearchChar ,
const TypeChar* APC_WrapStart ,
const TypeChar* APC_WrapClose ,
bool AB_DoEndWhenNoMatch=true ,
bool AB_DoAppendEachLink=false
/*/////////*/ ) const ////////////////////////////////////////////
{
using ZNsMain::ZftGetLengthType ;
return ZCMainChars::SplitToListWrap( ////////////////////////////////////
RR(ARR_SaveList),
mpc_Data ,
APC_SearchChar ,
APC_WrapStart ,
APC_WrapClose ,
ml_UseLen ,
ZftGetLengthType<TypeLength, TypeChar>(APC_SearchChar),
ZftGetLengthType<TypeLength, TypeChar>(APC_WrapStart) ,
ZftGetLengthType<TypeLength, TypeChar>(APC_WrapClose) ,
AB_DoEndWhenNoMatch,
AB_DoAppendEachLink
/*//////////*/ ); ///////////////////////////////////////////////////////
}/*
template<typename TStringList> TStringList& SplitToListWrap( /////
TStringList& ARR_SaveList ,
const TypeChar* APC_SearchChar ,
const TypeChar* APC_WrapStart ,
const TypeChar* APC_WrapClose ,
bool AB_DoEndWhenNoMatch=true ,
bool AB_DoAppendEachLink=false
///////////// ) const //////////////////////////////////////////*/
// cf) TStringList=CHugeList<ZCStringBase>
template<typename TStringList> static TStringList& SplitByCondOr
(
TStringList& ARR_SaveList ,
TypeCharC* APC_OriginChar,
TypeCharC* APC_SearchChar,
TypeLength AL_OriginLen ,
TypeLength AL_SearchLen
)
////////////////////////////////////////////////////////////////
{
// APC_SearchChar이 가리키는 각 문자들 중 하나라도 만족하면
// 그 문자로 분리해서 ARR_SaveList 에 저장한다.
typedef typename TStringList::TypeData CString;
if(AL_OriginLen<1 || AL_SearchLen<1) return ARR_SaveList;
TypeLength VL_CopyStartPos =0 ;
TypeChar* VP_CopyStartChar=
const_cast<TypeChar*>(APC_OriginChar) ;
TypeChar* VP_CopyCloseChar=VP_CopyStartChar;
for(TypeLength i=0; i<AL_OriginLen; ++i)
{
TypeLength j=0; TypeChar VC_TempChar = *VP_CopyCloseChar++ ;
for(j=0; j<AL_SearchLen; ++j)
{
if(VC_TempChar==APC_SearchChar[j]) break;
}/*
for(j=0; j<AL_SearchLen; ++j)*/
if(j<AL_SearchLen)
{
if(i>VL_CopyStartPos)
{
((CString&)ARR_SaveList).append
( VP_CopyStartChar, i-VL_CopyStartPos ) ;
}/*
if(i>VL_CopyStartPos)*/
VL_CopyStartPos =i+1;
VP_CopyStartChar=VP_CopyCloseChar ;
}/*
if(j<AL_SearchLen)*/
}/*
for(TypeLength i=0; i<AL_OriginLen; ++i)*/
if(VL_CopyStartPos<AL_OriginLen)
{
((CString&)ARR_SaveList).append
(VP_CopyStartChar, AL_OriginLen-VL_CopyStartPos) ;
}/*
if(VL_CopyStartPos<AL_OriginLen)*/
return ARR_SaveList;
}/*
template<typename TStringList> static TStringList& SplitByCondOr
(
TStringList& ARR_SaveList ,
TypeCharC* APC_OriginChar,
TypeCharC* APC_SearchChar,
TypeLength AL_OriginLen ,
TypeLength AL_SearchLen
)
//////////////////////////////////////////////////////////////*/
template<typename TStringList> TStringList& SplitByCondOr( ///////
TStringList& ARR_SaveList ,
TypeCharC* APC_SearchChar,
TypeLength AL_SearchLen
/*//////////*/ ) const ///////////////////////////////////////////
{
return SplitByCondOr<TStringList>(
RR(ARR_SaveList), mpc_Data, APC_SearchChar, ml_UseLen, AL_SearchLen);
}/*
TStringList& SplitByCondOr( //////////////////////////////////////
TStringList& ARR_SaveList ,
TypeCharC* APC_SearchChar,
TypeLength AL_SearchLen
////////////// ) const /////////////////////////////////////////*/
template<typename TStringList> TStringList& SplitByCondOr( ///////
TStringList& ARR_SaveList,
TypeCharC* APC_SearchChar
/*/////////*/ ) const ////////////////////////////////////////////
{
return SplitByCondOr<TStringList>( ////////////////////////////////////
RR(ARR_SaveList),
mpc_Data ,
APC_SearchChar ,
ml_UseLen ,
ZNsMain::ZftGetLengthType
<TypeLength, TypeChar>(APC_SearchChar)
/*/////////*/ );
}/*
template<typename TStringList> TStringList& SplitByCondOr( ///////
TStringList& ARR_SaveList,
TypeCharC* APC_SearchChar
////////////// ) const /////////////////////////////////////////*/
static ZCStringList& SplitByCondOrEx( /////////////////////////////
ZCStringList& ARR_SaveList ,
ZCStringList& AR_FindList ,
TypeCharC* APC_OriginChar ,
TypeLength AL_OriginLen ,
TypeLength AL_SearchMinLen=1
/*/////////*/ ) //////////////////////////////////////////////////
{
// AR_FindList 의 각 원소가 가리키는 각 문자열 object 들 중 하나라도 만족하면
// 그 문자열로 분리해서 ARR_SaveList 에 저장한다. 이 때 문자열의 길이가 들쭉
// 날쭉할 수 있으므로 AL_SearchMinLen 을 전달하여 찾는 문자열의 길이가 최소 어
// 느 정도인지를 알려준다.
const bool CB_IsOK =
AL_OriginLen<1 || AR_FindList.size()<1 ||
/*//////////*/ AL_OriginLen<AL_SearchMinLen || AL_SearchMinLen <1 ;
if(CB_IsOK) return ARR_SaveList;
TypeChar* VPC_StartChar = const_cast<TypeChar*>(APC_OriginChar);
TypeChar* VPC_StartCopy = VPC_StartChar;
TypeChar* VPC_CloseChar = VPC_StartChar;
TypeChar* VPC_SearchChar= 0 ;
IterEasyID VI_Iter_OR_List ;
TypeLength VL_StartPos=0; // VPC_StartChar 의 위치값
TypeLength VL_CopyPos =0; // VPC_StartCopy 의 위치값
TypeLength VL_ClosePos=0; // VPC_CloseChar 의 위치값
TypeLength VL_SearchLen ; // AR_FindList 의 각 원소의 문자열 크기
TypeLength VL_LoopSize=AR_FindList.size();
TypeLength j=0;
while(VL_StartPos<AL_OriginLen)
{
VI_Iter_OR_List=AR_FindList.GetHeadIterEasyID() ;
for(j=1; j<=VL_LoopSize; ++j)
{
TypeLength k;
VL_SearchLen = AR_FindList.ItD(VI_Iter_OR_List).size() ;
VPC_SearchChar=const_cast<TypeChar*>(AR_FindList.ItD(VI_Iter_OR_List).data());
VPC_CloseChar =VPC_StartChar;
VL_ClosePos =VL_StartPos ;
if(VL_SearchLen<AL_SearchMinLen) continue;
for(k=0; k<AL_SearchMinLen; ++k)
{
if(*VPC_CloseChar++ != *VPC_SearchChar++) break; ++VL_ClosePos;
}/*
for(k=0; k<AL_SearchMinLen; ++k)*/
// AL_SearchMinLen 개의 문자열이 일치한다면 나머지 문자열을 비교한다.
if(k>=AL_SearchMinLen) // 실제로는 k==VL_SearchLen
{
for(k=AL_SearchMinLen; k<VL_SearchLen; ++k)
{
if(*VPC_CloseChar++ != *VPC_SearchChar++) break; ++VL_ClosePos;
}/*
for(k=AL_SearchMinLen; k<VL_SearchLen; ++k)*/
}/*
if(k>=AL_SearchMinLen)*/
if(k>=VL_SearchLen)
{
break; // 이때는 찾는 문자열이 있는 것이다.
}/*
if(k>=VL_SearchLen)*/
AR_FindList.MoveNextIter(VI_Iter_OR_List);
}/*
for(j=1; j<=VL_LoopSize; ++j)*/
if(j<=VL_LoopSize)
{
// 이때는 찾는 문자열이 있는 것이다.
if(VL_CopyPos<VL_StartPos)
{
((ZCStringBase&)ARR_SaveList).append
(
VPC_StartCopy, VL_StartPos-VL_CopyPos
) ;
////////////////////////////////////
}/*
if(VL_CopyPos<VL_StartPos)*/
VPC_StartChar=VPC_StartCopy=VPC_CloseChar;
VL_CopyPos =VL_StartPos =VL_ClosePos ;
}
else //j>VL_LoopSize
{
++VL_StartPos ;
++VPC_StartChar;
}/*
else //j>VL_LoopSize*/
}/*
while(VL_StartPos<AL_OriginLen)*/
if(VL_CopyPos<AL_OriginLen)
{
((ZCStringBase&)ARR_SaveList).append( //////////////
VPC_StartCopy,
AL_OriginLen-VL_CopyPos
/*/////////*/ ) ; /////////////////////////////////
}/*
if(VL_CopyPos<AL_OriginLen)*/
return ARR_SaveList;
}/*
static ZCStringList& SplitByCondOrEx( ////////////////////////////
ZCStringList& ARR_SaveList ,
ZCStringList& AR_FindList ,
TypeCharC* APC_OriginChar ,
TypeLength AL_OriginLen ,
TypeLength AL_SearchMinLen=1
///////////// ) ////////////////////////////////////////////////*/
ZCStringList& SplitByCondOrEx( ///////////////////////////////////
ZCStringList& ARR_SaveList,
ZCStringList& AR_FindList ,
TypeLength AL_SearchMinLen=1
/*/////////*/ ) const ////////////////////////////////////////////
{
return SplitByCondOrEx(
RR(ARR_SaveList), AR_FindList, mpc_Data, ml_UseLen, AL_SearchMinLen) ;
}/*
ZCStringList& SplitByCondOrEx( ///////////////////////////////////
ZCStringList& ARR_SaveList,
ZCStringList& AR_FindList ,
TypeLength AL_SearchMinLen=1
///////////// ) const /////////////////////////////////////////*/
template<typename TSaveList, typename TFindList> /*#############*/
static TSaveList& SplitByCondOrExType
(
TSaveList& ARR_SaveList ,
TFindList& AR_FindList ,
TypeCharC* APC_OriginChar ,
TypeLength AL_OriginLen ,
TypeLength AL_SearchMinLen=1
)
/*##############################################################*/
{
/*//////////////////////////////////////////////////////////
■ ARR_SaveList 의 각 원소들은 문자열 object 이어야 한다.
AR_FindList 도 각 원소들은 문자열 object 이어야 하며 각
object 는 멤버함수로 c_str() 과 size() 를 가져야 한다.
■ AR_FindList 의 각 원소가 가리키는 각 문자열 object 들 중
하나라도 만족하면 그 문자열로 분리해서 ARR_SaveList 에
저장한다. 이 때 문자열의 길이가 들쭉날쭉 할 수 있으므로
AL_SearchMinLen 을 전달하여 찾는 문자열의 길이가 최소 어
느 정도인지를 알려준다.
//////////////////////////////////////////////////////////*/
const bool CB_IsTrue =
(
AL_OriginLen<1 || AR_FindList.size()<1 ||
AL_OriginLen<AL_SearchMinLen || AL_SearchMinLen <1
) ;
//////////////////////
if(CB_IsTrue) return ARR_SaveList;
TypeChar* VPC_StartChar=const_cast<TypeChar*>(APC_OriginChar);
TypeChar* VPC_StartCopy=VPC_StartChar;
TypeChar* VPC_CloseChar=VPC_StartChar;
TypeChar* VPC_SearchChar;
ZCStringBase VO_CStringTemp;
IterEasyID VO_Iter_OR_List(AR_FindList.GetHeadIterEasyID()) ;
TypeLength VL_StartPos=0; // VPC_StartChar 의 위치값
TypeLength VL_CopyPos =0; // VPC_StartCopy 의 위치값
TypeLength VL_ClosePos=0; // VPC_CloseChar 의 위치값
TypeLength VL_SearchLen ; // AR_FindList 의 각 원소의 문자열 크기
TypeLength VL_LoopSize=AR_FindList.size();
TypeLength j;
while(VL_StartPos<AL_OriginLen)
{
for(j=1; j<=VL_LoopSize; ++j)
{
TypeLength k=0;
VL_SearchLen =AR_FindList.ItD(VO_Iter_OR_List).size();
VPC_SearchChar=const_cast<TypeChar*>
(AR_FindList.ItD(VO_Iter_OR_List).data()) ;
VPC_CloseChar =VPC_StartChar;
VL_ClosePos =VL_StartPos ;
if(VL_SearchLen<1 || VL_SearchLen<AL_SearchMinLen) continue;
for(k=0; k<AL_SearchMinLen; ++k)
{
if(*VPC_CloseChar++ != *VPC_SearchChar++) break; ++VL_ClosePos;
}/*
for(k=0; k<AL_SearchMinLen; ++k)*/
// AL_SearchMinLen 개의 문자열이 일치한다면 나머지 문자열을 비교한다.
if(k>=AL_SearchMinLen) // 실제로는 k==AL_SearchMinLen
{
for(k=AL_SearchMinLen; k<VL_SearchLen; ++k)
{
if(*VPC_CloseChar++ != *VPC_SearchChar++) break; ++VL_ClosePos;
}/*
for(k=AL_SearchMinLen; k<VL_SearchLen; ++k)*/
}/*
if(k>=AL_SearchMinLen)*/
if(k>=VL_SearchLen) // 이때는 찾는 문자열이 있는 것이다.
break;
//endif
AR_FindList.MoveNextIter(VO_Iter_OR_List);
}/*
for(j=1; j<=VL_LoopSize; ++j)*/
if(j<=VL_LoopSize)
{
// 이때는 찾는 문자열이 있는 것이다.
if(VL_CopyPos<VL_StartPos)
{
VO_CStringTemp.Invalidate();
ARR_SaveList.push_back
(
VO_CStringTemp(VPC_StartCopy, VL_StartPos-VL_CopyPos)
) ;
//////////////////////
}/*
if(VL_CopyPos<VL_StartPos)*/
VPC_StartChar=VPC_StartCopy=VPC_CloseChar;
VL_CopyPos =VL_StartPos =VL_ClosePos ;
}
else // j>VL_LoopSize
{
++VL_StartPos ;
++VPC_StartChar;
}/*
else // j>VL_LoopSize*/
VO_Iter_OR_List=AR_FindList.GetHeadIterEasyID() ;
}/*
while(VL_StartPos<AL_OriginLen)*/
if(VL_CopyPos<AL_OriginLen)
{
VO_CStringTemp.Invalidate();
ARR_SaveList.push_back
(
VO_CStringTemp(VPC_StartCopy, AL_OriginLen-VL_CopyPos)
) ;
//////////////////////
}/*
if(VL_CopyPos<AL_OriginLen)*/
return ARR_SaveList;
}/*
template<typename TSaveList, typename TFindList> #################
static TSaveList& SplitByCondOrExType
(
TSaveList& ARR_SaveList ,
TFindList& AR_FindList ,
TypeCharC* APC_OriginChar,
TypeLength AL_OriginLen ,
TypeLength AL_SearchMinLen=1
)
/*##############################################################*/
template<typename TSaveList, typename TFindList>
TSaveList& SplitByCondOrExType( //////////////////////////////
TSaveList& ARR_SaveList ,
TFindList& AR_FindList ,
TypeLength AL_SearchMinLen=1
/*/////////////*/ ) const
{
return SplitByCondOrExType<TSaveList, TFindList>(
ARR_SaveList, AR_FindList, mpc_Data, ml_UseLen, AL_SearchMinLen);
}/*
template<typename TSaveList, typename TFindList>
TSaveList& SplitByCondOrExType( //////////////////////////////
TSaveList& ARR_SaveList ,
TFindList& AR_FindList ,
TypeLength AL_SearchMinLen=1
////////////// ) const ////////////////////////////////////////*/
static ZCStringList& ExtractBetweenToList /*####################*/
(
ZCStringList& ARR_SaveList ,
TypeCharC* APC_OriginChar ,
TypeCharC* APC_Search1Char ,
TypeCharC* APC_Search2Char ,
TypeLength AL_OriginLen ,
TypeLength AL_Search1Len ,
TypeLength AL_Search2Len ,
bool AB_DoIncludeSearch=false
)
/*##############################################################*/
{
/* APC_OriginChar에서 APC_Search1Char와 APC_Search2Char사이에
있는 문자열을 차례로 ARR_SaveList 에 대입한다.
AB_DoIncludeSearch=false 이면 APC_Search1Char 와 APC_Search2Char
도 찾은 문자열에 포함시키지 않는다.
*/
if(AL_OriginLen<1 || AL_Search1Len<1 || AL_Search2Len<1)
{ return ARR_SaveList; }
////////////////////////////////////////////////////////
TypeLength VL_Pos1=0;
TypeLength VL_Pos2=0;
while ( ////////////////////////////////////////////////
( VL_Pos1 = FindPos
(
APC_OriginChar, APC_Search1Char,
AL_OriginLen , AL_Search1Len , VL_Pos1
)
) >=0
)
////////////////////////////////////////////////////////
{
VL_Pos2 = FindPos /////////////////////
(
APC_OriginChar, APC_Search2Char,
AL_OriginLen , AL_Search2Len , VL_Pos1+AL_Search1Len
);
////////////////////////////////////////
if(VL_Pos2<0) { return ARR_SaveList; }
if(AB_DoIncludeSearch==true)
{
((ZCStringBase&)ARR_SaveList).Invalidate().append(
APC_OriginChar+VL_Pos1 , VL_Pos2-VL_Pos1+AL_Search2Len) ;
}
else if(VL_Pos2>VL_Pos1+AL_Search1Len) // AB_DoIncludeSearch==false
{
((ZCStringBase&)ARR_SaveList).Invalidate().append(
APC_OriginChar+VL_Pos1+AL_Search1Len, VL_Pos2-VL_Pos1-AL_Search1Len) ;
// APC_Search1Char 와 APC_Search2Char 사이에 문자열이 하나 이상 있어야 한다.
}/*
else if(VL_Pos2>VL_Pos1+AL_Search1Len) // AB_DoIncludeSearch==false*/
VL_Pos1=VL_Pos2+AL_Search2Len;
}/*
while ( //////////////////////////////////////////////
( VL_Pos1 = FindPos
(
APC_OriginChar, APC_Search1Char,
AL_OriginLen , AL_Search1Len , VL_Pos1
)
) >=0
)
////////////////////////////////////////////////////*/
return ARR_SaveList;
}/*
static ZCStringList& ExtractBetweenToList #######################
(
ZCStringList& ARR_SaveList ,
TypeCharC* APC_OriginChar ,
TypeCharC* APC_Search1Char ,
TypeCharC* APC_Search2Char ,
TypeLength AL_OriginLen ,
TypeLength AL_Search1Len ,
TypeLength AL_Search2Len ,
bool AB_DoIncludeSearch=false
)
/*##############################################################*/
ZCStringList& ExtractBetweenToList( //////////////////////////////
ZCStringList& ARR_SaveList ,
TypeCharC* APC_Search1Char,
TypeCharC* APC_Search2Char,
TypeLength AL_Search1Len ,
TypeLength AL_Search2Len ,
bool AB_DoIncludeSearch=false
/*/////////*/ ) const ////////////////////////////////////////////
{
return ExtractBetweenToList( ////////////
ARR_SaveList ,
mpc_Data ,
APC_Search1Char ,
APC_Search2Char ,
ml_UseLen ,
AL_Search1Len ,
AL_Search2Len ,
AB_DoIncludeSearch
/*/////////*/ ); ////////////////////////
}/*
ZCStringList& ExtractBetweenToList( //////////////////////////////
ZCStringList& ARR_SaveList ,
TypeCharC* APC_Search1Char ,
TypeCharC* APC_Search2Char ,
TypeLength AL_Search1Len ,
TypeLength AL_Search2Len ,
bool AB_DoIncludeSearch=false
//////////// ) const /////////////////////////////////////////*/
ZCStringList& ExtractBetweenToList( //////////////////////////////
ZCStringList& ARR_SaveList ,
TypeCharC* APC_Search1Char,
TypeCharC* APC_Search2Char,
bool AB_DoIncludeSearch=false
/*/////////*/ ) const ////////////////////////////////////////////
{
using ZNsMain::ZftGetLengthType ;
return ExtractBetweenToList(RR(ARR_SaveList), ///////////////////////////
mpc_Data ,
APC_Search1Char ,
APC_Search2Char ,
ml_UseLen ,
ZftGetLengthType<TypeLength, TypeChar>(APC_Search1Char),
ZftGetLengthType<TypeLength, TypeChar>(APC_Search2Char),
AB_DoIncludeSearch
/*/////////*/ ); ////////////////////////////////////////////////////////
}/*
ZCStringList& ExtractBetweenToList( ///////////////////////////////
ZCStringList& ARR_SaveList ,
TypeCharC* APC_Search1Char,
TypeCharC* APC_Search2Char,
bool AB_DoIncludeSearch=false
//////////// ) const //////////////////////////////////////////*/
template<typename TypeList>
static TypeList& ExtractBetweenToListType( ///////////////////
TypeList& ARR_SaveList ,
TypeCharC* APC_OriginChar ,
TypeCharC* APC_Search1Char ,
TypeCharC* APC_Search2Char ,
TypeLength AL_OriginLen ,
TypeLength AL_Search1Len ,
TypeLength AL_Search2Len ,
bool AB_DoIncludeSearch=false
/*//////////*/ ) /////////////////////////////////////////////////
{
/* APC_OriginChar에서 APC_Search1Char와 APC_Search2Char사이에 있는 문자열을
차례로 ARR_SaveList 에 대입한다. AB_DoIncludeSearch=false 이면 APC_Search1Char
와 APC_Search2Char도 찾은 문자열에 포함시키지 않는다.
ExtractBetweenToList() 멤버 함수를 일반화한 것인데, STL 과 억지로 맞출 것
같으면 임시 object 가 생성디는 문제가 있어서 STL 과 호환되게 하지는 않고
있다. */
typedef typename TypeList::TypeData CString;
if(AL_OriginLen<1 || AL_Search1Len<1 || AL_Search2Len<1)
{
return ARR_SaveList; /*###########################*/
}/*
if(AL_OriginLen<1 || AL_Search1Len<1 || AL_Search2Len<1)*/
TypeLength VL_Pos1=0;
TypeLength VL_Pos2=0;
while ( ( VL_Pos1 = FindPos( ////////////////////////
APC_OriginChar, APC_Search1Char,
AL_OriginLen , AL_Search1Len , VL_Pos1)
) >= 0
)
/////////////////////////////////////////////////////
{
VL_Pos2=FindPos(
APC_OriginChar, APC_Search2Char,
AL_OriginLen , AL_Search2Len , VL_Pos1+AL_Search1Len );
if(VL_Pos2<0) return ARR_SaveList;
if(AB_DoIncludeSearch==true)
{
((CString&)ARR_SaveList).Invalidate().append(
APC_OriginChar+VL_Pos1 , VL_Pos2-VL_Pos1+AL_Search2Len) ;
}
else if(VL_Pos2>VL_Pos1+AL_Search1Len) // AB_DoIncludeSearch==false
{
((CString&)ARR_SaveList).Invalidate().append(
APC_OriginChar+VL_Pos1+AL_Search1Len, VL_Pos2-VL_Pos1-AL_Search1Len) ;
// APC_Search1Char 와 APC_Search2Char 사이에 문자열이 하나 이상 있어야 한다.
}/*
else if(VL_Pos2>VL_Pos1+AL_Search1Len) // AB_DoIncludeSearch==false*/
VL_Pos1=VL_Pos2+AL_Search2Len;
}/*
while ( ( VL_Pos1 = FindPos( ////////////////////////
APC_OriginChar, APC_Search1Char,
AL_OriginLen , AL_Search1Len , VL_Pos1)
) >= 0
)
///////////////////////////////////////////////////*/
return ARR_SaveList;
}/*
template<typename TypeList>
static TypeList& ExtractBetweenToListType( ///////////////////
TypeList& ARR_SaveList ,
TypeCharC* APC_OriginChar ,
TypeCharC* APC_Search1Char ,
TypeCharC* APC_Search2Char ,
TypeLength AL_OriginLen ,
TypeLength AL_Search1Len ,
TypeLength AL_Search2Len ,
bool AB_DoIncludeSearch=false
///////////// ) ///////////////////////////////////////////////*/
template<typename TypeList>
TypeList& ExtractBetweenToListType( //////////////////////////
TypeList& ARR_SaveList ,
TypeCharC* APC_Search1Char ,
TypeCharC* APC_Search2Char ,
TypeLength AL_Search1Len ,
TypeLength AL_Search2Len ,
bool AB_DoIncludeSearch=false
/*/////////*/ ) const
{
return ExtractBetweenToListType<TypeList>( //////
ARR_SaveList ,
mpc_Data ,
APC_Search1Char ,
APC_Search2Char ,
ml_UseLen ,
AL_Search1Len ,
AL_Search2Len ,
AB_DoIncludeSearch
/*/////////*/ ); ////////////////////////////////
}/*
template<typename TypeList>
TypeList& ExtractBetweenToListType( //////////////////////////
TypeList& ARR_SaveList ,
TypeCharC* APC_Search1Char ,
TypeCharC* APC_Search2Char ,
TypeLength AL_Search1Len ,
TypeLength AL_Search2Len ,
bool AB_DoIncludeSearch=false
/*/////////*/ ) const //////////////////////////////////////////*/
template<typename TypeList>
TypeList& ExtractBetweenToListType( //////////////////////////
TypeList& ARR_SaveList ,
TypeCharC* APC_Search1Char,
TypeCharC* APC_Search2Char,
bool AB_DoIncludeSearch=false
/*/////////*/ ) const
{
using ZNsMain::ZftGetLengthType ;
return ExtractBetweenToListType<TypeList>( //////////////////////////////
ARR_SaveList ,
mpc_Data ,
APC_Search1Char ,
APC_Search2Char ,
ml_UseLen ,
ZftGetLengthType<TypeLength, TypeChar>(APC_Search1Char),
ZftGetLengthType<TypeLength, TypeChar>(APC_Search2Char),
AB_DoIncludeSearch
/*/////////*/ ); ////////////////////////////////////////////////////////
}/*
template<typename TypeList>
TypeList& ExtractBetweenToListType( //////////////////////////
TypeList& ARR_SaveList ,
TypeCharC* APC_Search1Char,
TypeCharC* APC_Search2Char,
bool AB_DoIncludeSearch=false
///////////// ) const //////////////////////////////////////////*/
template<typename TStringList>
static TStringList& MakeNullAllLink(TStringList& ARR_SaveList)
{
/* 리스트 자료구조는 프로그램상에서 구현한 정적 버퍼에서 링크를 만들어서 가져오고
링크가 삭제될 때도 이 정적버퍼로 보내게 되는데 이 링크를 다시 가져올 때 원치
않는 자료가 이미 있을 수 있으므로 각 링크를 Null 로 초기화한다. */
TypeLength VL_MaxLoop =ARR_SaveList.GetSize();
IterEasyID VI_IterEasy=ARR_SaveList.GetHeadIterEasyID();
for(TypeLength i=0; i<VL_MaxLoop; ++i)
{
ARR_SaveList.ItD(VI_IterEasy).Invalidate();
ARR_SaveList.MoveNextIter(VI_IterEasy);
}/*
for(TypeLength i=0; i<VL_MaxLoop; ++i)*/
return ARR_SaveList;
}/*
template<typename TStringList>
static TStringList& MakeNullAllLink(TStringList& ARR_SaveList) */
template<typename TStringList>
static TStringList& MakeNullAllDelete(TStringList& ARR_SaveList)
{
MakeNullAllLink(RR(ARR_SaveList)); ARR_SaveList.DeleteAll(); return ARR_SaveList;
}/*
template<typename TStringList>
static TStringList& MakeNullAllDelete(TStringList& ARR_SaveList) */
ZtCStringBase& AddSlashes()
{
if(ml_UseLen<1) return *this;
TypeLength VL_Index =0;
TypeLength VL_AddedCnt=0; // '\' 를 삽입해야 되는 문자 수를 구한다.
TypeLength VL_PrevSize=ml_UseLen;
TypeLength VL_NextSize=0;
TypeChar VC_TempChar=0;
do //////
{
const bool CB_IsOK=
(VC_TempChar= mpc_Data[VL_Index])
=='\"' ||
VC_TempChar=='\'' ||
VC_TempChar=='\\' ||
/*//////////*/ VC_TempChar=='\0' ;
if(CB_IsOK) ++VL_AddedCnt;
}
while(++VL_Index<VL_PrevSize);
if(VL_AddedCnt==0) return *this;
// 필요한 만큼의 메모리를 할당하고...
reserve(VL_NextSize=ml_UseLen+VL_AddedCnt);
/* 배열 인덱스 변수로 TypeLength 형 변수 하나가 필요한데 기존의 VL_AddedCnt 를 쓴다.
그래서 의미가 햇깔리지 않도록 매크로 정의해서 사용한다. */
#define VL_Index2 VL_AddedCnt
VL_Index =VL_PrevSize-1 ;
VL_Index2 =VL_NextSize-1 ;
mpc_Data[ml_UseLen=VL_NextSize]=0;
do //////
{
if((VC_TempChar=mpc_Data[VL_Index])=='"' || VC_TempChar=='\'' || VC_TempChar=='\\')
{
mpc_Data[VL_Index2--]=VC_TempChar;
mpc_Data[VL_Index2--]='\\';
}
else if(VC_TempChar=='\0')
{
mpc_Data[VL_Index2--]='0' ;
mpc_Data[VL_Index2--]='\\';
}
else
{
mpc_Data[VL_Index2--]=VC_TempChar;
}/*
else*/
}
while(--VL_Index>=0);
return *this;
#undef VL_AddedCnt
}/*
ZCStringBase& AddSlashes()*/
ZCStringBase& AddSlashesEx()
{
// \r 과 \n 에 대해서도 탈출시킨다.
if(ml_UseLen<1) return *this;
TypeLength VL_Index =0;
TypeLength VL_AddedCnt=0; // '\' 를 삽입해야 되는 문자 수를 구한다.
TypeLength VL_PrevSize=ml_UseLen;
TypeLength VL_NextSize=0;
TypeChar VC_TempChar=0;
do //////
{
const bool CB_IsOK = //////////
(
(VC_TempChar=mpc_Data[VL_Index] )=='\"' ||
VC_TempChar=='\'' || VC_TempChar=='\n' ||
VC_TempChar=='\r' || VC_TempChar=='\\' ||
VC_TempChar=='\0'
);
///////////////////////////////
if(CB_IsOK) ++VL_AddedCnt;
}
while(++VL_Index<VL_PrevSize);
if(VL_AddedCnt==0) return *this;
// 필요한 만큼의 메모리를 할당하고...
reserve(VL_NextSize=ml_UseLen+VL_AddedCnt);
/* 배열 인덱스 변수로 TypeLength 형 변수 하나가 필요한데 기존의 VL_AddedCnt 를 쓴다.
그래서 의미가 햇깔리지 않도록 매크로 정의해서 사용한다. */
#define VL_Index2 VL_AddedCnt
VL_Index =VL_PrevSize-1 ;
VL_Index2 =VL_NextSize-1 ;
mpc_Data[ml_UseLen=VL_NextSize]=0;
do //////
{
if((VC_TempChar=mpc_Data[VL_Index])=='"' || VC_TempChar=='\'' || VC_TempChar=='\\')
{
mpc_Data[VL_Index2--]=VC_TempChar;
mpc_Data[VL_Index2--]='\\';
}
else if(VC_TempChar=='\0')
{
mpc_Data[VL_Index2--]='0' ;
mpc_Data[VL_Index2--]='\\';
}
else if(VC_TempChar=='\r')
{
mpc_Data[VL_Index2--]='r' ;
mpc_Data[VL_Index2--]='\\';
}
else if(VC_TempChar=='\n')
{
mpc_Data[VL_Index2--]='n' ;
mpc_Data[VL_Index2--]='\\';
}
else
{
mpc_Data[VL_Index2--]=VC_TempChar;
}/*
else*/
}
while(--VL_Index>=0);
return *this;
#undef VL_AddedCnt
}/*
ZCStringBase& AddSlashesEx()*/
static TypeChar* StripSlashes(TypeChar* APC_Data, TypeLength AL_Length)
{
if(AL_Length<2) return APC_Data;
TypeLength VL_MaxLoop=AL_Length-1;
TypeLength i =0 ;
TypeLength j =0 ;
TypeChar VC_TempChar1;
TypeChar VC_TempChar2;
while(i<VL_MaxLoop)
{
if((VC_TempChar1=APC_Data[i])=='\\')
{
VC_TempChar2=APC_Data[i+1];
if(VC_TempChar2=='\'' || VC_TempChar2=='\\' || VC_TempChar2=='\"' || VC_TempChar2=='\0')
{
APC_Data[j++]=VC_TempChar2; i+=2;
}
else
{
APC_Data[j++]=VC_TempChar1; ++i;
}/*
else*/
}
else
{
APC_Data[j++]=VC_TempChar1; ++i;
}/*
else*/
}/*
while(i<VL_MaxLoop)*/
if(i==VL_MaxLoop)
{
APC_Data[j++]=APC_Data[i];
}/*
if(i==VL_MaxLoop)*/
APC_Data[j]=0; return APC_Data;
}/*
static TypeChar* StripSlashes(TypeChar* APC_Data, TypeLength AL_Length)*/
static TypeChar* StripSlashesEx(TypeChar* APC_Data, TypeLength AL_Length)
{
if(AL_Length<2) return APC_Data;
TypeLength VL_MaxLoop=AL_Length-1;
TypeLength i =0 ;
TypeLength j =0 ;
TypeChar VC_TempChar1;
TypeChar VC_TempChar2;
while(i<VL_MaxLoop)
{
if((VC_TempChar1=APC_Data[i])=='\\')
{
VC_TempChar2=APC_Data[i+1];
if ( VC_TempChar2=='\'' || VC_TempChar2=='\\' ||
VC_TempChar2=='\"' || VC_TempChar2=='\0'
)
{
APC_Data[j++]=VC_TempChar2; i+=2;
}
else if(VC_TempChar2=='r')
{
APC_Data[j++]='\r'; i+=2;
}
else if(VC_TempChar2=='n')
{
APC_Data[j++]='\n'; i+=2;
}
else
{
APC_Data[j++]=VC_TempChar1; ++i;
}/*
else*/
}
else // (VC_TempChar1=APC_Data[i])!='\\'
{
APC_Data[j++]=VC_TempChar1; ++i;
}/*
else*/
}/*
while(i<VL_MaxLoop)*/
if(i==VL_MaxLoop)
{
APC_Data[j++]=APC_Data[i];
}/*
if(i==VL_MaxLoop)*/
APC_Data[j]=0; return APC_Data;
}/*
static TypeChar* StripSlashesEx(TypeChar* APC_Data, TypeLength AL_Length)*/
ZCStringBase& StripSlashes()
{
if(ml_UseLen<2) return *this;
TypeLength VL_MaxLoop=ml_UseLen-1;
TypeLength i =0;
TypeLength j =0;
TypeChar VC_TempChar1;
TypeChar VC_TempChar2;
while(i<VL_MaxLoop)
{
if((VC_TempChar1=mpc_Data[i])=='\\')
{
VC_TempChar2=mpc_Data[i+1];
if(VC_TempChar2=='\'' || VC_TempChar2=='\\' || VC_TempChar2=='\"' || VC_TempChar2=='\0')
{
mpc_Data[j++]=VC_TempChar2; i+=2; --ml_UseLen;
}
else
{
mpc_Data[j++]=VC_TempChar1; ++i;
}/*
else*/
}
else //VC_TempChar1!='\\'
{
mpc_Data[j++]=VC_TempChar1; ++i;
}/*
else //VC_TempChar1!='\\'*/
}/*
while(i<VL_MaxLoop)*/
if(i==VL_MaxLoop)
{
mpc_Data[j++]=mpc_Data[i];
}/*
if(i==VL_MaxLoop)*/
mpc_Data[j]=0; return *this;
}/*
ZCStringBase& StripSlashes()*/
ZCStringBase& StripSlashesEx()
{
if(ml_UseLen<2) return *this;
TypeLength VL_MaxLoop=ml_UseLen-1;
TypeLength i=0;
TypeLength j=0;
TypeChar VC_TempChar1;
TypeChar VC_TempChar2;
while(i<VL_MaxLoop)
{
if((VC_TempChar1=mpc_Data[i])=='\\')
{
VC_TempChar2=mpc_Data[i+1];
if ( VC_TempChar2=='\'' || VC_TempChar2=='\\' ||
VC_TempChar2=='\"' || VC_TempChar2=='\0'
)
{
mpc_Data[j++]=VC_TempChar2; i+=2; --ml_UseLen;
}
else if(VC_TempChar2=='r')
{
mpc_Data[j++]='\r'; i+=2; --ml_UseLen;
}
else if(VC_TempChar2=='n')
{
mpc_Data[j++]='\n'; i+=2; --ml_UseLen;
}
else
{
mpc_Data[j++]=VC_TempChar1; ++i;
}/*
else*/
}
else //VC_TempChar1!='\\'
{
mpc_Data[j++]=VC_TempChar1; ++i;
}/*
else //VC_TempChar1!='\\'*/
}/*
while(i<VL_MaxLoop)*/
if(i==VL_MaxLoop)
{
mpc_Data[j++]=mpc_Data[i];
}/*
if(i==VL_MaxLoop)*/
mpc_Data[j]=0; return *this;
}/*
ZCStringBase& StripSlashesEx()*/
ZCStringBase& AddPerChunk(
TypeLength AL_ChunkSize, TypeCharC* APC_AddChar, TypeLength AL_AddLen)
{
// TypeLength AL_ChunkSize 마다 문자열 APC_AddChar을 삽입한다.
if(ml_UseLen<AL_ChunkSize || AL_ChunkSize<1)
{ return *this ; }
////////////////////////////////////////////
TypeLength VL_PrevSize=ml_UseLen ;
TypeLength VL_Count =(VL_PrevSize/AL_ChunkSize);
TypeLength VL_Mod =(VL_PrevSize%AL_ChunkSize);
TypeLength VL_NewSize=VL_PrevSize+VL_Count*AL_AddLen;
ReAllocKeep(VL_NewSize);
mpc_Data[ml_UseLen =VL_NewSize]=0;
TypeLength VL_Index=VL_NewSize-1 ;
for(int p=0; p<VL_Mod; ++p)
{
mpc_Data[VL_Index--] = mpc_Data[VL_PrevSize-1-p];
}/*
for(int p=0; p<VL_Mod; ++p)*/
TypeLength i=0, j=0, t=0;
for(i=VL_Count-1; i>=0; --i)
{
t= i*AL_ChunkSize;
for(j=AL_AddLen-1; j>=0; --j)
{
mpc_Data[VL_Index--]=APC_AddChar[j];
}/*
for(j=AL_AddLen-1; j>=0; --j)*/
for(j=AL_ChunkSize-1; j>=0; --j)
{
mpc_Data[VL_Index--]=mpc_Data[t+j];
}/*
for(j=AL_ChunkSize-1; j>=0; --j)*/
}/*
for(i=VL_Count-1; i>=0; --i)*/
return *this;
}/*
ZCStringBase& AddPerChunk(
TypeLength AL_ChunkSize, TypeCharC* APC_AddChar, TypeLength AL_AddLen)*/
ZCStringBase& AddPerChunk(TypeLength AL_ChunkSize, TypeCharC* APC_AddChar)
{
return AddPerChunk(
AL_ChunkSize, APC_AddChar, ZNsMain::ZftGetLengthType<TypeLength, TypeChar>(APC_AddChar));
}/*
ZCStringBase& AddPerChunk(TypeLength AL_ChunkSize, TypeCharC* APC_AddChar)*/
bool LoadFile
(
TypeCharC* APC_FileName , bool AB_DoAppend=true,
TypeLength AL_AddAllocSize=0, TypeLength AL_LoadSize=0
)
/////////////
{
// window 에서 _open() 함수는 \r\n 을 한 문자로 입력받음에 주의.
// AL_AddAllocSize 는 파일 APC_FileName 의 크기보다 더 큰 메모리가 필요할 경우에 전달한다.
#ifndef _WIN
int AH_FileDesc =
::open(APC_FileName,ZNsConst::ZNsLlioMode::Read);
if(AH_FileDesc == -1) return false;
// 파일기술자를 파일의 맨 끝으로 이동시켜 파일크기를 구한다.
off_t VL_Offset=
::lseek(AH_FileDesc, 0/*Offset*/, SEEK_END); // 실패시 -1
if(VL_Offset== -1)
{
::close(AH_FileDesc); return false;
}/*
if(VL_Offset== -1)*/
if(AL_LoadSize>0 && VL_Offset>AL_LoadSize) VL_Offset=AL_LoadSize;
// 파일 기술자를 다시 처음으로 옮긴다.
::lseek(AH_FileDesc, 0/*Offset*/, SEEK_SET);
TypeLength VL_PrevSize=(AB_DoAppend ? ml_UseLen : 0);
ReAlloc(VL_PrevSize+VL_Offset+AL_AddAllocSize, AB_DoAppend);
// 윈도우에서 read() 함수는 \r\n 을 한 문자로 읽어들이므로 주의
TypeLength VL_ReadSize=0;
if((VL_ReadSize=read(AH_FileDesc, mpc_Data+VL_PrevSize, VL_Offset))<0)
{
mpc_Data[ml_UseLen=VL_PrevSize]=0; ::close(AH_FileDesc); return false;
}/*
if((VL_ReadSize=read(AH_FileDesc, mpc_Data+VL_PrevSize, VL_Offset))<0)*/
if(VL_ReadSize>0)
mpc_Data[ml_UseLen=VL_PrevSize+VL_ReadSize]=0;
::close(AH_FileDesc); return true;
#else //defined(_WIN)
TypeLength VL_PrevSize=AB_DoAppend ? ml_UseLen : 0 ;
HANDLE VH_File=::CreateFile( ////////////////////////////////////////////////////////////
APC_FileName ,
GENERIC_READ ,
FILE_SHARE_READ , // 공유모드: 이미 열려 있는 파일을 열 수 있게 한다.
NULL ,
OPEN_EXISTING ,
FILE_ATTRIBUTE_NORMAL, // 반드시 단독으로 사용되는 플래그
NULL
/*/////////*/ ); /////////////////////////////////////////////////////////////////////////
if(INVALID_HANDLE_VALUE==VH_File) return false;
DWORD dwRead2 = 0 ;
DWORD dwRead =
SetFilePointer(VH_File, 0, NULL, FILE_END);
if(AL_LoadSize>0 && dwRead>AL_LoadSize)
{ dwRead=AL_LoadSize; }
ReAlloc(VL_PrevSize+dwRead, AB_DoAppend);
::SetFilePointer(VH_File, 0, NULL, FILE_BEGIN);
if(::ReadFile(VH_File, mpc_Data+VL_PrevSize, dwRead, &dwRead2, NULL)==FALSE)
{
Invalidate(); CloseHandle(VH_File); return false;
}/*
if(::ReadFile(VH_File, mpc_Data+VL_PrevSize, dwRead, &dwRead2, NULL)==FALSE)*/
::CloseHandle(VH_File);
if(dwRead2>0)
mpc_Data[ml_UseLen=VL_PrevSize+dwRead2]=0;
else
Invalidate();
/*else*/
return true;
#endif //defined(_WIN)
}/*
bool LoadFile
(
TypeCharC* APC_FileName , bool AB_DoAppend=true,
TypeLength AL_AddAllocSize=0, TypeLength AL_LoadSize=0
)
///////////*/
bool LoadFile
(
const ZCStringBase& AR_CStrFileName , bool AB_DoAppend=true,
TypeLength AL_AddAllocSize=0, TypeLength AL_LoadSize=0
)
/////////////
{
return LoadFile(AR_CStrFileName.data(), AB_DoAppend, AL_AddAllocSize, AL_LoadSize);
}/*
bool LoadFile
(
const ZCStringBase& AR_CStrFileName , bool AB_DoAppend=true,
TypeLength AL_AddAllocSize=0, TypeLength AL_LoadSize=0
)
///////////*/
static TypeLength SearchFileOffset
(
const int AH_FileDesc , TypeCharC* APC_Search,
TypeLength AL_SearchLen, TypeLength AL_WantSearchCnt=1
)
/*##############################*/
{
/*///////////////////////////////////////////////////////////////////////////////////////////////////////
■ AH_FileDesc 가 지정하는 파일에서 APC_Search 라는 문자열을 AL_WantSearchCnt 번째 나오는 위치를 찾는다.
문자를 파일에서 BUFSIZ 만큼 읽어와서 문자열을 찾는데, 찾는 문자가 10 이면 읽어 올때마다 9 개(10-1) 문
자열을 읽어온 문자열 앞에 붙여서 조사해야 한다. 예를 들어 I Love C++ 이란 문자열을 찾는데 이전 문자열
의 뒷부분에서 I Love 까지는 있을 수 있기 때문이다.
///////////////////////////////////////////////////////////////////////////////////////////////////////*/
const int CI_SearchNo = -1 ; // 찾지 못한 상태.
if(AL_SearchLen<1 || AL_WantSearchCnt<1) return CI_SearchNo;
TypeLength VL_LoadLen =(((AL_SearchLen-1)/BUFSIZ)+1)*BUFSIZ;
TypeLength VL_ReadCnt =0;
TypeLength VL_SearchCnt =0;
TypeLength VL_FindedPos =0;
TypeLength VL_Offset =::lseek(AH_FileDesc,0,SEEK_CUR);
TypeLength VL_InnerOffset=0;
ZCStringBase VO_CStringBuff; VO_CStringBuff.ReAlloc(VL_LoadLen+AL_SearchLen-1);
while /*#######################################################*/
(
( VL_ReadCnt = ::read
(
AH_FileDesc, VO_CStringBuff.mpc_Data+VO_CStringBuff.ml_UseLen, VL_LoadLen
)
) > 0
)
/*#############################################################*/
{
VO_CStringBuff.mpc_Data
[VO_CStringBuff.ml_UseLen+=VL_ReadCnt]=0; VL_InnerOffset=0;
while //////////////////////////////////////////////////
( ( VL_FindedPos =
VO_CStringBuff.FindPos
(
APC_Search, AL_SearchLen, VL_InnerOffset
)
) >= 0
)
////////////////////////////////////////////////////////
{
if(++VL_SearchCnt>=AL_WantSearchCnt)
{
/* 이전에는 찾은 경우에 아래 코드로 찾았다면 파일 포인터를
원래 위치로 돌렸었다. 크게 의미가 없는 것 같다. */
// lseek(AH_FileDesc,VL_PrevOffset,SEEK_SET);
return VL_Offset+VL_FindedPos ;
}/*
if(++VL_SearchCnt>=AL_WantSearchCnt)*/
VL_InnerOffset = VL_FindedPos + AL_SearchLen ;
}/*
while(VL_FindedPos=VO_CStringBuff.FindPos(~))>=0)*/
if(VO_CStringBuff.ml_UseLen>=AL_SearchLen)
{
VL_Offset += VO_CStringBuff.ml_UseLen-AL_SearchLen+1 ;
VO_CStringBuff.MoveFirst(VO_CStringBuff.ml_UseLen-AL_SearchLen+1);
}/*
if(VO_CStringBuff.ml_UseLen>=AL_SearchLen)*/
}/*
while ###############################################################################
(
( VL_ReadCnt = ::read
(
AH_FileDesc, VO_CStringBuff.mpc_Data+VO_CStringBuff.ml_UseLen, VL_LoadLen
)
) > 0
)
###################################################################################*/
return CI_SearchNo; // 이때는 못 찾은 것이다
}/*
static TypeLength SearchFileOffset
(
const int AH_FileDesc , TypeCharC* APC_Search,
TypeLength AL_SearchLen, TypeLength AL_WantSearchCnt=1
)
////////////////////////////////*/
#ifdef _WIN
static TypeLength SearchFileOffset( //////////////////////////////
HANDLE AH_File ,
TypeCharC* APC_Search ,
TypeLength AL_SearchLen ,
TypeLength AL_WantSearchCnt=1 ,
LPOVERLAPPED lpOverlapped =NULL
/*/////////*/ ) ///////////////////////////////////////////////*/
{
if(AL_SearchLen<1 || AL_WantSearchCnt<1) return -1;
DWORD VL_ReadCnt =0;
TypeLength VL_LoadLen=(((AL_SearchLen-1)/BUFSIZ)+1)*BUFSIZ;
TypeLength VL_SearchCnt =0;
TypeLength VL_FindedPos =0;
ZTypLLong VL_Offset =Seek(AH_File, 0, FILE_CURRENT); //lseek(AH_FileDesc,0,SEEK_CUR);
TypeLength VL_PrevOffset =VL_Offset;
TypeLength VL_InnerOffset=0;
ZCStringBase VO_CStringBuff; VO_CStringBuff.ReAlloc(VL_LoadLen+AL_SearchLen-1);
while(true)
{
const bool CB_IsFalse = //////////////////////////////////////
(
::ReadFile
(
AH_File ,
VO_CStringBuff.c_str() + VO_CStringBuff.ml_UseLen,
VL_LoadLen ,
&VL_ReadCnt ,
lpOverlapped
)==FALSE || VL_ReadCnt<1
);
//////////////////////////////////////////////////////////////
if(CB_IsFalse){ return -1; }
VO_CStringBuff.mpc_Data[VO_CStringBuff.ml_UseLen+=VL_ReadCnt]=0; VL_InnerOffset=0;
while((VL_FindedPos =VO_CStringBuff.
FindPos(APC_Search, AL_SearchLen, VL_InnerOffset))>=0)
{
if(++VL_SearchCnt>=AL_WantSearchCnt)
{
return VL_Offset+VL_FindedPos ;
}/*
if(++VL_SearchCnt>=AL_WantSearchCnt)*/
VL_InnerOffset = VL_FindedPos + AL_SearchLen ;
}/*
while((VL_FindedPos =VO_CStringBuff.
FindPos(APC_Search, AL_SearchLen, VL_InnerOffset))>=0)*/
if(VO_CStringBuff.ml_UseLen>=AL_SearchLen)
{
VL_Offset +=
VO_CStringBuff.ml_UseLen-AL_SearchLen+1 ;
VO_CStringBuff.MoveFirst(
VO_CStringBuff.ml_UseLen-AL_SearchLen+1 );
}/*
if(VO_CStringBuff.ml_UseLen>=AL_SearchLen)*/
}/*
while(true)*/
return -1; // 이때는 못 찾은 것이다
}/*
static TypeLength SearchFileOffset( //////////////////////////////
HANDLE AH_File ,
TypeCharC* APC_Search ,
TypeLength AL_SearchLen ,
TypeLength AL_WantSearchCnt=1 ,
LPOVERLAPPED lpOverlapped =NULL
///////////// ) ///////////////////////////////////////////////*/
#endif // _WIN
#ifdef _WIN
static TypeLength SearchFileOffset( //////////////////////////////
LPCTSTR APC_FileName ,
TypeCharC* APC_Search ,
TypeLength AL_SearchLen ,
TypeLength AL_WantSearchCnt=1,
LPOVERLAPPED lpOverlapped =NULL
/*/////////*/ ) ///////////////////////////////////////////////*/
{
HANDLE VH_File=::CreateFile(
APC_FileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(VH_File==INVALID_HANDLE_VALUE) return -1;
TypeLength VL_Offset=SearchFileOffset(
VH_File, APC_Search, AL_SearchLen, AL_WantSearchCnt, lpOverlapped);
::CloseHandle(VH_File); return VL_Offset;
}/*
static TypeLength SearchFileOffset( //////////////////////////////
LPCTSTR APC_FileName ,
TypeCharC* APC_Search ,
TypeLength AL_SearchLen ,
TypeLength AL_WantSearchCnt=1,
LPOVERLAPPED lpOverlapped =NULL
///////////// ) ///////////////////////////////////////////////*/
#else // !defined(_WIN)
// 리눅스의 경우
static TypeLength SearchFileOffset
(
TypeCharC* APC_FileName, TypeCharC* APC_Search,
TypeLength AL_SearchLen, TypeLength AL_WantSearchCnt=1
)
//////////////////////////////////
{
int AH_FileDesc = ::open(APC_FileName,O_RDONLY);
if(AH_FileDesc<0) return -1;
TypeLength VL_Offset=SearchFileOffset(
AH_FileDesc, APC_Search, AL_SearchLen, AL_WantSearchCnt);
::close(AH_FileDesc); return VL_Offset;
}/*
static TypeLength SearchFileOffset
(
TypeCharC* APC_FileName, TypeCharC* APC_Search,
TypeLength AL_SearchLen, TypeLength AL_WantSearchCnt=1
)
////////////////////////////////*/
#endif //!defined(_WIN)
static TypeLength SearchFileOffsetBackward
(
const int AH_FileDesc , TypeCharC* APC_Search,
TypeLength AL_SearchLen, TypeLength AL_WantSearchCnt=1
)
//////////////////////////////////////////
{
// SearchFileOffset() 함수와 역할은 비슷하나 뒤에서 앞으로 접근한다.
if(AL_SearchLen<1 || AL_WantSearchCnt<1) return -1;
TypeLength VL_LoadLen =(((AL_SearchLen-1)/BUFSIZ)+1)*BUFSIZ;
TypeLength VL_ReadCnt =0;
TypeLength VL_SearchCnt =0;
TypeLength VL_FindedPos =0;
TypeLength VL_Offset =::lseek(AH_FileDesc,0,SEEK_CUR);
TypeLength VL_InnerOffset=0;
TypeLength VL_Offset2 =VL_Offset;
if(VL_Offset<AL_SearchLen) return -1;
ZCStringBase VO_CStringBuff;
ZCStringBase VO_CStringBack; // 뒤에 덧붙여야 되는 문자열
VO_CStringBuff.ReAlloc(VL_LoadLen+AL_SearchLen-1);
VO_CStringBack.ReAlloc(AL_SearchLen-1 );
while(VL_Offset>0)
{
VL_Offset2=VL_Offset;
if((VL_Offset2 -= VL_LoadLen)<0) VL_Offset2 = 0 ;
if(::lseek(AH_FileDesc, VL_Offset2, SEEK_SET)<0)
{ return -1; }
////////////////////////////////////////////////
const bool VB_IsFalse =
(
( VL_ReadCnt=::read
(
AH_FileDesc, VO_CStringBuff.mpc_Data, VL_Offset-VL_Offset2
)
)<1 || VL_Offset-VL_Offset2!=VL_ReadCnt
);
/*###################*/ if(VB_IsFalse) return -1;
VO_CStringBuff.mpc_Data
[VO_CStringBuff.ml_UseLen=VL_ReadCnt]=0;
if(AL_SearchLen>1) VO_CStringBuff(VO_CStringBack);
VL_InnerOffset=VO_CStringBuff.ml_UseLen-1;
while((VL_FindedPos=VO_CStringBuff.
FindPosFromEnd(APC_Search, AL_SearchLen, VL_InnerOffset))>=0)
{
if(++VL_SearchCnt>=AL_WantSearchCnt)
{ return VL_Offset2+VL_FindedPos; }
VO_CStringBack.Invalidate();
VO_CStringBack(
VO_CStringBuff.mpc_Data, AL_SearchLen-1);
VL_InnerOffset = VL_FindedPos ;
}/*
while((VL_FindedPos=VO_CStringBuff.
FindPosFromEnd(APC_Search, AL_SearchLen, VL_InnerOffset))>=0)*/
VL_Offset=VL_Offset2 ;
}/*
while(VL_Offset>0)*/
return -1; // 이때는 못 찾은 것이다
}/*
static TypeLength SearchFileOffsetBackward
(
const int AH_FileDesc , TypeCharC* APC_Search,
TypeLength AL_SearchLen, TypeLength AL_WantSearchCnt=1
)
////////////////////////////////////////*/
#ifdef _WIN
static TypeLength SearchFileOffsetBackward( //////////////////////
HANDLE AH_File ,
TypeCharC* APC_Search ,
TypeLength AL_SearchLen ,
TypeLength AL_WantSearchCnt=1 ,
LPOVERLAPPED lpOverlapped =NULL
/*/////////*/ ) ///////////////////////////////////////////////*/
{
// SearchFileOffset() 함수와 역할은 비슷하나 뒤에서 앞으로 접근한다.
if(AL_SearchLen<1 || AL_WantSearchCnt<1) return -1;
TypeLength VL_LoadLen =(((AL_SearchLen-1)/BUFSIZ)+1)*BUFSIZ;
DWORD VL_ReadCnt =0;
TypeLength VL_SearchCnt =0;
TypeLength VL_FindedPos =0;
ZTypLLong VL_Offset =Seek(AH_File, 0, FILE_CURRENT);
TypeLength VL_InnerOffset=0;
TypeLength VL_Offset2 =VL_Offset;
if(VL_Offset<AL_SearchLen) return -1;
ZCStringBase VO_CStringBuff;
ZCStringBase VO_CStringBack; // 뒤에 덧붙여야 되는 문자열
VO_CStringBuff.ReAlloc(VL_LoadLen+AL_SearchLen-1);
VO_CStringBack.ReAlloc(AL_SearchLen-1 );
while(VL_Offset>0)
{
VL_Offset2=VL_Offset;
if((VL_Offset2-=VL_LoadLen)<0) VL_Offset2 = 0 ;
if(Seek(AH_File,VL_Offset2,FILE_BEGIN)<0) return -1;
const bool CB_IsFalse = //////////////////////////////
(
::ReadFile
(
AH_File ,
VO_CStringBuff.mpc_Data ,
VL_Offset-VL_Offset2 ,
&VL_ReadCnt ,
lpOverlapped
)==FALSE || VL_Offset-VL_Offset2 != VL_ReadCnt
);
//////////////////////////////////////////////////////
if(CB_IsFalse) return -1;
VO_CStringBuff.mpc_Data
[VO_CStringBuff.ml_UseLen=VL_ReadCnt]=0;
if(AL_SearchLen>1) VO_CStringBuff(VO_CStringBack);
VL_InnerOffset=VO_CStringBuff.ml_UseLen-1;
while ( ( VL_FindedPos = VO_CStringBuff.FindPosFromEnd
( APC_Search, AL_SearchLen, VL_InnerOffset )
) >= 0
)
////////////////////////////////////////////////////////
{
if(++VL_SearchCnt>=AL_WantSearchCnt)
{ return VL_Offset2+VL_FindedPos; }
VO_CStringBack.Invalidate();
VO_CStringBack
(VO_CStringBuff.mpc_Data, AL_SearchLen-1);
VL_InnerOffset = VL_FindedPos ;
}/*
while ( ( VL_FindedPos = VO_CStringBuff.FindPosFromEnd
( APC_Search, AL_SearchLen, VL_InnerOffset )
) >= 0
)
//////////////////////////////////////////////////////*/
VL_Offset=VL_Offset2 ;
}/*
while(VL_Offset>0)*/
return -1; // 이때는 못 찾은 것이다
}/*
static TypeLength SearchFileOffsetBackward( //////////////////////
HANDLE AH_File ,
TypeCharC* APC_Search ,
TypeLength AL_SearchLen ,
TypeLength AL_WantSearchCnt=1 ,
LPOVERLAPPED lpOverlapped =NULL
///////////// ) ///////////////////////////////////////////////*/
#endif // _WIN
bool LoadFilePart(
TypeCharC* APC_FileName, TypeLength AL_LoadSize, TypeLength AL_Offset=0)
{
#ifndef _WIN
int AH_FileDesc =
::open(APC_FileName, ZNsConst::ZNsLlioMode::Read);
if(AH_FileDesc==-1) return false;
TypeLength VL_TempOffset=::lseek(
AH_FileDesc, AL_Offset, SEEK_SET); // 실패시 -1
if(VL_TempOffset==-1) return false;
bool VB_Return=ReadFile(AH_FileDesc, AL_LoadSize);
::close(AH_FileDesc); return VB_Return;
#else //!defined(_WIN)
HANDLE VH_File = ::CreateFile /////////////////
(
APC_FileName ,
GENERIC_READ ,
FILE_SHARE_READ ,/* 공유모드: 이미 열려 있는 파일을 열 수 있게 한다. */
NULL ,
OPEN_EXISTING ,
FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_READONLY,
NULL
);
if(INVALID_HANDLE_VALUE==VH_File) return false;
::SetFilePointer(
VH_File, AL_Offset, NULL, FILE_BEGIN);
bool VB_Return=ReadFile(VH_File, AL_LoadSize);
::CloseHandle(VH_File); return VB_Return;
#endif //!defined(_WIN)
}/*
bool LoadFilePart(
TypeCharC* APC_FileName, TypeLength AL_LoadSize, TypeLength AL_Offset=0)*/
TypeLength ReadFile(int AH_FileDesc, TypeLength AL_ReadByte)
{
TypeLength VL_PrevLen = ml_UseLen ;
TypeLength VL_ReadCnt = 0 ;
ReAllocKeep(VL_PrevLen+AL_ReadByte);
VL_ReadCnt = ::read(
AH_FileDesc, mpc_Data+VL_PrevLen, AL_ReadByte);
if(VL_ReadCnt>0)
mpc_Data[ml_UseLen=VL_PrevLen+VL_ReadCnt]=0;
else mpc_Data[ml_UseLen=VL_PrevLen ]=0;
return VL_ReadCnt;
}/*
TypeLength ReadFile(int AH_FileDesc, TypeLength AL_ReadByte)*/
TypeLength ReadFile(FILE* AP_HFile, TypeLength AL_ReadByte)
{
TypeLength VL_PrevLen = ml_UseLen ;
TypeLength VL_ReadCnt = 0 ;
ReAllocKeep(VL_PrevLen+AL_ReadByte);
VL_ReadCnt = ::fread(
mpc_Data+VL_PrevLen, sizeof(TypeChar), AL_ReadByte, AP_HFile);
if(VL_ReadCnt>0)
mpc_Data[ml_UseLen=VL_PrevLen+VL_ReadCnt]=0;
else mpc_Data[ml_UseLen=VL_PrevLen ]=0;
return VL_ReadCnt;
}/*
TypeLength ReadFile(FILE* AP_HFile, TypeLength AL_ReadByte)*/
/* ReadFileSearch() 함수는 한 문자씩 ZCStringBase object 에 더하고 있으므로
메모리 할당이 빈번히 일어나지 않도록 충분한 메모리를 미리 잡아두는 것이 중요하다. */
TypeLength ReadFileSearch /*##########################*/
(
int AH_FileDesc , TypeCharC* APC_Search,
TypeLength AL_SearchLen, TypeLength AL_SearchCnt
)
/*####################################################*/
{
if(AL_SearchLen<1 || AL_SearchCnt<1) return 0;
TypeLength VL_ReadSize ;
TypeLength VL_AllReadSize=0;
TypeLength VL_SearchIndex=0;
TypeLength i ;
TypeLength VL_NowSearchCnt=0 ;
TypeChar VC_TempChar ;
TypeChar VCA_FileBuff[BUFSIZ+1];
while((VL_ReadSize=::read(AH_FileDesc, VCA_FileBuff, BUFSIZ))>0)
{
for(i=0; i<VL_ReadSize; ++i)
{
VC_TempChar=VCA_FileBuff[i]; (*this)(VC_TempChar);
if(VC_TempChar!=APC_Search[VL_SearchIndex])
{ VL_SearchIndex=0; continue; }
if(++VL_SearchIndex>=AL_SearchLen)
{
// 해당하는 문자열을 찾았다면...
if(++VL_NowSearchCnt>=AL_SearchCnt)
{ return VL_AllReadSize+i+1; }
VL_SearchIndex=0;
}/*
if(++VL_SearchIndex>=AL_SearchLen)*/
}/*
for(i=0; i<VL_ReadSize; ++i)*/
VL_AllReadSize += VL_ReadSize ;
}/*
while((VL_ReadSize=read(AH_FileDesc, VCA_FileBuff, BUFSIZ))>0)*/
return 0;
}/*
TypeLength ReadFileSearch ##############################
(
int AH_FileDesc , TypeCharC* APC_Search,
TypeLength AL_SearchLen, TypeLength AL_SearchCnt
)
######################################################*/
TypeLength ReadFileSearch /*##########################*/
(
FILE* AP_HFile , TypeCharC* APC_Search,
TypeLength AL_SearchLen, TypeLength AL_SearchCnt
)
/*####################################################*/
{
if(AL_SearchLen<1 || AL_SearchCnt<1) return 0;
TypeLength VL_ReadSize ;
TypeLength VL_AllReadSize=0;
TypeLength VL_SearchIndex=0;
TypeLength i ;
TypeLength VL_NowSearchCnt=0;
TypeChar VC_TempChar;
TypeChar VCA_FileBuff[BUFSIZ+1];
while((VL_ReadSize=::fread(
VCA_FileBuff, sizeof(TypeChar), BUFSIZ, AP_HFile))>0)
{
for(i=0; i<VL_ReadSize; ++i)
{
VC_TempChar=VCA_FileBuff[i]; (*this)(VC_TempChar);
if(VC_TempChar!=APC_Search[VL_SearchIndex])
{ VL_SearchIndex=0; continue; }
if(++VL_SearchIndex>=AL_SearchLen)
{
// 해당하는 문자열을 찾았다면...
if(++VL_NowSearchCnt>=AL_SearchCnt)
{ return VL_AllReadSize+i+1; }
VL_SearchIndex=0;
}/*
if(++VL_SearchIndex>=AL_SearchLen)*/
}/*
for(i=0; i<VL_ReadSize; ++i)*/
VL_AllReadSize += VL_ReadSize ;
}/*
while((VL_ReadSize=fread(
VCA_FileBuff, sizeof(TypeChar), BUFSIZ, AP_HFile))>0)*/
return 0;
}/*
TypeLength ReadFileSearch ##############################
(
FILE* AP_HFile , TypeCharC* APC_Search,
TypeLength AL_SearchLen, TypeLength AL_SearchCnt
)
######################################################*/
TypeLength ReadFileSearch
(
TypeCharC* APC_FileName, TypeCharC* APC_Search,
TypeLength AL_SearchLen, TypeLength AL_SearchCnt
)
/*#####################*/
{
#ifdef _WIN
#define MyCloseFleHandle CloseHandle
HANDLE AH_FileDesc=::CreateFile
(
APC_FileName, GENERIC_READ , FILE_SHARE_READ ,
NULL , OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL
);
///////////////////////////////
if(AH_FileDesc==INVALID_HANDLE_VALUE) return -1;
#else
#define MyCloseFleHandle close
int AH_FileDesc=::open(
APC_FileName, ZNsConst::ZNsLlioMode::Read);
if(AH_FileDesc==-1) return -1;
#endif
TypeLength VL_ReadSize=ReadFileSearch(
AH_FileDesc, APC_Search, AL_SearchLen, AL_SearchCnt);
MyCloseFleHandle(AH_FileDesc);
return VL_ReadSize; //////////
#undef MyCloseFleHandle
}/*
TypeLength ReadFileSearch
(
TypeCharC* APC_FileName, TypeCharC* APC_Search,
TypeLength AL_SearchLen, TypeLength AL_SearchCnt
)
#######################*/
#ifdef _WIN
TypeLength ReadFile(
HANDLE AH_FileHandle, TypeLength AL_ReadByte, LPOVERLAPPED lpOverlaped=NULL)
{
/*//////////////////////////////////////////////////////////////////
ReadFile( HANDLE AH_File,
LPVOID lpBuffer,
DWORD nNumberOfBytesToRead,
LPDWORD lpNumberOfBytesRead,
LPOVERLAPPED lpOverlaped // 비동기 입출력이 아니면 NULL
////// )
//////////////////////////////////////////////////////////////////*/
TypeLength VL_PrevLen=ml_UseLen;
DWORD VL_ReadCnt=0 ;
ReAllocKeep(VL_PrevLen+AL_ReadByte);
const BOOL VB_IsOK = ::ReadFile
(
AH_FileHandle, (TypeChar*)(mpc_Data)+VL_PrevLen,
AL_ReadByte , &VL_ReadCnt, lpOverlaped
);
///////////////////////////////
if(VB_IsOK==FALSE)
{
CorrectLength(VL_PrevLen); return -1;
}/*
if(VB_IsOK==FALSE)*/
if(VL_ReadCnt>0)
mpc_Data[ml_UseLen=VL_PrevLen+VL_ReadCnt]=0;
else mpc_Data[ml_UseLen=VL_PrevLen ]=0;
return VL_ReadCnt;
}/*
TypeLength ReadFile(
HANDLE AH_FileHandle, TypeLength AL_ReadByte, LPOVERLAPPED lpOverlaped=NULL)*/
TypeLength ReadFileSearch( ///////////////////////////////////////
HANDLE AH_FileHandle ,
TypeCharC* APC_Search ,
TypeLength AL_SearchLen ,
TypeLength AL_SearchCnt ,
LPOVERLAPPED lpOverlapped=NULL
/*/////////*/ ) ///////////////////////////////////////////////*/
{
if(AL_SearchLen<1 || AL_SearchCnt<1) return 0;
DWORD VL_ReadSize ;
TypeLength VL_AllReadSize =0;
TypeLength VL_SearchIndex =0;
TypeLength VL_NowSearchCnt=0;
TypeLength i ;
TypeChar VC_TempChar ;
TypeChar VCA_FileBuff[BUFSIZ+1];
while ( ::ReadFile /////////////////////////////////////////////
(
AH_FileHandle, (TypeChar*)VCA_FileBuff,
BUFSIZ , &VL_ReadSize , lpOverlapped
)==TRUE && VL_ReadSize > 0
)
////////////////////////////////////////////////////////////////
{
for(i=0; i<VL_ReadSize; ++i)
{
VC_TempChar=VCA_FileBuff[i]; (*this)(VC_TempChar);
if(VC_TempChar!=APC_Search[VL_SearchIndex])
{ VL_SearchIndex=0; continue; }
if(++VL_SearchIndex>=AL_SearchLen)
{
// 해당하는 문자열을 찾았다면...
if(++VL_NowSearchCnt>=AL_SearchCnt)
{ return VL_AllReadSize+i+1; }
VL_SearchIndex=0;
}/*
if(++VL_SearchIndex>=AL_SearchLen)*/
}/*
for(i=0;i<VL_ReadSize;++i)*/
VL_AllReadSize += VL_ReadSize ;
}/*
while ( ::ReadFile /////////////////////////////////////////////
(
AH_FileHandle, (TypeChar*)VCA_FileBuff,
BUFSIZ , &VL_ReadSize , lpOverlapped
)==TRUE && VL_ReadSize > 0
)
//////////////////////////////////////////////////////////////*/
return 0;
}/*
TypeLength ReadFileSearch( ///////////////////////////////////////
HANDLE AH_FileHandle ,
TypeCharC* APC_Search ,
TypeLength AL_SearchLen ,
TypeLength AL_SearchCnt ,
LPOVERLAPPED lpOverlapped=NULL
///////////// ) ///////////////////////////////////////////////*/
bool WriteFile(HANDLE AH_FileHandle) const
{
if(ml_UseLen<1) return true;
/*//////////////////////////////////////////////////////////////////
WriteFile( HANDLE hFile,
LPCVOID lpBuffer,
DWORD nNumberOfBytesToWrite,
LPDWORD lpNumberOfBytesWritten,
LPOVERLAPPED lpOverlapped // 비동기 입출력이 아니면 NULL
/////// )
//////////////////////////////////////////////////////////////////*/
DWORD VDW_WriteCnt=0;
return ::WriteFile( ////////////////
AH_FileHandle,
mpc_Data ,
ml_UseLen ,
&VDW_WriteCnt,
NULL
/*/////////*/ )==TRUE; /////////////
}/*
bool WriteFile(HANDLE AH_FileHandle) const*/
#endif // _WIN
bool WriteFile(int AH_FileDesc) const
{
if(ml_UseLen<1) return true; TypeLength VUL_AllSize=ml_UseLen;
return ::write(
AH_FileDesc, mpc_Data, VUL_AllSize)>=VUL_AllSize ;
}/*
bool WriteFile(int AH_FileDesc) const*/
bool WriteFile(FILE* AP_HFile) const
{
if(ml_UseLen<1) return true; TypeLength VUL_AllSize=ml_UseLen;
return ::fwrite(
mpc_Data, sizeof(TypeChar), ml_UseLen, AP_HFile)>=VUL_AllSize;
}/*
bool WriteFile(FILE* AP_HFile) const*/
bool WriteFile(TypeCharC* APC_FileName, bool AB_DoAppend=true, int AI_RightMode=-1) const
{
// int AI_RightMode 은 리눅스에서만 쓴다.
#ifdef _WIN
HANDLE VH_File=::CreateFile
(
APC_FileName, GENERIC_WRITE, FILE_SHARE_WRITE ,
NULL , OPEN_ALWAYS , FILE_ATTRIBUTE_NORMAL, NULL
);
///////////////////////////
if(VH_File==INVALID_HANDLE_VALUE) return false;
if(AB_DoAppend==true)
::SetFilePointer(VH_File, 0, NULL, FILE_END); // 덧붙이는 경우라면 파일포인터를 맨 끝으로 옮긴다.
else
::SetEndOfFile(VH_File) ; // 덧붙이는 경우가 아니면, 기존 내용을 지운다.
//else
DWORD NumberOfBytesWritten = 0 ; const BOOL CB_IsWriteOK =
::WriteFile(VH_File, mpc_Data, ml_UseLen, &NumberOfBytesWritten, NULL);
if(CB_IsWriteOK==FALSE)
{
::CloseHandle(VH_File); return false;
}/*
if(CB_IsWriteOK==FALSE)*/
return ::CloseHandle(VH_File)==TRUE ;
#else // !defined(_WIN)
// 리눅스의 경우
TypeLength VUL_AllSize=ml_UseLen; if(VUL_AllSize<1) return true;
int AH_FileDesc ;
const int CI_FileOpenErr = -1 ;
const int CI_FileOpenTag =
(AI_RightMode<0 ? S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP : AI_RightMode ) ;
if(AB_DoAppend==true)
{
if((AH_FileDesc = ::open( APC_FileName, ZNsConst::ZNsLlioMode::AppendMake , CI_FileOpenTag))==CI_FileOpenErr)
{ return false; }
}else{if((AH_FileDesc = ::open( APC_FileName, ZNsConst::ZNsLlioMode::WriteMakeCut, CI_FileOpenTag))==CI_FileOpenErr)
{ return false; }
}
if(write(AH_FileDesc, mpc_Data, VUL_AllSize)<VUL_AllSize)
{
::close(AH_FileDesc); return false;
}/*
if(write(AH_FileDesc, mpc_Data, VUL_AllSize)<VUL_AllSize)*/
return ::close(AH_FileDesc)==0 ;
#endif // !defined(_WIN)
}/*
bool WriteFile(TypeCharC* APC_FileName, bool AB_DoAppend=true, int AI_RightMode=-1) const*/
bool WriteFile(const ZCStringBase& AR_FileName, bool AB_DoAppend=true, int AI_RightMode=-1) const
{
return WriteFile(AR_FileName.data(), AB_DoAppend, AI_RightMode);
}/*
bool WriteFile(const ZCStringBase& AR_FileName, bool AB_DoAppend=true, int AI_RightMode=-1) const*/
bool WriteFile(TypeCharC* APC_FileName, EWriteFile AE_EWriteFile, int AI_RightMode=-1) const
{
return WriteFile(APC_FileName, AE_EWriteFile==EWriteFile_Append, AI_RightMode);
}/*
bool WriteFile(TypeCharC* APC_FileName, EWriteFile AE_EWriteFile, int AI_RightMode=-1) const*/
bool WriteFile(const ZCStringBase& AR_FileName, EWriteFile AE_EWriteFile, int AI_RightMode=-1) const
{
return WriteFile(AR_FileName, AE_EWriteFile==EWriteFile_Append, AI_RightMode);
}/*
bool WriteFile(const ZCStringBase& AR_FileName, EWriteFile AE_EWriteFile, int AI_RightMode=-1) const*/
static bool WriteFileRaw(
TypeCharC* APC_FileName, const TypeChar* APC_Content, TypeLength AL_ContentLen, bool AB_DoAppend=true, int AI_RightMode=-1)
{
return ZNsMain::ZfWriteFileRaw(APC_FileName, APC_Content, AL_ContentLen, AB_DoAppend, AI_RightMode);
}/*
static bool WriteFileRaw(
TypeCharC* APC_FileName, const TypeChar* APC_Content, TypeLength AL_ContentLen, bool AB_DoAppend=true, int AI_RightMode=-1)*/
static bool WriteFileRaw(
const ZCStringBase& rhs, const TypeChar* APC_Content, TypeLength AL_ContentLen, bool AB_DoAppend=true, int AI_RightMode=-1)
{
return WriteFileRaw(rhs.data(), APC_Content, AL_ContentLen, AB_DoAppend, AI_RightMode);
}/*
static bool ZfWriteFileRaw(
const ZCStringBase& rhs, const TypeChar* APC_Content, TypeLength AL_ContentLen, bool AB_DoAppend=true, int AI_RightMode=-1)*/
static bool WriteFileRaw(
const ZCStringBase& rhs, const ZCStringBase& AR_CStringBody, bool AB_DoAppend=true, int AI_RightMode=-1)
{
return WriteFileRaw(rhs.data(), AR_CStringBody.data(), AR_CStringBody.size(), AB_DoAppend, AI_RightMode);
}/*
static bool WriteFileRaw(
const ZCStringBase& rhs, const ZCStringBase& AR_CStringBody, bool AB_DoAppend=true, int AI_RightMode=-1)*/
static TypeLength FindPos( ///////////////////////////////////////
TypeCharC* APC_Origin ,
TypeCharC* APC_Search ,
TypeLength AL_OriginLen ,
TypeLength AL_SearchLen ,
TypeLength AL_StartPos=0
/*/////////*/ ) //////////////////////////////////////////////////
{
return ZCMainChars::FindPos( ////////
APC_Origin ,
APC_Search ,
AL_OriginLen,
AL_SearchLen,
AL_StartPos
/*/////////*/ ); ///////////////////
}/*
static TypeLength FindPos( ///////////////////////////////////////
TypeCharC* APC_Origin ,
TypeCharC* APC_Search ,
TypeLength AL_OriginLen ,
TypeLength AL_SearchLen ,
TypeLength AL_StartPos=0
///////////// ) ///////////////////////////////////////////////*/
static TypeLength FindPos( ///////////////////////////////////////
TypeCharC* APC_Origin ,
TypeCharC* APC_Search ,
TypeLength AL_StartPos=0
/*//////////*/ ) /////////////////////////////////////////////////
{
using ZNsMain::ZftGetLengthType ;
return FindPos ///////////////////////////////////////////////
(
APC_Origin ,
APC_Search ,
ZftGetLengthType<TypeLength, TypeChar>(APC_Origin),
ZftGetLengthType<TypeLength, TypeChar>(APC_Search),
AL_StartPos
);
//////////////////////////////////////////////////////////////
}/*
static TypeLength FindPos( ///////////////////////////////////////
TypeCharC* APC_Origin ,
TypeCharC* APC_Search ,
TypeLength AL_StartPos=0
///////////// ) ////////////////////////////////////////////////*/
TypeLength FindPos(
TypeCharC* APC_Search, TypeLength AL_SearchLen, TypeLength AL_StartPos=0) const
{
return FindPos(mpc_Data, APC_Search, ml_UseLen, AL_SearchLen, AL_StartPos) ;
}/*
TypeLength FindPos(
TypeCharC* APC_Search, TypeLength AL_SearchLen, TypeLength AL_StartPos=0) const*/
TypeLength FindPos(TypeCharC* APC_Search) const
{
return FindPos //////////////
(
mpc_Data , APC_Search,
ml_UseLen, ZNsMain::ZftGetLengthType
<TypeLength, TypeChar>(APC_Search)
);
/////////////////////////////
}/*
TypeLength FindPos(TypeCharC* APC_Search) const*/
TypeLength FindPos(const ZCStringBase& rhs, TypeLength AL_StartPos=0) const
{
return FindPos(mpc_Data, rhs.data(), ml_UseLen, rhs.size(), AL_StartPos) ;
}/*
TypeLength FindPos(const ZCStringBase& rhs, TypeLength AL_StartPos=0) const*/
TypeLength FindPosEsc /*###############################*/
(
TypeCharC* APC_Search , TypeCharC* APC_Escape ,
TypeLength AL_SearchLen, TypeLength AL_EscapeLen,
TypeLength AL_StartPos=0
) const
/*#####################################################*/
{
return ZCMainChars::FindPosEsc
(
mpc_Data , APC_Search , APC_Escape ,
ml_UseLen, AL_SearchLen, AL_EscapeLen, AL_StartPos
);
//////////////////////////////
}/*
TypeLength FindPosEsc
(
TypeCharC* APC_Search , TypeCharC* APC_Escape ,
TypeLength AL_SearchLen, TypeLength AL_EscapeLen,
TypeLength AL_StartPos=0
) const
#######################################################*/
TypeLength FindPosEsc(
TypeCharC* APC_Search, TypeCharC* APC_Escape, TypeLength AL_StartPos=0) const
{
using ZNsMain::ZftGetLengthType ;
return ZCMainChars::FindPosEsc
(
mpc_Data, APC_Search , APC_Escape, ml_UseLen,
ZftGetLengthType<TypeLength, TypeChar>(APC_Search),
ZftGetLengthType<TypeLength, TypeChar>(APC_Escape), AL_StartPos
);
//////////////////////////////
}/*
TypeLength FindPosEsc(
TypeCharC* APC_Search, TypeCharC* APC_Escape, TypeLength AL_StartPos=0) const*/
static TypeLength FindPosFromEnd( ////////////////////////////////
TypeCharC* APC_Origin ,
TypeCharC* APC_Search ,
TypeLength AL_OriginLen,
TypeLength AL_SearchLen
/*/////////*/ ) //////////////////////////////////////////////////
{
// APC_Origin 문자열에서 APC_Search 을 AL_StartPos 번째 부터 역방향으로 접근해서 찾는다.
if(AL_OriginLen<1 || AL_SearchLen<1)
{ return -1; }
TypeLength i=AL_OriginLen-AL_SearchLen;
while(i>=0)
{
TypeLength j=0;
for(; j<AL_SearchLen; ++j)
{ if(APC_Origin[i+j]!=APC_Search[j]) break; }
if(j==AL_SearchLen) return i; --i;
}/*
while(i>=0)*/
return -1;
}/*
static TypeLength FindPosFromEnd( ////////////////////////////////
TypeCharC* APC_Origin ,
TypeCharC* APC_Search ,
TypeLength AL_OriginLen,
TypeLength AL_SearchLen
//////////// ) ////////////////////////////////////////////////*/
TypeLength FindPosFromEnd(TypeCharC* APC_Search, TypeLength AL_SearchLen, TypeLength AL_StartPos) const
{
// AL_StartPos 는 0 부터 시작
if(AL_StartPos>=ml_UseLen) AL_StartPos=ml_UseLen-1; /*##################*/
return FindPosFromEnd(mpc_Data, APC_Search, AL_StartPos+1, AL_SearchLen) ;
}/*
TypeLength FindPosFromEnd(TypeCharC* APC_Search, TypeLength AL_SearchLen, TypeLength AL_StartPos) const*/
TypeLength FindPosFromEnd(TypeCharC* APC_Search,TypeLength AL_SearchLen) const
{
return FindPosFromEnd(mpc_Data, APC_Search, ml_UseLen, AL_SearchLen) ;
}/*
TypeLength FindPosFromEnd(TypeCharC* APC_Search,TypeLength AL_SearchLen) const*/
TypeLength FindPosFromEnd(TypeCharC* APC_Search) const
{
return FindPosFromEnd
(
mpc_Data, APC_Search, ml_UseLen,
ZNsMain::ZftGetLengthType
<TypeLength, TypeChar>(APC_Search)
) ;
/////////////////////
}/*
TypeLength FindPosFromEnd(TypeCharC* APC_Search) const*/
template<typename TList> static TypeLength FindPosType( /*######*/
TypeCharC* APC_Origin ,
TList& AR_SearchList,
TypeLength AL_OriginLen ,
TypeLength& ARRL_MatchLen,
TypeLength AL_StartPos=0
/*#########*/ ) /*##############################################*/
{
/*////////////////////////////////////////////////////////////////////
■ TList 는 *this 의 container 이어야 한다.
■ APC_Origin 에서 AR_SearchList 의 각 원소를 찾는다. 존재하는 원소가
있다며 그 원소의 인덱스 번호를 리턴한다.
인덱스 번호는 0 부터 시작한다. (유효하지 않으면 -1)
만약 찾았다면 AR_SearchList 의 어느 원소를 찾았는지를 알 수 없으므
로 찾은 길이 정보를 ARRL_MatchLen 에 전달한다.
////////////////////////////////////////////////////////////////////*/
const bool CB_IsBad = (
AL_OriginLen<1 || AL_StartPos>=AL_OriginLen || AR_SearchList.size()<1 );
if(CB_IsBad) return -1; TypeLength VL_SearchCnt=AR_SearchList.size();
for(TypeLength i=AL_StartPos; i<AL_OriginLen; ++i)
{
IterEasyID VI_IterEasyID(AR_SearchList.GetHeadIterEasyID());
for(TypeLength j=0; j<VL_SearchCnt; ++j)
{
const bool CB_IsOK = DoStart
(
APC_Origin +i, AR_SearchList.ItD(VI_IterEasyID).data(),
AL_OriginLen-i, AR_SearchList.ItD(VI_IterEasyID).size()
);
////////////////////////////
if(CB_IsOK)
{
ARRL_MatchLen=AR_SearchList.ItD(VI_IterEasyID).size(); return i;
}/*
if(CB_IsOK)*/
AR_SearchList.MoveNextIter(VI_IterEasyID);
}/*
for(TypeLength j=0; j<VL_SearchCnt; ++j)*/
}/*
for(TypeLength i=AL_StartPos; i<AL_OriginLen; ++i)*/
return -1;
}/*
template<typename TList> static TypeLength FindPosType( ##########
TypeCharC* APC_Origin ,
TList& AR_SearchList,
TypeLength AL_OriginLen ,
TypeLength& ARRL_MatchLen,
TypeLength AL_StartPos=0
########### ) ################################################*/
template<typename TList> static TypeLength FindPosType( /*######*/
TypeCharC* APC_Origin ,
TList& AR_SearchList,
TypeLength& ARRL_MatchLen
/*#########*/ ) /*##############################################*/
{
return FindPosType
(
APC_Origin, AR_SearchList,
ZNsMain::ZftGetLengthType
<TypeLength, TypeChar>(APC_Origin),
ARRL_MatchLen
);
//////////////////
}/*
template<typename TList> static TypeLength FindPosType( ##########
TypeCharC* APC_Origin ,
TList& AR_SearchList,
TypeLength& ARRL_MatchLen
############ ) ################################################*/
template<typename TList> static TypeLength
FindPosType(TypeCharC* APC_Origin, TList& AR_SearchList)
{
using ZNsMain::ZftGetLengthType ;
TypeLength VL_MatchLen=0; return FindPosType( /*##########################*/
APC_Origin ,
AR_SearchList ,
ZftGetLengthType<TypeLength, TypeChar>(APC_Origin),
RR(VL_MatchLen)
/*########*/ ); /*########################################################*/
}/*
template<typename TList> static TypeLength
FindPosType(TypeCharC* APC_Origin, TList& AR_SearchList) */
/*/////////////////////////////////////////////////////////////////////////////////////////
■ 어떤 원본문자열의 끝에서 찾으려는 문자열이 몇 개의 문자나 일치하는지 그 갯수를 가져온다.
예를 들어 원본 문자열이 "@ABCDE" 이고 찾는 문자열이 "DEFGH" 라면 "DE" 의 문자열 길이 2
를 반환한다.
/////////////////////////////////////////////////////////////////////////////////////////*/
TypeLength GetMatchLenFromEnd(TypeCharC* APC_Search, TypeLength AL_SearchLen)
{
return ZCMainChars::GetMatchLenFromEnd(
mpc_Data, APC_Search, ml_UseLen, AL_SearchLen);
}/*
TypeLength GetMatchLenFromEnd(TypeCharC* APC_Search, TypeLength AL_SearchLen)*/
static TypeLength GetFindCnt /*#######################*/
(
TypeCharC* APC_Origin , TypeCharC* APC_Search,
TypeLength AL_OriginLen, TypeLength AL_SearchLen
)
/*####################################################*/
{
const bool CB_IsBad = (
AL_OriginLen<1 || AL_SearchLen<1 || AL_OriginLen<AL_SearchLen );
if(CB_IsBad) return 0; /*/////////////////////////////////////////*/
TypeLength VL_SearchOffset=0;
TypeLength VL_SearchCount =0;
for(TypeLength i=0; i<AL_OriginLen; ++i)
{
if(APC_Origin[i]==APC_Search[VL_SearchOffset])
{
if(++VL_SearchOffset==AL_SearchLen)
{++VL_SearchCount; VL_SearchOffset=0;}
}
else {VL_SearchOffset=0;}
}/*
for(TypeLength i=0; i<AL_OriginLen; ++i)*/
return VL_SearchCount;
}/*
static TypeLength GetFindCnt ###########################
(
TypeCharC* APC_Origin , TypeCharC* APC_Search,
TypeLength AL_OriginLen, TypeLength AL_SearchLen
)
######################################################*/
TypeLength GetFindCnt(TypeCharC* APC_Search, TypeLength AL_SearchLen)
{
return GetFindCnt(mpc_Data, APC_Search, ml_UseLen, AL_SearchLen);
}/*
TypeLength GetFindCnt(TypeCharC* APC_Search, TypeLength AL_SearchLen)*/
TypeLength GetFindCnt(TypeCharC* APC_Search)
{
return GetFindCnt(APC_Search, ZNsMain::ZftGetLengthType<TypeLength, TypeChar>(APC_Search));
}/*
TypeLength GetFindCnt(TypeCharC* APC_Search)*/
TypeLength GetFindCnt(const ZCStringBase& rhs)
{
return GetFindCnt(rhs.data(), rhs.size());
}/*
TypeLength GetFindCnt(const ZCStringBase& rhs)*/
static bool DoHave(
TypeCharC* APC_Origin, TypeCharC* APC_FindChars, TypeLength AL_OriginLen, TypeLength AL_FindLen, TypeLength AL_StartPos=0)
{
return FindPos(APC_Origin, APC_FindChars, AL_OriginLen, AL_FindLen, AL_StartPos)>=0;
}/*
static bool DoHave(
TypeCharC* APC_Origin, TypeCharC* APC_FindChars, TypeLength AL_OriginLen, TypeLength AL_FindLen, TypeLength AL_StartPos=0)*/
static bool DoHave(TypeCharC* APC_Origin, TypeCharC* APC_FindChars, TypeLength AL_StartPos=0)
{
return FindPos(APC_Origin, APC_FindChars, AL_StartPos)>=0;
}/*
static bool DoHave(TypeCharC* APC_Origin, TypeCharC* APC_FindChars, TypeLength AL_StartPos=0)*/
bool DoHave(TypeCharC* APC_FindChars, TypeLength AL_FindLen, TypeLength AL_StartPos=0) const
{
if(size()<1 || AL_FindLen<1) return false;
return FindPos(APC_FindChars, AL_FindLen, AL_StartPos)>=0 ;
}/*
bool DoHave(TypeCharC* APC_FindChars, TypeLength AL_FindLen, TypeLength AL_StartPos=0) const*/
bool DoHave(TypeCharC* APC_FindChars) const
{
return DoHave(APC_FindChars, ZNsMain::ZftGetLengthType<TypeLength, TypeChar>(APC_FindChars));
}/*
bool DoHave(TypeCharC* APC_FindChars) const*/
bool DoHave(const ZCStringBase& rhs, TypeLength AL_StartPos=0) const
{
return DoHave(rhs.data(), rhs.size(), AL_StartPos);
}/*
bool DoHave(const ZCStringBase& rhs, TypeLength AL_StartPos=0) const*/
static bool IsDigit(TypeChar AC_Char)
{
return AC_Char>='0' && AC_Char<='9' ;
}/*
static bool IsDigit(TypeChar AC_Char)*/
static bool IsDigit(TypeCharC* APC_CheckChar, TypeLength AL_CheckLen)
{
// APC_CheckChar 이 모두 숫자형인가. 소수도 숫자형으로 간주한다.
if(AL_CheckLen<1 || APC_CheckChar[0]=='.') return false;
TypeChar VC_CharTemp; bool VB_DoHavePeriod=false;
for(TypeLength i=0; i<AL_CheckLen; ++i)
{
if((VC_CharTemp=APC_CheckChar[i])=='.')
{
if(i==AL_CheckLen-1) return false;
if(VB_DoHavePeriod) return false;
VB_DoHavePeriod=true; /*#######*/
}
else if(VC_CharTemp<'0' || VC_CharTemp>'9')
{
return false;
}/*
else if(VC_CharTemp<'0' || VC_CharTemp>'9')*/
}/*
for(TypeLength i=0; i<AL_CheckLen; ++i)*/
return true;
}/*
static bool IsDigit(TypeCharC* APC_CheckChar, TypeLength AL_CheckLen)*/
static bool IsDigit(TypeCharC* APC_CheckChar)
{
using ZNsMain::ZftGetLengthType ;
return IsDigit
(
APC_CheckChar, ZftGetLengthType
<TypeLength, TypeChar>(APC_CheckChar)
);
//////////////
}/*
static bool IsDigit(TypeCharC* APC_CheckChar)*/
bool IsDigit() const
{
return IsDigit(mpc_Data, ml_UseLen);
}/*
bool IsDigit() const*/
static bool DoStart
(
TypeCharC* APC_Origin , TypeCharC* APC_FindChars,
TypeLength AL_OriginLen, TypeLength AL_FindLen
)
/*###############*/
{
// mpc_Data 문자열이 APC_FindChars 로 시작하면 true;
if(AL_OriginLen<1 || AL_FindLen<1 || AL_OriginLen<AL_FindLen)
{ return false; }
return ZCMainChars::Minus(
APC_Origin, APC_FindChars, AL_FindLen, AL_FindLen)==0 ;
}/*
static bool DoStart
(
TypeCharC* APC_Origin , TypeCharC* APC_FindChars,
TypeLength AL_OriginLen, TypeLength AL_FindLen
)
/////////////////*/
static bool DoStart(TypeCharC* APC_Origin, TypeCharC* APC_FindChars)
{
// mpc_Data 문자열이 APC_FindChars 로 시작하면 true;
using ZNsMain::ZftGetLengthType ;
return DoStart( APC_Origin , /////////////////////////////////////
APC_FindChars ,
ZftGetLengthType<TypeLength, TypeChar>(APC_Origin) ,
ZftGetLengthType<TypeLength, TypeChar>(APC_FindChars)
/*/////////*/ );
}/*
static bool DoStart(TypeCharC* APC_Origin, TypeCharC* APC_FindChars)*/
bool DoStart(TypeCharC* APC_FindChars, TypeLength AL_FindLen) const
{
// mpc_Data 문자열이 APC_FindChars 로 시작하면 true;
if(ml_UseLen<1 || AL_FindLen<1 || ml_UseLen<AL_FindLen) return false;
return ZCMainChars::Minus(mpc_Data, APC_FindChars, AL_FindLen, AL_FindLen)==0 ;
}/*
bool DoStart(TypeCharC* APC_FindChars, TypeLength AL_FindLen) const*/
/* 아래 멤버함수가 없으면 컴파일러에 따라서, DoStart() 의 2 번 인수가
TypeLength 이 아니면, TypeLength 으로 형변환을 해주어야 하는 경우가 있다. */
bool DoStart(TypeCharC* APC_FindChars, int AI_FindLen) const
{
return DoStart(APC_FindChars, (TypeLength)AI_FindLen);
}/*
bool DoStart(TypeCharC* APC_FindChars, int AI_FindLen) const*/
bool DoStart(TypeCharC* APC_FindChars) const
{
return DoStart
(
APC_FindChars, ZNsMain::ZftGetLengthType
<TypeLength, TypeChar>(APC_FindChars)
);
//////////////
}/*
bool DoStart(TypeCharC* APC_FindChars) const*/
bool DoStart(const ZCStringBase& rhs) const
{
return this->DoStart(rhs.data(), rhs.size());
}/*
bool DoStart(const ZCStringBase& rhs) const*/
bool DoClose(TypeCharC* APC_FindChars, TypeLength AL_FindLen) const
{
return ZCMainChars::DoClose(mpc_Data, APC_FindChars, ml_UseLen, AL_FindLen);
}/*
bool DoClose(TypeCharC* APC_FindChars, TypeLength AL_FindLen) const*/
bool DoClose(TypeCharC* APC_FindChars) const
{
return ZCMainChars::DoClose
(
mpc_Data, APC_FindChars, ml_UseLen,
ZNsMain::ZftGetLengthType
<TypeLength, TypeChar>(APC_FindChars)
);
///////////////////////////
}/*
bool DoClose(TypeCharC* APC_FindChars) const*/
bool DoClose(const ZCStringBase& rhs) const
{
return ZCMainChars::DoClose(mpc_Data, rhs.mpc_Data, ml_UseLen, rhs.ml_UseLen);
}/*
bool DoClose(const ZCStringBase& rhs) const*/
bool DoWrap(TypeCharC* APC_FindChars, TypeLength AL_FindLen) const
{
return ZCMainChars::DoWrap(mpc_Data, APC_FindChars, ml_UseLen, AL_FindLen);
}/*
bool DoWrap(TypeCharC* APC_FindChars, TypeLength AL_FindLen) const*/
bool DoWrap(TypeCharC* APC_FindChars) const
{
return ZCMainChars::DoWrap
(
mpc_Data, APC_FindChars, ml_UseLen,
ZNsMain::ZftGetLengthType
<TypeLength, TypeChar>(APC_FindChars)
);
//////////////////////////
}/*
bool DoWrap(TypeCharC* APC_FindChars) const*/
bool DoWrap(const ZCStringBase& rhs) const
{
return ZCMainChars::DoWrap(mpc_Data, rhs.data(), ml_UseLen, rhs.size());
}/*
bool DoWrap(const ZCStringBase& rhs) const*/
ZCStringBase& MoveFirst(TypeLength AL_StartPos)
{
if(AL_StartPos>=ml_UseLen && ml_UseLen>0)
{
mpc_Data[ml_UseLen=0]=0;
}
else if(AL_StartPos<ml_UseLen && AL_StartPos>0)
{
TypeLength VL_Index=0;
for(TypeLength i=AL_StartPos; i<ml_UseLen; ++i)
{ mpc_Data[VL_Index++]=mpc_Data[i]; }
mpc_Data[VL_Index++]=0; ml_UseLen -= AL_StartPos ;
}/*
else if(AL_StartPos<ml_UseLen && AL_StartPos>0)*/
return *this;
}/*
ZCStringBase& MoveFirst(TypeLength AL_StartPos)*/
ZCStringBase& MoveRight(TypeLength AL_RightMoveCnt, TypeChar AC_FillChar=' ')
{
/* 문자열을 오른쪽으로 AL_RightMoveCnt 만큼 옮긴다.
왼쪽에 비어있게 되는 문자열은 각각을 AC_FillChar 로 채운다. */
if(AL_RightMoveCnt<1) return *this;
if(ml_UseLen <1)
{ resize(AL_RightMoveCnt, AC_FillChar); return *this; }
/////////////////////
ReAllocKeep(ml_UseLen+AL_RightMoveCnt);
TypeChar* VPC_CharOrgin=mpc_Data+ml_UseLen-1 ;
TypeChar* VPC_CharDest =mpc_Data+ml_UseLen+AL_RightMoveCnt-1;
TypeLength i=1;
for(; i<=ml_UseLen; ++i)
{
*VPC_CharDest-- = *VPC_CharOrgin-- ;
}/*
for(; i<=ml_UseLen; ++i)*/
/* 오른쪽으로 문자열을 이동시키게 됨에 따라, 앞에서
비게 되는 문자열을 AC_FillChar 로 채운다. */
VPC_CharOrgin=mpc_Data;
for(i=1; i<=AL_RightMoveCnt; ++i)
{
*VPC_CharOrgin++ = AC_FillChar ;
}/*
for(i=1; i<=AL_RightMoveCnt; ++i)*/
mpc_Data[ml_UseLen+=AL_RightMoveCnt]=0; return *this;
}/*
ZCStringBase& MoveRight(TypeLength AL_RightMoveCnt, TypeChar AC_FillChar=' ')*/
ZCStringBase& PadLeft(TypeLength AL_NewSize, TypeChar AC_FillChar=' ')
{
if(AL_NewSize<=ml_UseLen) return Invalidate(AL_NewSize);
return MoveRight(AL_NewSize-ml_UseLen, AC_FillChar);
}/*
ZCStringBase& PadLeft(TypeLength AL_NewSize, TypeChar AC_FillChar=' ')*/
ZCStringBase& PadRight(TypeLength AL_NewSize, TypeChar AC_FillChar=' ')
{
if(AL_NewSize<=ml_UseLen)
{ return Invalidate(AL_NewSize); }
this->ReAllocKeep(AL_NewSize);
TypeLength VUL_FillCnt=AL_NewSize-this->size();
return this->append(AC_FillChar, VUL_FillCnt);
}/*
ZCStringBase& PadRight(TypeLength AL_NewSize, TypeChar AC_FillChar=' ')*/
ZCStringBase& Rotate(int AI_RotateSize)
{
if(ml_UseLen<1) return *this;
/* AI_RotateSize 이 음수이면(왼쪽 이동이면)
양수로 바꾸어준다. (오른쪽 이동으로 바꾸어 준다) */
if(AI_RotateSize>=ml_UseLen)
{
AI_RotateSize%=ml_UseLen;
}
else if(AI_RotateSize<0 && -AI_RotateSize>=ml_UseLen)
{
AI_RotateSize%=ml_UseLen-(-AI_RotateSize)%ml_UseLen;
}/*
else if(AI_RotateSize<0 && -AI_RotateSize>=ml_UseLen)*/
if(AI_RotateSize==0) return *this;
if(AI_RotateSize>(ml_UseLen/2))
{
// 왼쪽으로 이동하는 것이 더 빠를 경우
TypeLength VL_MoveSize =ml_UseLen-AI_RotateSize ;
TypeChar* VPC_HeadBuff=new TypeChar[VL_MoveSize];
::memcpy (VPC_HeadBuff, mpc_Data, VL_MoveSize );
::memmove(mpc_Data, mpc_Data+VL_MoveSize,AI_RotateSize);
::memcpy (mpc_Data+AI_RotateSize, VPC_HeadBuff, VL_MoveSize );
return *this;
}/*
if(AI_RotateSize>(ml_UseLen/2))*/
// 오른쪽으로 이동하는 것이 더 빠를 경우
TypeLength VL_Offset =ml_UseLen-AI_RotateSize ;
TypeChar* VPC_TailBuff=new TypeChar[AI_RotateSize];
::memcpy (VPC_TailBuff, mpc_Data+VL_Offset, AI_RotateSize );
::memmove(mpc_Data+AI_RotateSize, mpc_Data, VL_Offset );
::memcpy (mpc_Data, VPC_TailBuff, AI_RotateSize );
return *this;
}/*
ZCStringBase& Rotate(int AI_RotateSize)*/
ZCStringBase& Trim()
{
ZCMainChars::Trim(mpc_Data, RR(ml_UseLen));
if(mpc_Data!=0) mpc_Data[ml_UseLen]=0;
return *this; /*####################*/
}/*
ZCStringBase& Trim()*/
static TypeChar* TrimDecimalZero(TypeChar* APC_Data, TypeLength AI_LengthDec=-1)
{
/* 문자열 APC_Data 이 어떤 소수를 표현할 경우
소수점 뒤에 맨 끝에 있는 의미없는 0 을 지운다. */
TypeChar* VPC_StartChar=APC_Data;
if(AI_LengthDec<0)
{
AI_LengthDec = ZNsMain::
ZftGetLengthType<TypeLength, TypeChar>(APC_Data) ;
}/*
if(AI_LengthDec<0)*/
if(AI_LengthDec<1) return 0;
TypeLength VL_PeriodPos ;
TypeLength VL_CurrentPos;
for(VL_PeriodPos=0; VL_PeriodPos<AI_LengthDec; ++VL_PeriodPos)
{
if( *VPC_StartChar++ =='.' ) break;
}/*
for(VL_PeriodPos=0; VL_PeriodPos<AI_LengthDec; ++VL_PeriodPos)*/
// 마침표가 없거나, 맨 앞에 오거나 맨 끝에 오는 경우도 유효하지 않다.
if(VL_PeriodPos<1 || VL_PeriodPos>=AI_LengthDec-1)
{ return APC_Data; }
//////////////////////////////////////////////////
VPC_StartChar=APC_Data+(VL_CurrentPos=AI_LengthDec-1) ;
while(VL_PeriodPos<VL_CurrentPos)
{
if(*VPC_StartChar!='0') break;
*VPC_StartChar=0;
--VL_CurrentPos;
--VPC_StartChar;
}/*
while(VL_PeriodPos<VL_CurrentPos)*/
/* 소수부 맨 끝에 0 을 삭제한 결과 마침표가 끝에 온다면 그 마침표도 지운다. */
if(VL_PeriodPos==VL_CurrentPos) *VPC_StartChar=0;
return APC_Data; /*############################*/
}/*
static TypeChar* TrimDecimalZero(TypeChar* APC_Data, TypeLength AI_Length=-1)*/
ZCStringBase& TrimDecimalZero()
{
TypeChar* VPC_StartChar=mpc_Data ;
TypeLength AI_LengthDec =ml_UseLen;
TypeLength VL_PeriodPos =0 ;
TypeLength VL_CurrentPos ;
for(; VL_PeriodPos<AI_LengthDec; ++VL_PeriodPos)
{
if( *VPC_StartChar++ =='.' ) break;
}/*
for(; VL_PeriodPos<AI_LengthDec; ++VL_PeriodPos)*/
// 마침표가 없거나, 맨 앞에 오거나 맨 끝에 오는 경우도 유효하지 않다.
if(VL_PeriodPos<1 || VL_PeriodPos>=AI_LengthDec-1)
{ return *this; }
//////////////////////////////////////////////////
VPC_StartChar = mpc_Data+(VL_CurrentPos=AI_LengthDec-1) ;
while(VL_PeriodPos<VL_CurrentPos)
{
if(*VPC_StartChar!='0')
{ break; }
///////////////////////
*VPC_StartChar=0;
--VL_CurrentPos ;
--VPC_StartChar ;
--ml_UseLen ;
}/*
while(VL_PeriodPos<VL_CurrentPos)*/
// 소수부 맨 끝에 0 을 삭제한 결과 마침표가 끝에 온다면 그 마침표도 지운다.
if(VL_PeriodPos==VL_CurrentPos)
{
*VPC_StartChar=0; --ml_UseLen;
}/*
if(VL_PeriodPos==VL_CurrentPos)*/
return *this;
}/*
ZCStringBase& TrimDecimalZero()*/
static TypeChar MakeSmall(TypeChar AC_Char)
{
const int CI_Gap='a'-'A';
if(AC_Char>='A' && AC_Char<='Z')
return AC_Char+CI_Gap;
else
return AC_Char;
//else
}/*
static TypeChar MakeSmall(TypeChar AC_Char)*/
static TypeChar MakeBig(TypeChar AC_Char)
{
const int CI_Gap='a'-'A';
if(AC_Char>='a' && AC_Char<='z')
return AC_Char-CI_Gap;
else
return AC_Char;
//else
}/*
static TypeChar MakeBig(TypeChar AC_Char)*/
static TypeChar* MakeSmall(TypeChar* APC_Data)
{
// 소문자로 바꾼다.
if(APC_Data==0) return 0;
const int CI_Gap='a'-'A';
TypeChar* VPC_Start=APC_Data;
TypeChar VC_Temp ;
while(VC_Temp=*VPC_Start)
{
if(VC_Temp>='A' && VC_Temp<='Z')
{ (*VPC_Start) += CI_Gap; }
++VPC_Start;
}/*
while(VC_Temp=*VPC_Start)*/
return APC_Data;
}/*
static TypeChar* MakeSmall(TypeChar* APC_Data)*/
ZCStringBase& MakeSmall()
{
MakeSmall(mpc_Data); return *this;
}/*
ZCStringBase& MakeSmall()*/
static TypeChar* MakeBig(TypeChar* APC_Data)
{
// 대문자로 바꾼다.
if(APC_Data==0) return 0;
const int CI_Gap='a'-'A';
TypeChar* VPC_Start=APC_Data;
TypeChar VC_Temp ;
while(VC_Temp=*VPC_Start)
{
if(VC_Temp>='a' && VC_Temp<='z')
{ (*VPC_Start) -= CI_Gap ; }
////////////////////////////////
++VPC_Start;
}/*
while(VC_Temp=*VPC_Start)*/
return APC_Data;
}/*
static TypeChar* MakeBig(TypeChar* APC_Data)*/
ZCStringBase& MakeBig()
{
MakeBig(mpc_Data); return *this;
}/*
ZCStringBase& MakeBig()*/
static int Minus
(
TypeCharC* APC_Left , TypeCharC* APC_Right ,
TypeLength AL_LeftLen, TypeLength AL_RightLen
)
{
return ZCMainChars::Minus(APC_Left, APC_Right, AL_LeftLen, AL_RightLen);
}/*
static int Minus
(
TypeCharC* APC_Left , TypeCharC* APC_Right ,
TypeLength AL_LeftLen, TypeLength AL_RightLen
)*/
static int Minus( TypeCharC* APC_Left, TypeCharC* APC_Right)
{
using ZNsMain::ZftGetLengthType ;
return Minus ///////////////
(
APC_Left, APC_Right,
ZftGetLengthType<TypeLength, TypeChar>(APC_Left),
ZftGetLengthType<TypeLength, TypeChar>(APC_Right)
);
////////////////////////////
}/*
static int Minus( TypeCharC* APC_Left, TypeCharC* APC_Right)*/
int Minus(TypeCharC* APC_Left, TypeLength AL_Length) const
{
return Minus(mpc_Data, APC_Left, ml_UseLen, AL_Length);
}/*
int Minus(TypeCharC* APC_Left, TypeLength AL_Length) const*/
int Minus(TypeCharC* APC_Left) const
{
return Minus
(
mpc_Data, APC_Left, ml_UseLen,
ZNsMain::ZftGetLengthType
<TypeLength, TypeChar>(APC_Left)
);
////////////
}/*
int Minus(TypeCharC* APC_Left) const*/
int Minus(const ZCStringBase& rhs) const
{
return Minus(mpc_Data, rhs.mpc_Data, ml_UseLen, rhs.GetUseLength());
}/*
int Minus(const ZCStringBase& rhs) const*/
static ZCStringBase& GetDirFromPath(
ZCStringBase& ARR_CStrDir, TypeCharC* APC_FullPath, TypeLength AL_FullPathLen)
{
// 파일 이름을 포함한 전체 경로명 APC_FullPath 로부터 디렉토리 정보만 가지고 온다.
if(AL_FullPathLen<1) { return ARR_CStrDir; }
if(APC_FullPath[AL_FullPathLen-1]==ZNsMain::ZNsConst::CC_DirDelimiter)
{
// 맨 끝의 디렉토리 구분자는 디렉토리명에 포함시키지 않는다.
return ARR_CStrDir(APC_FullPath, AL_FullPathLen-1);
}/*
if(APC_FullPath[AL_FullPathLen-1]==ZNsMain::ZNsConst::CC_DirDelimiter)*/
using ZNsMain::ZNsConst::CPC_DirDelimiter ;
TypeLength AL_StartPos = FindPosFromEnd
(
APC_FullPath , CPC_DirDelimiter,
AL_FullPathLen, ::strlen(CPC_DirDelimiter)
);
///////////////////////////////////////
if(AL_StartPos<=0)
return ARR_CStrDir; // 디렉토리 구분자가 없거나 맨 앞에 있어 의미가 없을 경우
else
return ARR_CStrDir(APC_FullPath, AL_StartPos);
//else
}/*
static ZCStringBase& GetDirFromPath(
ZCStringBase& ARR_CStrDir, TypeCharC* APC_FullPath, TypeLength AL_FullPathLen)*/
static ZCStringBase& GetDirFromPath(ZCStringBase& ARR_CStrDir, TypeCharC* APC_FullPath)
{
return GetDirFromPath( RR(ARR_CStrDir),
APC_FullPath, ZNsMain::ZftGetLengthType<TypeLength, TypeChar>(APC_FullPath));
}/*
static ZCStringBase& GetDirFromPath(ZCStringBase& ARR_CStrDir, TypeCharC* APC_FullPath)*/
ZCStringBase& GetDirFromPath(TypeCharC* APC_FullPath, TypeLength AL_FullPathLen)
{
return GetDirFromPath(RR(*this), APC_FullPath, AL_FullPathLen);
}/*
ZCStringBase& GetDirFromPath(TypeCharC* APC_FullPath, TypeLength AL_FullPathLen)*/
ZCStringBase& GetDirFromPath(TypeCharC* APC_FullPath)
{
return GetDirFromPath
(
RR(*this), APC_FullPath,
ZNsMain::ZftGetLengthType
<TypeLength, TypeChar>(APC_FullPath)
);
/////////////////////
}/*
ZCStringBase& GetDirFromPath(TypeCharC* APC_FullPath)*/
static ZCStringBase& MinusExt
(
ZCStringBase& ARR_CStrSave, TypeCharC* APC_FullName, TypeLength AL_FullNameLen
)
/////////////////////////////
{
/* 파일 이름을 포함한 전체 경로명 APC_FullName 에서 확장자를 떼어낸 문자열을 반환한다. */
if(AL_FullNameLen<1) return ARR_CStrSave;
TypeLength AL_StartPos=FindPosFromEnd //////////////
(
APC_FullName, ".", AL_FullNameLen,
ZNsMain::ZftGetLengthType
<TypeLength, TypeChar>(".")
);
////////////////////////////////////////////////////
if(AL_StartPos<0)
return ARR_CStrSave; // 확자자 구분표시 '.' 이 없을 경우
else
return ARR_CStrSave(APC_FullName, AL_StartPos);
//else
}/*
static ZCStringBase& MinusExt
(
ZCStringBase& ARR_CStrSave, TypeCharC* APC_FullName, TypeLength AL_FullNameLen
)
///////////////////////////*/
static ZCStringBase& MinusExt(ZCStringBase& ARR_CStrSave, TypeCharC* APC_FullName)
{
return MinusExt
(
RR(ARR_CStrSave), APC_FullName,
ZNsMain::ZftGetLengthType
<TypeLength, TypeChar>(APC_FullName)
);
///////////////
}/*
static ZCStringBase& MinusExt(ZCStringBase& ARR_CStrSave, TypeCharC* APC_FullName)*/
ZCStringBase& MinusExt(TypeCharC* APC_FullName, TypeLength AL_FullNameLen)
{
return MinusExt(RR(*this), APC_FullName, AL_FullNameLen);
}/*
ZCStringBase& MinusExt(TypeCharC* APC_FullName, TypeLength AL_FullNameLen)*/
ZCStringBase& MinusExt(TypeCharC* APC_FullName)
{
return MinusExt(RR(*this), APC_FullName);
}/*
ZCStringBase& MinusExt(TypeCharC* APC_FullName)*/
ZCStringBase& MinusExt()
{
if(ml_UseLen<1) return *this;
TypeLength AL_StartPos=FindPosFromEnd //////////
(
mpc_Data, ".", ml_UseLen,
ZNsMain::ZftGetLengthType
<TypeLength, TypeChar>(".")
);
////////////////////////////////////////////////
if(AL_StartPos<0)
return *this; // 확장자 구분표시 '.' 이 없을 경우
else
return Invalidate(AL_StartPos);
//else
}/*
ZCStringBase& MinusExt()*/
static ZCStringBase& GetExtFromPath
(
ZCStringBase& ARR_CStrExt, TypeCharC* APC_FullPath, TypeLength AL_FullPathLen
)
/*###############################*/
{
// 파일이름을 포함한 전체 경로명 APC_FullPath 로부터 확장자 정보만 가지고 온다.
if(AL_FullPathLen<1 || APC_FullPath[AL_FullPathLen-1]=='.')
{
return ARR_CStrExt;
}
if(APC_FullPath[AL_FullPathLen-1]==ZNsMain::ZNsConst::CC_DirDelimiter)
{
return ARR_CStrExt;
}/*
if(APC_FullPath[AL_FullPathLen-1]==ZNsMain::ZNsConst::CC_DirDelimiter)*/
TypeLength AL_StartPos = FindPosFromEnd ////////////
(
APC_FullPath, ".", AL_FullPathLen,
ZNsMain::ZftGetLengthType
<TypeLength, TypeChar>(".")
);
////////////////////////////////////////////////////
if(AL_StartPos<0)
{
return ARR_CStrExt; // 확장자 구분자 -- 즉 마침표 -- 가 없을 경우
}
else
{
return ARR_CStrExt
(
APC_FullPath+AL_StartPos+1, AL_FullPathLen-(AL_StartPos+1)
);
//////////////////
}/*
else*/
}/*
static ZCStringBase& GetExtFromPath
(
ZCStringBase& ARR_CStrExt, TypeCharC* APC_FullPath, TypeLength AL_FullPathLen
)
#################################*/
static ZCStringBase& GetExtFromPath(ZCStringBase& ARR_CStrExt, TypeCharC* APC_FullPath)
{
return GetExtFromPath(RR(ARR_CStrExt), APC_FullPath, ZNsMain::ZftGetLengthType<TypeLength, TypeChar>(APC_FullPath));
}/*
static ZCStringBase & GetExtFromPath(ZCStringBase& ARR_CStrExt, TypeCharC* APC_FullPath)*/
ZCStringBase& GetExtFromPath(TypeCharC* APC_FullPath, TypeLength AL_FullPathLen)
{
return GetExtFromPath(RR(*this), APC_FullPath, AL_FullPathLen);
}/*
ZCStringBase& GetExtFromPath(TypeCharC* APC_FullPath, TypeLength AL_FullPathLen)*/
ZCStringBase& GetExtFromPath(TypeCharC* APC_FullPath)
{
return GetExtFromPath(RR(*this), APC_FullPath, ZNsMain::ZftGetLengthType<TypeLength, TypeChar>(APC_FullPath));
}/*
ZCStringBase& GetExtFromPath(TypeCharC* APC_FullPath)*/
static void SplitPath
(
ZCStringBase& ARR_CStrNoExt, ZCStringBase& ARR_CStrExt ,
TypeCharC* APC_FullPath , TypeLength AL_FullPathLen
)
/*#################*/
{
/* APC_FullPath 를 마침표를 구분자로 하여 확장자를 제외한 부분은
ARR_CStrNoExt 에, 확장자는 ARR_CStrExt 에 전달한다. */
if(AL_FullPathLen<1) return ;
TypeLength AL_StartPos = FindPosFromEnd ////////
(
APC_FullPath, ".", AL_FullPathLen,
ZNsMain::ZftGetLengthType
<TypeLength, TypeChar>(".")
);
////////////////////////////////////////////////
if(AL_StartPos<0)
{
// 확장자 구분자 -- 즉 마침표(.) -- 가 없을 경우
ARR_CStrNoExt(APC_FullPath,AL_FullPathLen);
}
else
{
ARR_CStrNoExt(APC_FullPath,AL_StartPos);
ARR_CStrExt (APC_FullPath+AL_StartPos+1, AL_FullPathLen-(AL_StartPos+1));
}/*
else*/
}/*
static void SplitPath
(
ZCStringBase& ARR_CStrNoExt, ZCStringBase& ARR_CStrExt,
TypeCharC* APC_FullPath , TypeLength AL_FullPathLen
)
###################*/
static void SplitPath(
ZCStringBase& ARR_CStrNoExt, ZCStringBase& ARR_CStrExt, TypeCharC* APC_FullPath)
{
using ZNsMain::ZftGetLengthType ;
SplitPath ///////////////////////////////////////////////////
(
RR(ARR_CStrNoExt), RR(ARR_CStrExt),
APC_FullPath , ZftGetLengthType
<TypeLength, TypeChar>(APC_FullPath)
);
/////////////////////////////////////////////////////////////
}/*
static void SplitPath(
ZCStringBase& ARR_CStrNoExt, ZCStringBase& ARR_CStrExt, TypeCharC* APC_FullPath)*/
void SplitPath(ZCStringBase& ARR_CStrNoExt, ZCStringBase& ARR_CStrExt)
{
SplitPath(RR(ARR_CStrNoExt), RR(ARR_CStrExt), this->mpc_Data, this->ml_UseLen);
}/*
void SplitPath(ZCStringBase& ARR_CStrNoExt, ZCStringBase& ARR_CStrExt)*/
inline static bool DoExist(const char* APC_FileName, int AI_Mode=0)
{
/* AI_Mode 가 0 이면 파일의 존재를 조사하며,
2 이면 읽기, 4면 쓰기, 6 이면 읽기 쓰기 모두 가능한지 조사한다.
요청한 액세스 타입이 맞으면 0, 그렇지 않으면 -1 을 리턴. */
return ::access(APC_FileName,AI_Mode)==0 ;
}/*
inline static bool DoExist(const char* APC_FileName, int AI_Mode=0)*/
inline bool DoExist(int AI_Mode=0)
{
/* AI_Mode 가 0 이면 파일의 존재를 조사하며,
2 이면 읽기, 4면 쓰기, 6 이면 읽기 쓰기 모두 가능한지 조사한다.
요청한 액세스 타입이 맞으면 0, 그렇지 않으면 -1 을 리턴. */
return ::access(this->mpc_Data, AI_Mode)==0 ;
}/*
inline bool DoExist(int AI_Mode=0)*/
#ifdef _WIN
static ZTypLLong Seek(
HANDLE AH_File, ZTypLLong ALL_Offset, DWORD ADW_MoveMethod=FILE_BEGIN)
{
/* ADW_MoveMethod : FILE_BEGIN, FILE_CURRENT, FILE_END 중 하나.
파일포인터가 파일의 끝을 넘고 그 위치부터 쓰게 되면 그 간격은 공백으로 채워진다. */
LARGE_INTEGER VLL_LargeInt;
VLL_LargeInt.QuadPart=ALL_Offset;
VLL_LargeInt.LowPart =SetFilePointer(
AH_File, VLL_LargeInt.LowPart, &VLL_LargeInt.HighPart, ADW_MoveMethod);
const bool CB_IsError = (
VLL_LargeInt.LowPart==INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR );
if(CB_IsError) VLL_LargeInt.QuadPart=-1; return VLL_LargeInt.QuadPart;
}/*
static ZTypLLong Seek(
HANDLE AH_File, ZTypLLong ALL_Offset, DWORD ADW_MoveMethod=FILE_BEGIN)*/
static inline LARGE_INTEGER To_LARGE_INTEGER (__int64 ALL_Distance)
{
/* WINDOW API 에는 큰 정수 64 비트의 하위비트와 상위비트를 인수로
받는 함수가 몇 있는데 그 함수에 __int64 형을 전달하기 위해 설계한다. */
/* LARGE_INTEGER::HighPart 상위비트
LARGE_INTEGER::LowPart 하위비트 */
LARGE_INTEGER VO_LI; VO_LI.QuadPart = ALL_Distance; return VO_LI ;
}/*
static inline LARGE_INTEGER To_LARGE_INTEGER (__int64 ALL_Distance)*/
#endif //_WIN
int Compare(const ZCStringBase& rhs) const
{
return ZNsMain::ZftGetCompareCode(mpc_Data, ml_UseLen, rhs.mpc_Data, rhs.ml_UseLen);
}/*
int Compare(const ZCStringBase& rhs) const*/
int Compare(const TypeChar* APC_Data) const
{
return ZNsMain::ZftGetCompareCode
(
mpc_Data, ml_UseLen,
APC_Data, ZNsMain::ZftGetLengthType
< TypeLength, TypeChar >( APC_Data )
);
/////////////////////////////////
}/*
int Compare(const TypeChar* APC_Data) const*/
ZCStringBase& ConvertXhtml()
{
return ZNsMain::ZftConvertXhtml(*this);
}/*
ZCStringBase& ConvertXhtml()*/
ZCStringBase& ConvertXhtmlAtt()
{
return ZNsMain::ZftConvertXhtmlAtt(*this);
}/*
ZCStringBase& ConvertXhtmlAtt()*/
ZCStringBase& Fetch(ZCStringBase& rhs)
{
// rhs 로부터 문자열 메모리를 그대로 가져온다.
clear();
ml_UseLen=rhs.ml_UseLen;
ml_AllLen=rhs.ml_AllLen;
mpc_Data =rhs.mpc_Data ;
rhs.ml_UseLen=0;
rhs.ml_AllLen=0;
rhs.mpc_Data =0;
return *this;
}/*
ZCStringBase& Fetch(ZCStringBase& rhs)*/
// Fetch() 의 반대 함수.
ZCStringBase& SendOut(ZCStringBase& rhs)
{
return rhs.Fetch(*this);
}/*
ZCStringBase& SendOut(ZCStringBase& rhs)*/
template<typename TyUInt>
ZCStringBase& AddBitByUInt(TyUInt AUC_Value)
{
// TyUInt 은 unsigned 형이어야 한다.
const int CI_Byte=sizeof(TyUInt)*8;
TyUInt VUI_Value=(0x01)<<(CI_Byte-1);
for(int i=1; i<CI_Byte; ++i)
{
if((VUI_Value & AUC_Value)>0)
{(*this)("1");}
else{(*this)("0");}
VUI_Value>>=1; /*##########*/
}/*
for(int i=1; i<CI_Byte; ++i)*/
return *this;
}/*
template<typename TyUInt>
ZCStringBase& AddBitByUInt(TyUInt AUC_Value)*/
// 아래 멤버함수는 class CFileLarge 에서 펑크터로 사용할 때 필요하다.
template<typename TFileHandle>
void OnKnowFileSize(ZTypLLong ALL_FileSize, TFileHandle AH_FileHandle)
{
ReAllocKeep(ml_UseLen+ALL_FileSize); // 파일 크기를 대입받는다.
}/*
template<typename TFileHandle>
void OnKnowFileSize(ZTypLLong ALL_FileSize, TFileHandle AH_FileHandle) */
bool OnRead(TypeCharC* APC_Buff, TypeLength AL_BuffSize)
{
(*this)(APC_Buff, AL_BuffSize); return false;
}/*
bool OnRead(TypeCharC* APC_Buff, TypeLength AL_BuffSize)*/
////////////////////////////////////////
//////////// class ZCFindPos ////////////
////////////////////////////////////////
class ZCFindPos
{
protected:
ZCStringBase& mr_CString;
TypeLength ml_NowPos ;
public :
ZCStringBase& GetCString(){return mr_CString;}
TypeLength& GetNowPos (){return ml_NowPos ;}
const ZCStringBase& GetCString() const{return mr_CString;}
TypeLength GetNowPos () const{return ml_NowPos ;}
ZCFindPos(ZCStringBase& AR_CString, TypeLength NowPos=0) :
mr_CString(AR_CString), ml_NowPos(NowPos)
{
}/*
ZCFindPos(ZCStringBase& AR_CString,TypeLength NowPos=0)*/
ZCFindPos(const ZCFindPos& rhs) :
mr_CString(rhs.mr_CString),
/*//////////*/ ml_NowPos(rhs.ml_NowPos)
{
}/*
ZCFindPos(const ZCFindPos& rhs)*/
ZCFindPos& operator=(TypeLength NewPos)
{
ml_NowPos=NewPos; return *this;
}/*
ZCFindPos& operator=(TypeLength NewPos)*/
TypeLength Find(TypeCharC* APC_FindChars, TypeLength AL_FindLen)
{
// APC_FindChars 을 찾아서 ml_NowPos 를 해당 위치로 셋팅한다.
// 찾지 못하면 셋팅하지 않는다.
TypeLength VL_TempPos=
mr_CString.FindPos(APC_FindChars, AL_FindLen, ml_NowPos);
if(VL_TempPos<0) return -1; return ml_NowPos=VL_TempPos;
}/*
TypeLength Find(TypeCharC* APC_FindChars, TypeLength AL_FindLen)*/
TypeLength Find(TypeCharC* APC_FindChars)
{
return Find
(
APC_FindChars, ZNsMain::ZftGetLengthType
< TypeLength, TypeChar >( APC_FindChars )
);
///////////
}/*
TypeLength Find(TypeCharC* APC_FindChars)*/
TypeLength FindBackward(TypeCharC* APC_FindChars, TypeLength AL_FindLen)
{
// APC_FindChars 을 찾아서 ml_NowPos 를 해당 위치로 셋팅한다.
// 찾지 못하면 셋팅하지 않는다.
TypeLength VL_TempPos=mr_CString.
FindPosFromEnd(APC_FindChars, AL_FindLen, ml_NowPos);
if(VL_TempPos<0) return -1; return ml_NowPos=VL_TempPos;
}/*
TypeLength Find(TypeCharC* APC_FindChars, TypeLength AL_FindLen)*/
TypeLength FindBackward(TypeCharC* APC_FindChars)
{
using ZNsMain::ZftGetLengthType ;
return FindBackward
(
APC_FindChars, ZftGetLengthType
<TypeLength, TypeChar>(APC_FindChars)
);
///////////////////
}/*
TypeLength Find(TypeCharC* APC_FindChars)*/
operator TypeLength () const
{
return ml_NowPos;
}/*
operator TypeLength () const*/
operator TypeLength& ()
{
return ml_NowPos;
}/*
operator TypeLength& ()*/
ZCFindPos& operator+=(TypeLength AI_AddPos)
{
ml_NowPos+=AI_AddPos; return *this;
}/*
ZCFindPos& operator+=(TypeLength AI_AddPos)*/
ZCFindPos& operator-=(TypeLength AI_AddPos)
{
ml_NowPos-=AI_AddPos; return *this;
}/*
ZCFindPos& operator-=(TypeLength AI_AddPos)*/
public:
};/*
class ZCFindPos*/
public:
};/*
template< typename TTypCh,
typename TAlloc =ZNsMain::ZtCAllocClass <TTypCh>,
typename TAllocSize =ZNsMain::ZtCAllocMemSize<TTypCh>,
typename TTypeString=ZNsMain::ZNsType::ZtCTypeStringBase
<
TTypCh ,
TAlloc ,
TAllocSize
>
>
class ZtCStringBase /////////////////////////////////////////*/
template< typename TTypCh,
typename TAlloc =ZNsMain::ZtCAllocClass <TTypCh>,
typename TAllocSize =ZNsMain::ZtCAllocMemSize<TTypCh>,
typename TTypeString=ZNsMain::ZNsType::ZtCTypeStringBase
<
TTypCh ,
TAlloc ,
TAllocSize
>
>
class ZtCStringEx :
public ZtCStringBase<TTypCh, TAlloc, TAllocSize, TTypeString>
{
public :
typedef TTypCh TypeChar ;
typedef TTypCh TypeData ;
typedef ZtCStringBase
<TTypCh, TAlloc, TAllocSize, TTypeString> TypeBase ;
typedef ZtCStringBase
<TTypCh, TAlloc, TAllocSize, TTypeString> ZCStringBase;
typedef typename ZCStringBase::ZCStringList ZCStringList;
typedef typename ZCStringBase::TypeLength TypeLength ;
protected:
typedef ZtCStringEx ZCStringEx ;
protected:
ZCStringList mo_CStringListBuff;
TypeLength ml_ListBuffAllByte;
/* AddList, AddListTail 멤버 함수를 사용한 경우에,
mo_CStringListBuff 에 추가된 바이트 길이를 누적한다. */
public :
ZtCStringEx()
{
ml_ListBuffAllByte=0;
}/*
ZtCStringEx()*/
ZtCStringEx(const ZtCStringEx& rhs) : TypeBase(rhs)
{
mo_CStringListBuff=rhs.mo_CStringListBuff;
ml_ListBuffAllByte=rhs.ml_ListBuffAllByte;
}/*
ZtCStringEx(const ZtCStringEx& rhs)*/
ZtCStringEx(const ZCStringBase& rhs) : TypeBase(rhs)
{
ml_ListBuffAllByte=0;
}/*
ZtCStringEx(const ZCStringBase& rhs)*/
ZtCStringEx(const TypeChar* APC_Data, TypeLength AL_Length) : TypeBase(APC_Data, AL_Length)
{
ml_ListBuffAllByte=0;
}/*
ZtCStringEx(const TypeChar* APC_Data, TypeLength AL_Length)*/
ZtCStringEx(const TypeChar* APC_Data) : TypeBase(APC_Data)
{
ml_ListBuffAllByte=0;
}/*
ZtCStringEx(const TypeChar* APC_Data)*/
ZCStringEx& operator=(const ZtCStringEx& rhs)
{
if(this==&rhs) return *this;
(ZCStringBase&)(*this)=(ZCStringBase&)rhs ;
mo_CStringListBuff =rhs.mo_CStringListBuff;
return *this;
}/*
ZCStringEx& operator=(const ZtCStringEx& rhs)*/
ZCStringEx& operator=(const ZCStringBase& rhs)
{
if((ZCStringBase*)this==&rhs)
return *this;
(ZCStringBase&)(*this)=rhs; return *this;
}/*
ZtCStringEx& operator=(const ZCStringBase& rhs)*/
ZCStringEx& operator=(const TypeChar* APC_Data)
{
(ZCStringBase&)(*this)=APC_Data; return *this;
}/*
ZtCStringEx& operator=(const TypeChar* APC_Data)*/
ZCStringEx& operator=(TypeLength AL_Long)
{
(ZCStringBase&)(*this)=AL_Long; return *this;
}/*
ZCStringEx& operator=(TypeLength AL_Long)*/
ZCStringEx& operator=(const std::string& AR_CString)
{
(ZCStringBase&)(*this)=AR_CString; return *this;
}/*
ZCStringEx& operator=(const std::string& AR_CString)*/
ZCStringBase& NewObj()
{
return (ZCStringBase&)mo_CStringListBuff;
}/*
ZCStringBase& NewObj()*/
ZCStringList& GetCStringListBuff()
{
return mo_CStringListBuff;
}/*
ZCStringList& GetCStringListBuff()*/
ZCStringEx& ClearListBuff()
{
mo_CStringListBuff.clear(); ml_ListBuffAllByte=0; return *this;
}/*
ZCStringEx& ClearListBuff()*/
TypeLength GetListBuffAllByte() const
{
return ml_ListBuffAllByte;
}/*
TypeLength GetListBuffAllByte() const*/
ZCStringEx& AddList(const TypeChar* APC_AddData, TypeLength AL_Length)
{
if(AL_Length<1) return *this;
ml_ListBuffAllByte+=AL_Length;
((ZCStringBase&)mo_CStringListBuff).
append( APC_AddData, AL_Length ) ;
return *this;
}/*
ZCStringEx& AddList(const TypeChar* APC_AddData, TypeLength AL_Length)*/
ZCStringEx& AddList(const ZCStringBase& AR_CStringBase)
{
return AddList(AR_CStringBase.data(), AR_CStringBase.size());
}/*
ZCStringEx& AddList(const ZCStringBase& AR_CStringBase)*/
ZCStringEx& AddList(const TypeChar* APC_AddData)
{
using ZNsMain::ZftGetLengthType ;
return AddList
(
APC_AddData, ZftGetLengthType
<TypeLength, TypeChar>(APC_AddData)
);
//////////////
}/*
ZCStringEx& AddList(const TypeChar* APC_AddData)*/
// AddListTail() 멤버함수는 버퍼 리스트의 끝 원소에 데이타를 추가한다.
ZCStringEx& AddListTail(const TypeChar* APC_AddData, TypeLength AL_Length)
{
if(AL_Length<1) return *this;
ml_ListBuffAllByte+=AL_Length;
if(mo_CStringListBuff.size()<1)
((ZCStringBase&)mo_CStringListBuff).append(APC_AddData, AL_Length);
else mo_CStringListBuff.GetTailData() .append(APC_AddData, AL_Length);
return *this;
}/*
ZCStringEx& AddListTail(const TypeChar* APC_AddData, TypeLength AL_Length)*/
ZCStringEx& AddListTail(const ZCStringBase& AR_CStringBase)
{
return AddListTail(AR_CStringBase.data(), AR_CStringBase.size());
}/*
ZCStringEx& AddListTail(const ZCStringBase& AR_CStringBase)*/
ZCStringEx& AddListTail(const TypeChar* APC_AddData)
{
using ZNsMain::ZftGetLengthType ;
return AddListTail
(
APC_AddData, ZftGetLengthType
<TypeLength, TypeChar>(APC_AddData)
);
//////////////////
}/*
ZCStringEx& AddListTail(const TypeChar* APC_AddData)*/
ZCStringBase& CopyListBuffChars(ZCStringBase& ARR_CStringSave)
{
if(mo_CStringListBuff.size()<1) return ARR_CStringSave;
if(ml_ListBuffAllByte>0)
{ ARR_CStringSave.reserve
( ARR_CStringSave.size()+ml_ListBuffAllByte ); }
TypeLength VL_ListSize=mo_CStringListBuff.size();
IterEasyID VI_IterEasy=mo_CStringListBuff.GetHeadIterEasyID() ;
for(TypeLength i=1; i<=VL_ListSize; ++i)
{
ARR_CStringSave += mo_CStringListBuff.ItD(VI_IterEasy);
mo_CStringListBuff.MoveNextIter(VI_IterEasy);
}/*
for(TypeLength i=1; i<=VL_ListSize; ++i)*/
return ARR_CStringSave;
}/*
ZCStringBase& CopyListBuffChars(ZCStringBase& ARR_CStringSave)*/
ZCStringBase& CopyListBuffChars()
{
return CopyListBuffChars(static_cast<ZCStringBase&>(*this));
}/*
ZCStringBase& CopyListBuffChars()*/
void clear()
{
this->TypeBase::clear();
this->ml_ListBuffAllByte=0;
this->mo_CStringListBuff.clear();
}/*
void clear()*/
void erase()
{
clear();
}/*
void erase()
public:*/
public:
class ZCSerial
{
protected:
ZCStringEx& mr_CStringEx;
public :
ZCSerial(ZCStringEx& AR_CStringEx):mr_CStringEx(AR_CStringEx){}
ZCSerial& operator()(const TypeChar* APC_Data, TypeLength AL_Length)
{
mr_CStringEx.AddList(APC_Data, AL_Length); return *this;
}/*
ZCSerial& operator()(const TypeChar* APC_Data, TypeLength AL_Length)*/
ZCSerial& operator()(const ZCStringBase& AR_CStringBase)
{
return (*this)(AR_CStringBase.data(), AR_CStringBase.size());
}/*
ZCSerial& operator()(const ZCStringBase& AR_CStringBase)*/
ZCSerial& operator()(const TypeChar* APC_Data)
{
return (*this)(APC_Data,ZNsMain::ZftGetLengthType<TypeLength, TypeChar>(APC_Data));
}/*
ZCSerial& operator()(const TypeChar* APC_Data)*/
ZCStringBase& MemCopy(ZCStringBase& ARR_CStringSave)
{
return mr_CStringEx.CopyListBuffChars(RR(ARR_CStringSave));
}/*
ZCStringBase& MemCopy(ZCStringBase& ARR_CStringSave)*/
ZCStringBase& MemCopy()
{
return mr_CStringEx.CopyListBuffChars();
}/*
ZCStringBase& MemCopy()*/
public:
};/*
class ZCSerial*/
public:
};/*
template< typename TTypCh,
typename TAlloc =ZNsMain::ZtCAllocClass <TTypCh>,
typename TAllocSize =ZNsMain::ZtCAllocMemSize<TTypCh>,
typename TTypeString=ZNsMain::ZNsType::ZtCTypeStringBase
<
TTypCh, TAlloc, TAllocSize
>
>
class ZtCStringEx //////////////////////////////////////////////*/
template
<typename TTypCh, typename TAlloc, typename TAllocSize, typename TTypeString>
std::ostream& operator <<
(
std::ostream& AR_COStream, const ZtCStringBase
<TTypCh, TAlloc, TAllocSize, TTypeString>& AR_CStringBase
)
{
/*/////////////////////////////////////////////////////////////////////////////////////
■ ZtCStringBase~ 앞에 const 를 붙이지 않으면, 비 const ZtCStringBase<> object 에 대하
여, 이 중첩 함수는 호출되지 않는다. 따라서 const 는 아주 중요한 역할을 한다.
/////////////////////////////////////////////////////////////////////////////////////*/
if(AR_CStringBase.size()>0) AR_COStream<<AR_CStringBase.data(); return AR_COStream;
}/*
template
<typename TTypCh, typename TAlloc, typename TAllocSize, typename TTypeString>
std::ostream& operator <<
(
std::ostream& AR_COStream, const ZtCStringBase
<TTypCh, TAlloc, TAllocSize, TTypeString>& AR_CStringBase
) */
namespace NsFunc
{
template<typename TTypCh, typename TAlloc, typename TAllocSize, typename TTypeString>
void __FastMoveObj(
ZNsMain::ZtCStringBase<TTypCh, TAlloc, TAllocSize, TTypeString>& AR_CString1,
ZNsMain::ZtCStringBase<TTypCh, TAlloc, TAllocSize, TTypeString>& AR_CString2
/*//////////*/ )
{
#ifdef _DEBUG_FAST_MOVE_OBJ_
cout<<" ▶▶ __FastMoveObj(CString&, CString&) Start!"<<endl;
#endif //_DEBUG_FAST_MOVE_OBJ_
AR_CString1.Fetch(AR_CString2);
#ifdef _DEBUG_FAST_MOVE_OBJ_
cout<<" ▶▶ __FastMoveObj(CString&, CString&) Close!"<<endl;
#endif //_DEBUG_FAST_MOVE_OBJ_
}/*
template<typename TTypCh, typename TAlloc, typename TAllocSize, typename TTypeString>
void __FastMoveObj(
ZNsMain::ZtCStringBase<TTypCh, TAlloc, TAllocSize, TTypeString>& AR_CString1,
ZNsMain::ZtCStringBase<TTypCh, TAlloc, TAllocSize, TTypeString>& AR_CString2
////////////// ) */
template<typename TTypCh, typename TAlloc, typename TAllocSize, typename TTypeString>
void __FastMoveObj(
ZNsMain::ZtCStringBase<TTypCh, TAlloc, TAllocSize, TTypeString>& AR_CString1,
const ZNsMain::ZtCStringBase<TTypCh, TAlloc, TAllocSize, TTypeString>& AR_CString2
/*//////////*/ )
{
typedef ZNsMain::ZtCStringBase<TTypCh, TAlloc, TAllocSize, TTypeString> CStringType;
#ifdef _DEBUG_FAST_MOVE_OBJ_
cout<<" ▶▶ __FastMoveObj(CString&, const CString&) Start!"<<endl;
#endif //_DEBUG_FAST_MOVE_OBJ_
AR_CString1.Fetch(const_cast<CStringType&>(AR_CString2));
#ifdef _DEBUG_FAST_MOVE_OBJ_
cout<<" ▶▶ __FastMoveObj(CString&, const CString&) Close!"<<endl;
#endif //_DEBUG_FAST_MOVE_OBJ_
}/*
template<typename TTypCh, typename TAlloc, typename TAllocSize, typename TTypeString>
void __FastMoveObj(
ZNsMain::ZtCStringBase<TTypCh, TAlloc, TAllocSize, TTypeString>& AR_CString1,
const ZNsMain::ZtCStringBase<TTypCh, TAlloc, TAllocSize, TTypeString>& AR_CString2
////////////// ) */
}/*
namespace NsFunc*/
}/*
namespace ZNsMain */
/*///////////////////////////////////////////////////////////////////////////////////
■ 문자열 메모리를 복사할 때, for 문을 쓰지 말고, memcpy() 를 썼으면 더 좋을 뻔 했다.
-- 2012-02-29 10:45:00
///////////////////////////////////////////////////////////////////////////////////*/
#endif //__ZCPPMAIIN__ZTCSTRINGEX_H__