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