Files
RepoMain/ZCppMain/ZtCStringEx.H

7722 lines
289 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/ZtCMainChars.H"
using namespace std ;
using namespace ZNsMain;
namespace ZNsMain
{
/*//////////////////////////////////////////////////////////////////////////
■ 문자열을 편하게 다루기 위해서 ZtCStringBase 클래스 템플릿을 설계하였는데
이 클래스 템플릿은 동적으로 생성된 문자열만 다루고 있으므로, 정적 문자열을
다룰 수 있는 class ZtCCharPtr 템플릿을 설계한다. 단 정적 문자열의 길이는
맨 끝에 널문자를 위해, 필요한 길이 + 1 이 됨을 명심할 것.
//////////////////////////////////////////////////////////////////////////*/
template<typename TTypCh> class ZtCCharPtr
{
public :
typedef long TypeLength;
typedef TTypCh TypeData ;
typedef TTypCh TypeChar ;
typedef TTypCh* TypePChar ;
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 개의 공간을 뺀 길이다.
ml_Length = 0 ;
ml_AllLen = AL_ArgAllLen;
mpc_Buff = APC_ArgBuf ;
}/*
ZtCCharPtr(TypeChar* APC_ArgBuf, TypeLength AL_ArgAllLen)*/
ZtCCharPtr<TypeChar>& SetCharSet(TypeChar* APC_ArgBuf, TypeLength AL_ArgAllLen)
{
// AL_ArgAllLen 는 맨 끝에 널 문자를 위한 1 개의 공간을 뺀 길이다.
ml_Length = 0 ;
ml_AllLen = AL_ArgAllLen;
mpc_Buff = APC_ArgBuf ;
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] ;
}
/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
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, GetLength(APC_ArgChar));
}/*
ZtCCharPtr<TypeChar>& Add(TypeChar* APC_ArgChar)*/
operator TypeChar* () {return mpc_Buff ;}
operator TypeCharC*() const{return mpc_Buff ;}
TypeChar* data () {return mpc_Buff ;}
TypeCharC* data () const{return mpc_Buff ;}
TypeLength size () const{return ml_Length;}
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; /*::::::::::::::::::::::::::::::::::::::::::::*/
template //////////////////////////////////////////////////////////////////
<
template<typename, typename, typename, typename>
class ZtCStringBase,
typename TTypCh , typename TAlloc,
typename TAllocSize, typename TTypeString
>
class ZtCCharType
< ZtCStringBase<TTypCh, TAlloc, TAllocSize, TTypeString> >
/*#######################################################################*/
{
public:
typedef ZtCStringBase ///////////////////////////
<
TTypCh, TAlloc, TAllocSize, TTypeString
>
/*/////////////////////////////////*/ TypeCStr ;
typedef TTypCh /*//////////////////*/ TypeChar ;
static const int CI_ByteSize = sizeof(TypeChar) ;
typedef typename
ZtCCharInt<TypeChar> ::TypeInt TypeInt ;
typedef typename TypeCStr::TypeSize TypeSize ;
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
typedef TypeChar char_type ; // for stl string/wstring
typedef TypeInt int_type ; // for stl string/wstring
typedef TypeSize size_type ; // for stl string/wstring
public:
};/*
class ZtCCharType #######################################################*/
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 TypeSize ;
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 ;
typedef typename ZCTypeChars::ZCChars ZCCharView; // for string_view in C++17
public:
template<typename TDeriveString> class ZtCHelpBase
{
public:
typedef ZNsMain::ZtCBaseList< /////////////////
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::ZtCBaseList ////////////////////
<
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*/
/*/////////////////////////////////////////////////////////////////
■ 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 TTypCh TypeChar ;
typedef const TTypCh TypeCharC ;
typedef const TTypCh* TypeCharCP ;
typedef const TTypCh* TypeCPChar ;
typedef TTypCh* TypePChar ;
typedef TTypeString ZCTypeString;
typedef ZtCStringBase ZCStringBase;
typedef ZtCStringBase TypeThis ;
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
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 TypeSize ;
typedef typename ZCTypeString::TypeLong TypeLength ;
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
typedef typename ZCTypeChars ::ZCChars ZCChars ;
typedef typename ZCTypeChars ::ZCChars ZCCharView ; // for string_view in C++17
typedef const ZCChars ZCCharsC ;
typedef const ZCChars ZCCharViewC ;
typedef TypeChar TypeData ;
typedef ZCStringList TypeList ;
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
typedef ZtCCharType<ZtCStringBase> ZCCharType ;
typedef typename ZCCharType::TypeInt TypeCharInt;
typedef ZtCCharType<ZtCStringBase> traits_type; // for strl string/wstring
typedef TypeSize size_type ; // for strl string/wstring
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
enum EWriteFile // WriteFile() 에서 사용한다.
{
EWriteFile_Append , // 데이타를 파일에 덧붙인다.
EWriteFile_OverWrite // 기존 파일의 내용을 지우고 데이타를 파일에 쓴다.
};/*
enum EWriteFile*/
public:
static TypeLength GetLength(const TypeChar* AP_Data)
{
return ZNsMain::ZftGetLengthType<TypeLength, TypeChar>(AP_Data) ;
}
////////////////////////////////////////////////////
public:
template<typename TPosList> void FindPosToList /////////////
(
TPosList& ARR_CPosList, TypeCPChar APC_SearchData,
TypeLength AL_SearchLen, TypeLength AL_Offset=0
)
/*########################################################*/
{
// TPosList : ZNsMain::ZtCBaseList<TypeLength> etc
if(0 > AL_Offset) AL_Offset=0 ;
if(this->size() <= AL_Offset) return ;
if(this->size() < 1 ) return ;
const char* VPC_OriginStart = this->data();
TypeLength VL_OriginLen = this->size();
TypeLength VL_FindPos = -1 ;
TypeLength VL_OffsetNow = AL_Offset ;
while /*::::::::::::::::::::::::::::::::::::::::::::::*/
(
( VL_FindPos = ZCMainChars::FindPos
( VPC_OriginStart, APC_SearchData,
VL_OriginLen , AL_SearchLen , VL_OffsetNow
)
) >= 0
)
/*::::::::::::::::::::::::::::::::::::::::::::::::::::*/
{
ARR_CPosList.push_back(VL_FindPos);
VL_OffsetNow = VL_FindPos + AL_SearchLen;
}
/*::::::::::::::::::::::::::::::::::::::::::::::::::::*/
}/*
template<typename TPosList> void FindPosToList /////////////
(
TPosList& ARR_CPosList, TypeCPChar APC_SearchData,
TypeLength AL_SearchLen, TypeLength AL_Offset=0
)
##########################################################*/
template<typename TPosList> void FindPosToList /////////////
(
TPosList& ARR_CPosList, const ZCCharView& AR_CCharView, TypeLength AL_Offset=0
)
/*########################################################*/
{
FindPosToList
( ARR_CPosList, AR_CCharView.data(), AR_CCharView.size(), AL_Offset );
}
/*########################################################*/
/*//////////////////////////////////////////////////////////
■ -- 2025-09-19 20:11
■ AL_Searched >= AL_Replace
□ 메모리 증가 불필요.
□ 찾은 원소의 시작 원소부터 memmove() 호출.
■ AL_Searched < AL_Replace
□ 메모리 증가 필요.
□ 찾은 원소의 끝쪽 원소부터 memmove() 호출
# 원본 : 12###345###6789###AB
# 교체본 : 12#####345#####6789#####AB
# 교체 문자열 : #####
# 찾은 문자 길이 : 3(###)
# 교체 문자 길이 : 5(#####)
# 문자 길이 차이 : 2(#####-###)
# 처리 순서-01
AB 를 맨 뒤로 이동.
memmove() 시작 위치 : 원본의 3번 ### 위치 + 찾은 문자 길이
memmove() 대상 위치 : 원본의 3번 ### 위치 + 찾은 문자 길이 + 문자 길이 차이 * 3
memmove() 처리 길이 : 원본의 전체 길이 - (원본의 3번 ### 위치 + 찾은 문자 길이)
# 처리 순서-02
원본의 3번 ### 에 memmcpy()
memcpy() 시작 위치 : 교체 문자열
memcpy() 대상 위치 : 원본의 3번 ### 위치 + 문자 길이 차이 * (3 - 1)
memcpy() 처리 길이 : 교체 문자 길이
# 처리 순서-11
6789 를 뒤로 이동.
memmove() 시작 위치 : 원본의 2번 ### 위치 + 찾은 문자 길이
memmove() 대상 위치 : 원본의 2번 ### 위치 + 찾은 문자 길이 + 문자 길이 차이 * 2
memmove() 처리 길이 : 원본의 3번 ### 위치 - (원본의 2번 ### 위치 + 찾은 문자 길이)
# 처리 순서-12
원본의 2번 ### 에 memmcpy()
memcpy() 시작 위치 : 교체 문자열
memcpy() 대상 위치 : 원본의 2번 ### 위치 + 문자 길이 차이 * (3 - 2)
memcpy() 처리 길이 : 교체 문자 길이
......
□ 위를 이렇게 다시 정리한다.
TypeLength VL_PosListSize = AR_CPosList.size();
TypeLength VL_SearchedPre = this->size() ; // 현재 순회 중인 원소의 다음의 원소가 가리키는, 원본에서의 시작 위치.
TypeLength VL_NowEleNo = VL_PosListSize ; // AR_CPosList 에서 순회 중인 원소의 순서. 처음이 1.
TypeLength VL_DiffLength = AL_Replace-AL_Searched ;
TypeLength VL_SearchedPos : VL_NowEleNo 번 원소가 가리키는, 원본에서의 시작 위치
TypeLength AL_Searched : 인수, 찾은 문자 길이
TypeLength AL_Replace : 인수, 교체 문자 길이
TypeLength APC_Replace : 인수, 교체 문자열
TypeLength i : 순회 증가 번호. 1부터 시작.
# 처리 순서-101
AB 를 맨 뒤로 이동.
memmove() 시작 위치 : VL_SearchedPos + AL_Searched
memmove() 대상 위치 : VL_SearchedPos + AL_Searched + VL_DiffLength * VL_NowEleNo
memmove() 처리 길이 : VL_SearchedPre - (VL_SearchedPos + AL_Searched)
# 처리 순서-102
원본의 3번 ### 에 memcpy()
memcpy() 시작 위치 : APC_Replace
memcpy() 대상 위치 : VL_SearchedPos + VL_DiffLength * (VL_PosListSize - i)
memcpy() 처리 길이 : AL_Replace
--VL_NowEleNo ;
VL_SearchedPre = VL_SearchedPos ;
VL_SearchedPos 을 다음 순회 원소를 참고해 설정.
/////////////////////////////////////////////////////////////////////////*/
public :
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
private:
template<typename TPosList> ZCStringBase& ReplaceByPosList ////////////////
(
TPosList& AR_CPosList ,
TypeCPChar APC_Replace ,
TypeLength AL_Replace ,
TypeLength AL_Searched
)
/*#######################################################################*/
{
/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
■ TPosList : ZNsMain::ZtCBaseList<TypeLength> etc
AL_Replace : APC_Replace 의 길이
AL_Searched : 이전에 찾은 길이
Replace() 에서 FindPosToList() 다음에 호출한다.
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
if(AR_CPosList.size()<1) return *this;
TypeLength VL_PosListSize= AR_CPosList.size() ;
TypeLength VL_ThisSize = this->size() ;
TypeLength VL_NeedSize = VL_ThisSize +
(AL_Replace-AL_Searched) * VL_PosListSize ;
TypePChar VPC_ThisStart = this->data() ;
IterEasyID VH_IterEasyID = AR_CPosList.ItHID();
TypeLength VL_SearchedPos= 0 ;
TypeLength VL_SearchedPre= 0 ; // VL_SearchedPos 의 이전 값
TypePChar VPC_MoveStart = 0 ;
TypePChar VPC_DestStart = 0 ;
TypeLength VL_MoveStart = 0 ;
TypeLength VL_DestStart = 0 ;
TypeLength VL_MemMoveSize= 0 ;
if(AL_Replace<=AL_Searched) // 메모리 증가 불필요
{
TypePChar VPC_RepalcePos= 0 ;
__for1(TypeLength, i, VL_PosListSize)
{
VL_SearchedPos = AR_CPosList.ItD(VH_IterEasyID) ;
VPC_RepalcePos = VPC_ThisStart + VL_SearchedPos -
( AL_Searched-AL_Replace ) * (i-1) ;
if(VL_MoveStart>VL_DestStart)
{
VL_MemMoveSize =
VL_SearchedPos - VL_SearchedPre - AL_Searched ;
VPC_MoveStart = VPC_ThisStart + VL_MoveStart ;
VPC_DestStart = VPC_ThisStart + VL_DestStart ;
::memmove /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
(
VPC_DestStart, VPC_MoveStart, VL_MemMoveSize*sizeof(TypeChar)
);
/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
}/*
if(VL_MoveStart>VL_DestStart)*/
VL_SearchedPre = VL_SearchedPos ;
VL_MoveStart = VL_SearchedPos+ AL_Searched ;
VL_DestStart = VL_SearchedPos+ AL_Searched -
( AL_Searched-AL_Replace ) * i ;
::memcpy /*:::::::::::::::::::::::::::::::::::::::::::::::::::*/
(
VPC_RepalcePos, APC_Replace, AL_Replace*sizeof(TypeChar)
);
/*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
AR_CPosList.ItNext(VH_IterEasyID);
}/*
__for1(TypeLength, i, VL_PosListSize)*/
if(VL_ThisSize > VL_MoveStart)
{
::memmove /*::::::::::::::::::::::::::::::::::::::::*/
(
VPC_ThisStart + VL_DestStart,
VPC_ThisStart + VL_MoveStart,
(VL_ThisSize - VL_MoveStart)*sizeof(TypeChar)
);
/*::::::::::::::::::::::::::::::::::::::::::::::::::*/
}/*
if(VL_ThisSize > VL_MoveStart)*/
this->resize(VL_NeedSize); return *this;
}/*
if(AL_Replace<=AL_Searched) // 메모리 증가 불필요*/
/*======*/ VL_SearchedPre = this->size() ;
/*======*/ VH_IterEasyID = AR_CPosList.ItTID() ;
TypeLength VL_NowEleNo = VL_PosListSize ;
TypeLength VL_DiffLength = AL_Replace-AL_Searched;
this->resize(VL_NeedSize); VPC_ThisStart = this->data();
__for1(TypeLength, i, VL_PosListSize)
{
VL_SearchedPos = AR_CPosList.ItD(VH_IterEasyID) ;
VL_MemMoveSize = VL_SearchedPre - (VL_SearchedPos+AL_Searched);
if(VL_MemMoveSize>0)
{
VPC_MoveStart = VPC_ThisStart + VL_SearchedPos + AL_Searched ;
VPC_DestStart = VPC_ThisStart + VL_SearchedPos + AL_Searched + VL_DiffLength*VL_NowEleNo ;
::memmove /*::::::::::::::::::::::::::::::::::::::::*/
(
VPC_DestStart, VPC_MoveStart, VL_MemMoveSize
);
/*::::::::::::::::::::::::::::::::::::::::::::::::::*/
}/*
if(VL_MemMoveSize>0)*/
VPC_DestStart = VPC_ThisStart +
VL_SearchedPos + VL_DiffLength*(VL_PosListSize - i) ;
::memcpy /*::::::::::::::::::::::::::::::::::::::::*/
(
VPC_DestStart, APC_Replace, AL_Replace
);
/*::::::::::::::::::::::::::::::::::::::::::::::::::*/
VL_SearchedPre = VL_SearchedPos; --VL_NowEleNo;
AR_CPosList.ItPrev(VH_IterEasyID);
}/*
__for1(TypeLength, i, VL_PosListSize)*/
return *this;
}/*
template<typename TPosList> ZCStringBase& ReplaceByPosList ////////////////
(
TPosList& AR_CPosList ,
TypeCPChar APC_Replace ,
TypeLength AL_Replace ,
TypeLength AL_Searched
)
#########################################################################*/
private:
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
public :
/* template<typename TSearchInfoList> void MakeSplitInfoList()
APC_Search 문자열로 나뉘어지는 각 구간의 문자열 정보리스트를 얻는다.
*/
template<typename TSearchInfoList> void MakeSplitInfoList
(
TSearchInfoList& ARR_InfoList,
TypeCharC* APC_Search ,
TypeLength AL_SearchLen,
TypeLength AL_StartPos=0
)
/////////////////////////////////////////////////////////
{
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;
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;
}/*
///////////////////////////*/
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 ;
}
/*<<<<<<<<<<<<<<*/
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
(
TSearchInfoList& ARR_InfoList,
TypeCharC* APC_Search ,
TypeLength AL_SearchLen,
TypeLength AL_StartPos=0
)
///////////////////////////////////////////////////////*/
template<typename TSearchInfoList> void MakeSplitInfoList
(
TSearchInfoList& ARR_InfoList,
ZCCharViewC & AR_CCharView,
TypeLength AL_StartPos=0
)
/////////////////////////////////////////////////////////
{
MakeSplitInfoList
(
RR(ARR_InfoList) , AR_CCharView.data(),
AR_CCharView,size(), AL_StartPos
);
}
/////////////////////////////////////////////////////////
public :
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++*/
protected:
TypeLength ml_AllLen;
TypeLength ml_UseLen;
TypeChar* mpc_Data ;
public :
ZtCStringBase()
{
ml_AllLen=0;
ml_UseLen=0;
mpc_Data =0;
}/*
ZtCStringBase()*/
explicit 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, GetLength(APC_Data)
);
/////////////////////////////////////////
}/*
explicit 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(const ZCCharView& AR_View)
{
ml_AllLen=0;
ml_UseLen=0;
mpc_Data =0;
MakeWord(AR_View.data(), AR_View.size());
}/*
ZtCStringBase(const ZCCharView& AR_View)*/
explicit ZtCStringBase(TypeLength AL_Long)
{
ml_AllLen=0;
ml_UseLen=0;
mpc_Data =0;
(*this)(AL_Long);
}/*
explicit ZtCStringBase(TypeLength AL_Long)*/
~ZtCStringBase()
{
if(ml_AllLen>0) this->FiniMem(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->FiniMem(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->FiniMem(mpc_Data);
mpc_Data =this->InitMem
( (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->InitMem((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->FiniMem(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->FiniMem(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 Invalid(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(TypeLength AL_Count, TypeChar CharParam) // for string
{
return (*this)(CharParam, AL_Count);
}/*
ZCStringBase& append(TypeLength AL_Count, TypeChar CharParam)*/
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 번 더한다.
__for1(TypeLength, i, AL_LoopCnt) (*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)*/
ZCStringBase& append(const ZCCharView& AR_View)
{ return append(AR_View.data(), AR_View.size()); }
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 ) ;
/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
__for0( TypeLength, i, VL_LoopCnt )
{ 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& 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_Index2-1==ml_UseLen) return Invalid(AL_Index1);
::memmove( mpc_Data +AL_Index1 ,
mpc_Data +AL_Index2+1,
(ml_UseLen-AL_Index2-1)*sizeof(TypeChar)
/*::::*/ );
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)
{
// Invalid() 와의 차이에 주의
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& InvalidSearch ////////////////////////////////
(
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& InvalidSearch(const ZCCharView& AR_View, TypeLength AL_Index=0)
{
return InvalidSearch(AR_View.data(), AR_View.size(), AL_Index);
}/*
ZCStringBase& InvalidSearch(const ZCCharView& AR_View, TypeLength AL_Index=0)*/
ZCStringBase& InvalidSearchFromEnd(
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& InvalidSearchFromEnd(
TypeCharC* APC_Search, TypeLength AL_SearchLen, TypeLength AL_StartPos)*/
ZCStringBase& InvalidSearchFromEnd(
const ZCCharView& AR_View, TypeLength AL_StartPos)
{
return InvalidSearchFromEnd(AR_View.data(), AR_View.size(), AL_StartPos);
}/*
ZCStringBase& InvalidSearchFromEnd(
const ZCCharView& AR_View, TypeLength AL_StartPos)*/
ZCStringBase& InvalidSearchFromEnd /*///////////////*/
(
TypeCharC* APC_Search, TypeLength AL_SearchLen
)
/*##################################################*/
{
// APC_Search 를 뒤로부터 찾아서 그 부분을 무효화시킨다.
if(ml_UseLen<1) return *this;
return InvalidSearchFromEnd
(
APC_Search, AL_SearchLen, ml_UseLen-1
);
/*<<<<<<<<<<<<<<<<<<<<<<<<<<*/
}
/*##################################################*/
ZCStringBase& InvalidSearchFromEnd(const ZCCharView& AR_View)
{
return InvalidSearchFromEnd(AR_View.data(), AR_View.size());
}/*
ZCStringBase& InvalidSearchFromEnd(const ZCCharView& AR_View)*/
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, GetLength(APC_Search) );
/*++++++++++++++*/
}/*
ZCStringBase& InvalidHead(TypeCharC* APC_Search)*/
ZCStringBase& InvalidHead(const ZCCharView& AR_View)
{
return InvalidHead(AR_View.data(), AR_View.size());
}/*
ZCStringBase& InvalidHead(const ZCCharView& AR_View)*/
/*//////////////////////////////////////////////
// 가끔 오류가 나는 경우가 있어서 주석 처리한다.
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)
{ Invalid(); return *this; }
/*+++++++++++++++*/
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, GetLength(APC_Data)
);
/*:::::::::::::::::::::::::::::::::*/
}/*
ZCStringBase& operator=(TypeCharC* APC_Data)*/
ZCStringBase& operator=(const ZCCharView& AR_View)
{
Invalid(); return (*this)(AR_View.data(), AR_View.size());
}/*
ZCStringBase& operator=(const ZCCharView& AR_View)*/
ZCStringBase& operator=(int AI_Int ){Invalid(); return (*this)(AI_Int );}
ZCStringBase& operator=(long AL_Long ){Invalid(); return (*this)(AL_Long );}
ZCStringBase& operator=(double AD_Double){Invalid(); return (*this)(AD_Double);}
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+(const TypeThis& rhs)
{
return (*this)(rhs);
}/*
ZCStringBase operator+(const TypeThis& rhs)*/
ZCStringBase operator+(TypeCharC* APC_Data)
{
#if(_CODE_OLD_)
if(APC_Data==0 || APC_Data[0]+=0) return *this;
ZCStringBase VO_CStringTemp;
TypeLength VL_ArgLen =GetLength(APC_Data);
VO_CStringTemp.ReAlloc(ml_UseLen+VL_ArgLen);
VO_CStringTemp(*this) (APC_Data, VL_ArgLen);
return VO_CStringTemp;
#else
return (*this)(APC_Data);
#endif
}/*
ZCStringBase operator+(TypeCharC* APC_Data)*/
ZCStringBase operator+(const ZCCharView& AR_View)
{
#if(_CODE_OLD_)
ZCStringBase VO_CStringTemp;
VO_CStringTemp.ReAlloc
( ml_UseLen + AR_View.size() );
VO_CStringTemp(*this)
( AR_View.data(), AR_View.size() );
return VO_CStringTemp;
#else
return (*this)(AR_View);
#endif
}/*
ZCStringBase operator+(const ZCCharView& AR_View)*/
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)*/
ZCStringBase& operator+=(const ZCCharView& AR_View)
{
return (*this)(AR_View.data(), AR_View.size());
}/*
ZCStringBase& operator+=(const ZCCharView& AR_View)*/
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.data(), rhs.size()))
MoveFirst(rhs.size());
return *this; ///////////////////////////
}/*
ZCStringBase& operator-(const ZCStringBase& rhs)*/
ZCStringBase& operator-(TypeCharC* APC_Data)
{
TypeLength VL_Length = GetLength(APC_Data) ;
if(this->DoStart(APC_Data, VL_Length))
MoveFirst(VL_Length);
return *this; ////////////////////////
}/*
ZCStringBase& operator-(TypeCharC* APC_Data)*/
ZCStringBase& operator-(const ZCCharView& AR_View)
{
if(this->DoStart(AR_View.data(), AR_View.size()))
MoveFirst(AR_View.size());
return *this; ///////////////////////////////////
}/*
ZCStringBase& operator-(const ZCCharView& AR_View)*/
ZCStringBase& operator-=(TypeCharC* APC_Data)
{
TypeLength VL_Length = GetLength(APC_Data) ;
if(this->DoStart(APC_Data, VL_Length))
MoveFirst(VL_Length);
return *this; ////////////////////////
}/*
ZCStringBase& operator-=(TypeCharC* APC_Data)*/
ZCStringBase& operator-=(const ZCCharView& AR_View)
{
if(this->DoStart(AR_View.data(), AR_View.size()))
MoveFirst(AR_View.size());
return *this; ///////////////////////////////////
}/*
ZCStringBase& operator-=(const ZCCharView& AR_View)*/
bool IsEqual(TypeCharC* APC_Data, TypeLength AL_Length) const
{
return TypeThis::Minus(data(), APC_Data, size(), AL_Length)==0;
}/*
bool IsEqual(TypeCharC* APC_Data, TypeLength AL_Length) const*/
bool IsEqual(const ZCCharView& AR_View) const
{
return IsEqual(AR_View.data(), AR_View.size());
}/*
bool IsEqual(const ZCCharView& AR_View) const*/
ZCStringBase& Minus(TypeCharC* APC_Data, TypeLength AL_Length)
{
if(this->DoStart(APC_Data, AL_Length))
{ MoveFirst( AL_Length ); }
return *this; /*++++++++++++++++++++*/
}/*
ZCStringBase& Minus(TypeCharC* APC_Data, TypeLength AL_Length)*/
ZCStringBase& Minus(const ZCCharView& AR_View)
{
return Minus(AR_View.data(), AR_View.size());
}/*
ZCStringBase& Minus(const ZCCharView& AR_View)*/
ZCStringBase& Reverse()
{
/* 문자열의 순서를 뒤집는다. 문자열의 길이가 2 이상이어야 한다. */
const int CI_MinLength=2 ;
if(ml_UseLen<CI_MinLength)
{ 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)
{
Invalid(); return *this;
}
/*<<<<<<<<<<<*/
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& MakeWord(const ZCCharView& AR_View)
{
return MakeWord(AR_View.data(), AR_View.size());
}/*
ZCStringBase& MakeWord(const ZCCharView& AR_View)*/
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, GetLength(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; TypeChar VCA_BuffParam[CI_BuffSize] ;
int VI_ResultSize = /*::::::::::::::::::::::::::::::::::::::::*/
(
sizeof(TypeChar)<=1
? ::sprintf ((char* )VCA_BuffParam, /*+++++++*/ "%d", AI_IntParam)
: ::swprintf((wchar_t*)VCA_BuffParam, CI_BuffSize, L"%d", AI_IntParam)
);
return (*this)(VCA_BuffParam, VI_ResultSize); /*::::::::::::::*/
}/*
ZCStringBase& operator()(int AI_IntParam)*/
ZCStringBase& operator()(ZTypUInt AUI_UIntParam)
{
const int CI_BuffSize= 21; TypeChar VCA_BuffParam[CI_BuffSize] ;
int VI_ResultSize = /*::::::::::::::::::::::::::::::::::::::::*/
(
sizeof(TypeChar)<=1
? ::sprintf ((char* )VCA_BuffParam, /*++++++++*/ "%u", AUI_UIntParam)
: ::swprintf((wchar_t*)VCA_BuffParam, CI_BuffSize, L"%u", AUI_UIntParam)
);
return (*this)(VCA_BuffParam, VI_ResultSize); /*::::::::::::::*/
}/*
ZCStringBase& operator()(ZTypUInt AUI_UIntParam)*/
ZCStringBase& operator()(ZTypLong AL_LongParam)
{
const int CI_BuffSize= 31; TypeChar VCA_BuffParam[CI_BuffSize] ;
int VI_ResultSize = /*::::::::::::::::::::::::::::::::::::::::*/
(
sizeof(TypeChar)<=1
? ::sprintf ((char* )VCA_BuffParam, /*++++++++*/ "%ld", AL_LongParam)
: ::swprintf((wchar_t*)VCA_BuffParam, CI_BuffSize, L"%ld", AL_LongParam)
);
return (*this)(VCA_BuffParam, VI_ResultSize); /*::::::::::::::*/
}/*
ZCStringBase& operator()(ZTypLong AL_LongParam)*/
ZCStringBase& operator()(ZTypULong AUL_ULongParam)
{
const int CI_BuffSize= 31; TypeChar VCA_BuffParam[CI_BuffSize] ;
int VI_ResultSize = /*::::::::::::::::::::::::::::::::::::::::*/
(
sizeof(TypeChar)<=1
? ::sprintf ((char* )VCA_BuffParam, /*++++++++*/ "%lu", AUL_ULongParam)
: ::swprintf((wchar_t*)VCA_BuffParam, CI_BuffSize, L"%lu", AUL_ULongParam)
);
return (*this)(VCA_BuffParam, VI_ResultSize); /*::::::::::::::*/
}/*
ZCStringBase& operator()(ZTypULong AUL_ULongParam)*/
ZCStringBase& operator()(ZTypLLong ALL_LLongParam)
{
const int CI_BuffSize= 41; TypeChar VCA_BuffParam[CI_BuffSize] ;
int VI_ResultSize = /*::::::::::::::::::::::::::::::::::::::::*/
(
sizeof(TypeChar)<=1
? ::sprintf ((char* )VCA_BuffParam, /*++++++++*/ "%lld" , ALL_LLongParam)
: ::swprintf((wchar_t*)VCA_BuffParam, CI_BuffSize, L"%lld" , ALL_LLongParam)
);
return (*this)(VCA_BuffParam, VI_ResultSize); /*::::::::::::::*/
}/*
ZCStringBase& operator()(ZTypLLong ALL_LLongParam)*/
ZCStringBase& operator()(ZTypULLong AULL_LLongParam)
{
const int CI_BuffSize= 41; TypeChar VCA_BuffParam[CI_BuffSize] ;
int VI_ResultSize = /*::::::::::::::::::::::::::::::::::::::::*/
(
sizeof(TypeChar)<=1
? ::sprintf ((char* )VCA_BuffParam, /*++++++++*/ "%llu" , AULL_LLongParam)
: ::swprintf((wchar_t*)VCA_BuffParam, CI_BuffSize, L"%llu" , AULL_LLongParam)
);
return (*this)(VCA_BuffParam, VI_ResultSize); /*::::::::::::::*/
}/*
ZCStringBase& operator()(ZTypULLong AULL_LLongParam)*/
ZCStringBase& operator()(double AD_DoubleParam)
{
const int CI_BuffSize= 51; TypeChar VCA_BuffParam[CI_BuffSize] ;
int VI_ResultSize = /*::::::::::::::::::::::::::::::::::::::::*/
(
sizeof(TypeChar)<=1
? ::sprintf ((char* )VCA_BuffParam, /*++++++++*/ "%f", AD_DoubleParam)
: ::swprintf((wchar_t*)VCA_BuffParam, CI_BuffSize, L"%f", AD_DoubleParam)
);
ZNsMain::ZftTrimDecimalZero(VCA_BuffParam, RR(VI_ResultSize));
return (*this)(VCA_BuffParam, VI_ResultSize); /*::::::::::::::*/
}/*
ZCStringBase& operator()(double AD_DoubleParam)*/
ZCStringBase& operator()(bool AB_Bool)
{
typedef typename TypeThis::TypeChar TypeChar ;
typedef typename TypeThis::TypeSize TypeSize ;
typedef ZtCBoolStr
<TypeChar, TypeSize> ZCBoolStr;
return (*this)( ZCBoolStr::GetMark(AB_Bool) );
}/*
ZCStringBase& operator()(bool AB_Bool)*/
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& InvalidNull(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& InvalidNull(TypeLength AL_StartPos=0)*/
TypeLength ReadLongFromIndex(TypeLength AL_Index1, TypeLength AL_Index2)
{
// 이 함수는 약간의 속도를 위해 에러처리를 하지 않는 것에 주의
// Index1 번째 문자부터 VL_Index2 번째 문자까지 정수로 읽는다.
TypeChar* VP_Char = this->
InitMem(AL_Index2-AL_Index1+1+1/*Null Char*/);
if(VP_Char==0)
{
return 0; // Add Codes For Memory Over
}
/*//////////*/
int i;
for(i=0;i<=AL_Index2-AL_Index1;++i)
{
VP_Char[i]=mpc_Data[AL_Index1+i];
}/*
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
VP_Char[i] = 0 ; TypeLength
VL_Return = ZNsMain::ZfAtoL(VP_Char);
this->FiniMem(VP_Char); return VL_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 ;
const bool CB_IsBad = ////////////////////
(
ml_UseLen<1 || AL_Index1<0
|| AL_Index2<0 || AL_Index1>AL_Index2
);
if(CB_IsBad) return 0; ///////////////////
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
)
###############################################################################*/
TypeLength ReadLong(TypeLength AL_Index, const ZCCharView& AR_View)
{
return ReadLong(AL_Index, AR_View.data(), AR_View.size());
}/*
TypeLength ReadLong(TypeLength AL_Index, const ZCCharView& AR_View)*/
ZCStringBase& ReadCStr(
ZCStringBase& ARR_Rhs, TypeLength AL_Index1, TypeLength AL_Index2)
{
// Index1 번째 문자부터 VL_Index2 문자까지를 ARR_Rhs 에 전달한다.
return ARR_Rhs(mpc_Data+AL_Index1, AL_Index2-AL_Index1+1);
}/*
ZCStringBase& ReadCStr(
ZCStringBase& ARR_Rhs, TypeLength AL_Index1, TypeLength AL_Index2)*/
ZCStringBase& ReadString_E /*##################################################*/
(
ZCStringBase& ARR_Rhs ,
TypeLength AL_Index1 ,
TypeLength AL_Index2
)
/*#############################################################################*/
{
// Index1 번째 문자부터 VL_Index2 문자까지를 ARR_Rhs 에 전달한다.
// ReadCStr 과는 달리 에러검사를 한다.
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_Rhs;} return
ARR_Rhs( mpc_Data+AL_Index1, AL_Index2-AL_Index1+1 );
}/*
ZCStringBase& ReadString_E ######################################################
(
ZCStringBase& ARR_Rhs ,
TypeLength AL_Index1 ,
TypeLength AL_Index2
)
###############################################################################*/
ZCStringBase& ReadCStr //////////////////////////
(
ZCStringBase& ARR_Rhs ,
TypeLength AL_Index ,
TypeCharC* APC_Search ,
TypeLength AL_SearchLen
)
/*/////////////////////////////////////////////*/
{
// AL_Index 번째 문자부터 APC_Search 문자를 찾아서 그 앞부분까지 ARR_Rhs 에 전달한다.
if(AL_Index>=ml_UseLen) return ARR_Rhs;
TypeLength VL_Pos = FindPos
(APC_Search, AL_SearchLen, AL_Index);
if(VL_Pos==AL_Index) return ARR_Rhs;
if(VL_Pos<0)
VL_Pos = ml_UseLen-1;
else VL_Pos-- ;
return ReadCStr
(ARR_Rhs, AL_Index, VL_Pos);
}/*
ZCStringBase& ReadCStr //////////////////////////
(
ZCStringBase& ARR_Rhs ,
TypeLength AL_Index ,
TypeCharC* APC_Search ,
TypeLength AL_SearchLen
)
///////////////////////////////////////////////*/
ZCStringBase& ReadCStr //////////////////////////
(
ZCStringBase& ARR_Rhs, ZCCharViewC& AR_View, TypeLength AL_SearchLen
)
/*/////////////////////////////////////////////*/
{
return ReadCStr(ARR_Rhs, AR_View.data(), AR_View.size());
}
/*/////////////////////////////////////////////*/
// AL_Index 번째 부터 끝문자까지의 데이타를 가져온다.
ZCStringBase& ReadStrToEnd(ZCStringBase& ARR_Rhs, TypeLength AL_Index)
{
return ReadCStr(RR(ARR_Rhs), AL_Index, ml_UseLen-1);
}/*
ZCStringBase& ReadStrToEnd(ZCStringBase& ARR_Rhs, TypeLength AL_Index)*/
bool IsEmpty() const
{
return ml_UseLen<1;
}/*
bool IsEmpty() const*/
int GetInt () const{return ZNsMain::ZftAtoI (mpc_Data);}
ZTypLong GetLong () const{return ZNsMain::ZftAtoL (mpc_Data);}
ZTypLLong GetLongLong() const{return ZNsMain::ZftAtoLL(mpc_Data);}
ZTypLLong GetLLong () const{return ZNsMain::ZftAtoLL(mpc_Data);}
double GetDouble () const{return ZNsMain::ZftAtoD (mpc_Data);}
ZCStringBase& Format(TypeCharC* APC_Format, ...)
{
// 이 함수 수행전에 적당한 문자열 메모리가 할당되어 있어야 한다.
va_list VP_VarParam;
va_start(VP_VarParam, APC_Format);
if(sizeof(TypeChar)<=1)
::vsprintf ((char* )mpc_Data, /*+++*/ (char* )APC_Format, VP_VarParam);
else ::vswprintf((wchar_t*)mpc_Data, size(), (wchar_t*)APC_Format, VP_VarParam);
InvalidNull(); 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);
if(sizeof(TypeChar)<=1)
::vsprintf ((char* )mpc_Data, /*+++*/ (char* )APC_Format, VP_VarParam);
else ::vswprintf((wchar_t*)mpc_Data, size(), (wchar_t*)APC_Format, VP_VarParam);
InvalidNull(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;
}/*
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
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 /*///////////////////////////////////////////////////*/
(
ZCCharView& AR_Search, const ZCCharView& AR_Replace, TypeLength AL_StartPos=0
)
/*#############################################################################*/
{
return ReplaceOnce
(AR_Search.data(), AR_Replace.data(), AR_Search.size(), AR_Replace.size(), AL_StartPos);
}
/*#############################################################################*/
ZCStringBase& ReplaceOnce(
TypeCharC* APC_Search, TypeCharC* APC_Replace, TypeLength AL_StartPos=0)
{
return ReplaceOnce( /////////////////////////////////////////////////
APC_Search ,
APC_Replace ,
GetLength(APC_Search) ,
GetLength(APC_Replace) ,
AL_StartPos
/*/////////*/ ); ////////////////////////////////////////////////////
}/*
ZCStringBase& ReplaceOnce(
TypeCharC* APC_Search, TypeCharC* APC_Replace, TypeLength AL_StartPos=0)*/
ZCStringBase& Replace /*////////////////////////////////////////////////////*/
(
TypeCPChar APC_Search, TypeCPChar APC_Replace,
TypeLength AL_Search , TypeLength AL_Replace , TypeLength AL_Offset=0
)
/*##########################################################################*/
{
if(0 > AL_Offset) AL_Offset=0 ;
if(this->size() <= AL_Offset) return *this;
if(this->size() < 1 ) return *this;
ZtCBaseList<TypeLength> VO_CPosCList; FindPosToList
(
RR(VO_CPosCList), APC_Search, AL_Search, AL_Offset
);
/*////////////////////////////////////////////////*/
return ReplaceByPosList /*::::::::::::::::::::::::::::*/
(
VO_CPosCList, APC_Replace, AL_Replace, AL_Search
);
/*::::::::::::::::::::::::::::::::::::::::::::::::::::*/
}
/*##########################################################################*/
ZCStringBase& Replace ////////////////////////////////////////////////////////
(
TypeCharC* APC_Search, TypeCharC* APC_Replace, TypeLength AL_StartPos=0
)
/*##########################################################################*/
{
return Replace /////////////////////////////////////////////
(
APC_Search , APC_Replace ,
GetLength(APC_Search ), GetLength(APC_Replace), AL_StartPos
);
////////////////////////////////////////////////////////////
}
/*##########################################################################*/
ZCStringBase& Replace /*////////////////////////////////////////////////////*/
(
const TypeThis& AR_Search, const TypeThis& AR_Replace, TypeLength AL_StartPos=0
)
/*##########################################################################*/
{
return Replace /////////////////////////////////////
(
AR_Search. data(), AR_Replace.data(),
AR_Search. size(), AR_Replace.size(), AL_StartPos
);
////////////////////////////////////////////////////
}
/*##########################################################################*/
ZCStringBase& Replace /*///////////////////////////////////////////////////////*/
(
const ZCCharView& AR_CStrSearch ,
const ZCCharView& AR_CStrReplace,
TypeLength AL_StartPos=0
)
/*#############################################################################*/
{
return Replace //////////////////////////////////////
(
AR_CStrSearch. data(), AR_CStrReplace.data(),
AR_CStrSearch. size(), AR_CStrReplace.size(), AL_StartPos
);
/////////////////////////////////////////////////////
}
/*#############################################################################*/
static ZCStringBase& ReplaceSection /*#########################################*/
(
ZCStringBase& ARR_Rhs ,
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_Rhs 에 저장한다.
if(AL_SectLen<1 || AL_OriginLen<1)
{ return ARR_Rhs ; }
if(AL_ReplaceLen<0)
{ AL_ReplaceLen=0 ; }
TypeLength VL_AllMemSize=0;
// 아래 if 문에 대해서는 ReplaceFromInfoList() 를 참고
if(ARR_Rhs.data()==APC_Origin)
{
ARR_Rhs.ReAllocKeep(
VL_AllMemSize=AL_OriginLen+AL_ReplaceLen-AL_SectLen);
TypeChar* VPC_Origin2=ARR_Rhs.data();
if(AL_ReplaceLen<AL_SectLen)
{
TypeChar* VPC_Dest=ARR_Rhs.data() + AL_SectPos ;
for(int i=0; i<AL_ReplaceLen; ++i)
{
*VPC_Dest++ = APC_Replace[i] ;
}/*
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
for(int j=AL_SectPos+AL_SectLen; j<AL_OriginLen; ++j)
{
*VPC_Dest++ = VPC_Origin2[j] ;
}/*
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
ARR_Rhs.data()[VL_AllMemSize]=0;
ARR_Rhs.InvalidNull(VL_AllMemSize-1);
return ARR_Rhs;
}
else // AL_ReplaceLen>=AL_SectLen
{
TypeLength VL_NowIndex=AL_OriginLen-1 ;
TypeChar* VPC_Dest =ARR_Rhs.data()+VL_AllMemSize-1;
while(VL_NowIndex>=AL_SectPos+AL_SectLen)
{
*VPC_Dest-- = VPC_Origin2[VL_NowIndex--] ;
}
/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
for(int i=AL_ReplaceLen-1; i>=0; --i)
{
*VPC_Dest-- = APC_Replace[i] ;
}/*
///////////////////////////////////*/
ARR_Rhs.data()[VL_AllMemSize]=0;
ARR_Rhs.InvalidNull(VL_AllMemSize-1);
return ARR_Rhs;
}/*
else // AL_ReplaceLen>=AL_SectLen*/
}/*
if(ARR_Rhs.data()==APC_Origin)*/
ARR_Rhs.ReAllocKeep
(
VL_AllMemSize += ARR_Rhs.size() +
AL_OriginLen + AL_ReplaceLen - AL_SectLen
);
/////////////////////
TypeLength VL_NowIndex=AL_OriginLen-1 ;
TypeChar* VPC_Dest =ARR_Rhs.data()+VL_AllMemSize-1;
while(VL_NowIndex>=AL_SectPos+AL_SectLen)
{
*VPC_Dest-- = APC_Origin[VL_NowIndex--] ;
}
/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
for(int i=AL_ReplaceLen-1; i>=0; --i)
{
*VPC_Dest-- = APC_Replace[i] ;
}
/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
for(int j=AL_SectPos-1; j>=0; --j)
{
*VPC_Dest-- = APC_Origin[j] ;
}
/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
ARR_Rhs.data()[VL_AllMemSize]=0;
ARR_Rhs.InvalidNull(VL_AllMemSize-1);
return ARR_Rhs;
}/*
static ZCStringBase& ReplaceSection #############################################
(
ZCStringBase& ARR_Rhs ,
TypeCharC* APC_Origin ,
TypeLength AL_SectPos ,
TypeLength AL_SectLen ,
TypeCharC* APC_Replace ,
TypeLength AL_OriginLen ,
TypeLength AL_ReplaceLen
)
###############################################################################*/
static ZCStringBase& ReplaceSection /*/////////////////////////////////////////*/
(
ZCStringBase& ARR_Rhs ,
TypeCharC* APC_Origin ,
TypeLength AL_SectPos , // APC_Origin의 특정위치
TypeLength AL_SectLen ,
TypeCharC* APC_Replace
)
/*############################################################################*/
{
return ReplaceSection( ARR_Rhs , //////////////////////////////////////
APC_Origin ,
AL_SectPos ,
AL_SectLen ,
APC_Replace ,
GetLength(APC_Origin ),
GetLength(APC_Replace)
/*////////////////*/ ) ;
}
/*############################################################################*/
static ZCStringBase& ReplaceSection /*/////////////////////////////////////////*/
(
ZCStringBase& ARR_Rhs ,
ZCCharViewC& AR_Origin ,
TypeLength AL_SectPos ,
TypeLength AL_SectLen ,
ZCCharViewC& AR_Replace
)
/*############################################################################*/
{
return ReplaceSection ///////////////
(
ARR_Rhs ,
AR_Origin.data() ,
AL_SectPos ,
AL_SectLen ,
AR_Replace.data() ,
AR_Origin .size() ,
AR_Replace.size()
) ;
/////////////////////////////////////
}
/*############################################################################*/
// TSearchInfoList 은 class ZCSearchInfo 의 리스트
template<typename TSearchInfoList> ZCStringBase& ReplaceFromInfoList /*#######*/
(
TSearchInfoList& AR_InfoList ,
TypeCharC* APC_Origin ,
TypeCharC* APC_Replace ,
TypeLength AL_OriginLen ,
TypeLength AL_ReplaceLen
)
/*############################################################################*/
{
// APC_Origi n문자열을 어떤 기준에 적합한 부문자열 정보가 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.data()
인 경우에, 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); }
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--];
}/*
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
for(int p=AL_ReplaceLen-1; p>=0; --p)
{
*VPC_CharDest-- = APC_Replace[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--];
}
/*>>>>>>>>>>>>>>>>>*/
}/*
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
)
##############################################################################*/
template<typename TSearchInfoList> ZCStringBase& ReplaceFromInfoList /*///////*/
(
TSearchInfoList& AR_InfoList, ZCCharViewC& AR_Origin, ZCCharViewC& AR_Replace
)
/*############################################################################*/
{
return ReplaceFromInfoList
(
AR_InfoList,
AR_Origin.data(), AR_Replace.data(),
AR_Origin.size(), AR_Replace.size()
);
//////////////////////////
}
/*############################################################################*/
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, ZCCharViewC& AR_Replace
)
/*############################################################################*/
{
return ReplaceSection( /////////////////////
*this ,
mpc_Data ,
AL_SectPos ,
AL_SectLen ,
AR_Replace.data() ,
ml_UseLen ,
AR_Replace.size()
/*//////////*/ ); //////////////////////////
}
/*############################################################################*/
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; // 찾은 두 문자열 사이에 문자가 없을 때
}
/*:::::::::::::::::::::::::::::::::::::::::::*/
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) Invalid(VL_SearchPos1+AL_SearchLen1 );
else Invalid(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 //////////////////////////////////////////////////////
(
ZCCharViewC& AR_CStrSearch1 ,
ZCCharViewC& AR_CStrSearch2 ,
ZCCharViewC& 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( ///////////////////////////////////
TypeCharC* APC_Search1 ,
TypeCharC* APC_Search2 ,
TypeCharC* APC_Replace ,
bool AB_DoKeepSearch=false,
TypeLength AL_StartPos =0 ,
bool AB_IsExactTwo =true
/*/////////*/ ) ///////////////////////////////////////////////
{
return ReplaceRange( ////////////////////////////////////////////////
APC_Search1 ,
APC_Search2 ,
APC_Replace ,
AB_DoKeepSearch ,
AL_StartPos ,
GetLength(APC_Search1),
GetLength(APC_Search2),
GetLength(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;
}/*
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
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 ///////////////////////////////////////////////////
(
ZCCharViewC& AR_CStrSearch1 ,
ZCCharViewC& AR_CStrSearch2 ,
ZCCharViewC& 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( ////////////////////////////////
TypeCharC* APC_Search1 ,
TypeCharC* APC_Search2 ,
TypeCharC* APC_Replace ,
bool AB_DoKeepSearch=false,
TypeLength AL_StartPos =0
/*/////////*/ ) ///////////////////////////////////////////////
{
return ReplaceAllRange //>>>>>>>>>>>>>>>>>
(
APC_Search1 ,
APC_Search2 ,
APC_Replace ,
AB_DoKeepSearch ,
AL_StartPos ,
GetLength(APC_Search1),
GetLength(APC_Search2),
GetLength(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(TypeLength AL_InsertPos, const ZCCharView& AR_Insert)
{
return Insert //>>>>>>>>>>>>>>>>>>>>>>
(
AL_InsertPos ,
AR_Insert.data(),
AR_Insert.size()
);
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
}/*
ZCStringBase& Insert(TypeLength AL_InsertPos, const ZCCharView& AR_Insert)*/
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, const ZCCharView& AR_Insert
)
/*#############################################################################*/
{
return Insert_E(AL_InsertPos, AR_Insert.data(), AR_Insert.size());
}
/*#############################################################################*/
ZCStringBase& Insert_E(TypeLength AL_InsertPos, TypeCharC* APC_Insert)
{
return Insert_E /*>>>>>>>>*/
(
AL_InsertPos, APC_Insert, GetLength(APC_Insert)
) ;
/*<<<<<<<<<<<<<<<<<<<<<<<<*/
}/*
ZCStringBase& Insert_E(TypeLength AL_InsertPos, TypeCharC* APC_Insert)*/
ZCStringBase& GetSubString /*//////////////////////////////////////////////////*/
(
TypeLength AL_Index, TypeLength AL_Count, ZCStringBase& ARR_Rhs
)
/*#############################################################################*/
{
if(AL_Index<0 || AL_Count<1) return ARR_Rhs;
ARR_Rhs.ReAllocAdd(AL_Count,true); ::memcpy ////////////
(
ARR_Rhs.mpc_Data +
ARR_Rhs.ml_UseLen ,
mpc_Data + AL_Index ,
AL_Count * sizeof(TypeChar)
);
//////////////////////////////////////////////////////////
ARR_Rhs.mpc_Data
[ARR_Rhs.ml_UseLen += AL_Count] =0 ;
return ARR_Rhs ;
}/*
ZCStringBase& GetSubString //////////////////////////////////////////////////////
(
TypeLength AL_Index, TypeLength AL_Count, ZCStringBase& ARR_Rhs
)
###############################################################################*/
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;
}/*
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
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_Rhs ,
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_Rhs) ,
AB_IsExactTwo
/*/////////*/ ); ////////////////////////
}/*
ZCStringBase& GetSubSearch( #######################################
TypeCharC* APC_Find1 ,
TypeCharC* APC_Find2 ,
TypeLength AL_Find1Len ,
TypeLength AL_Find2Len ,
ZCStringBase& ARR_Rhs ,
bool AB_IsExactTwo=false
############# ) const ##########################################*/
ZCStringBase& GetSubSearch( /*###################################*/
TypeCharC* APC_Find1 ,
TypeCharC* APC_Find2 ,
TypeLength& ARRL_StartPos,
ZCStringBase& ARR_Rhs ,
bool AB_IsExactTwo=false
/*#########*/ ) const /*########################################*/
{
return GetSubSearch( //////////////////////////////////////////////
mpc_Data ,
APC_Find1 ,
APC_Find2 ,
ml_UseLen ,
GetLength(APC_Find1),
GetLength(APC_Find2),
RR(ARRL_StartPos) ,
RR(ARR_Rhs) ,
AB_IsExactTwo
/*/////////*/ ); //////////////////////////////////////////////////
}/*
ZCStringBase& GetSubSearch( #######################################
TypeCharC* APC_Find1 ,
TypeCharC* APC_Find2 ,
TypeLength& ARRL_StartPos,
ZCStringBase& ARR_Rhs ,
bool AB_IsExactTwo=false
############# ) const ##########################################*/
ZCStringBase& GetSubSearch( /*###################################*/
TypeCharC* APC_Find1 ,
TypeCharC* APC_Find2 ,
ZCStringBase& ARR_Rhs ,
bool AB_IsExactTwo=false
/*#########*/ ) const /*########################################*/
{
TypeLength VL_StartPos=0;
return GetSubSearch( //////////////////////////////////////////////
mpc_Data ,
APC_Find1 ,
APC_Find2 ,
ml_UseLen ,
GetLength(APC_Find1),
GetLength(APC_Find2),
RR(VL_StartPos) ,
RR(ARR_Rhs) ,
AB_IsExactTwo
/*/////////*/ ); //////////////////////////////////////////////////
}/*
ZCStringBase& GetSubSearch( #######################################
TypeCharC* APC_Find1 ,
TypeCharC* APC_Find2 ,
ZCStringBase& ARR_Rhs ,
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
/*//////////*/ ); //////////////////////////////
}
/*############################################################################*/
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 ##########################################*/
static ZCStringBase& GetSubSearch //////////////////////////////////////////////
(
const ZCCharView& AR_CStringOrigin,
const ZCCharView& AR_CStringFind1 ,
const ZCCharView& 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
/*//////////*/ ); //////////////////////////////
}
/*############################################################################*/
ZCStringBase& GetSubSearch( /*###################################*/
const ZCCharView& AR_CStringFind1,
const ZCCharView& 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 ZCCharView& AR_CStringFind1,
const ZCCharView& AR_CStringFind2,
TypeLength& ARRL_StartPos ,
ZCStringBase& ARR_CStringSave,
bool AB_IsExactTwo=false
############# ) const ##########################################*/
ZCStringBase& GetSubSearch( /*###################################*/
const ZCCharView& AR_CStringFind1,
const ZCCharView& 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 ZCCharView& AR_CStringFind1,
const ZCCharView& AR_CStringFind2,
ZCStringBase& ARR_CStringSave,
bool AB_IsExactTwo=false
############# ) const ##########################################*/
ZCStringBase GetSubSearch( /*####################################*/
const ZCCharView& AR_CStringFind1,
const ZCCharView& AR_CStringFind2,
bool AB_IsExactTwo=false
/*#########*/ ) const /*########################################*/
{
ZCStringBase VO_SaveCStr; return GetSubSearch(
AR_CStringFind1, AR_CStringFind2, RR(VO_SaveCStr), AB_IsExactTwo);
}/*
ZCStringBase GetSubSearch( #######################################
const ZCCharView& AR_CStringFind1,
const ZCCharView& 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_Rhs ,
bool AB_IsExactTwo=false
)
/*##############################################################*/
{
TypeLength VL_MatchLen= 0 ;
TypeLength VL_Pos1 = FindPosByList
(
APC_Origin , AR_FindList1 ,
AL_OriginLen, RR(VL_MatchLen), ARRL_StartPos
);
/////////////////////////////////////
if(VL_Pos1<0){ return ARR_Rhs; }
VL_Pos1 += VL_MatchLen ;
TypeLength VL_Pos2 = FindPosByList //////////
(
APC_Origin , AR_FindList2 ,
AL_OriginLen, RR(VL_MatchLen), VL_Pos1
);
//////////////////////////////////////////////
if(VL_Pos2<0)
{
if(AB_IsExactTwo==true)
{
ARRL_StartPos=-1; return ARR_Rhs;
}/*
>>>>>>>>>>>>>>>>>>>>>*/
ARRL_StartPos=AL_OriginLen;
ARR_Rhs.MakeWord(
APC_Origin+VL_Pos1, AL_OriginLen-VL_Pos1);
return ARR_Rhs; ///////
}/*
if(VL_Pos2<0)*/
ARRL_StartPos = VL_Pos2+VL_MatchLen ;
ARR_Rhs.MakeWord
(APC_Origin+VL_Pos1, VL_Pos2-VL_Pos1);
return ARR_Rhs;
}/*
template<typename TStringList> static ZCStringBase& GetSubSearchEx
(
TypeCharC* APC_Origin ,
TStringList AR_FindList1 ,
TStringList AR_FindList2 ,
TypeLength AL_OriginLen ,
TypeLength& ARRL_StartPos ,
ZCStringBase& ARR_Rhs ,
bool AB_IsExactTwo=false
)
################################################################*/
template<typename TStringList> static ZCStringBase& GetSubSearchEx(
TypeCharC* APC_Origin ,
TStringList AR_FindList1 ,
TStringList AR_FindList2 ,
TypeLength& ARRL_StartPos ,
ZCStringBase& ARR_Rhs ,
bool AB_IsExactTwo=false
/*//////////*/ ) //////////////////////////////////////////////////
{
return GetSubSearchEx( /////////////////////////////////////////////
APC_Origin ,
AR_FindList1 ,
AR_FindList2 ,
GetLength(APC_Origin) ,
ARRL_StartPos ,
ARR_Rhs ,
AB_IsExactTwo
/*//////////*/ ); //////////////////////////////////////////////////
}/*
template<typename TStringList> static ZCStringBase& GetSubSearchEx(
TypeCharC* APC_Origin ,
TStringList AR_FindList1 ,
TStringList AR_FindList2 ,
TypeLength& ARRL_StartPos ,
ZCStringBase& ARR_Rhs ,
bool AB_IsExactTwo=false
//////////// ) ////////////////////////////////////////////////*/
template<typename TStringList> ZCStringBase& GetSubSearchEx( //////
TStringList AR_FindList1 ,
TStringList AR_FindList2 ,
TypeLength& ARRL_StartPos ,
ZCStringBase& ARR_Rhs ,
bool AB_IsExactTwo=false
/*//////////*/ ) //////////////////////////////////////////////////
{
return GetSubSearchEx( ///////////////////
mpc_Data ,
AR_FindList1 ,
AR_FindList2 ,
ml_UseLen ,
RR(ARRL_StartPos) ,
RR(ARR_Rhs) ,
AB_IsExactTwo
/*/////////*/ ); /////////////////////////
}/*
template<typename TStringList> ZCStringBase& GetSubSearchEx( //////
TStringList AR_FindList1 ,
TStringList AR_FindList2 ,
TypeLength& ARRL_StartPos ,
ZCStringBase& ARR_Rhs ,
bool AB_IsExactTwo=false
/*/////////// ) /////////////////////////////////////////////////*/
template<typename TStringList> ZCStringBase& GetSubSearchEx( //////
TStringList AR_FindList1 ,
TStringList AR_FindList2 ,
ZCStringBase& ARR_Rhs ,
bool AB_IsExactTwo=false
/*/////////*/ ) ///////////////////////////////////////////////////
{
TypeLength VL_StartPos=0;
return GetSubSearchEx( //////////////////
mpc_Data ,
AR_FindList1 ,
AR_FindList2 ,
ml_UseLen ,
RR(VL_StartPos) ,
RR(ARR_Rhs) ,
AB_IsExactTwo
/*/////////*/ ); ////////////////////////
}/*
template<typename TStringList> ZCStringBase& GetSubSearchEx( //////
TStringList AR_FindList1,
TStringList AR_FindList2,
ZCStringBase& ARR_Rhs ,
bool AB_IsExactTwo=false
//////////// ) /////////////////////////////////////////////////*/
template<typename TFunctor> static void Split /*#################*/
(
TFunctor AO_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)
{
ZtCTypeData<TFunctor>::GetObjRef(AO_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=0;
for(; j<AL_SearchLen; ++j)
{
if(APC_OriginChar[VL_Index+j]!=APC_SearchChar[j]) break;
}/*
>>>>>>>>>>>>>>>>>>>>>>>>*/
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)
{
ZtCTypeData<TFunctor>::
GetObjRef(AO_TFunctor)(RR(VO_CStringList));
return; //////////////
}/*
if(VL_CopyStartPos>=AL_OriginLen)*/
if(VO_CStringList.IsEmpty() && VL_CopyStartPos==0)
{
ZtCTypeData<TFunctor>::GetObjRef
(AO_TFunctor)(APC_OriginChar, AL_OriginLen) ;
}
else
{
((ZCStringBase&)VO_CStringList).append
(
APC_OriginChar+VL_CopyStartPos, AL_OriginLen-VL_CopyStartPos
) ;
//////////////////////////////////////
ZtCTypeData<TFunctor>::
GetObjRef(AO_TFunctor)(RR(VO_CStringList)) ;
}/*
else*/
}/*
template<typename TFunctor> static void Split ####################
(
TFunctor AO_TFunctor ,
TypeCharC* APC_OriginChar,
TypeCharC* APC_SearchChar,
TypeLength AL_OriginLen ,
TypeLength AL_SearchLen
)
#################################################################*/
template<typename TFunctor> void Split( //////////////////////////
TFunctor AO_TFunctor ,
TypeCharC* APC_Search ,
TypeLength AL_SearchLen ,
TypeLength AL_StartPos=0
/*//////////*/ ) /////////////////////////////////////////////////
{
Split(AO_TFunctor, mpc_Data+AL_StartPos, APC_Search, ml_UseLen, AL_SearchLen);
}/*
template<typename TFunctor> void Split( //////////////////////////
TFunctor AO_TFunctor ,
TypeCharC* APC_Search ,
TypeLength AL_SearchLen,
TypeLength AL_StartPos=0
///////// ) ////////////////////////////////////////////////////*/
template<typename TFunctor, typename TSplitList> static void SplitEx
(
TFunctor AO_TFunctor ,
TypeCharC* APC_OriginChar ,
TypeCharC* APC_SearchChar ,
TypeLength AL_OriginLen ,
TypeLength AL_SearchLen
)
/*################################################################*/
{
typedef typename TSplitList::TypeData ZCString; TSplitList VO_CStringList;
/*/////////////////////////////////////////////////////////////////////////////////////
■ 이 함수는 찾아낸 문자열을 복사해서 VO_CStringList 에 담는데, 펑크터는 구분 문자열로
나뉜 문자가 없을 경우 (즉 찾아낸 문자열을 별도로 할당할 필요가 없을 경우) 원래 문자
열 APC_OriginChar 을 인수로 받고 그 외에는 VO_CStringList 참조를 인수로 받는다. 따
라 서 펑크터는 TypeChar* 과 VO_CStringList 을 인수로 받는 () 연산자를 가져야 한다.
/////////////////////////////////////////////////////////////////////////////////////*/
if(AL_OriginLen<1) return;
if(AL_SearchLen<1)
{
ZtCTypeData<TFunctor>::GetObjRef
(AO_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;
}/*
>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
if(j!=AL_SearchLen) /*AAAAA*/
{
++VL_Index; continue; // 못찾은 경우
}/*
AAAAAAAAAAAAAAAAAAAAAAAAAAA*/
if(VL_Index>VL_CopyStartPos)
{
((ZCString&)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)
{
ZtCTypeData<TFunctor>::GetObjRef
(AO_TFunctor)(RR(VO_CStringList)); return;
}/*
if(VL_CopyStartPos>=AL_OriginLen)*/
if(VO_CStringList.IsEmpty() && VL_CopyStartPos==0)
{
ZtCTypeData<TFunctor>::GetObjRef
(AO_TFunctor)(APC_OriginChar, AL_OriginLen) ;
}
else
{
((ZCStringBase&)VO_CStringList).append
(
APC_OriginChar+VL_CopyStartPos,
AL_OriginLen -VL_CopyStartPos
) ;
///////////////////////////////////////
ZtCTypeData<TFunctor>::GetObjRef
(AO_TFunctor)(RR(VO_CStringList)) ;
}/*
else*/
}/*
template<typename TFunctor, typename TSplitList> static void SplitEx
(
TFunctor AO_TFunctor ,
TypeCharC* APC_OriginChar,
TypeCharC* APC_SearchChar,
TypeLength AL_OriginLen ,
TypeLength AL_SearchLen
)
##################################################################*/
template
<typename TFunctor, typename TSplitList> ///////////////////////////////////
void SplitEx
(
TFunctor AO_TFunctor ,
TypeCharC* APC_SearchChar,
TypeLength AL_SearchLen ,
TypeLength AL_StartPos=0
)
/*############################################################################*/
{
SplitEx<TFunctor, TSplitList>( ///////////////
AO_TFunctor ,
mpc_Data+AL_StartPos,
APC_SearchChar ,
ml_UseLen ,
AL_SearchLen
/*//////////*/ ); ////////////////////////////
}
/*############################################################################*/
template
<typename TFunctor, typename TSplitList> ///////////////////////////////////
void SplitEx
(
TFunctor AO_TFunctor, ZCCharViewC& AR_Search, TypeLength AL_StartPos=0
)
/*############################################################################*/
{
SplitEx<TFunctor, TSplitList>( ///////////////
AO_TFunctor ,
mpc_Data+AL_StartPos,
AR_Search.data() ,
ml_UseLen ,
AR_Search.size()
/*//////////*/ ); ////////////////////////////
}
/*############################################################################*/
template<typename TFunctor> static void SplitEach /*############*/
(
TFunctor AO_TFunctor ,
TypeCharC* APC_OriginChar ,
TypeCharC* APC_SearchChar ,
TypeLength AL_OriginLen ,
TypeLength AL_SearchLen ,
bool AB_DoExecNull =true
)
/*##############################################################*/
{
/* bool AB_DoExecNull 이 true 이면 구분 문자로 잘린 문자열 길이
가 0 인 경우에도 AO_TFunctor 를 수행한다. */
if(AL_OriginLen<1){return;} int VL_SearchCount=0;
if(AL_SearchLen<1)
{
ZtCTypeData<TFunctor>::GetObjRef(AO_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;
}/*
>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
if(j!=AL_SearchLen) /*AAAAA*/
{
++VL_Index; continue; // 못찾은 경우
}/*
AAAAAAAAAAAAAAAAAAAAAAAAAAA*/
// 찾은 경우
if(VL_Index>VL_CopyStartPos)
{
ZtCTypeData<TFunctor>::GetObjRef(AO_TFunctor)
(
APC_OriginChar+VL_CopyStartPos,
VL_Index -VL_CopyStartPos,
++VL_SearchCount
) ;
/////////////////////////////////////////////
}
else if(AB_DoExecNull==true)
{
ZtCTypeData<TFunctor>::GetObjRef
(AO_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)
{
ZtCTypeData<TFunctor>::GetObjRef(AO_TFunctor)
(
APC_OriginChar, AL_OriginLen, ++VL_SearchCount
) ;
/////////////////////////////////////////////
}
else
{
ZtCTypeData<TFunctor>::GetObjRef(AO_TFunctor)
(
APC_OriginChar+VL_CopyStartPos,
AL_OriginLen -VL_CopyStartPos,
++VL_SearchCount
) ;
/////////////////////////////////////////////
}
}/*
template<typename TFunctor> static void SplitEach ################
(
TFunctor AO_TFunctor ,
TypeCharC* APC_OriginChar ,
TypeCharC* APC_SearchChar ,
TypeLength AL_OriginLen ,
TypeLength AL_SearchLen ,
bool AB_DoExecNull =true
)
################################################################*/
template<typename TFunctor> void SplitEach /*/////////////////////////////////*/
(
TFunctor AO_TFunctor ,
TypeCharC* APC_SearchChar,
TypeLength AL_SearchLen ,
TypeLength AL_StartPos=0 ,
bool AB_DoExecNull=true
)
/*############################################################################*/
{
SplitEach<TFunctor> /////////
(
AO_TFunctor ,
mpc_Data+AL_StartPos,
APC_SearchChar ,
ml_UseLen ,
AL_SearchLen ,
AB_DoExecNull
);
/*/////////////////////////*/
}
/*############################################################################*/
template<typename TFunctor> void SplitEach /*/////////////////////////////////*/
(
TFunctor AO_TFunctor ,
ZCCharViewC& AR_Search ,
TypeLength AL_StartPos=0 ,
bool AB_DoExecNull=true
)
/*############################################################################*/
{
SplitEach<TFunctor> /////////
(
AO_TFunctor ,
mpc_Data+AL_StartPos,
AR_Search.data() ,
ml_UseLen ,
AR_Search.size() ,
AB_DoExecNull
);
/*/////////////////////////*/
}
/*############################################################################*/
// 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 ZCString;
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;
}/*
>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
if(j!=AL_SearchLen)
{
++VL_Index; continue; // 못찾은 경우
}/*
if(j!=AL_SearchLen)*/
// 찾은 경우
if(VL_Index>VL_CopyStartPos)
{
if(AB_DoAppendEachLink==true)
{
((ZCString&)ARR_SaveList).append
(
APC_OriginChar+VL_CopyStartPos, VL_Index-VL_CopyStartPos
) ;
////////////////////////////////
}
else
{
((ZCString&)ARR_SaveList).Invalid().append
(
APC_OriginChar+VL_CopyStartPos, VL_Index-VL_CopyStartPos
) ;
//////////////////////////////////////////
}/*
else*/
}
else if(AB_DoAppendEmpty==true)
{
(ZCString&)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).Invalid().
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 ,
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 ,
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(GetLength(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 ZCString;
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 ;
ZCString 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;
}/*
>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
if(j!=AL_SearchLen)
{
++VL_Index; continue; // 못찾은 경우
}/*
if(j!=AL_SearchLen)*/
// 찾은 경우
if(VL_Index>VL_CopyStartPos)
{
VO_CStringTemp.Invalid();
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_PrevListSize<ARR_SaveList.size() || AB_DoEndWhenNoMatch==false)
{
/* VL_PrevListSize==ARR_SaveList.size() 인 경우는, 분리
문자열을 찾을 수 없는 경우다. 이때는 아무짓도 하지 말자.
*/
VO_CStringTemp.Invalid();
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
, ZCCharViewC& AR_Search
, ZCCharViewC& AR_WrapStart
, ZCCharViewC& AR_WrapClose
, bool AB_DoEndWhenNoMatch=true
, bool AB_DoAppendEachLink=false
) const
/*############################################################################*/
{
return ZCMainChars::SplitToListWrap
(
RR(ARR_SaveList) ,
mpc_Data ,
AR_Search.data() ,
AR_WrapStart.data() ,
AR_WrapClose.data() ,
ml_UseLen ,
AR_Search.size() ,
AR_WrapStart.size() ,
AR_WrapClose.size() ,
AB_DoEndWhenNoMatch ,
AB_DoAppendEachLink
);
}
/*############################################################################*/
// 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 ZCString;
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;
}/*
>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
if(j<AL_SearchLen)
{
if(i>VL_CopyStartPos)
{
((ZCString&)ARR_SaveList).append
( VP_CopyStartChar, 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)
{
((ZCString&)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, ZCCharViewC& AR_Search) const
{
return SplitByCondOr<TStringList>
(
RR(ARR_SaveList),
mpc_Data , AR_Search.data(),
ml_UseLen , AR_Search.size()
);
/////////////////////////////////
}/*
template<typename TStringList> TStringList& SplitByCondOr
(TStringList& ARR_SaveList, ZCCharViewC& AR_Search) 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;
}/*
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
// 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;
}/*
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
}/*
if(k>=AL_SearchMinLen)*/
if(k>=VL_SearchLen)
{
break; // 이때는 찾는 문자열이 있는 것이다.
}/*
>>>>>>>>>>>>>>>>>*/
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=0;
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;
}/*
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
// 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;
}/*
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
}/*
if(k>=AL_SearchMinLen)*/
if(k>=VL_SearchLen) // 이때는 찾는 문자열이 있는 것이다.
{break;}
/*@@@@@@@@@@@@@@@*/
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.Invalid();
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.Invalid();
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).Invalid().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).Invalid().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
)
################################################################*/
ZCStringList& ExtractBetweenToList /*###########################*/
(
ZCStringList& ARR_SaveList,
ZCCharViewC& AR_Search1 ,
ZCCharViewC& AR_Search2 ,
bool AB_DoIncludeSearch=false
) const
/*##############################################################*/
{
return ExtractBetweenToList ////////////////////////////
(
RR(ARR_SaveList) ,
mpc_Data ,
AR_Search1.data() ,
AR_Search2.data() ,
ml_UseLen ,
AR_Search1.size() ,
AR_Search2.size() ,
AB_DoIncludeSearch
);
////////////////////////////////////////////////////////
}
/*##############################################################*/
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 ZCString;
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)
{
((ZCString&)ARR_SaveList).Invalid().append
(
APC_OriginChar+VL_Pos1, VL_Pos2-VL_Pos1+AL_Search2Len
) ;
/*::::::::::::::::::::::::::::::::::::::*/
}
else if(VL_Pos2>VL_Pos1+AL_Search1Len) // AB_DoIncludeSearch==false
{
((ZCString&)ARR_SaveList).Invalid().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,
ZCCharViewC& AR_Search1 ,
ZCCharViewC& AR_Search2 ,
bool AB_DoIncludeSearch=false
) const
/*############################################################################*/
{
return ExtractBetweenToListType<TypeList> //////////////
(
ARR_SaveList ,
mpc_Data ,
AR_Search1.data() ,
AR_Search2.data() ,
ml_UseLen ,
AR_Search1.size() ,
AR_Search2.size() ,
AB_DoIncludeSearch
);
////////////////////////////////////////////////////////
}
/*############################################################################*/
template<typename TStringList>
static TStringList& MakeNullAllLink(TStringList& ARR_SaveList)
{
/* 리스트 자료구조는 프로그램상에서 구현한 정적 버퍼에서 링크를 만들어서 가져오고
링크가 삭제될 때도 이 정적버퍼로 보내게 되는데 이 링크를 다시 가져올 때 원치
않는 자료가 이미 있을 수 있으므로 각 링크를 Null 로 초기화한다. */
TypeLength VL_MaxLoop =ARR_SaveList.GetSize();
IterEasyID VO_IterEasy=ARR_SaveList.ItHID ();
for(TypeLength i=0; i<VL_MaxLoop; ++i)
{
ARR_SaveList.ItD(VO_IterEasy).Invalid();
ARR_SaveList.ItNext(VO_IterEasy);
}/*
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
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];
}/*
>>>>>>>>>>>>>>>*/
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];
}/*
>>>>>>>>>>>>>>>*/
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];
}/*
>>>>>>>>>>>>>>>*/
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];
}/*
>>>>>>>>>>>>>>>*/
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];
}/*
>>>>>>>>>>>>>>>>>>>>>>>>>*/
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_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, ZCCharViewC& AR_Add)
{
return AddPerChunk ///////////////////////////////
(
AL_ChunkSize, AR_Add.data(), AR_Add.size()
);
//////////////////////////////////////////////////
}/*
ZCStringBase& AddPerChunk(TypeLength AL_ChunkSize, TypeCharC* APC_AddChar)*/
#ifdef _WIN
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; TypeLength VL_WriteCnt=ml_UseLen*sizeof(TypeChar);
return ::WriteFile //::::::::::::::::::::::::::::::::::::::::::::::::::::
(
AH_FileHandle ,
mpc_Data ,
VL_WriteCnt ,
&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 VL_AllSize = ml_UseLen*sizeof(TypeChar) ;
return ::write(
AH_FileDesc, mpc_Data, VL_AllSize)>=VL_AllSize ;
}/*
bool WriteFile(int AH_FileDesc) const*/
bool WriteFile(FILE* AP_HFile) const
{
if(ml_UseLen<1) return true;
TypeLength VL_AllSize = ml_UseLen;
return ::fwrite(
mpc_Data, sizeof(TypeChar), VL_AllSize, AP_HFile)>=VL_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 = ::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) ; // 덧붙이는 경우가 아니면, 기존 내용을 지운다.
TypeLength VL_AllSize = ml_UseLen*sizeof(TypeChar);
DWORD NumberOfBytesWritten = 0 ; const BOOL CB_IsWriteOK =
::WriteFile(VH_File, mpc_Data, VL_AllSize, &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; }
}
TypeLength VL_AllSize = ml_UseLen*sizeof(TypeChar);
if(write(AH_FileDesc, mpc_Data, VL_AllSize)<VL_AllSize)
{
::close(AH_FileDesc); return false;
}/*
if(write(AH_FileDesc, mpc_Data, VL_AllSize)<VL_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 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_StartPos=0
)
/*##############################################################*/
{
return FindPos ///////////////////////////////////////////////
(
APC_Origin , APC_Search ,
GetLength(APC_Origin) , GetLength(APC_Search) ,
AL_StartPos
);
//////////////////////////////////////////////////////////////
}
/*##############################################################*/
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) const
{
return FindPos /*********************************************/
(
mpc_Data , APC_Search, ml_UseLen, GetLength(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 FindPos(const ZCCharView& AR_View, TypeLength AL_StartPos=0) const
{
return FindPos(mpc_Data, AR_View.data(), ml_UseLen, AR_View.size(), AL_StartPos) ;
}/*
TypeLength FindPos(const ZCCharView& AR_View, 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 /*//////////////////////////////////////////////////////*/
(
ZCCharViewC& AR_Search, ZCCharViewC& AR_Escape, TypeLength AL_StartPos=0
) const
/*############################################################################*/
{
return ZCMainChars::FindPosEsc
(
mpc_Data , AR_Search.data(), AR_Escape.data(),
ml_UseLen, AR_Search.size(), AR_Escape.size(), AL_StartPos
);
//////////////////////////////
}
/*############################################################################*/
TypeLength FindPosEsc //////////////////////////////////////////////////////////
(
TypeCharC* APC_Search, TypeCharC* APC_Escape, TypeLength AL_StartPos=0
) const
/*############################################################################*/
{
return ZCMainChars::FindPosEsc
(
mpc_Data , APC_Search,
APC_Escape, ml_UseLen ,
GetLength(APC_Search) ,
GetLength(APC_Escape) , AL_StartPos
);
//////////////////////////////
}
/*############################################################################*/
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;
}
/*############################################################################*/
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(ZCCharViewC& AR_Search, TypeLength AL_StartPos=0) const
{
return FindPosFromEnd(AR_Search.data(), AR_Search.size(), AL_StartPos);
}/*
TypeLength FindPosFromEnd(ZCCharViewC& AR_Search, TypeLength AL_StartPos=0) 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, GetLength(APC_Search)
) ;
/////////////////////
}/*
TypeLength FindPosFromEnd(TypeCharC* APC_Search) const*/
template<typename TList> static TypeLength FindPosByList
(
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.ItHID());
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.ItNext(VI_IterEasyID);
}/*
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
}/*
for(TypeLength i=AL_StartPos; i<AL_OriginLen; ++i)*/
return -1;
}/*
template<typename TList> static TypeLength FindPosByList
(
TypeCharC* APC_Origin ,
TList& AR_SearchList ,
TypeLength AL_OriginLen ,
TypeLength& ARRL_MatchLen ,
TypeLength AL_StartPos=0
)
######################################################*/
template<typename TList> static TypeLength FindPosByList ///////////////////////
(
TypeCharC* APC_Origin ,
TList& AR_SearchList,
TypeLength& ARRL_MatchLen
)
/*############################################################################*/
{
return FindPosByList
(
APC_Origin, AR_SearchList, GetLength(APC_Origin), ARRL_MatchLen
);
//////////////////
}
/*############################################################################*/
template<typename TList> static TypeLength
FindPosByList(TypeCharC* APC_Origin, TList& AR_SearchList)
{
TypeLength VL_MatchLen=0; return FindPosByList //////
(
APC_Origin , AR_SearchList,
GetLength(APC_Origin), RR(VL_MatchLen)
);
/////////////////////////////////////////////////////
}/*
template<typename TList> static TypeLength
FindPosByList(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;}
}/*
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
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, GetLength(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_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, GetLength(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;
}/*
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
}/*
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)
{
return IsDigit ///////////
(
APC_CheckChar, GetLength(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
)
/*################################################################*/
{
// APC_Origin 문자열이 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)
{
return DoStart /*****************************************/
(
APC_Origin , APC_FindChars
, GetLength(APC_Origin ), GetLength(APC_FindChars)
);
/********************************************************/
}/*
static bool DoStart(TypeCharC* APC_Origin, TypeCharC* APC_FindChars)*/
bool DoStart(TypeCharC* APC_FindChars, TypeLength AL_FindLen) const
{
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*/
bool DoStart(TypeCharC* APC_FindChars) const
{
return DoStart( APC_FindChars, GetLength(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 DoStart(const ZCCharView& AR_View) const
{
return this->DoStart(AR_View.data(), AR_View.size());
}/*
bool DoStart(const ZCCharView& AR_View) 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, GetLength(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 DoClose(const ZCCharView& AR_View) const
{
return ZCMainChars::DoClose
(mpc_Data, AR_View.data(), ml_UseLen, AR_View.size());
}/*
bool DoClose(const ZCCharView& AR_View) 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, GetLength(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*/
bool DoWrap(const ZCCharView& AR_View) const
{
return ZCMainChars::DoWrap
(mpc_Data, AR_View.data(), ml_UseLen, AR_View.size());
}/*
bool DoWrap(const ZCCharView& AR_View) 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-- ;
}/*
>>>>>>>>>>>>>>>>>>>>>>*/
/* 오른쪽으로 문자열을 이동시키게 됨에 따라, 앞에서
비게 되는 문자열을 AC_FillChar 로 채운다. */
VPC_CharOrgin=mpc_Data;
for(i=1; i<=AL_RightMoveCnt; ++i)
{
*VPC_CharOrgin++ = AC_FillChar ;
}/*
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
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 Invalid(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 Invalid(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(TypeLength 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(TypeLength AI_RotateSize)*/
ZCStringBase& Trim()
{
ZCMainChars::Trim(mpc_Data, RR(ml_UseLen));
if(mpc_Data!=0) mpc_Data[ml_UseLen]=0;
return *this; /*::::::::::::::::::::*/
}/*
ZCStringBase& Trim()*/
ZCStringBase& TrimDecimalZero()
{
TypeChar* VPC_StartChar=mpc_Data ;
TypeLength AI_LengthDec =ml_UseLen;
TypeLength VL_PeriodPos =0 ;
TypeLength VL_CurrentPos=0 ;
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;
}
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;
}/*
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;
}/*
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;
}/*
>>>>>>>>>>>>>>>>>>>>>>>*/
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)
{
return Minus ///////////////////
(
APC_Left, APC_Right, GetLength(APC_Left), GetLength(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, GetLength(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*/
int Minus(const ZCCharView& AR_View) const
{
return Minus(mpc_Data, AR_View.data(), ml_UseLen, AR_View.size());
}/*
int Minus(const ZCCharView& AR_View) 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);
}/*
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
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, GetLength(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(const ZCCharView& AR_FullPath)
{
return GetDirFromPath(RR(*this), AR_FullPath.data(), AR_FullPath.size());
}/*
ZCStringBase& GetDirFromPath(const ZCCharView& AR_FullPath)*/
ZCStringBase& GetDirFromPath(TypeCharC* APC_FullPath)
{
return GetDirFromPath
(
RR(*this), APC_FullPath, GetLength(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, GetLength(".")
);
////////////////////////////////////////////////////
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, GetLength(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(const ZCCharView& AR_FullName)
{
return MinusExt(RR(*this), AR_FullName.data(), AR_FullName.size());
}/*
ZCStringBase& MinusExt(const ZCCharView& AR_FullName)*/
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, GetLength(".")
);
////////////////////////////////////////////////
if(AL_StartPos<0)
return *this; // 확장자 구분표시 '.' 이 없을 경우
else
return Invalid(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;
}
/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
TypeLength AL_StartPos = FindPosFromEnd ////////////
(
APC_FullPath, ".", AL_FullPathLen, GetLength(".")
);
////////////////////////////////////////////////////
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, GetLength(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(const ZCCharView& AR_FullPath)
{
return GetExtFromPath(RR(*this), AR_FullPath.data(), AR_FullPath.size());
}/*
ZCStringBase& GetExtFromPath(const ZCCharView& AR_FullPath)*/
ZCStringBase& GetExtFromPath(TypeCharC* APC_FullPath)
{
return GetExtFromPath(RR(*this), APC_FullPath, GetLength(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, GetLength(".")
);
////////////////////////////////////////////////
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)
{
SplitPath ///////////////////////////////////////////////////
(
RR(ARR_CStrNoExt), RR(ARR_CStrExt),
APC_FullPath , GetLength(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, GetLength(APC_Data)
);
/////////////////////////////////
}/*
int Compare(const TypeChar* APC_Data) const*/
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; //////////////
}
/*<<<<<<<<<<<<<<<<<<<<<<<<*/
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, GetLength(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)
{
return FindBackward
(
APC_FindChars, GetLength(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::ZCCharView ZCCharView ;
typedef typename ZCStringBase::TypeLength TypeLength ;
typedef typename ZCStringBase::TypeLength TypeSize ;
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)*/
ZtCStringEx(const ZCCharView& AR_View) : TypeBase(AR_View)
{
ml_ListBuffAllByte=0;
}/*
ZtCStringEx(const ZCCharView& AR_View)*/
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)
{
if(this->data()==APC_Data) {return *this;}
(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)
{
return AddList
(
APC_AddData, GetLength(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)
{
return AddListTail
(
APC_AddData, GetLength(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 VO_IterEasy = mo_CStringListBuff.ItHID();
for(TypeLength i=1; i<=VL_ListSize; ++i)
{
ARR_CStringSave += mo_CStringListBuff.ItD(VO_IterEasy);
mo_CStringListBuff.ItNext(VO_IterEasy);
}
/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
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(); }
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, GetLength(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
) */
#define _ZCSTRINGBASE_ ZtCStringBase \
< TTypCh, TAlloc, TAllocSize, TTypeString >
#define _ZCSTRINGBASE_ARG_ \
template< typename TTypCh , typename TAlloc , \
typename TAllocSize , typename TTypeString \
>
_ZCSTRINGBASE_ARG_ _ZCSTRINGBASE_& ZftMakeStr
( _ZCSTRINGBASE_& ARR_SaveCStr, const _ZCSTRINGBASE_& AR_DataCStr)
{ return ARR_SaveCStr(AR_DataCStr); }
_ZCSTRINGBASE_ARG_ _ZCSTRINGBASE_& ZftMakeStr
( _ZCSTRINGBASE_& ARR_SaveCStr, const typename
_ZCSTRINGBASE_::ZCChars& AR_DataCStr )
{ return ARR_SaveCStr(AR_DataCStr); }
_ZCSTRINGBASE_ARG_ _ZCSTRINGBASE_& ZftMakeStr
( _ZCSTRINGBASE_& ARR_SaveCStr, typename
_ZCSTRINGBASE_::TypeChar AC_Char )
{ return ARR_SaveCStr(AC_Char ); }
_ZCSTRINGBASE_ARG_ _ZCSTRINGBASE_& ZftMakeStr
( _ZCSTRINGBASE_& ARR_SaveCStr, ZTypIntI AI_IntI )
{ return ARR_SaveCStr(AI_IntI ); }
_ZCSTRINGBASE_ARG_ _ZCSTRINGBASE_& ZftMakeStr
( _ZCSTRINGBASE_& ARR_SaveCStr, ZTypIntL AL_Long )
{ return ARR_SaveCStr(AL_Long ); }
_ZCSTRINGBASE_ARG_ _ZCSTRINGBASE_& ZftMakeStr
( _ZCSTRINGBASE_& ARR_SaveCStr, ZTypIntUI AUI_Int )
{ return ARR_SaveCStr(AUI_Int ); }
_ZCSTRINGBASE_ARG_ _ZCSTRINGBASE_& ZftMakeStr
( _ZCSTRINGBASE_& ARR_SaveCStr, ZTypIntUL AUL_Int )
{ return ARR_SaveCStr(AUL_Int ); }
_ZCSTRINGBASE_ARG_ _ZCSTRINGBASE_& ZftMakeStr
( _ZCSTRINGBASE_& ARR_SaveCStr, ZTypIntULL AULL_Int )
{ return ARR_SaveCStr(AULL_Int ); }
_ZCSTRINGBASE_ARG_ _ZCSTRINGBASE_& ZftMakeStr
( _ZCSTRINGBASE_& ARR_SaveCStr, double AD_Double )
{ return ARR_SaveCStr(AD_Double ); }
_ZCSTRINGBASE_ARG_ _ZCSTRINGBASE_& ZftMakeStr
( _ZCSTRINGBASE_& ARR_SaveCStr, bool AB_Bool )
{
typedef typename _ZCSTRINGBASE_::TypeChar TypeChar;
typedef typename _ZCSTRINGBASE_::TypeSize TypeSize;
typedef ZtCBoolStr<TypeChar, TypeSize> ZCBoolStr;
return ARR_SaveCStr(ZCBoolStr::GetMark(AB_Bool));
}/*
_ZCSTRINGBASE_ARG_ _ZCSTRINGBASE_& ZftMakeStr
( _ZCSTRINGBASE_& ARR_SaveCStr, bool AB_Bool ) */
#undef _ZCSTRINGBASE_
#undef _ZCSTRINGBASE_ARG_
#if (_CODE_OLD_)
template ////////////////////////////////////////////////////////////
<
template<typename, typename, typename, typename>
class ZtCStringBase,
typename TTypCh , typename TAlloc,
typename TAllocSize, typename TTypeString
>
class ZtCMoveObj /*################################################*/
<
ZtCStringBase<TTypCh, TAlloc, TAllocSize, TTypeString> ,
ZtCStringBase<TTypCh, TAlloc, TAllocSize, TTypeString>&, true
>
/////////////////////////////////////////////////////////////////////
{
public:
typedef ZtCStringBase
<TTypCh, TAlloc, TAllocSize, TTypeString> ZCStringBase;
public:
enum {ZEUseMoveObj = 1};
public:
static void Exec(ZCStringBase& AR_TypeArg1, ZCStringBase& AR_TypeArg2)
{
AR_TypeArg1.Fetch(AR_TypeArg2) ;
}/*
static void Exec(ZCStringBase& AR_TypeArg1, ZCStringBase& AR_TypeArg2)*/
public:
};/*
class ZtCMoveObj ##################################################*/
#endif //_CODE_OLD_
#if (_CODE_NEW_)
template
<
typename TTypCh , typename TAlloc,
typename TAllocSize, typename TTypeString
>
class ZtCMoveObj /*################################################*/
<
ZtCStringBase<TTypCh, TAlloc, TAllocSize, TTypeString> ,
ZtCStringBase<TTypCh, TAlloc, TAllocSize, TTypeString>&, true
>
/////////////////////////////////////////////////////////////////////
{
public:
typedef ZtCStringBase
<TTypCh, TAlloc, TAllocSize, TTypeString> ZCStringBase;
public:
enum {ZEUseMoveObj = 1};
public:
static void Exec(ZCStringBase& AR_TypeArg1, ZCStringBase& AR_TypeArg2)
{
AR_TypeArg1.Fetch(AR_TypeArg2) ;
}/*
static void Exec(ZCStringBase& AR_TypeArg1, ZCStringBase& AR_TypeArg2)*/
public:
};/*
template
<
typename TTypCh , typename TAlloc,
typename TAllocSize, typename TTypeString
>
class ZtCMoveObj ####################################################
<
ZtCStringBase<TTypCh, TAlloc, TAllocSize, TTypeString> ,
ZtCStringBase<TTypCh, TAlloc, TAllocSize, TTypeString>&, true
>
///////////////////////////////////////////////////////////////////*/
#endif //_CODE_NEW_
namespace ZNsFunc
{
#if (_CODE_OLD_)
template //////////////////////////////////////////////////////////////////
<
typename TTypCh , typename TAlloc,
typename TAllocSize, typename TTypeString
>
void ZftMoveFast //////////////////////////////////////////////////////////
(
ZtCStringBase<TTypCh, TAlloc, TAllocSize, TTypeString>& AR_CString1,
ZtCStringBase<TTypCh, TAlloc, TAllocSize, TTypeString>& AR_CString2
)
{
#ifdef _DEBUG_FAST_MOVE_OBJ_
cout<<" ▶▶ ZftMoveFast(ZCString&, ZCString&) Start!"<<endl;
#endif //_DEBUG_FAST_MOVE_OBJ_
AR_CString1.Fetch(AR_CString2);
#ifdef _DEBUG_FAST_MOVE_OBJ_
cout<<" ▶▶ ZftMoveFast(ZCString&, ZCString&) Close!"<<endl;
#endif //_DEBUG_FAST_MOVE_OBJ_
}/*
template //////////////////////////////////////////////////////////////////
<
typename TTypCh , typename TAlloc,
typename TAllocSize, typename TTypeString
>
void ZftMoveFast ////////////////////////////////////////////////////////*/
#endif //_CODE_OLD_
#if (_CODE_BAD_)
template //////////////////////////////////////////////////////////////////
<
template<typename, typename, typename, typename>
class ZtCStringBase,
typename TTypCh , typename TAlloc,
typename TAllocSize, typename TTypeString
>
void ZftMoveFast //////////////////////////////////////////////////////////
(
ZtCStringBase<TTypCh, TAlloc, TAllocSize, TTypeString>& AR_CString1,
ZtCStringBase<TTypCh, TAlloc, TAllocSize, TTypeString>& AR_CString2,
)
{
#ifdef _DEBUG_FAST_MOVE_OBJ_
cout<<" ▶▶ ZftMoveFast(ZCString&, ZCString&) Start!"<<endl;
#endif //_DEBUG_FAST_MOVE_OBJ_
AR_CString1.Fetch(AR_CString2);
#ifdef _DEBUG_FAST_MOVE_OBJ_
cout<<" ▶▶ ZftMoveFast(ZCString&, ZCString&) Close!"<<endl;
#endif //_DEBUG_FAST_MOVE_OBJ_
}/*
template //////////////////////////////////////////////////////////////////
<
typename TTypCh , typename TAlloc,
typename TAllocSize, typename TTypeString
>
void ZftMoveFast ////////////////////////////////////////////////////////*/
#endif //_CODE_BAD_
}/*
namespace ZNsFunc*/
}/*
namespace ZNsMain */
/*///////////////////////////////////////////////////////////////////////////////////
■ 문자열 메모리를 복사할 때, for 문을 쓰지 말고, memcpy() 를 썼으면 더 좋을 뻔 했다.
-- 2012-02-29 10:45:00
///////////////////////////////////////////////////////////////////////////////////*/
#endif //__ZCPPMAIIN__ZTCSTRINGEX_H__