From f7636ecc5df00738cff1b486a8507575ae5d8640 Mon Sep 17 00:00:00 2001 From: sauron Date: Sat, 16 Aug 2025 23:35:44 +0900 Subject: [PATCH] commit 2025-08-16 34:34 git add ZCppMain/ZMainHead.H git add ZCppMain/ZtCArray.H git add ZCppMain/ZtCObjList.H git add ZCppMain/ZMainAVL.H git add ZCppMain/ZMainHeadEx.H git add ZCppMain/ZMainXhtml.H git add ZCppMain/ZtCLoadDataBlock.H git add ZCppMain/ZtCMainChars.H git add ZCppMain/ZtCObjAVL.H git add ZCppMain/ZtCStringEx.H git add ZCppMain/ZtCTreeData.H --- ZCppMain/ZMainAVL.H | 360 ++ ZCppMain/ZMainHead.H | 1022 ++---- ZCppMain/ZMainHeadEx.H | 7194 +++++++++++++++++++++++++++++++++++++ ZCppMain/ZMainXhtml.H | 38 + ZCppMain/ZtCArray.H | 546 ++- ZCppMain/ZtCLoadDataBlock.H | 1862 ++++++++++ ZCppMain/ZtCMainChars.H | 7212 +++++++++++++++++++++++++++++++++++++ ZCppMain/ZtCObjAVL.H | 2483 +++++++++++++ ZCppMain/ZtCObjList.H | 1003 +++--- ZCppMain/ZtCStringEx.H | 8276 +++++++++++++++++++++++++++++++++++++++++++ ZCppMain/ZtCTreeData.H | 993 ++++++ 11 files changed, 29679 insertions(+), 1310 deletions(-) create mode 100644 ZCppMain/ZMainAVL.H create mode 100644 ZCppMain/ZMainHeadEx.H create mode 100644 ZCppMain/ZMainXhtml.H create mode 100644 ZCppMain/ZtCLoadDataBlock.H create mode 100644 ZCppMain/ZtCMainChars.H create mode 100644 ZCppMain/ZtCObjAVL.H create mode 100644 ZCppMain/ZtCStringEx.H create mode 100644 ZCppMain/ZtCTreeData.H diff --git a/ZCppMain/ZMainAVL.H b/ZCppMain/ZMainAVL.H new file mode 100644 index 0000000..885321a --- /dev/null +++ b/ZCppMain/ZMainAVL.H @@ -0,0 +1,360 @@ + + +#ifndef __ZCPPMAIN_ZMAINAVL_H__ +#define __ZCPPMAIN_ZMAINAVL_H__ + + +#include "ZCppMain/ZMainHead.H" + + +namespace ZNsMain +{ + + namespace ZNsEnum + { + + enum ZEAVL_INSERT + { + ZEAVL_INSERT_RIGHT = +1, + ZEAVL_INSERT_OK = 0, /* 0 ̴. */ + ZEAVL_INSERT_LEFT = -1, + ZEAVL_INSERT_NONE = -2 /* */ + };/* + enum ZEAVL_INSERT*/ + + }/* + namespace ZNsEnum*/ + + + namespace ZNsInterface + { + + template class ZtCAVL_BASE + { + protected: + + template void OnEqual(TypeArg AR_Data, TNode* AP_Node) + { + }/* + template void OnEqual(TypeArg AR_Data, TNode* AP_Node) */ + + template void OnEqualKey(TKey AR_Key, TNode* AP_Node) + { + }/* + template void OnEqualKey(TKey AR_Key, TNode* AP_Node) */ + + protected: + };/* + template class ZtCAVL_BASE*/ + + + /*////////////////////////////////////////////////////////////////////////// + + Ʒ ZtCAVL_NodeBase<> Լ ZtCAVL_BASE<> Լ + μ ϳ پ ִ. ZtCAVL_BASE<> ̸ Լ + ڿ ȣ ְ ̴. ZtCAVL_BASE<> Լ + , AP_Node->OnEqual() ZtCAVL_NodeBase<> Լ ȣ + , ZtCAVL_NodeBase<> 𿡼 ȣ ʴ´. + ̷ . ߴµ, Ƹ ZtCAVL_Multi_BASE<> + ZtCAVL_Multi_NodeBase<> ҷ ׷ ̴. + + -- 2012-09-03 19:20:00 + + //////////////////////////////////////////////////////////////////////////*/ + + template class ZtCAVL_NodeBase + { + protected: + + void OnEqual(TNodeArg AR_Data) + { + }/* + void OnEqual(TNodeArg AR_Data)*/ + + template void OnEqualKey(TKey AR_Key) + { + }/* + template void OnEqualKey(TKey AR_Key)*/ + + protected: + };/* + template class ZtCAVL_NodeBase*/ + + + template class ZtCAVL_Multi_BASE + { + protected: + + template void OnEqual(TypeArg AR_Data, TNode* AP_Node) + { + AP_Node->OnEqual(AR_Data); + }/* + template void OnEqual(TypeArg AR_Data, TNode* AP_Node) */ + + template void OnEqualKey(TKey AR_Key, TNode* AP_Node) + { + AP_Node->OnEqualKey(AR_Key); + }/* + template void OnEqualKey(TKey AR_Key, TNode* AP_Node) */ + + protected: + };/* + template class ZtCAVL_Multi_BASE*/ + + + /*////////////////////////////////////////////////////////////// + + ZtCAVL_Multi_NodeBase template multi set/map ϴ , + ZtCAVL_Multi_NodeBase::TypeEqual ڷ ϴ . + + class CTypeMy + { + public: + typedef CLargeAVL CLargeMap; + typedef typename CLargeMap::ZCNode::TypeEqual TypeEqual; + } + + //////////////////////////////////////////////////////////////*/ + + template< typename TNodeArg, typename TEqualList + > + class ZtCAVL_Multi_NodeBase //////////////////// + { + public : + typedef TEqualList TypeEqual; + protected: + TEqualList mo_EqualList; + public : + + void OnEqual(TNodeArg AR_Data) + { + mo_EqualList.push_back(AR_Data); + }/* + void OnEqual(TNodeArg AR_Data)*/ + + template void OnEqualKey(TKey AR_Key) + { + mo_EqualList.push_back(AR_Key); + }/* + template void OnEqualKey(TKey AR_Key) */ + + const TEqualList& GetCEqualList() const + { + return mo_EqualList; + }/* + const TEqualList& GetCEqualList() const*/ + + public: + };/* + template< typename TNodeArg, typename TEqualList + > + class ZtCAVL_Multi_NodeBase //////////////////*/ + + + + /*///////////////////////////////////////////////////////////////////// + + AVL Ʈ Ÿ Ÿ , ͸ ó ٷ + ڸ ϴ Ŭ ø̴. + + /////////////////////////////////////////////////////////////////////*/ + + template class ZtCAVL_PtrLongData + { + public : + typedef TData* TypeData; + protected: + TData* mp_CData; + public : + + ZtCAVL_PtrLongData() + { + mp_CData=0; + }/* + ZtCAVL_PtrLongData()*/ + + TData* GetDataPtr() const + { + return mp_CData; + }/* + TData* GetDataPtr() const*/ + + void SetDataPtr(TData* AP_CData) + { + mp_CData=AP_CData; + }/* + void SetDataPtr(TData* AP_CData)*/ + + operator ZNsMain::ZTypIntPtr() const + { + return mp_CData; + }/* + operator ZNsMain::ZTypIntPtr() const*/ + + + ZtCAVL_PtrLongData& operator=(const ZtCAVL_PtrLongData& rhs) + { + mp_CData=rhs.mp_CData; return *this; + }/* + ZtCAVL_PtrLongData& operator=(const ZtCAVL_PtrLongData& rhs)*/ + + ZtCAVL_PtrLongData& operator=(const TData* AP_CData) + { + mp_CData=const_cast(AP_CData); return *this; + }/* + ZtCAVL_PtrLongData& operator=(const TData* AP_CData)*/ + + bool operator==(const ZtCAVL_PtrLongData& rhs) const{return mp_CData==rhs.mp_CData;} + bool operator> (const ZtCAVL_PtrLongData& rhs) const{return (ZNsMain::ZTypIntPtr)mp_CData > (ZNsMain::ZTypIntPtr)rhs.mp_CData;} + bool operator< (const ZtCAVL_PtrLongData& rhs) const{return (ZNsMain::ZTypIntPtr)mp_CData < (ZNsMain::ZTypIntPtr)rhs.mp_CData;} + + bool operator==(const TData* AP_CData) const{return mp_CData==AP_CData;} + bool operator> (const TData* AP_CData) const{return (ZNsMain::ZTypIntPtr)mp_CData > (ZNsMain::ZTypIntPtr)AP_CData;} + bool operator< (const TData* AP_CData) const{return (ZNsMain::ZTypIntPtr)mp_CData < (ZNsMain::ZTypIntPtr)AP_CData;} + + protected: + };/* + template class ZtCAVL_PtrLongData*/ + + + /* int, long 񱳿 primitive Ÿ̳ object + key ִ 쿡, ش AVL Ʈ Ÿ ٷ + ֵ wrap Ŭ ø */ + + template< typename TKeyData , + typename TMainData, + typename TKeyArg =const TKeyData &, + typename TMainArg=const TMainData& + > + class ZtCAVL_KeyData ////////////////////////// + { + public : + typedef TKeyData TypeKey ; + typedef TMainData TypeData; + protected: + TKeyData mo_CKeyData ; mutable + TMainData mo_CMainData; + public : + + ZtCAVL_KeyData(){} + + ZtCAVL_KeyData(TKeyArg AO_TKeyArg) + { + mo_CKeyData=AO_TKeyArg; + }/* + ZtCAVL_KeyData(TKeyArg AO_TKeyArg)*/ + + ZtCAVL_KeyData(TKeyArg AO_TKeyArg, TMainArg AO_TMainArg) + { + mo_CKeyData =AO_TKeyArg ; + mo_CMainData=AO_TMainArg; + }/* + ZtCAVL_KeyData(TKeyArg AO_TKeyArg, TMainArg AO_TMainArg)*/ + + TKeyArg GetCKeyData () const{return mo_CKeyData ;} + TMainArg GetCMainData () const{return mo_CMainData;} + TMainData& GetCMainDataRef() const{return mo_CMainData;} + + void SetCMainData(TMainArg AO_TRealArg) const + { + mo_CMainData=AO_TRealArg; + }/* + void SetCMainData(TMainArg AO_TRealArg) const*/ + + void SetKeyData(TKeyArg AO_TKeylArg) + { + mo_CKeyData=AO_TKeylArg; + }/* + void SetKeyData(TKeyArg AO_TKeylArg)*/ + + bool operator==(const ZtCAVL_KeyData& rhs) const{return mo_CKeyData==rhs.mo_CKeyData;} + bool operator> (const ZtCAVL_KeyData& rhs) const{return mo_CKeyData> rhs.mo_CKeyData;} + bool operator< (const ZtCAVL_KeyData& rhs) const{return mo_CKeyData< rhs.mo_CKeyData;} + + bool operator==(TKeyArg AO_TPrimitive) const{return mo_CKeyData==AO_TPrimitive;} + bool operator> (TKeyArg AO_TPrimitive) const{return mo_CKeyData> AO_TPrimitive;} + bool operator< (TKeyArg AO_TPrimitive) const{return mo_CKeyData< AO_TPrimitive;} + + ZtCAVL_KeyData& operator=(const ZtCAVL_KeyData& rhs) + { + if(this==&rhs) return *this; + + mo_CKeyData =rhs.mo_CKeyData ; + mo_CMainData=rhs.mo_CMainData; return *this; + }/* + ZtCAVL_KeyData& operator=(const ZtCAVL_KeyData& rhs)*/ + + ZtCAVL_KeyData& operator=(TKeyArg AO_TPrimitive) + { + mo_CKeyData=AO_TPrimitive; return *this; + }/* + ZtCAVL_KeyData& operator=(TKeyArg AO_TPrimitive)*/ + + public: + };/* + template< typename TKeyData , + typename TMainData, + typename TKeyArg =const TKeyData &, + typename TMainArg=const TMainData& + > + class ZtCAVL_KeyData ////////////////////////*/ + + }/* + namespace ZNsInterface*/ + + + /*///////////////////////////////////////////////////////////////////////////////////// + + mulit set Ȱϴ ڵ + + ZNsMain::CLargeAVL /////////////////////////////////// + < + int, + int, + ZNsMain::ZNsInterface::ZtCAVL_Multi_BASE, + ZNsMain::ZNsInterface::ZtCAVL_Multi_NodeBase > + > + VO_CLargeAvl_Multi; ////////////////////////////////// + + VO_CLargeAvl_Multi.AddData(1); + VO_CLargeAvl_Multi.AddData(2); + VO_CLargeAvl_Multi.AddData(2); + VO_CLargeAvl_Multi.AddData(2); + VO_CLargeAvl_Multi.AddData(2); + + /////////////////////////////////////////////////////////////////////////////////////*/ + + + namespace NsType + { + + template< typename TStringData, //= ZNsMain::ZtCStringBase , + typename TEnvVar , //= ZNsMain::ZNsCGI::ZNsBase::ZtCEnvVar, + typename TEnvVarSet //= ZNsMain::ZtCObjAVL + > + class ZtCTypeEnvVarSet /*############################################################*/ + { + public: + typedef TStringData ZCStringData; + typedef TEnvVar ZCEnvVar ; + typedef TEnvVarSet ZCEnvVarSet ; + typedef typename ZCEnvVarSet ::ZCNode ZCEnvVarNode; + typedef typename ZCStringData::ZCMainChars ZCMainChars ; + typedef typename ZCStringData::TypeChar TypeChar ; + typedef typename ZCStringData::TypeLength TypeLength ; + public: + };/* + template< typename TStringData, //= ZNsMain::ZtCStringBase , + typename TEnvVar , //= ZNsMain::ZNsCGI::ZNsBase::ZtCEnvVar, + typename TEnvVarSet //= NsCPP::ZtCObjAVL + > + class ZtCTypeEnvVarSet /*############################################################*/ + + }/* + namespace NsType*/ + +}/* +namespace ZNsMain */ + + +#endif // __ZCPPMAIN_ZMAINAVL_H__ diff --git a/ZCppMain/ZMainHead.H b/ZCppMain/ZMainHead.H index 4b394f7..f4cf7f9 100644 --- a/ZCppMain/ZMainHead.H +++ b/ZCppMain/ZMainHead.H @@ -1,4 +1,4 @@ - + /*////////////////////////////////////////////////////////////////////////////////////// @@ -181,8 +181,8 @@ //////////////////////////////////////////////////////////////////////////////////////*/ -#ifndef __MAINHEADER_H__ -#define __MAINHEADER_H__ +#ifndef __ZCPPMAIIN_ZMAINHEAD_H__ +#define __ZCPPMAIIN_ZMAINHEAD_H__ #include @@ -556,37 +556,43 @@ namespace ZNsMain */ #endif - typedef unsigned int ZTypUInt ; - typedef unsigned short ZTypUShort ; - typedef unsigned long ZTypULong ; + typedef unsigned int ZTypUInt ; + typedef unsigned short ZTypUShort ; + typedef unsigned long ZTypULong ; - typedef unsigned char ZTypIntUChar ; - typedef unsigned int ZTypIntUInt ; - typedef unsigned short ZTypIntUShort ; - typedef unsigned long ZTypIntULong ; + typedef unsigned char ZTypIntUChar ; + typedef unsigned int ZTypIntUInt ; + typedef unsigned short ZTypIntUShort ; + typedef unsigned long ZTypIntULong ; - typedef unsigned char ZTypIntUC ; - typedef unsigned int ZTypIntUI ; - typedef unsigned short ZTypIntUS ; - typedef unsigned long ZTypIntUL ; + typedef unsigned char ZTypIntUC ; + typedef unsigned int ZTypIntUI ; + typedef unsigned short ZTypIntUS ; + typedef unsigned long ZTypIntUL ; #if(defined(__CPU_BIT_CNT__) && __CPU_BIT_CNT__>=64) #ifdef _WIN - typedef __int64 ZTypLength ; // 문자열의 길이를 나타내는 자료형. + typedef __int64 ZTypLength ; // 문자열의 길이를 나타내는 자료형. // 송수신 버퍼의 크기 자료형으로도 쓰인다. + typedef unsigned __int64 ZTypULen ; + typedef unsigned __int64 ZTypULength; #else - typedef long ZTypLength ; + typedef long ZTypLength ; + typedef unsigend long ZTypULen ; + typedef unsigend long ZTypULength ; #endif #else // !defined(__CPU_BIT_CNT__) || __CPU_BIT_CNT__<64 - typedef long ZTypLength ; + typedef long ZTypLength ; + typedef unsigend long ZTypULen ; + typedef unsigend long ZTypULength ; #endif // !defined(__CPU_BIT_CNT__) || __CPU_BIT_CNT__<64 #ifdef _WIN - typedef __int64 ZTypLengthFile; // 파일의 크기를 나타내는 자료형. + typedef __int64 ZTypLengthFile ; // 파일의 크기를 나타내는 자료형. #else - typedef long ZTypLengthFile; // 파일의 크기를 나타내는 자료형. + typedef long ZTypLengthFile ; // 파일의 크기를 나타내는 자료형. #endif typedef ZTypLengthFile ZTypLengthF; @@ -707,7 +713,7 @@ namespace ZNsMain { // ECompareResult 는 어떤 두 개의 값을 비교한 결과를 표시한다. - // GetCompareCode() 나 class ZZtCCompare<> 에서 사용할 것이다. + // ZftGetCompareCode() 나 class ZtCCompare<> 에서 사용할 것이다. enum ZECompareResult { @@ -721,55 +727,82 @@ namespace ZNsMain namespace ZNsEnum*/ - template ZTypIntE GetCompareCode - ( - const TTypeChar* ApcLeft , TTypeLength AI_LeftLength , - const TTypeChar* ApcRight, TTypeLength AI_RightLength - ) + template ZTypIntE ZftGetCompareCode + ( + const ZtpChar* ZApcLeft , ZtpiLength ZAiLenLeft , + const ZtpChar* ZApcRight, ZtpiLength zAiLenRight + ) /*######################################################################*/ { - if(AI_LeftLength<1 && AI_RightLength<1) return ZNsEnum::ZECompareResult_Equal; + if(ZAiLenLeft<1 && zAiLenRight<1) + return ZNsEnum::ZECompareResult_Equal; - TTypeLength ViLoopCnt= (AI_LeftLength<=AI_RightLength ? AI_LeftLength : AI_RightLength); + ZtpiLength ViLoopCnt = + (ZAiLenLeft<=zAiLenRight ? ZAiLenLeft : zAiLenRight); - __for0(TTypeLength, i, ViLoopCnt) + __for0(ZtpiLength, i, ViLoopCnt) { - if(ApcLeft[i] > ApcRight[i]) return ZNsEnum::ZECompareResult_More; - if(ApcLeft[i] < ApcRight[i]) return ZNsEnum::ZECompareResult_Less; + if(ZApcLeft[i] > ZApcRight[i]) return ZNsEnum::ZECompareResult_More; + if(ZApcLeft[i] < ZApcRight[i]) return ZNsEnum::ZECompareResult_Less; }/* - __for0(TTypeLength, i, ViLoopCnt)*/ + __for0(ZtpiLength, i, ViLoopCnt)*/ - if(AI_LeftLength==AI_RightLength) return ZNsEnum::ZECompareResult_Equal; - if(AI_LeftLength> AI_RightLength) return ZNsEnum::ZECompareResult_More ; - if(AI_LeftLength< AI_RightLength) return ZNsEnum::ZECompareResult_Less ; + if(ZAiLenLeft==zAiLenRight) return ZNsEnum::ZECompareResult_Equal; + if(ZAiLenLeft> zAiLenRight) return ZNsEnum::ZECompareResult_More ; + if(ZAiLenLeft< zAiLenRight) return ZNsEnum::ZECompareResult_Less ; return ZNsEnum::ZECompareResult_Equal; }/* - template ZTypIntE GetCompareCode - ( - const TTypeChar* ApcLeft , TTypeLength AI_LeftLength, - const TTypeChar* ApcRight, TTypeLength AI_RightLength - ) - ########################################################################*/ + template ZTypIntE ZftGetCompareCode + ( + const ZtpChar* ZApcLeft , ZtpiLength ZAiLenLeft , + const ZtpChar* ZApcRight, ZtpiLength zAiLenRight + ) + /*######################################################################*/ /* 어떤 변수를 강제적으로 참조로 인식하게 하는 클래스. 인수를 참조로 넘어가게 하고 싶을 때 사용한다. class ZtCCheckRef 에서 사용하고 있다. -- 2021-04-10 16:15 */ - template class ZtCRef + template class ZtCRef { public : - typedef TType& TypeData; - typedef TType TypeRaw ; + typedef ZtpType& TypeData; + typedef ZtpType TypeRaw ; private: TypeData mr_Data; public : - ZtCRef(TypeData AR_TypeData) : mr_Data(AR_TypeData){} + ZtCRef(TypeData ZArTypeData) : mr_Data(ZArTypeData){} public : TypeData GetData(){return mr_Data;} + public : };/* - template class ZtCRef*/ + template class ZtCRef*/ + + + template inline ZtCRef + ZftMakeCRef(ZtpType& ZArTypeData){ return ZtCRef (ZArTypeData );} + template inline ZtCRef* + ZftMakeCPtr(ZtpType& ZArTypeData){ return (ZtCRef*)(&ZArTypeData);} + /*////////////////////////////////////////////////////////////////////////////// + + ■ ZftMakeCPtr() 은 인수 ZArTypeData 이 ZtCRef* 인 것처럼 반환한다. + + 그래서 template class ZtCCheckRef< ZtCRef* > 에서 사용할 + 것이다. + + -- 2025-08-07 17:16 + + ■ 사용례는 ZCppMain/ZtCArray.H 의 IterElement() 의 주석에 있다. + + ■ 아래 ZftMCR() 와 ZftMCP() 는 위 함수명을 더 축약한 것이다. -- 2025-08-07 17:41 + + //////////////////////////////////////////////////////////////////////////////*/ + template inline ZtCRef + ZftMCR(ZtpType& ZArTypeData){ return ZtCRef (ZArTypeData );} + template inline ZtCRef* + ZftMCP(ZtpType& ZArTypeData){ return (ZtCRef*)(&ZArTypeData);} /* template 인수에 ZtCRef 가 있으면, 해당 값을 참조로 인식하고 @@ -795,6 +828,7 @@ namespace ZNsMain };/* template class ZtCCheckRef*/ + /* ZtCRef 전문화 */ template class ZtCCheckRef< ZtCRef > { @@ -811,12 +845,47 @@ namespace ZNsMain public : static TypeData PassData(TypeData AO_Data){return AO_Data;} static TypeData PassData(ZCRef& AO_Data){return AO_Data.GetData();} - static TypeData PassData(const ZCRef& AO_Data) - {return (const_cast(AO_Data)).GetData();} };/* template class ZtCCheckRef< ZtCRef >*/ + /*////////////////////////////////////////////////////////// + + ■ ZtCRef* 전문화 + + 아래 함수 + + template inline ZtCRef* + ZftMakeCPtr(ZtpType& ZArTypeData){ return (ZtCRef*)(&ZArTypeData);} + + 를 통해, 생성된 포인터에 대해서, 정적 멤버 PassData() 로 + TypeRaw* 로 강제변환하고 있다. 그래서 ZtCRef 객 + 체의 생성없이 TypeRaw 를 참조로 다룰려고 하는 것이다. + + -- 2025=08-07 17:19 + + //////////////////////////////////////////////////////////*/ + template class ZtCCheckRef< ZtCRef* > + { + public : + typedef TType& TypeData; + typedef TType TypeRaw ; + typedef ZtCRef ZCRef ; + private: + TypeData mr_Data; + public : + ZtCCheckRef(TypeData AR_TypeData) : mr_Data(AR_TypeData){} + public : + TypeData GetData(){return mr_Data;} + public : + static TypeData PassData(TypeData AO_Data){return AO_Data;} + static TypeData PassData(ZCRef& AO_Data){return AO_Data.GetData();} + static TypeData PassData(ZCRef* AP_CRef) + { return *reinterpret_cast(AP_CRef); } + };/* + template class ZtCCheckRef< ZtCRef* >*/ + + namespace ZNsType { @@ -833,8 +902,8 @@ namespace ZNsMain -- 2010-03-12 20:00:00 - class ZtCTypeCRTP 는 상속 클래스만을 표시하고, - class ZtCTypeCRTP2_T 는 상속 클래스와 기반 클래스 모두를 표시한다. + class ZtCTypeCRTP 는 상속 클래스만을 표시하고, + class ZtCTypeCRTP2 는 상속 클래스와 기반 클래스 모두를 표시한다. 어쩌면 모든 상속 클래스는 내부적으로, ZtCTypeCRTP 클래스를 갖는 원칙을 세우는 것도 좋겠 다. 그래서 상속 클래스가 CDerive0 라면, 기반 클래스에 접근하고 싶을 때, @@ -871,7 +940,7 @@ namespace ZNsMain , typename TTypeBase =ZCEmpty , bool TTypebUseCRTP=false > - class ZtCTypeCRTP2_T ///////////////////// + class ZtCTypeCRTP2 /////////////////////// { public: typedef TTypeChild TypeData; @@ -903,6 +972,9 @@ namespace ZNsMain class ZtCTypeNowCRTP<> 을 설계한다. 이 클래스의 사용예는 예전 파일 CCtrlAsyncSock.H 에 있었다. + + -- 현재(2025-08-02 22:37) CCtrlAsyncSock.H 는 없다. + 아래 코드에서 TAsyncServ 의 상속 클래스가 없다면, CMainServ 는 TAsyncServ 과 같고, @@ -984,339 +1056,12 @@ namespace ZNsMain }/* namespace ZNsTmplParam*/ - - /*////////////////////////////////////////////////////////////////////////////// - - ■ class ZtCTypeArguBind 은 class ZtCArguBind 에서 사용된다. - - class ZtCTypeArguBind 와 class ZtCArguBind 의 사용예는 CArguBind_test.cpp 에 - 있다. - - ZtCArguBind 은 boost 의 bind 를 흉내낸 것인데, 용법은 좀 다르다. - - -- 2014-07-05 18:49:00 - - //////////////////////////////////////////////////////////////////////////////*/ - - - template< typename TTypeArgu1 , typename TTypeArgu2 - , typename TTypeArgu3=ZCEmpty, typename TTypeArgu4 =ZCEmpty - , typename TTypeArgu5=ZCEmpty, typename TTypeArgu6 =ZCEmpty - , typename TTypeArgu7=ZCEmpty, typename TTypeArgu8 =ZCEmpty - , typename TTypeArgu9=ZCEmpty, typename TTypeArgu10=ZCEmpty - > - class ZtCTypeArguBind /////////////////////////////////////////////// - { - public: - - typedef typename ZtCTypeCheckRef::TypeData TypeArgu1 ; - typedef typename ZtCTypeCheckRef::TypeData TypeArgu2 ; - typedef typename ZtCTypeCheckRef::TypeData TypeArgu3 ; - typedef typename ZtCTypeCheckRef::TypeData TypeArgu4 ; - typedef typename ZtCTypeCheckRef::TypeData TypeArgu5 ; - typedef typename ZtCTypeCheckRef::TypeData TypeArgu6 ; - typedef typename ZtCTypeCheckRef::TypeData TypeArgu7 ; - typedef typename ZtCTypeCheckRef::TypeData TypeArgu8 ; - typedef typename ZtCTypeCheckRef::TypeData TypeArgu9 ; - typedef typename ZtCTypeCheckRef::TypeData TypeArgu10; - - struct ZStArguments2{ ZStArguments2( - TypeArgu1 AR_TypeArgu1, TypeArgu2 AR_TypeArgu2): - _1(AR_TypeArgu1), _2(AR_TypeArgu2){} - - TypeArgu1 _1; TypeArgu2 _2; - };/* - struct ZStArguments2*/ - struct ZStArguments3{ZStArguments3( - TypeArgu1 AR_TypeArgu1, TypeArgu2 AR_TypeArgu2, TypeArgu3 AR_TypeArgu3): - _1(AR_TypeArgu1), _2(AR_TypeArgu2), _3(AR_TypeArgu3){} - - TypeArgu1 _1; TypeArgu2 _2; TypeArgu3 _3; - };/* - struct ZStArguments3*/ - struct ZStArguments4{ZStArguments4( - TypeArgu1 AR_TypeArgu1, TypeArgu2 AR_TypeArgu2, TypeArgu3 AR_TypeArgu3, TypeArgu4 AR_TypeArgu4): - _1(AR_TypeArgu1), _2(AR_TypeArgu2), _3(AR_TypeArgu3), _4(AR_TypeArgu4){} - - TypeArgu1 _1; TypeArgu2 _2; TypeArgu3 _3; TypeArgu4 _4; - };/* - struct ZStArguments4*/ - struct ZStArguments5{ZStArguments5( - TypeArgu1 AR_TypeArgu1, TypeArgu2 AR_TypeArgu2, TypeArgu3 AR_TypeArgu3, TypeArgu4 AR_TypeArgu4, TypeArgu5 AR_TypeArgu5): - _1(AR_TypeArgu1), _2(AR_TypeArgu2), _3(AR_TypeArgu3), _4(AR_TypeArgu4), _5(AR_TypeArgu5){} - - TypeArgu1 _1; TypeArgu2 _2; TypeArgu3 _3; TypeArgu4 _4; TypeArgu5 _5; - };/* - struct ZStArguments5*/ - struct ZStArguments6{ZStArguments6( - TypeArgu1 AR_TypeArgu1, TypeArgu2 AR_TypeArgu2, TypeArgu3 AR_TypeArgu3, TypeArgu4 AR_TypeArgu4, TypeArgu5 AR_TypeArgu5, TypeArgu6 AR_TypeArgu6): - _1(AR_TypeArgu1), _2(AR_TypeArgu2), _3(AR_TypeArgu3), _4(AR_TypeArgu4), _5(AR_TypeArgu5), _6(AR_TypeArgu6){} - - TypeArgu1 _1; TypeArgu2 _2; TypeArgu3 _3; TypeArgu4 _4; TypeArgu5 _5; TypeArgu6 _6; - };/* - struct ZStArguments6*/ - struct ZStArguments7{ZStArguments7( - TypeArgu1 AR_TypeArgu1, TypeArgu2 AR_TypeArgu2, TypeArgu3 AR_TypeArgu3, TypeArgu4 AR_TypeArgu4, TypeArgu5 AR_TypeArgu5, TypeArgu6 AR_TypeArgu6, TypeArgu7& AR_TypeArgu7): - _1(AR_TypeArgu1), _2(AR_TypeArgu2), _3(AR_TypeArgu3), _4(AR_TypeArgu4), _5(AR_TypeArgu5), _6(AR_TypeArgu6), _7(AR_TypeArgu7){} - - TypeArgu1 _1; TypeArgu2 _2; TypeArgu3 _3; TypeArgu4 _4; TypeArgu5 _5; TypeArgu6 _6; TypeArgu7 _7; - };/* - struct ZStArguments7*/ - struct ZStArguments8{ZStArguments8( - TypeArgu1 AR_TypeArgu1, TypeArgu2 AR_TypeArgu2, TypeArgu3 AR_TypeArgu3, TypeArgu4 AR_TypeArgu4, TypeArgu5 AR_TypeArgu5, TypeArgu6 AR_TypeArgu6, TypeArgu7& AR_TypeArgu7, TypeArgu8& AR_TypeArgu8): - _1(AR_TypeArgu1), _2(AR_TypeArgu2), _3(AR_TypeArgu3), _4(AR_TypeArgu4), _5(AR_TypeArgu5), _6(AR_TypeArgu6), _7(AR_TypeArgu7), _8(AR_TypeArgu8){} - - TypeArgu1 _1; TypeArgu2 _2; TypeArgu3 _3; TypeArgu4 _4; TypeArgu5 _5; TypeArgu6 _6; TypeArgu7 _7; TypeArgu8 _8; - };/* - struct ZStArguments8*/ - struct ZStArguments9{ZStArguments9( - TypeArgu1 AR_TypeArgu1, TypeArgu2 AR_TypeArgu2, TypeArgu3 AR_TypeArgu3, TypeArgu4 AR_TypeArgu4, TypeArgu5 AR_TypeArgu5, TypeArgu6 AR_TypeArgu6, TypeArgu7& AR_TypeArgu7, TypeArgu8& AR_TypeArgu8, TypeArgu9 AR_TypeArgu9): - _1(AR_TypeArgu1), _2(AR_TypeArgu2), _3(AR_TypeArgu3), _4(AR_TypeArgu4), _5(AR_TypeArgu5), _6(AR_TypeArgu6), _7(AR_TypeArgu7), _8(AR_TypeArgu8), _9(AR_TypeArgu9){} - - TypeArgu1 _1; TypeArgu2 _2; TypeArgu3 _3; TypeArgu4 _4; TypeArgu5 _5; TypeArgu6 _6; TypeArgu7 _7; TypeArgu8 _8; TypeArgu9 _9; - };/* - struct ZStArguments9*/ - struct ZStArguments10{ZStArguments10( - TypeArgu1 AR_TypeArgu1, TypeArgu2 AR_TypeArgu2, TypeArgu3 AR_TypeArgu3, TypeArgu4 AR_TypeArgu4, TypeArgu5 AR_TypeArgu5, TypeArgu6 AR_TypeArgu6, TypeArgu7& AR_TypeArgu7, TypeArgu8& AR_TypeArgu8, TypeArgu9 AR_TypeArgu9, TypeArgu10 AR_TypeArgu10): - _1(AR_TypeArgu1), _2(AR_TypeArgu2), _3(AR_TypeArgu3), _4(AR_TypeArgu4), _5(AR_TypeArgu5), _6(AR_TypeArgu6), _7(AR_TypeArgu7), _8(AR_TypeArgu8), _9(AR_TypeArgu9), _10(AR_TypeArgu10){} - - TypeArgu1 _1; TypeArgu2 _2; TypeArgu3 _3; TypeArgu4 _4; TypeArgu5 _5; TypeArgu6 _6; TypeArgu7 _7; TypeArgu8 _8; TypeArgu9 _9; TypeArgu10 _10; - };/* - struct ZStArguments10*/ - - public: - };/* - template< typename TTypeArgu1 , typename TTypeArgu2 - , typename TTypeArgu3=ZCEmpty, typename TTypeArgu4 =ZCEmpty - , typename TTypeArgu5=ZCEmpty, typename TTypeArgu6 =ZCEmpty - , typename TTypeArgu7=ZCEmpty, typename TTypeArgu8 =ZCEmpty - , typename TTypeArgu9=ZCEmpty, typename TTypeArgu10=ZCEmpty - > - class ZtCTypeArguBind /////////////////////////////////////////////*/ - }/* namespace ZNsType*/ - template class ZtCArguBind - { - public: - - template - static void Exec2(Type1& AR_Type1, Type2& AR_Type2) - { - typename ZNsType::ZtCTypeArguBind:: - ZStArguments2 VO_ZtCTypeArguBind(AR_Type1, AR_Type2); - - TClassExec::Exec2(VO_ZtCTypeArguBind); - }/* - template - static void Exec2(Type1& AR_Type1, Type2& AR_Type2)*/ - - template - static void Exec2(Type1& AR_Type1, Type2& AR_Type2, THelpType& ArHelpType) - { - typename ZNsType::ZtCTypeArguBind:: - ZStArguments2 VO_ZtCTypeArguBind(AR_Type1, AR_Type2); - - TClassExec::Exec2(VO_ZtCTypeArguBind, ArHelpType); - }/* - template - static void Exec2(Type1& AR_Type1, Type2& AR_Type2, THelpType& ArHelpType)*/ - - - template - static void Exec3(Type1& AR_Type1, Type2& AR_Type2, Type3& AR_Type3) - { - typename ZNsType::ZtCTypeArguBind:: - ZStArguments3 VO_ZtCTypeArguBind(AR_Type1, AR_Type2, AR_Type3); - - TClassExec::Exec3(VO_ZtCTypeArguBind); - }/* - template - static void Exec3(Type1& AR_Type1, Type2& AR_Type2, Type3& AR_Type3)*/ - - template - static void Exec3(Type1& AR_Type1, Type2& AR_Type2, Type3& AR_Type3, THelpType& ArHelpType) - { - typename ZNsType::ZtCTypeArguBind:: - ZStArguments3 VO_ZtCTypeArguBind(AR_Type1, AR_Type2, AR_Type3); - - TClassExec::Exec4(VO_ZtCTypeArguBind, ArHelpType); - }/* - template - static void Exec3(Type1& AR_Type1, Type2& AR_Type2, Type3& AR_Type3, THelpType& ArHelpType)*/ - - - template - static void Exec4(Type1& AR_Type1, Type2& AR_Type2, Type3& AR_Type3, Type4& AR_Type4) - { - typename ZNsType::ZtCTypeArguBind:: - ZStArguments4 VO_ZtCTypeArguBind(AR_Type1, AR_Type2, AR_Type3, AR_Type4); - - TClassExec::Exec4(VO_ZtCTypeArguBind); - }/* - template - static void Exec4(Type1& AR_Type1, Type2& AR_Type2, Type3& AR_Type3, Type4& AR_Type4)*/ - - template - static void Exec4(Type1& AR_Type1, Type2& AR_Type2, Type3& AR_Type3, Type4& AR_Type4, THelpType& ArHelpType) - { - typename ZNsType::ZtCTypeArguBind:: - ZStArguments4 VO_ZtCTypeArguBind(AR_Type1, AR_Type2, AR_Type3, AR_Type4); - - TClassExec::Exec4(VO_ZtCTypeArguBind, ArHelpType); - }/* - template - static void Exec4(Type1& AR_Type1, Type2& AR_Type2, Type3& AR_Type3, Type4& AR_Type4, THelpType& ArHelpType)*/ - - - template - static void Exec5(Type1& AR_Type1, Type2& AR_Type2, Type3& AR_Type3, Type4& AR_Type4, Type5& AR_Type5) - { - typename ZNsType::ZtCTypeArguBind:: - ZStArguments5 VO_ZtCTypeArguBind(AR_Type1, AR_Type2, AR_Type3, AR_Type4, AR_Type5); - - TClassExec::Exec5(VO_ZtCTypeArguBind); - }/* - template - static void Exec5(Type1& AR_Type1, Type2& AR_Type2, Type3& AR_Type3, Type4& AR_Type4, Type5& AR_Type5)*/ - - template - static void Exec5(Type1& AR_Type1, Type2& AR_Type2, Type3& AR_Type3, Type4& AR_Type4, Type5& AR_Type5, THelpType& ArHelpType) - { - typename ZNsType::ZtCTypeArguBind:: - ZStArguments5 VO_ZtCTypeArguBind(AR_Type1, AR_Type2, AR_Type3, AR_Type4, AR_Type5); - - TClassExec::Exec5(VO_ZtCTypeArguBind, ArHelpType); - }/* - template - static void Exec5(Type1& AR_Type1, Type2& AR_Type2, Type3& AR_Type3, Type4& AR_Type4, Type5& AR_Type5, THelpType& ArHelpType)*/ - - - template - static void Exec6(Type1& AR_Type1, Type2& AR_Type2, Type3& AR_Type3, Type4& AR_Type4, Type5& AR_Type5, Type6& AR_Type6) - { - typename ZNsType::ZtCTypeArguBind:: - ZStArguments6 VO_ZtCTypeArguBind(AR_Type1, AR_Type2, AR_Type3, AR_Type4, AR_Type5, AR_Type6); - - TClassExec::Exec6(VO_ZtCTypeArguBind); - }/* - template - static void Exec6(Type1& AR_Type1, Type2& AR_Type2, Type3& AR_Type3, Type4& AR_Type4, Type5& AR_Type5, Type6& AR_Type6)*/ - - template - static void Exec6(Type1& AR_Type1, Type2& AR_Type2, Type3& AR_Type3, Type4& AR_Type4, Type5& AR_Type5, Type6& AR_Type6, THelpType& ArHelpType) - { - typename ZNsType::ZtCTypeArguBind:: - ZStArguments6 VO_ZtCTypeArguBind(AR_Type1, AR_Type2, AR_Type3, AR_Type4, AR_Type5, AR_Type6); - - TClassExec::Exec6(VO_ZtCTypeArguBind, ArHelpType); - }/* - template - static void Exec6(Type1& AR_Type1, Type2& AR_Type2, Type3& AR_Type3, Type4& AR_Type4, Type5& AR_Type5, Type6& AR_Type6, THelpType& ArHelpType)*/ - - - template - static void Exec7(Type1& AR_Type1, Type2& AR_Type2, Type3& AR_Type3, Type4& AR_Type4, Type5& AR_Type5, Type6& AR_Type6, Type7& AR_Type7) - { - typename ZNsType::ZtCTypeArguBind:: - ZStArguments7 VO_ZtCTypeArguBind(AR_Type1, AR_Type2, AR_Type3, AR_Type4, AR_Type5, AR_Type6, AR_Type6, AR_Type7); - - TClassExec::Exec7(VO_ZtCTypeArguBind); - }/* - template - static void Exec7(Type1& AR_Type1, Type2& AR_Type2, Type3& AR_Type3, Type4& AR_Type4, Type5& AR_Type5, Type6& AR_Type6, Type7& AR_Type7)*/ - - template - static void Exec7(Type1& AR_Type1, Type2& AR_Type2, Type3& AR_Type3, Type4& AR_Type4, Type5& AR_Type5, Type6& AR_Type6, Type7& AR_Type7, THelpType& ArHelpType) - { - typename ZNsType::ZtCTypeArguBind:: - ZStArguments7 VO_ZtCTypeArguBind(AR_Type1, AR_Type2, AR_Type3, AR_Type4, AR_Type5, AR_Type6, AR_Type7); - - TClassExec::Exec7(VO_ZtCTypeArguBind, ArHelpType); - }/* - template - static void Exec7(Type1& AR_Type1, Type2& AR_Type2, Type3& AR_Type3, Type4& AR_Type4, Type5& AR_Type5, Type6& AR_Type6, Type7& AR_Type7 THelpType& ArHelpType)*/ - - - template - static void Exec8(Type1& AR_Type1, Type2& AR_Type2, Type3& AR_Type3, Type4& AR_Type4, Type5& AR_Type5, Type6& AR_Type6, Type7& AR_Type7, Type8& AR_Type8) - { - typename ZNsType::ZtCTypeArguBind:: - ZStArguments8 VO_ZtCTypeArguBind(AR_Type1, AR_Type2, AR_Type3, AR_Type4, AR_Type5, AR_Type6, AR_Type6, AR_Type7, AR_Type8); - - TClassExec::Exec8(VO_ZtCTypeArguBind); - }/* - template - static void Exec8(Type1& AR_Type1, Type2& AR_Type2, Type3& AR_Type3, Type4& AR_Type4, Type5& AR_Type5, Type6& AR_Type6, Type7& AR_Type7, Type8& AR_Type8)*/ - - template - static void Exec8(Type1& AR_Type1, Type2& AR_Type2, Type3& AR_Type3, Type4& AR_Type4, Type5& AR_Type5, Type6& AR_Type6, Type7& AR_Type7, Type8& AR_Type8, THelpType& ArHelpType) - { - typename ZNsType::ZtCTypeArguBind:: - ZStArguments8 VO_ZtCTypeArguBind(AR_Type1, AR_Type2, AR_Type3, AR_Type4, AR_Type5, AR_Type6, AR_Type7, AR_Type8); - - TClassExec::Exec8(VO_ZtCTypeArguBind, ArHelpType); - }/* - template - static void Exec8(Type1& AR_Type1, Type2& AR_Type2, Type3& AR_Type3, Type4& AR_Type4, Type5& AR_Type5, Type6& AR_Type6, Type7& AR_Type7, Type8& AR_Type8, THelpType& ArHelpType)*/ - - - template - static void Exec9(Type1& AR_Type1, Type2& AR_Type2, Type3& AR_Type3, Type4& AR_Type4, Type5& AR_Type5, Type6& AR_Type6, Type7& AR_Type7, Type8& AR_Type8, Type9& AR_Type9) - { - typename ZNsType::ZtCTypeArguBind:: - ZStArguments9 VO_ZtCTypeArguBind(AR_Type1, AR_Type2, AR_Type3, AR_Type4, AR_Type5, AR_Type6, AR_Type6, AR_Type7, AR_Type8, AR_Type9); - - TClassExec::Exec9(VO_ZtCTypeArguBind); - }/* - template - static void Exec9(Type1& AR_Type1, Type2& AR_Type2, Type3& AR_Type3, Type4& AR_Type4, Type5& AR_Type5, Type6& AR_Type6, Type7& AR_Type7, Type8& AR_Type8, Type9& AR_Type9)*/ - - template - static void Exec9(Type1& AR_Type1, Type2& AR_Type2, Type3& AR_Type3, Type4& AR_Type4, Type5& AR_Type5, Type6& AR_Type6, Type7& AR_Type7, Type8& AR_Type8, Type9& AR_Type9, THelpType& ArHelpType) - { - typename ZNsType::ZtCTypeArguBind:: - ZStArguments9 VO_ZtCTypeArguBind(AR_Type1, AR_Type2, AR_Type3, AR_Type4, AR_Type5, AR_Type6, AR_Type7, AR_Type8, AR_Type9); - - TClassExec::Exec9(VO_ZtCTypeArguBind, ArHelpType); - }/* - template - static void Exec9(Type1& AR_Type1, Type2& AR_Type2, Type3& AR_Type3, Type4& AR_Type4, Type5& AR_Type5, Type6& AR_Type6, Type7& AR_Type7, Type8& AR_Type8, Type9& AR_Type9, THelpType& ArHelpType)*/ - - - template - static void Exec10(Type1& AR_Type1, Type2& AR_Type2, Type3& AR_Type3, Type4& AR_Type4, Type5& AR_Type5, Type6& AR_Type6, Type7& AR_Type7, Type8& AR_Type8, Type9& AR_Type9, Type10& AR_Type10) - { - typename ZNsType::ZtCTypeArguBind:: - ZStArguments10 VO_ZtCTypeArguBind(AR_Type1, AR_Type2, AR_Type3, AR_Type4, AR_Type5, AR_Type6, AR_Type6, AR_Type7, AR_Type8, AR_Type9, AR_Type10); - - TClassExec::Exec10(VO_ZtCTypeArguBind); - }/* - template - static void Exec10(Type1& AR_Type1, Type2& AR_Type2, Type3& AR_Type3, Type4& AR_Type4, Type5& AR_Type5, Type6& AR_Type6, Type7& AR_Type7, Type8& AR_Type8, Type9& AR_Type9, Type10& AR_Type10)*/ - - template - static void Exec10(Type1& AR_Type1, Type2& AR_Type2, Type3& AR_Type3, Type4& AR_Type4, Type5& AR_Type5, Type6& AR_Type6, Type7& AR_Type7, Type8& AR_Type8, Type9& AR_Type9, Type10& AR_Type10, THelpType& ArHelpType) - { - typename ZNsType::ZtCTypeArguBind:: - ZStArguments10 VO_ZtCTypeArguBind(AR_Type1, AR_Type2, AR_Type3, AR_Type4, AR_Type5, AR_Type6, AR_Type7, AR_Type8, AR_Type9, AR_Type10); - - TClassExec::Exec10(VO_ZtCTypeArguBind, ArHelpType); - }/* - template - static void Exec10(Type1& AR_Type1, Type2& AR_Type2, Type3& AR_Type3, Type4& AR_Type4, Type5& AR_Type5, Type6& AR_Type6, Type7& AR_Type7, Type8& AR_Type8, Type9& AR_Type9, Type10& AR_Type10, THelpType& ArHelpType)*/ - - public: - };/* - template class ZtCArguBind*/ - - /*////////////////////////////////////////////////////////////////////////////////////////// - ■ 위 ZtCArguBind<> 보다는 아래 struct ZtStTuple<> 이 더 유용할 것이다. -- 2015-02-15 20:52:00 - ■ template 인수가 Type11 까지 있음에 주의한다. 그러면 Type10 까지 전문화할 수 있는 것이다. -- 2015-02-16 21:20:00 @@ -1339,19 +1084,14 @@ namespace ZNsMain > struct ZtStTuple ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// { - Type1 _1; - - ZtStTuple(){} - ZtStTuple(Type1 _T1):_1(_T1){} - };/* - template< typename Type1 , typename Type2 =void, - typename Type3=void, typename Type4 =void, - typename Type5=void, typename Type6 =void, - typename Type7=void, typename Type8 =void, - typename Type9=void, typename Type10=void, typename Type11=void - > - struct ZtStTuple ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/ + typedef typename ZNsType::ZtCTypeCheckRef::TypeData TypeData1 ; /* + typedef typename ZNsType::ZtCTypeCheckRef::TypeData TypeData2 ; */ + TypeData1 _1; + + ZtStTuple(TypeData1 _T1) : _1(_T1){} + }; + /*###########################################################################################*/ template< typename Type1, typename Type2 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// > struct ZtStTuple //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1362,14 +1102,10 @@ namespace ZNsMain TypeData1 _1; TypeData2 _2; ZtStTuple(){} - ZtStTuple( - TypeData1 _T1, TypeData2 _T2) : _1(_T1), _2(_T2) {} - };/* - template< typename Type1, typename Type2 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - > - struct ZtStTuple /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/ - + TypeData1 _T1, TypeData2 _T2) : _1(_T1), _2(_T2){} + }; + /*###########################################################################################*/ template< typename Type1, typename Type2, typename Type3 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// > struct ZtStTuple ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1379,17 +1115,14 @@ namespace ZNsMain typedef typename ZNsType::ZtCTypeCheckRef::TypeData TypeData3 ; TypeData1 _1; TypeData2 _2; TypeData3 _3; - - ZtStTuple(){} + ZtStTuple(){} ZtStTuple( TypeData1 _T1, TypeData2 _T2, TypeData3 _T3) : _1(_T1), _2(_T2), _3(_T3){} - };/* - template< typename Type1, typename Type2, typename Type3 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - > - struct ZtStTuple ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/ + }; + /*###########################################################################################*/ template< typename Type1, typename Type2, typename Type3, typename Type4 //////////////////////////////////////////////////////////////////////////////////////////////////////// > struct ZtStTuple ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1402,15 +1135,11 @@ namespace ZNsMain TypeData1 _1; TypeData2 _2; TypeData3 _3; TypeData4 _4; ZtStTuple(){} - ZtStTuple( TypeData1 _T1, TypeData2 _T2, TypeData3 _T3, TypeData4 _T4) : _1(_T1), _2(_T2), _3(_T3), _4(_T4) {} - };/* - template< typename Type1, typename Type2, typename Type3, typename Type4 //////////////////////////////////////////////////////////////////////////////////////////////////////// - > - struct ZtStTuple ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/ - + }; + /*###########################################################################################*/ template< typename Type1, typename Type2, typename Type3, typename Type4, typename Type5 //////////////////////////////////////////////////////////////////////////////////////// > struct ZtStTuple /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1424,15 +1153,11 @@ namespace ZNsMain TypeData1 _1; TypeData2 _2; TypeData3 _3; TypeData4 _4; TypeData5 _5; ZtStTuple(){} - ZtStTuple( TypeData1 _T1, TypeData2 _T2, TypeData3 _T3, TypeData4 _T4, TypeData5 _T5) : _1(_T1), _2(_T2), _3(_T3), _4(_T4), _5(_T5){} - };/* - template< typename Type1, typename Type2, typename Type3, typename Type4, typename Type5 //////////////////////////////////////////////////////////////////////////////////////// - > - struct ZtStTuple /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/ - + }; + /*###########################################################################################*/ template< typename Type1, typename Type2, typename Type3, typename Type4, typename Type5, typename Type6 //////////////////////////////////////////////////////////////////////// > struct ZtStTuple //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1448,16 +1173,12 @@ namespace ZNsMain TypeData4 _4; TypeData5 _5; TypeData6 _6; ZtStTuple(){} - ZtStTuple( TypeData1 _T1, TypeData2 _T2, TypeData3 _T3 , TypeData4 _T4, TypeData5 _T5, TypeData6 _T6) : _1(_T1), _2(_T2), _3(_T3), _4(_T4), _5(_T5), _6(_T6) {} - };/* - template< typename Type1, typename Type2, typename Type3, typename Type4, typename Type5, typename Type6 //////////////////////////////////////////////////////////////////////// - > - struct ZtStTuple //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/ - + }; + /*###########################################################################################*/ template< typename Type1, typename Type2, typename Type3, typename Type4, typename Type5, typename Type6, typename Type7 //////////////////////////////////////////////////////// > struct ZtStTuple ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1472,18 +1193,14 @@ namespace ZNsMain TypeData1 _1; TypeData2 _2; TypeData3 _3; TypeData4 _4; TypeData5 _5; TypeData6 _6; TypeData7 _7; - - ZtStTuple(){} + ZtStTuple(){} ZtStTuple( TypeData1 _T1, TypeData2 _T2, TypeData3 _T3, TypeData4 _T4, TypeData5 _T5, TypeData6 _T6, TypeData7 _T7) : _1(_T1), _2(_T2), _3(_T3), _4(_T4), _5(_T5), _6(_T6), _7(_T7) {} - };/* - template< typename Type1, typename Type2, typename Type3, typename Type4, typename Type5, typename Type6, typename Type7 //////////////////////////////////////////////////////// - > - struct ZtStTuple ///////////////////////////////////////////////////////////////////////////////////////////////////////////////*/ - + }; + /*###########################################################################################*/ template< typename Type1, typename Type2, typename Type3, typename Type4, typename Type5, typename Type6, typename Type7, typename Type8 //////////////////////////////////////// > struct ZtStTuple ////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1501,17 +1218,13 @@ namespace ZNsMain TypeData5 _5; TypeData6 _6; TypeData7 _7; TypeData8 _8; ZtStTuple(){} - ZtStTuple( TypeData1 _T1, TypeData2 _T2, TypeData3 _T3, TypeData4 _T4, TypeData5 _T5, TypeData6 _T6, TypeData7 _T7, TypeData8 _T8) : _1(_T1), _2(_T2), _3(_T3), _4(_T4) , _5(_T5), _6(_T6), _7(_T7), _8(_T8) {} - };/* - template< typename Type1, typename Type2, typename Type3, typename Type4, typename Type5, typename Type6, typename Type7, typename Type8 //////////////////////////////////////// - > - struct ZtStTuple ////////////////////////////////////////////////////////////////////////////////////////////////////////*/ - + }; + /*###########################################################################################*/ template< typename Type1, typename Type2, typename Type3, typename Type4, typename Type5, typename Type6, typename Type7, typename Type8, typename Type9 //////////////////////// > struct ZtStTuple /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1530,7 +1243,6 @@ namespace ZNsMain TypeData6 _6; TypeData7 _7; TypeData8 _8; TypeData9 _9; ZtStTuple(){} - ZtStTuple ( TypeData1 _T1, TypeData2 _T2, TypeData3 _T3, TypeData4 _T4, @@ -1538,11 +1250,8 @@ namespace ZNsMain ) : _1(_T1), _2(_T2), _3(_T3), _4(_T4), _5(_T5), _6(_T6), _7(_T7), _8(_T8), _9(_T9) {} - };/* - template< typename Type1, typename Type2, typename Type3, typename Type4, typename Type5, typename Type6, typename Type7, typename Type8, typename Type9 - > - struct ZtStTuple /////////////////////////////////////////////////////////////////////////////////////////////////*/ - + }; + /*###########################################################################################*/ template< typename Type1, typename Type2, typename Type3, typename Type4, typename Type5, typename Type6, typename Type7, typename Type8, typename Type9, typename Type10 > struct ZtStTuple /////////////////////////////////////////////////////////////////////////////////////////// @@ -1563,190 +1272,14 @@ namespace ZNsMain ZtStTuple< Type1, Type2, Type3, Type4, Type5, Type6, Type7, Type8, Type9, Type10>(){} - ZtStTuple< Type1, Type2, Type3, Type4, Type5, Type6, Type7, Type8, Type9, Type10>( TypeData1 _T1, TypeData2 _T2, TypeData3 _T3, TypeData4 _T4, TypeData5 _T5 , TypeData6 _T6, TypeData7 _T7, TypeData8 _T8, TypeData9 _T9, TypeData10 _T10) : _1(_T1), _2(_T2), _3(_T3), _4(_T4), _5 (_T5 ), _6(_T6), _7(_T7), _8(_T8), _9(_T9), _10(_T10) {} - };/* - template< typename Type1, typename Type2, typename Type3, typename Type4, typename Type5, typename Type6, typename Type7, typename Type8, typename Type9, typename Type10 - > - struct ZtStTuple /////////////////////////////////////////////////////////////////////////////////////////*/ - - - template< typename Type1, typename Type2 - > - ZtStTuple ZftMakeArguTuple - ( - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type1, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type2 - ) - { - return ZtStTuple(AO_Type1, AO_Type2); - };/* - template< typename Type1, typename Type2 - > - ZtStTuple ZftMakeArguTuple(Type1 AO_Type1, Type2 AO_Type2) */ - - template< typename Type1, typename Type2, typename Type3 - > - ZtStTuple ZftMakeArguTuple - ( - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type1, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type2, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type3 - ) - { - return ZtStTuple(AO_Type1, AO_Type2, AO_Type3); - };/* - template< typename Type1, typename Type2, typename Type3 - > - ZtStTuple ZftMakeArguTuple(Type1 AO_Type1, Type2 AO_Type2, Type2 AO_Type3) */ - - template< typename Type1, typename Type2, typename Type3, typename Type4 - > - ZtStTuple ZftMakeArguTuple - ( - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type1, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type2, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type3, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type4 - ) - { - return ZtStTuple - (AO_Type1, AO_Type2, AO_Type3, AO_Type4); - };/* - template< typename Type1, typename Type2, typename Type3, typename Type4 - > - ZtStTuple ZftMakeArguTuple(Type1 AO_Type1, Type2 AO_Type2, Type3 AO_Type3, Type4 AO_Type4) */ - - template< typename Type1, typename Type2, typename Type3, typename Type4, typename Type5 - > - ZtStTuple ZftMakeArguTuple - ( - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type1, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type2, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type3, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type4, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type5 - ) - { - return ZtStTuple - (AO_Type1, AO_Type2, AO_Type3, AO_Type4, AO_Type5); - };/* - template< typename Type1, typename Type2, typename Type3, typename Type4, typename Type5 - > - ZtStTuple ZftMakeArguTuple(Type1 AO_Type1, Type2 AO_Type2, Type3 AO_Type3, Type4 AO_Type4, Type5 AO_Type5) */ - - template< typename Type1, typename Type2, typename Type3, typename Type4, typename Type5, typename Type6 - > - ZtStTuple ZftMakeArguTuple - ( - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type1, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type2, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type3, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type4, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type5, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type6 - ) - { - return ZtStTuple - (AO_Type1, AO_Type2, AO_Type3, AO_Type4, AO_Type5, AO_Type6); - };/* - template< typename Type1, typename Type2, typename Type3, typename Type4, typename Type5, typename Type6 - > - ZtStTuple ZftMakeArguTuple(Type1 AO_Type1, Type2 AO_Type2, Type3 AO_Type3, Type4 AO_Type4, Type5 AO_Type5, Type6AO_Type6) */ - - template< typename Type1, typename Type2, typename Type3, typename Type4, typename Type5, typename Type6, typename Type7 - > - ZtStTuple ZftMakeArguTuple - ( - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type1, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type2, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type3, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type4, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type5, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type6, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type7 - ) - { - return ZtStTuple - (AO_Type1, AO_Type2, AO_Type3, AO_Type4, AO_Type5, AO_Type6, AO_Type7); - };/* - template< typename Type1, typename Type2, typename Type3, typename Type4, typename Type5, typename Type6, typename Type7 - > - ZtStTuple ZftMakeArguTuple(Type1 AO_Type1, Type2 AO_Type2, Type3 AO_Type3, Type4 AO_Type4, Type5 AO_Type5, Type6 AO_Type6, Type7 AO_Type7) */ - - template< typename Type1, typename Type2, typename Type3, typename Type4, typename Type5, typename Type6, typename Type7, typename Type8 - > - ZtStTuple ZftMakeArguTuple - ( - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type1, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type2, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type3, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type4, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type5, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type6, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type7, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type8 - ) - { - return ZtStTuple - (AO_Type1, AO_Type2, AO_Type3, AO_Type4, AO_Type5, AO_Type6, AO_Type7, AO_Type8); - };/* - template< typename Type1, typename Type2, typename Type3, typename Type4, typename Type5, typename Type6, typename Type7, typename Type8 - > - ZtStTuple ZftMakeArguTuple( - Type1 AO_Type1, Type2 AO_Type2, Type3 AO_Type3, Type4 AO_Type4, Type5 AO_Type5, Type6 AO_Type6, Type7 AO_Type7, Type8 AO_Type8) */ - - template< typename Type1, typename Type2, typename Type3, typename Type4, typename Type5, typename Type6, typename Type7, typename Type8, typename Type9 - > - ZtStTuple ZftMakeArguTuple - ( - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type1, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type2, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type3, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type4, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type5, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type6, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type7, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type8, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type9 - ) - { - return ZtStTuple - (AO_Type1, AO_Type2, AO_Type3, AO_Type4, AO_Type5, AO_Type6, AO_Type7, AO_Type8, AO_Type9); - };/* - template< typename Type1, typename Type2, typename Type3, typename Type4, typename Type5, typename Type6, typename Type7, typename Type8, typename Type9 - > - ZtStTuple ZftMakeArguTuple( - Type1 AO_Type1, Type2 AO_Type2, Type3 AO_Type3, Type4 AO_Type4, Type5 AO_Type5, Type6 AO_Type6, Type7 AO_Type7, Type8 AO_Type8, Type8 AO_Type9) */ - - template< typename Type1, typename Type2, typename Type3, typename Type4, typename Type5, typename Type6, typename Type7, typename Type8, typename Type9, typename Type10 - > - ZtStTuple ZftMakeArguTuple - ( - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type1, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type2, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type3, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type4, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type5, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type6, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type7, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type8, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type9, - typename ZNsType::ZtCTypeCheckRef::TypeData AO_Type10 - ) - { - return ZtStTuple - (AO_Type1, AO_Type2, AO_Type3, AO_Type4, AO_Type5, AO_Type6, AO_Type7, AO_Type8, AO_Type9, AO_Type10); - };/* - template< typename Type1, typename Type2, typename Type3, typename Type4, typename Type5, typename Type6, typename Type7, typename Type8, typename Type9, typename Type10 - > - ZtStTuple ZftMakeArguTuple( - Type1 AO_Type1, Type2 AO_Type2, Type3 AO_Type3, Type4 AO_Type4, Type5 AO_Type5, Type6 AO_Type6, Type7 AO_Type7, Type8 AO_Type8, Type9 AO_Type9, Type1 AO_Type10) */ + }; + /*###########################################################################################*/ namespace ZNsHide @@ -1779,7 +1312,7 @@ namespace ZNsMain namespace ZNsBase { - // 가상클래스도 아니고 인터페이스 전용의 함수도 아니면서 + // 가상 클래스도 아니고 인터페이스 전용의 함수도 아니면서 // 주로 기반 클래스로 사용되는 클래스는 여기에 둔다. }/* namespace ZNsBase*/ @@ -1907,7 +1440,7 @@ namespace ZNsMain ■ 특수한 목적으로 쓰이는 전역 템플릿 함수는 여기에 놓는다. - ■ __FastMoveObj<>(Type1& AR_Type1,Type2& AR_Type2) + ■ __FastMoveObj<>(Type1& AR_Type1, Type2& AR_Type2) 차기 표준에서 구현하는 RValue Reference 를 흉내낸 함수다. Move 생성자와 Move 대입연산 중 대입연산만을 흉내내는 것이며, 일반적으로 이 함수 호출후에 @@ -2147,7 +1680,7 @@ namespace ZNsMain };/* template< typename TTypeArg1, typename TTypeArg2 > - class ZtCMoveObj //*/ + class ZtCMoveObj ##*/ }/* namespace ZNsFunc*/ @@ -2401,9 +1934,9 @@ namespace ZNsMain enum ZERunEx { - ERunEx_NO, // 실행 중지 - ERunEx_OK, // 실행 계속 - ERunEx_Err // 실행 에러 + ZERunEx_NO, // 실행 중지 + ZERunEx_OK, // 실행 계속 + ZERunEx_Err // 실행 에러 };/* enum ZERun*/ @@ -2440,6 +1973,16 @@ namespace ZNsMain namespace ZNsEnum*/ + using ZNsEnum::ZERun ; + using ZNsEnum::ZERun_NO ; + using ZNsEnum::ZERun_OK ; + + using ZNsEnum::ZERunEx ; + using ZNsEnum::ZERunEx_NO ; + using ZNsEnum::ZERunEx_OK ; + using ZNsEnum::ZERunEx_Err; + + namespace ZNsInterface { @@ -2549,8 +2092,9 @@ namespace ZNsMain /////////////////////////////////////////////////////////////////*/ - template - class ZtCAllocClass : public ZCAllocator + template class ZtCAllocClass : + public ZCAllocator + ////////////////////////////////////////////// { public: TType* NewMem (size_t AL_AllocSize){return (TType*)::malloc(AL_AllocSize) ;} @@ -2607,18 +2151,37 @@ namespace ZNsMain //////////////////////////////////////////////////////////////*/ + typedef void (*ZfpNone)(void*); void ZfNone(void* AP_Void=0){}; + template class ZtCTypeData - { public: typedef TType TypeData; - static TType& GetObjRef(TType& AR_Type){return AR_Type ;}}; + { public: typedef TType TypeData; + static TType& GetObjRef(TType& AR_Type){return AR_Type ;}}; template class ZtCTypeData - { public: typedef TType TypeData; - static TType& GetObjRef(TType* AP_Type){return *AP_Type;}}; + { public: typedef TType TypeData; + static TType& GetObjRef(TType* AP_Type){return *AP_Type;}}; template class ZtCTypeData - { public: typedef TType TypeData; - static TType& GetObjRef(TType& AR_Type){return AR_Type ;}}; - template< > class ZtCTypeData - { public: typedef void* TypeData; - static void* GetObjRef(void* AP_Void){return AP_Void ;}}; + { public: typedef TType TypeData; + static TType& GetObjRef(TType& AR_Type){return AR_Type ;}}; + template< /*########*/ > class ZtCTypeData + { public: typedef ZfpNone TypeData; + static ZfpNone GetObjRef(void* AP_Void){return ZfNone ;}}; + + template class ZtCTD + { public: typedef TType TypeData; + static TType& GetObjRef(TType& AR_Type){return AR_Type ;} + static TType& GOR (TType& AR_Type){return AR_Type ;}}; + template class ZtCTD + { public: typedef TType TypeData; + static TType& GetObjRef(TType* AP_Type){return *AP_Type;} + static TType& GOR (TType* AP_Type){return *AP_Type;}}; + template class ZtCTD + { public: typedef TType TypeData; + static TType& GetObjRef(TType& AR_Type){return AR_Type ;} + static TType& GOR (TType& AR_Type){return AR_Type ;}}; + template< /*########*/ > class ZtCTD + { public: typedef ZfpNone TypeData; + static ZfpNone GetObjRef(void* AP_Void){return ZfNone ;} + static ZfpNone GOR (void* AP_Void){return ZfNone ;}}; /*//////////////////////////////////////////////////////////////////////////////// @@ -2633,16 +2196,16 @@ namespace ZNsMain { public: - template - TTypeSize GetNewAllocSize(TTypeSize AL_NowAllocSize, TTypeSize AL_AllAllocSize) + template static TTypeSize + GetNewAllocSize(TTypeSize AL_NowAllocSize, TTypeSize AL_AllAllocSize ) { /* AL_AllAllocSize : 해당 문자열 object 가 할당받은 문자 총갯수. AL_NowAllocSize : AL_AllAllocSize 에서 현재 유효한 문자 갯수. */ return AL_NowAllocSize<=AL_AllAllocSize ? AL_NowAllocSize : AL_NowAllocSize*2 ; }/* - template - TTypeSize GetNewAllocSize(TTypeSize AL_NowAllocSize, TTypeSize AL_AllAllocSize) */ + template static TTypeSize + GetNewAllocSize(TTypeSize AL_NowAllocSize, TTypeSize AL_AllAllocSize ) */ public: };/* @@ -2666,8 +2229,8 @@ namespace ZNsMain return (AI_Param<0 ? -AI_Param : AI_Param); }/* static inline TTypSize GetAbs(TTypSize AI_Param)*/ - - /*private:*/ + /* + private:*/ public : static ZTypIntI GetAbsMinOrder(TTypSize AI_One, TTypSize AI_Two, TTypSize AI_Three) @@ -2694,18 +2257,17 @@ namespace ZNsMain #ifdef _WIN - /*///////////////////////////////////////////////// - - inline ZTypIntI GetLastError(){return ::GetLastError();} - - /////////////////////////////////////////////////*/ - using ::GetLastError; - template - static bool GetLastErrMSG(TString& ARR_BuffCStr, ZTypIntI AI_ErrNo=0) + + inline ZTypIntI ZfGetLastError(){ return ::GetLastError(); } + + + template static bool + ZftGetLastErrMSG(TString& ARR_BuffCStr, ZTypIntI AI_ErrNo=0) { - LPVOID VP_MsgBuff; DWORD ViErrNo=(AI_ErrNo==0 ? ::GetLastError() : AI_ErrNo); + LPVOID VP_MsgBuff=0; DWORD ViErrNo = + (AI_ErrNo==0 ? ::GetLastError() : AI_ErrNo); const DWORD CI_RetCode = ::FormatMessage( /////////////// FORMAT_MESSAGE_ALLOCATE_BUFFER | @@ -2724,20 +2286,21 @@ namespace ZNsMain ::LocalFree(VP_MsgBuff); return true; }/* - template - static bool GetLastErrMSG(TString& ARR_BuffCStr, ZTypIntI AI_ErrNo=0) */ + template static bool + ZftGetLastErrMSG(TString& ARR_BuffCStr, ZTypIntI AI_ErrNo=0) */ // defined(_WIN) #elif defined(__unix__) - inline ZTypIntI GetLastError() + inline ZTypIntI GetLastError(){return errno ;} // for compatibility with windows + inline ZTypIntI ZfGetLastError() { return errno ; // ::error 로 하면 안된다. }/* - inline ZTypIntI GetLastError()*/ + inline ZTypIntI ZfGetLastError()*/ - template - static bool GetLastErrMSG(TString& ARR_BuffCStr, ZTypIntI AI_ErrNo=0) + template static bool + ZftGetLastErrMSG(TString& ARR_BuffCStr, ZTypIntI AI_ErrNo=0) { if(AI_ErrNo==0) ARR_BuffCStr = ::strerror(errno ); @@ -2745,27 +2308,25 @@ namespace ZNsMain return true; // for compatibility with window }/* - template - static bool GetLastErrMSG(TString& ARR_BuffCStr, ZTypIntI AI_ErrNo=0) */ + template static bool + ZftGetLastErrMSG(TString& ARR_BuffCStr, ZTypIntI AI_ErrNo=0) */ //#elif defined(__unix__) #else - inline ZTypIntI GetLastError(){return errno ;} + inline ZTypIntI ZfGetLastError(){return errno ;} - template - static bool GetLastErrMSG(TString& ARR_BuffCStr, ZTypIntI AI_ErrNo=0) + template static bool + ZftGetLastErrMSG(TString& ARR_BuffCStr, ZTypIntI AI_ErrNo=0) { if(AI_ErrNo==0) - ARR_BuffCStr = ::strerror(errno ); - else - ARR_BuffCStr = ::strerror(AI_ErrNo); - //else + ARR_BuffCStr = ::strerror(errno ); + else ARR_BuffCStr = ::strerror(AI_ErrNo); return true; // for compatibility with window }/* - template - static bool GetLastErrMSG(TString& ARR_BuffCStr, ZTypIntI AI_ErrNo=0) */ + template static bool + ZftGetLastErrMSG(TString& ARR_BuffCStr, ZTypIntI AI_ErrNo=0) */ #endif @@ -2866,7 +2427,7 @@ namespace ZNsMain template - inline ZTypLength GetLength(const TTypeCh* ApcChar) + inline ZTypLength ZftGetLength(const TTypeCh* ApcChar) { if(ApcChar==0) return 0; @@ -2879,10 +2440,11 @@ namespace ZNsMain return VL_Length; }/* template - inline ZTypLength GetLength(const TTypeCh* ApcChar) */ + inline ZTypLength ZftGetLength(const TTypeCh* ApcChar) */ + template - inline TTypeSize GetLengthType(const TTypeCh* ApcChar) + inline TTypeSize ZftGetLengthType(const TTypeCh* ApcChar) { if(ApcChar==0) return 0; @@ -2895,14 +2457,31 @@ namespace ZNsMain return VL_Length; }/* template - inline TTypeSize GetLengthType(const TTypeCh* ApcChar) */ + inline TTypeSize ZftGetLengthType(const TTypeCh* ApcChar) */ + + + template + inline ZTypLength ZftLength(const TTypeCh* ApcChar) + { + return ZftGetLength(ApcChar); + }/* + template + inline ZTypLength ZftLength(const TTypeCh* ApcChar) */ + + template + inline TTypeSize ZfLengthType(const TTypeCh* ApcChar) + { + return ZftGetLengthType(ApcChar); + }/* + template + inline TTypeSize ZftLengthType(const TTypeCh* ApcChar) */ /*////////////////////////////////////////////////////////////////////////////////////// - ■ CopyChars() 함수는 최대 AL_DestSize 만큼 복사하는데, ZNsWin.H 의 CRegistry 클래스에서 - Windows 의 Strsafe.h 에 정의된 StringCchCopy() 을 대신하려고 만들었다. mingw 에서는 - 헤더 파일 Strsafe.h 이 없는 경우가 있는 것이다. 원래 StringCchCopy() 선언은 이렇다. + ■ ZftCopyChars() 함수는 최대 AL_DestSize 만큼 복사하는데, ZNsWin.H 의 CRegistry 클래스 + 에서 Windows 의 Strsafe.h 에 정의된 StringCchCopy() 을 대신하려고 만들었다. mingw 에 + 서는 헤더 파일 Strsafe.h 이 없는 경우가 있는 것이다. 원래 StringCchCopy() 선언은 이렇다. HRESULT StringCchCopy( __out LPTSTR pszDest, @@ -2929,8 +2508,8 @@ namespace ZNsMain //////////////////////////////////////////////////////////////////////////////////////*/ - template - TTypeSize CopyChars(TTypeCh* ApcDest, TTypeSize AL_DestSize, const TTypeCh* ApcSource) + template TTypeSize + ZftCopyChars(TTypeCh* ApcDest, TTypeSize AL_DestSize, const TTypeCh* ApcSource) { /* ApcSource must be null-terminated. AL_DestSize must be equal to or more than strlen(ApcSource)+1. @@ -2948,10 +2527,7 @@ namespace ZNsMain if(*ApcSource==0) { if(VL_SourceSize - TTypeSize CopyChars(TTypeCh* ApcDest, TTypeSize AL_DestSize, const TTypeCh* ApcSource) */ + template TTypeSize + ZftCopyChars(TTypeCh* ApcDest, TTypeSize AL_DestSize, const TTypeCh* ApcSource) */ template class ZtCInit @@ -2991,26 +2567,26 @@ namespace ZNsMain class ZCInit*/ - class CExceptBase + class ZCExceptBase { public: void* operator()(){return 0;} };/* - class CExceptBase*/ + class ZCExceptBase*/ // 예외 기반 클래스를 template 로 하면 여러 기법을 사용할 수 있다. template< typename TType, typename TypeArg=const TType& > - class CExceptBase_T /*/////////////////////////////////*/ + class ZtCExceptBase_T /*///////////////////////////////*/ { protected: TType mo_Type; public : - CExceptBase_T(){} + ZtCExceptBase_T(){} - CExceptBase_T(TypeArg TypeArgObj):mo_Type(TypeArgObj){} + ZtCExceptBase_T(TypeArg TypeArgObj):mo_Type(TypeArgObj){} TType& operator()(){return mo_Type;} @@ -3018,7 +2594,7 @@ namespace ZNsMain };/* template< typename TType, typename TypeArg=const TType& > - class CExceptBase_T ///////////////////////////////////*/ + class ZtCExceptBase_T /////////////////////////////////*/ /*///////////////////////////////////////////////////////////////////////////////// @@ -3461,7 +3037,7 @@ namespace ZNsMain #if defined(_REENTRANT) - class ZCExceptSmallLock : public CExceptBase + class ZCExceptSmallLock : public ZCExceptBase { private: long ml_ErrCode; @@ -3476,13 +3052,12 @@ namespace ZNsMain }/* ZCExceptSmallLock(long AL_ErrCode, const char* AP_ErrMSG)*/ - long GetErrCode() const{return ml_ErrCode;} - - const string& GetErrMSG() const{return mo_ErrMSG;} + long GetErrCode() const{return ml_ErrCode;} + const string& GetErrMSG () const{return mo_ErrMSG ;} public: };/* - class ZCExceptSmallLock*/ + class ZCExceptSmallLock : public ZCExceptBase*/ #endif //defined(_REENTRANT) @@ -3890,7 +3465,8 @@ namespace ZNsMain ~ZCAllowAlloc() { - if(mb_AllowAlready==false) ZCCheckAlloc::GetAllowAllocBool()=false; + if(mb_AllowAlready==false) + ZCCheckAlloc::GetAllowAllocBool()=false; }/* ZCAllowAlloc()*/ @@ -3920,13 +3496,19 @@ namespace ZNsMain ZTypCPCCh CPC_DirDelimiter="\\"; ZTypCChar CC_DirDelimiter ='\\'; + ZTypCPCCh CPC_Delm ="\\"; + ZTypCChar CC_Delm ='\\'; + #else //!(defined(_WIN) #define __DIR_DELIMITERS__ "/" #define __DIR_DELIMITER__ '/' - ZTypCPCCh CPC_DirDelimiter="/"; - ZTypCChar CC_DirDelimiter ='/'; + ZTypCPCCh CPC_DirDelimiter="/" ; + ZTypCChar CC_DirDelimiter ='/' ; + + ZTypCPCCh CPC_Delm ="/" ; + ZTypCChar CC_Delm ='/' ; #endif //!(defined(_WIN) }/* @@ -4181,7 +3763,7 @@ namespace ZNsCPP */ (2007/04/03 16:20) http://blog.naver.com/cppis/60036113050 - bugmail에게 More Effective C++을 빌려 보던 중 일반적으로 많이 쓰던 new와 delete에 대해서 소홀하게 넘어갔던 부분을 + bugmail에게 More Effective C++을 빌려 보던 중 일반적으로 많이 쓰던 new 와 delete 에 대해서 소홀하게 넘어갔던 부분을 보고 정리를 하게 되었습니다. 저와 마찬가지로 많은 사람들이 'new operator' 와 'operator new'를 혼동하시는 것 같아서 간단히 정리해봤습니다. @@ -4320,7 +3902,7 @@ namespace ZNsCPP */ void clear(); }; - 위외 같은 형태가 될텐데, 이때 clear() 멤버를 정의하면서 기반클래스인 CMy 의 멤버변수와 함수를 어떻게 + 위외 같은 형태가 될텐데, 이때 clear() 멤버를 정의하면서 기반 클래스인 CMy 의 멤버변수와 함수를 어떻게 사용하겠는지 한 번쯤 생각을 하게 된다. 그런데 CMy 의 기반클래스인 CBaseClass 에 대해서는 자칫 생각을 못하게 된다. clear() 함수가 어떤 자원을 해제하는 함수라면 CBaseClass 의 관련 자원을 해제하는 처리를 빠트릴 수 있는 것이다. 따라서 템플릿 기반의 상속 구현에서 기반클래스의 관련 멤버에 대해서도 어떤 처리가 필요한지 한 번 더 따져봐 @@ -4332,7 +3914,7 @@ namespace ZNsCPP */ 위와 상황은 약간 다르지만 유사한 헛점이 생겼던 코드이다. clear() 멤버는 자원을 해제하는 함수인데 이 함수를 재정의 하지 않는 상태에서 - ZtCTypeLoadDataQuery_T<> ::clear() 을 호출하니 + ZtCTypeLoadDataQuery_T<> ::clear() 을 호출하니 std::CLoadDataBlockOne_T<>::clear() 만을 호출하고 또다른 기반 클래스인 TTypeBase 의 자원을 해제하지 못하고 있었다. 그래서 부랴부랴 TTypeBase 인자에 해당하는 클래스 @@ -4355,17 +3937,17 @@ namespace ZNsCPP */ 게다가 갑자기 breakpoint 가 먹질 않고... 휴 진땀뺏다. -- 2009-01-05 10:02:00 -■ CHttp.H 에 가상 기초클래스가 필요한 상황에 어떻게 템플릿으로 구현하는지 그 예가 있다. 여러 개의 상속클래스에서 공 - 통이 되는 멤버를, 상속클래스에서 선언및 정의하는 방법을 사용하고 있다. +■ CHttp.H 에 가상 기초 클래스가 필요한 상황에 어떻게 템플릿으로 구현하는지 그 예가 있다. 여러 개의 상속클래스에서 + 공통이 되는 멤버를, 상속 클래스에서 선언및 정의하는 방법을 사용하고 있다. 이 방법을 "가상 상속의 템플릿 구현(TIVI : Template Implementation Of Virtual Inheritance)" 이라고 하자. CHttp.H 에서 사용한 이런 기법이 다른 경우에도 적용될 수 있다. 프로그램이 커지면 여러 가지 클래스를 정의하게 되고, 어떠 클래스를 정의하기 전에, 다른 클래스 정의를 요구하고 또 다른 클래스 object 를 요구할 수 있다. 다른 클래스 정의 를 요구하는 경우는 그 클래스 앞에 요구하는 클래스를 미리 정의하면 간단한데, 다른 클래스 object (참조, 포인터) 를 - 외부에서 요구하는 경우는 처리가 복잡해진다. 그때마다 전역 인스턴스를 만들자니 뭔가 찝찝하다. 예를 들어 A, B, C,D,E + 외부에서 요구하는 경우는 처리가 복잡해진다. 그때마다 전역 인스턴스를 만들자니 뭔가 찝찝하다. 예를 들어 A/B/C/D/E 클래스가 있는데 - + B 는 외부의 A 의 object 참조를 요구하고 C 는 외부의 B 의 object 참조를 요구하고 D 는 외부의 C 의 object 참조를 요구하고 @@ -4383,7 +3965,7 @@ namespace ZNsCPP */ 음, "가상 상속의 템플릿 구현" 을 좀 더 곰곰히 생각해 보면, 스트립트 언어에서는 이런 경우를 '어떻게 처리할까' 라는 궁금증이 생긴다. 근데 스트립트 언어에서는 데이타형에서 자유롭기 때문에 이런 상황을 풀어 내기가 훨씬 쉬워 보인다. 데이타형에서 자유롭기 때문에 얻어지는 이 장점이 과연 좋은 것일까. 버그가 더 발생하기 쉽지 않을까. - + -- 2009-01-19 01:21:00 위에서 예로 든 object A,B,C,D,E 의 관계를 이렇게 풀 수도 있겠다. @@ -4393,12 +3975,12 @@ namespace ZNsCPP */ B 의 참조(나 포인터)를 생성자에서 인수로 받는 클래스 C 를 만들고 C 의 참조(나 포인터)를 생성자에서 인수로 받는 클래스 D 를 만든다. - 이 개념을 가상함수로 풀면, + 이 개념을 가상 함수로 풀면, A 를 정의하고 - A 의 기초클래스의 참조(나 포인터)를 생성자에서 인수로 받는 클래스 B 를 만들고 - B 의 기초클래스의 참조(나 포인터)를 생성자에서 인수로 받는 클래스 C 를 만들고 - C 의 기초클래스의 참조(나 포인터)를 생성자에서 인수로 받는 클래스 D 를 만든다. + A 의 기초 클래스의 참조(나 포인터)를 생성자에서 인수로 받는 클래스 B 를 만들고 + B 의 기초 클래스의 참조(나 포인터)를 생성자에서 인수로 받는 클래스 C 를 만들고 + C 의 기초 클래스의 참조(나 포인터)를 생성자에서 인수로 받는 클래스 D 를 만든다. -- 2009-01-19 01:26:00 @@ -4433,8 +4015,8 @@ namespace ZNsCPP */ "가상 상속의 템플릿 구현" 은 CURIOUSLY RECURRING TEMPLATE PATTERN 과 일맥상통한다. - class template A 가 다수 개의 class B1,B2,B3 의 존재를 알아야 하고, 또 class B1, B2, B3 는 A 의 존재를 알아야 하는 - 순환 인식 구조에서도 적용하면 아주 좋을 것 같다. 또한 class B1, B2, B3 가 서로의 존재를 알아야 할 때도 유용하다. + class template A 가 다수 개의 class B1, B2, B3 의 존재를 알아야 하고, 또 class B1, B2, B3 는 A 의 존재를 알아야 하 + 는 순환 인식 구조에서도 적용하면 아주 좋을 것 같다. 또한 class B1, B2, B3 가 서로의 존재를 알아야 할 때도 유용하다. class B1, B2, B3 의 멤버함수를 호출할 때, A 의 상속클래스 A2 를 넘기면, A2 에 B1, B2, B3 에 접근하는 interface 가 있기 때문에, B1 에서 B2 나 B3 의 interface 에 접근할 수가 있는 것이다. @@ -4461,11 +4043,11 @@ namespace ZNsCPP */ class A2 : public A { public: - class B1{public:void CallFunc() {cout<<"Call B1::CallFunc()"< P1 => B 가 된다. 그런데 P1 은 B 라 는 자료형을 알아야 하는데, 이것은 P1 의 작업쓰레드의 수행 함수를 템플릿으로 만들어서 인자를 받게 하고, P1 의 Instance 를 B 에서 만들면서 템플릿 인자로 B 를 넘겨주면 된다. @@ -4524,7 +4106,7 @@ namespace ZNsCPP */ -- 2009-02-27 10:02:00 -■ 멤버 함수 템플릿은 가상함수가 될 수 없다. -- 2009-02-28 04:21:00 +■ 멤버 함수 템플릿은 가상 함수가 될 수 없다. -- 2009-02-28 04:21:00 ■ C# 의 delegate 삼아서 std:ZNsIFace::ZIDelgtMSG 클래스를 설계하였다. 이 object 로부터 메시지를 수신하는 클래스는 이 클래스를 상속하거나, 이 클래스를 상속하여 관련 interface 를 재정의한 클래스를 멤버 변수로 가지고 있는 것이 좋다. @@ -4577,13 +4159,13 @@ namespace ZNsCPP */ int,std::ZNsIFace::ZIDelgtMSG*, /////////////////// > - 클래스를 설계한다. 이 클래스를 정적object 로 갖는 클래스를 만들고, 이 클래스 헤더를 각각의 메시지 송/수신이 필요한 + 클래스를 설계한다. 이 클래스를 정적 object 로 갖는 클래스를 만들고, 이 클래스 헤더를 각각의 메시지 송/수신이 필요한 클래스에서 #include 하면 된다. 이 다음 각 메시지 별로 std::ZNsIFace::ZIDelgtMSG 을 상속하는 클래스를 정의하여 사용하자. -- 2009-03-06 08:59:00 ■ Modeless 대화상자에서 Modeless 대화상자를 호출한 부모 윈도우에서 쓰레드가 동작하고 있는 경우, 부모창이 닫히면 Modeless - 대화상자가 자동으로 안닫히는 경우가 있다. 이때는 부모창의 종료이벤트에서 명시적으로 해당 Modeless 를 종료해 주는 + 대화상자가 자동으로 안닫히는 경우가 있다. 이때는 부모창의 종료 이벤트에서 명시적으로 해당 Modeless 를 종료해 주는 것이 좋다. -- 2009-03-08 21:28:00 @@ -4758,4 +4340,4 @@ namespace ZNsCPP */ -#endif //__MAINHEADER_H__ +#endif //__ZCPPMAIIN_ZMAINHEAD_H__ diff --git a/ZCppMain/ZMainHeadEx.H b/ZCppMain/ZMainHeadEx.H new file mode 100644 index 0000000..8775797 --- /dev/null +++ b/ZCppMain/ZMainHeadEx.H @@ -0,0 +1,7194 @@ + + +#ifndef __ZCPPMAIIN__MAINHEAD_EX_H__ +#define __ZCPPMAIIN__MAINHEAD_EX_H__ + + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "ZCppMain/ZtCMainChars.H" + + +/* cf) #define OPEN_MAX 32 in + OPEN_MAX is max file numbers to open */ + +#ifdef __linux__ + + #include // (In Linux) == + + ... (In Visual C++ 6.0) + #include + #include + #include + #include + #include + + #ifndef _T + #define _T(x) x + #endif + +#elif defined(__sun__) // In Solaris + + #include // (In Linux) == + + ... (In Visual C++ 6.0) + #include + #include + #include + #include + + #ifndef _T + #define _T(x) x + #endif + +#elif defined(_WIN) + + #include + #include + #include // for Win32 API + + #ifndef _T + #define _T(x) TEXT(x) + #endif + + #pragma comment(lib, "ws2_32") // ws2_32.lib 를 링크한다. + +#else // 기본적으로 UNIX 계열이라고 간주한다. + + #include // (In Linux) == + + ... (In Visual C++ 6.0) + #include + #include + #include + #include + + #ifndef _T + #define _T(x) x + #endif + +#endif + + +#ifndef _MAX_DIR + #define _MAX_DIR 512*2 // For unix. +#endif + + +using namespace std ; +using namespace ZNsMain; + + +/*///////////////////////////////////////////////////////////////////////////// + +■ char* ctime ( const time_t *timer ); + wchar_t* _wctime( const time_t *timer ); + + Routine Required Header Compatibility + ctime ANSI, Win 95, Win NT + _wctime or Win 95, Win NT + + For additional compatibility information, see Compatibility in the Introduction. + + Libraries + + LIBC.LIB Single thread static library, retail version + LIBCMT.LIB Multithread static library, retail version + MSVCRT.LIB Import library for MSVCRT.DLL, retail version + + Return Value + + Each of these functions returns a pointer to the character string result. + If time represents a date before midnight, January 1, 1970, UTC, the function returns NULL. + + +■ time_t mktime( struct tm *timeptr ); *** + + Routine Required Header Compatibility + mktime ANSI, Win 95, Win NT + + For additional compatibility information, see Compatibility in the Introduction. + + Libraries + + LIBC.LIB Single thread static library, retail version + LIBCMT.LIB Multithread static library, retail version + MSVCRT.LIB Import library for MSVCRT.DLL, retail version + + Return Value + + mktime returns the specified calendar time encoded as a value of type time_t. + If timeptr references a date before midnight, January 1, 1970, + or if the calendar time cannot be represented, the function returns ?1 cast to type time_t. + + Remarks + + The mktime function converts the supplied time structure (possibly incomplete) + pointed to by timeptr into a fully defined structure with normalized values + and then converts it to a time_t calendar time value. + For description of tm structure fields, see asctime. + The converted time has the same encoding as the values returned by the time function. + The original values of the tm_wday and tm_yday components of the timeptr structure are ignored, + and the original values of the other components are not restricted to their normal ranges. + + mktime handles dates in any time zone + from midnight, January 1, 1970, to January 18, 19:14:07, 2038. + If successful, mktime sets the values of tm_wday and tm_yday as appropriate + and sets the other components to represent the specified calendar time, + but with their values forced to the normal ranges; + the final value of tm_mday is not set + until tm_mon and tm_year are determined. + When specifying a tm structure time, + set the tm_isdst field to 0 to indicate that standard time is in effect, + or to a value greater than 0 to indicate that daylight savings time is in effect, + or to a value less than zero to have the C run-time library code compute + whether standard time or daylight savings time is in effect. + (The C run-time library assumes the United States’s rules for implementing the calculation of Daylight Saving Time). + tm_isdst is a required field. + If not set, its value is undefined and the return value from mktime is unpredictable. + If timeptr points to a tm structure returned by a previous call to asctime, gmtime, or localtime, + the tm_isdst field contains the correct value. + + Note that gmtime and localtime use a single statically allocated buffer for the conversion. + If you supply this buffer to mktime, the previous contents are destroyed. + + struct tm + { + int tm_sec ; // seconds after the minute - [0,59] + int tm_min ; // minutes after the hour - [0,59] + int tm_hour ; // hours since midnight - [0,23] + int tm_mday ; // day of the month - [1,31] + int tm_mon ; // months since January - [0,11] + int tm_year ; // years since 1900 + int tm_wday ; // days since Sunday - [0,6] + int tm_yday ; // days since January 1 - [0,365] + int tm_isdst; // daylight savings time flag + }; + +■ -- + +/////////////////////////////////////////////////////////////////////////////*/ + + +namespace ZNsMain +{ + +#if defined(_WIN) + + /*//////////////////////////////////////////////////////////////////////////// + + ■ AI_SleepMiliSec 초 동안 잠든다. 1 mili 초를 지정하면 실제로 1 mili 초간 잠 + 드는 것이 아니라 약 16 mili 초 정도 잠든다. 이것은 10 mili 초를 지정하는 것 + 과 비슷하다(Window 2003, zeon 3.2, Ram 1G). 비슷한 사양의 리눅스에서 1 mili + 초를 지정하면 약 4 mili 초 정도를 소요한다. + + ////////////////////////////////////////////////////////////////////////////*/ + + inline void ZfSuspendExec(int AI_SleepMiliSec) + { + ::Sleep(AI_SleepMiliSec); + }/* + inline void ZfSuspendExec(int AI_SleepMiliSec)*/ + + + /*/////////////////////////////////////////////////// + + ■ errno_t _putenv_s( + const char *name, + const char *value + ); + + errno_t _wputenv_s( + const wchar_t *name, + const wchar_t *value + ); + + ※ int _putenv(const char*) 함수가 있는데 "변수명=변수값" 형태로 넘긴다. + + 이 함수보다 좀 더 안전한 함수가 _putenv_s() 이다. + + ※ The _putenv_s and _getenv_s families of functions are not thread-safe. + _getenv_s could return a string pointer + while _putenv_s is modifying the string, causing random failures. + Make sure that calls to these functions are synchronized. + + _putenv_s 과 _getenv_s 류의 함수는 쓰레드에 안전하지 않다. + _putenv_s 과 _getenv_s 을 서로 다른 스레드에서 동시에 사용하는 경우 + _getenv_s 는 수정중인 문자열 포인터를 반환할 수 있다. + + ///////////////////////////////////////////////////*/ + + inline bool ZfPutEnv(const char* APC_EnvName, const char* APC_Value) + { + #if __VISUAL_CPP_VER__>=200500 + + return ::_putenv_s(APC_EnvName, APC_Value)==0; + + #else //__VISUAL_CPP_VER__<200500 + + std::string VO_CStringEnv; + + VO_CStringEnv+=APC_EnvName; + VO_CStringEnv+="=" ; + VO_CStringEnv+=APC_Value ; + + return ::_putenv(VO_CStringEnv.data())==0; + + #endif //__VISUAL_CPP_VER__<200500 + }/* + inline bool ZfPutEnv(const char* APC_EnvName, const char* APC_Value)*/ + + inline bool ZfPutEnv(const char* APC_EnvData) + { + return ::_putenv(APC_EnvData)==0; + }/* + inline bool ZfPutEnv(const char* APC_EnvData)*/ + + inline long ZfWriteStdOut(LPCVOID APC_Buffer, DWORD ADW_BuffSize, LPOVERLAPPED AP_Overlapped=NULL) + { + // 표준 출력에 쓴다. + + DWORD VDW_WrittenSize=0; + + const bool CB_IsOK = ////////////////////////////////////////// + ( + ::WriteFile + ( + ::GetStdHandle(STD_OUTPUT_HANDLE), APC_Buffer + , ADW_BuffSize , &VDW_WrittenSize + , AP_Overlapped + )==TRUE + ); + /////////////////////////////////////////////////////////////// + + if(CB_IsOK==false) return -1; return VDW_WrittenSize; + }/* + inline long ZfWriteStdOut(LPCVOID APC_Buffer, DWORD ADW_BuffSize, LPOVERLAPPED AP_Overlapped=NULL)*/ + + template + inline long ZfWriteStdOut(TString& AR_CStringOut, LPOVERLAPPED AP_Overlapped=NULL) + { + return ZfWriteStdOut(AR_CStringOut.c_str(), AR_CStringOut.size(), AP_Overlapped); + }/* + template + inline long ZfWriteStdOut(TString& AR_CStringOut, LPOVERLAPPED AP_Overlapped=NULL) */ + + inline long ZfReadStdIn(LPVOID AP_Buff, DWORD ADW_BuffSize, LPOVERLAPPED AP_Overlapped=NULL) + { + // 표준입력으로 부터 데이타를 읽는다. + // 에러이면 -1 을 그렇지 않으면 읽은 길이를 반환한다. + + DWORD VDW_ReadCnt =0 ; + + const bool CB_IsOK = ///////////////////////////////// + ( + ::ReadFile + ( + ::GetStdHandle(STD_INPUT_HANDLE), AP_Buff, + ADW_BuffSize, &VDW_ReadCnt, AP_Overlapped + )==TRUE + ); + ////////////////////////////////////////////////////// + + if(CB_IsOK==false) return -1; return VDW_ReadCnt; + }/* + inline long ZfReadStdIn(LPVOID AP_Buff, DWORD ADW_BuffSize, LPOVERLAPPED AP_Overlapped=NULL)*/ + + template long ZfReadStdIn( + TString& ARR_CStringRead, LPOVERLAPPED AP_Overlapped=NULL) + { + const int CI_StdBuffSize=512; + + if(ARR_CStringRead.size()<1) + ARR_CStringRead.resize(CI_StdBuffSize, ' '); + + DWORD VDW_ReadCnt = 0 ; + + const bool CB_IsOK = /////////////////////// + ( + ::ReadFile + ( + ::GetStdHandle(STD_INPUT_HANDLE) + , ARR_CStringRead.data() + , ARR_CStringRead.size() + , &VDW_ReadCnt, AP_Overlapped + )==TRUE + ); + //////////////////////////////////////////// + + if(CB_IsOK==false) + { + ARR_CStringRead=""; return -1; + }/* + if(CB_IsOK==false)*/ + + ARR_CStringRead.resize(VDW_ReadCnt,' '); return VDW_ReadCnt; + }/* + template long ZfReadStdIn( + TString& ARR_CStringRead, LPOVERLAPPED AP_Overlapped=NULL) */ + +#else // !defined(_WIN) + + /*///////////////////////////////////////////////////////////////////////////////////////////// + + ■ std::SleepExec(int) 함수가 이미 glibc 확장에 있다. + + ■ ZfSuspendExec() 함수는 uslee() 함수를 이용하여 쉬는데, 쉬는 시간이 너무 크면 + (1 초 이상이면)오류라는 뜻에서 음수를 반환하는 경우가 있다. '(주)인트라코어'의 + 취약점 진단 프로젝트를 하는데, KT 의 HP-UX(115.21.49.211) 가 그랬다. + uname -a 정보는 + + HP-UX sechpux B.11.11 U 9000/800 1106484218 unlimited-user license + + gcc -v 정보는 + + Using built-in specs. + COLLECT_GCC=gcc + COLLECT_LTO_WRAPPER=/opt/hp-gcc-4.6.2/libexec/gcc/hppa1.1-hp-hpux11.11/4.6.2/lto-wrapper + Target: hppa1.1-hp-hpux11.11 + Configured with: /tmp/gcc-4.6.2.tar.gz/gcc-4.6.2/configure --host=hppa1.1-hp-hpux11.11 + --target=hppa1.1-hp-hpux11.11 --build=hppa1.1-hp-hpux11.11 --prefix=/opt/hp-gcc-4.6.2 + --with-gnu-as --without-gnu-ld --enable-threads=posix --enable-languages=c,c++ + --with-gmp=/proj/opensrc/be/hppa1.1-hp-hpux11.11 + --with-mpfr=/proj/opensrc/be/hppa1.1-hp-hpux11.11 SED=/usr/bin/sed + Thread model: posix + gcc version 4.6.2 (GCC) + + 그래서 성공(0)을 반환하지 않으면, 500 밀리초 씩 쉬는 것으로 했다. + + -- 2012-04-01 21:35:00 + + /////////////////////////////////////////////////////////////////////////////////////////////*/ + + inline void ZfSuspendExec(int AI_SleepMiliSec) + { + if(::usleep(AI_SleepMiliSec*1000)==0) return; + + int VI_SleepSec =AI_SleepMiliSec/1000 ; + int VI_ExtraMili=AI_SleepMiliSec%1000 ; + + for(int i=0; i0) ::usleep(1000*VI_ExtraMili); + }/* + inline void ZfSuspendExec(int AI_SleepMiliSec)*/ + + + /*/////////////////////////////////////////////////// + + ■ setenv - 환경 변수를 바꾸거나 추가시킨다. + + #include + + int setenv(const char *name, const char *value, int overwrite); + void unsetenv(const char *name); + + setenv() 함수는만일 name이 이미 존재하지 않는다면, + 값 value를 가지고 있는 환경 변수 name을 추가시킨다. + 만일 name가 환경 변수에 존재한다면, overwrite가 0 이 아니라면 그 값은 value로 바뀐다. + 만일 overwrite가 0 이라면, name의 값은 바뀌지 않는다. + + unsetenv() 함수는 환경 변수에서 변수 name 를 지운다. + setenv() 함수는 성공시 0 을 반환하거나, + 만일 환경 변수에 공간이 충분하지 않다면 -1을 반환한다. + + ■ 미리 정의된 파일핸들 상수 + + 0 : 표준입력 파일핸들 + 1 : 표준출력 파일핸들 + 2 : 표준에러 파일핸들 + + ///////////////////////////////////////////////////*/ + + inline bool ZfPutEnv(const char* APC_EnvName, const char* APC_Value) + { + return ::setenv(APC_EnvName, APC_Value, 1)==0; + }/* + inline bool ZfPutEnv(const char* APC_EnvName, const char* APC_Value)*/ + + inline bool ZfPutEnv(const char* APC_EnvData) // "변수명=변수값" + { + return ::putenv(const_cast(APC_EnvData))==0; + }/* + inline bool ZfPutEnv(const char* APC_EnvData) // "변수명=변수값"*/ + + + inline ssize_t ZfWriteStdOut(const void* APC_Buffer, ZTypLength AI_BuffSize) + { + return ::write(1, APC_Buffer, AI_BuffSize); + }/* + inline ssize_t ZfWriteStdOut(const void* APC_Buffer, ZTypLength AI_BuffSize)*/ + + template + inline ssize_t ZfWriteStdOut(TString& AR_CStringOut) + { + return ZfWriteStdOut(AR_CStringOut.c_str(), AR_CStringOut.size()); + }/* + template + inline ssize_t ZfWriteStdOut(TString& AR_CStringOut) */ + + inline ssize_t ZfReadStdIn(void* AP_Buff, size_t AI_Count) + { + return ::read(0,AP_Buff,AI_Count); + }/* + inline ssize_t ZfReadStdIn(void* AP_Buff, size_t AI_Count)*/ + + template ssize_t ZfReadStdIn(TString& ARR_CStringRead) + { + const int CI_StdBuffSize=512; + + if(ARR_CStringRead.size()<1) + ARR_CStringRead.resize(CI_StdBuffSize,' '); + + ssize_t VI_ReadSize = ::read + ( 0, ARR_CStringRead.c_str(), ARR_CStringRead.size() ); + + if(VI_ReadSize<=0) + { + ARR_CStringRead=""; return VI_ReadSize; + }/* + if(VI_ReadSize<=0)*/ + + ARR_CStringRead.resize(VI_ReadSize,' '); return VI_ReadSize; + }/* + template ssize_t ZfReadStdIn(TString& ARR_CStringRead) */ + +#endif // !defined(_WIN) + + + /*//////////////////////////////////////////////////////////////////////// + + ■ ** IN time.h ** + + typedef struct tm + { + int tm_hour ; // hour (0 - 23) + int tm_isdst; // daylight saving time enabled/disabled + int tm_mday ; // day of month (1 - 31) + int tm_min ; // minutes (0 - 59) + int tm_mon ; // month (0 - 11 : 0 = January), 1 을 더한 값이 월이다. + int tm_sec ; // seconds (0 - 59) + int tm_wday ; // Day of week (0 - 6 : 0 = Sunday) + int tm_yday ; // Day of year (0 - 365), 1 을 더한 값이 그 해의 이 시점의 날수다. + int tm_year ; // Year less 1900, 1900 을 더한 값이 년도다. + } + + ■ ** timespec IN time.h ** + + SYNOPSIS + + -- 아래 함수를 사용하면 Linux 에서도 초 단위보다 정밀한 시간을 구할 수 있다. + + #include + + int clock_getres(clockid_t clk_id, struct timespec *res); + + int clock_gettime(clockid_t clk_id, struct timespec *tp); + + int clock_settime(clockid_t clk_id, const struct timespec *tp); + + Link with -lrt. + + Feature Test Macro Requirements for glibc (see feature_test_macros(7)): + + clock_getres(), clock_gettime(), clock_settime(): _POSIX_C_SOURCE >= 199309L + + DESCRIPTION + The function clock_getres() finds the resolution (precision) of the specified clock + clk_id, and, if res is non-NULL, stores it in the struct timespec pointed to by res. + The resolution of clocks depends on the implementation and cannot be configured by a + particular process. If the time value pointed to by the argument tp of clock_settime() + is not a multiple of res, then it is truncated to a multiple of res. + + The functions clock_gettime() and clock_settime() retrieve and set the time of the + specified clock clk_id. + + The res and tp arguments are timespec structures, as specified in : + + struct timespec { + time_t tv_sec ; // seconds + long tv_nsec; // nanoseconds + }; + + The clk_id argument is the identifier of the particular clock on which to act. A clock + may be system-wide and hence visible for all processes, or per-process if it measures + time only within a single process. + + All implementations support the system-wide real-time clock, which is identified by + CLOCK_REALTIME. Its time represents seconds and nanoseconds since the Epoch. When its + time is changed, timers for a relative interval are unaffected, but timers for an abso- + lute point in time are affected. + + More clocks may be implemented. The interpretation of the corresponding time values + and the effect on timers is unspecified. + + Sufficiently recent versions of glibc and the Linux kernel support the following + clocks: + + -- clk_id 은 아래 값 중 하나다 -- + + CLOCK_REALTIME + System-wide real-time clock. Setting this clock requires appropriate privi- + leges. + + CLOCK_REALTIME_COARSE (since Linux 2.6.32; Linux-specific) + A faster but less precise version of CLOCK_REALTIME. Use when you need very + fast, but not fine-grained timestamps. + + CLOCK_MONOTONIC + Clock that cannot be set and represents monotonic time since some unspecified + starting point. + + CLOCK_MONOTONIC_COARSE (since Linux 2.6.32; Linux-specific) + A faster but less precise version of CLOCK_MONOTONIC. Use when you need very + fast, but not fine-grained timestamps. + + CLOCK_MONOTONIC_RAW (since Linux 2.6.28; Linux-specific) + Similar to CLOCK_MONOTONIC, but provides access to a raw hardware-based time + that is not subject to NTP adjustments. + + CLOCK_PROCESS_CPUTIME_ID + High-resolution per-process timer from the CPU. + + CLOCK_THREAD_CPUTIME_ID + Thread-specific CPU-time clock. + + RETURN VALUE + clock_gettime(), clock_settime() and clock_getres() return 0 for success, or -1 for + failure (in which case errno is set appropriately). + + ERRORS + EFAULT tp points outside the accessible address space. + + EINVAL The clk_id specified is not supported on this system. + + EPERM clock_settime() does not have permission to set the clock indicated. + + ■ ** IN LINUX ** + + struct timeval + { + time_t tv_sec ; // seconds + suseconds_t tv_usec; // microseconds + }; + + struct timezone + { + int tz_minuteswest; // minutes W of Greenwich + int tz_dsttime; // type of dst correction + }; + + ■ ** IN Window ** + + typedef struct _SYSTEMTIME + { + WORD wYear ; + WORD wMonth ; + WORD wDayOfWeek; + WORD wDay ; + WORD wHour ; + WORD wMinute; + WORD wSecond; + WORD wMilliseconds; + } SYSTEMTIME, *PSYSTEMTIME; + + wYear + The year. The valid values for this member are 1601 through 30827. + wMonth + The month. This member can be one of the following values.Value Meaning + + 1 January + 2 February + 3 March + 4 April + 5 May + 6 June + 7 July + 8 August + 9 September + 10 October + 11 November + 12 December + wDayOfWeek + + The day of the week. This member can be one of the following values. Value Meaning + + 0 Sunday + 1 Monday + 2 Tuesday + 3 Wednesday + 4 Thursday + 5 Friday + 6 Saturday + + wDay + The day of the month. The valid values for this member are 1 through 31. + wHour + The hour. The valid values for this member are 0 through 23. + wMinute + The minute. The valid values for this member are 0 through 59. + wSecond + The second. The valid values for this member are 0 through 59. + wMilliseconds + The millisecond. The valid values for this member are 0 through 999. + + + void GetSystemTime(LPSYSTEMTIME lpSystemTime); + + ■ time_t time ( time_t *timer); + __time32_t _time32(__time32_t *timer); // In Only Window + __time64_t _time64(__time64_t *timer); // In Only Window + + Return the time as seconds elapsed since midnight, January 1, 1970. There is no error return. + + 1970 년 1월 1일 0시 이후 경과한 시간을 초로 나타낸다. + linux 64 bit 에서 time_t 는 8 바이트이다. + + ////////////////////////////////////////////////////////////////////////*/ + + + /*//////////////////////////////////////////////////////////////////////// + + ■ class ZCTime 에 시간을 더하거나 뺄 때에는, 더하거나 빼려는 시간을 + 초단위로 바꾼 후, 그 시간을 ZCTime::Plus() 와 Minus() 에 인수로 넘긴다. + + ////////////////////////////////////////////////////////////////////////*/ + + class ZCTime + { + public : + typedef time_t TypeIntTime; + private : + enum{ETimeBuffSize =30}; + enum{ESecResolution=1 }; // 1 초를 이루는 값. + private : + char* mpc_TimeBuff; + protected: + struct tm mo_TimeObj; + time_t ml_TimeSec; // typedef long time_t; + bool mb_IsLocal; + private : + + #if defined(_WIN) && defined(_REENTRANT) + + static CMutexSmallInit& GetCMutexSmallInit() + { + static CMutexSmallInit SO_CMutexSmallInit; return SO_CMutexSmallInit; + }/* + static CMutexSmallInit& GetCMutexSmallInit()*/ + + #endif //defined(_WIN) && defined(_REENTRANT) + + static bool SetLocalTimeObj(time_t AL_TimeSec,struct tm& ARR_StTime) + { + #ifdef _REENTRANT + #ifdef _WIN + ZNsMain::CMutexSmallLock VO_CMutexSmallLock(GetCMutexSmallInit()); + + struct tm* VP_StTime = ::localtime(&AL_TimeSec); + + if(VP_StTime==0) return false; + + ARR_StTime = *VP_StTime; return true; + #else + ::localtime_r(&AL_TimeSec, &ARR_StTime); return true; + #endif + #else // !_REENTRANT + struct tm* VP_StTime = ::localtime(&AL_TimeSec); + + if(VP_StTime==0) return false; + + ARR_StTime = *VP_StTime; return true; + #endif // !_REENTRANT + }/* + static bool SetLocalTimeObj(time_t AL_TimeSec, struct tm& ARR_StTime)*/ + + bool SetLocalTimeObj() + { + return SetLocalTimeObj(ml_TimeSec, RR(mo_TimeObj)); + }/* + bool SetLocalTimeObj()*/ + + static bool SetSystemTimeObj(time_t AL_TimeSec, struct tm& ARR_StTime) + { + #if defined(_REENTRANT) + #ifdef _WIN + ZNsMain::CMutexSmallLock + VO_CMutexSmallLock( GetCMutexSmallInit() ); + + struct tm* VP_StTime = ::gmtime(&AL_TimeSec); + + if(VP_StTime==0) return false; ////// + + ARR_StTime = *VP_StTime; return true; + #else + ::gmtime_r(&AL_TimeSec, &ARR_StTime); return true; + #endif + #else + struct tm* VP_StTime = ::gmtime(&AL_TimeSec); + + if(VP_StTime==0) return false; ////// + + ARR_StTime = *VP_StTime; return true; + #endif + }/* + static bool SetSystemTimeObj(time_t AL_TimeSec, struct tm& ARR_StTime)*/ + + bool SetSystemTimeObj() + { + return SetSystemTimeObj(ml_TimeSec, RR(mo_TimeObj)); + }/* + bool SetSystemTimeObj()*/ + + + static bool SetTimeObj(time_t AL_TimeSec, struct tm& ARR_StTime, bool AB_IsLocalTime=true) + { + if(AB_IsLocalTime) + return SetLocalTimeObj (AL_TimeSec, RR(ARR_StTime)); + else return SetSystemTimeObj(AL_TimeSec, RR(ARR_StTime)); + }/* + static bool SetTimeObj(time_t AL_TimeSec, struct tm& ARR_StTime, bool AB_IsLocalTime=true)*/ + + bool SetTimeObj(bool AB_IsLocalTime) + { + return SetTimeObj(ml_TimeSec, RR(mo_TimeObj), AB_IsLocalTime); + }/* + bool SetTimeObj(bool AB_IsLocalTime)*/ + + bool SetTimeObj() + { + return SetTimeObj(mb_IsLocal); + }/* + bool SetTimeObj()*/ + + /*private:*/ + public : + + static TypeIntTime GetSecResolution() + { + return (TypeIntTime)ESecResolution; + }/* + static TypeIntTime GetSecResolution()*/ + + ZCTime(bool AB_IsLocalTime=true) + { + mb_IsLocal =AB_IsLocalTime; + mpc_TimeBuff=0; ::time(&ml_TimeSec); + + ::memset(&mo_TimeObj, 0, sizeof(::tm)); + + SetTimeObj(AB_IsLocalTime); + }/* + ZCTime(bool AB_IsLocalTime=true)*/ + + ZCTime(time_t AI_TimeVal, bool AB_IsLocalTime=true) + { + mpc_TimeBuff=0 ; + mb_IsLocal =AB_IsLocalTime; + ml_TimeSec =AI_TimeVal ; + + ::memset(&mo_TimeObj, 0, sizeof(::tm)); + + SetTimeObj(AB_IsLocalTime); + }/* + ZCTime(time_t AI_TimeVal, bool AB_IsLocalTime=true)*/ + + ZCTime(const ZCTime& rhs) + { + mpc_TimeBuff=0 ; + mb_IsLocal =rhs.mb_IsLocal; + ml_TimeSec =rhs.ml_TimeSec; + + ::memset(&mo_TimeObj,0,sizeof(::tm)); + + SetTimeObj(mb_IsLocal); + }/* + ZCTime(const ZCTime& rhs)*/ + + ~ZCTime() + { + if(mpc_TimeBuff!=0) delete mpc_TimeBuff; + }/* + ~ZCTime()*/ + + ZCTime& operator=(const ZCTime& rhs) + { + if(this==&rhs) return *this; + + if(mpc_TimeBuff!=0) + { + delete mpc_TimeBuff; mpc_TimeBuff=0; + }/* + if(mpc_TimeBuff!=0)*/ + + mb_IsLocal=rhs.mb_IsLocal; + ml_TimeSec=rhs.ml_TimeSec; + + SetTimeObj(mb_IsLocal); return *this; + }/* + ZCTime& operator=(const ZCTime& rhs)*/ + + + bool InitTimeObj(bool AB_IsLocalTime) + { + ::time(&ml_TimeSec); return SetTimeObj(AB_IsLocalTime); + }/* + bool InitTimeObj(bool AB_IsLocalTime)*/ + + bool InitTimeObj(time_t AI_TimeVal, bool AB_IsLocalTime) + { + ml_TimeSec=AI_TimeVal; return SetTimeObj(AB_IsLocalTime); + }/* + bool InitTimeObj(time_t AI_TimeVal, bool AB_IsLocalTime)*/ + + bool InitTimeObj() + { + return InitTimeObj(mb_IsLocal); + }/* + bool InitTimeObj()*/ + + bool InitTimeObj(time_t AI_TimeVal) + { + return InitTimeObj(AI_TimeVal, mb_IsLocal); + }/* + bool InitTimeObj(time_t AI_TimeVal)*/ + + + bool InitLocalTimeObj (){return InitTimeObj(true );} + bool InitSystemTimeObj (){return InitTimeObj(false);} + bool InitTimeObjFromDate( + int AI_Year , int AI_Month, int AI_Day, + int AI_Hour=0, int AI_Min=0, int AI_Sec=0, int AI_MiliSec=0 + /*//////////*/ ) + { + ml_TimeSec = ZCTime::MakeTimeInt( ///////////// + AI_Year, AI_Month, AI_Day, + AI_Hour, AI_Min , AI_Sec + /*/////////*/ ); ////////////////////////////// + + if(SetTimeObj(mb_IsLocal)==false) return false; + + return AI_Year ==mo_TimeObj.tm_year+1900 && + AI_Month==mo_TimeObj.tm_mon +1 && + AI_Day ==mo_TimeObj.tm_mday && + AI_Hour ==mo_TimeObj.tm_hour && + AI_Min ==mo_TimeObj.tm_min && + AI_Sec ==mo_TimeObj.tm_sec ; + /////// + }/* + bool InitTimeObjFromDate( + int AI_Year , int AI_Month, int AI_Day, + int AI_Hour=0, int AI_Min=0, int AI_Sec=0, int AI_MiliSec=0 + ////////////// ) */ + + + tm& GetTimeObj() + { + return mo_TimeObj; + }/* + tm& GetTimeObj()*/ + + + inline TypeIntTime GetTimeSec() const{return ml_TimeSec;} + inline TypeIntTime GetTimeInt() const{return ml_TimeSec;} // for compatibility with linux + + inline TypeIntTime AddTimeIntMilli(TypeIntTime AI_AddMilli) const + { return ml_TimeSec + (AI_AddMilli/1000) ; } + inline TypeIntTime AddTimeIntSec (TypeIntTime AI_AddSec ) const + { return ml_TimeSec + AI_AddSec ; } + + inline TypeIntTime AddTimeIntMilliRev(TypeIntTime AI_AddMilli) const + { + // ESecResolution/1000 < 1 인 경우에는 1 milli 초를 표현할 수 없으니까, + // ESecResolution/1000 이상이면서 가장 가까운 배수로 보정(revise)하는 + // 것이다. 스케줄러에서 예약 시간을 등록할 때 필요하다. + // 근데 ESecResolution/1000 < 1 인 경우가 없게 ZCStdTime 클래스를 만들어 + // 서 AddTimeIntMilliRev() 이 필요없게 되었다. -- 2018-06-25 14:06:00 + + if(GetSecResolution()/1000 >= 1) return AddTimeIntMilli(AI_AddMilli); + + // AI_AddMilli>=0 이면서 가장 가까운 1000 의 배수에 맞춘다. + + TypeIntTime VI_Revised = + (AI_AddMilli/1000)*1000 + ( (AI_AddMilli%1000)>0 ? 1000 :0 ) ; + + AddTimeIntMilli(VI_Revised); + }/* + inline TypeIntTime AddTimeIntMilliRev(TypeIntTime AI_AddMilli) const*/ + + inline TypeIntTime AddTimeIntSecRev(TypeIntTime AI_AddSec) const + { + // ESecResolution < 1 인 경우에는 1 초를 표현할 수 없으니까, + // ESecResolution 이상이면서 가장 가까운 배수로 보정(revise)하는 + // 것이다. 스케줄러에서 예약 시간을 등록할 때 필요하다. + + return AddTimeIntSec(AI_AddSec); // 특별한 처리가 필요없다. + }/* + inline TypeIntTime AddTimeIntSecRev(TypeIntTime AI_AddSec) const*/ + + + inline time_t MakeTimeInt() + { + return ::mktime(&mo_TimeObj); + + /*//////////////////////////////////////////////////////////// + + ■ Get a integer that is information about day, hour, sec etc + from struct tm pointer mp_TimeObj + + ■ mktime() 은 에러의 경우 -1 을 반환한다. + + ////////////////////////////////////////////////////////////*/ + }/* + inline time_t MakeTimeInt()*/ + + static inline time_t MakeTimeInt(struct tm& AR_TimeStruct) + { + return ::mktime(&AR_TimeStruct); + }/* + static inline time_t MakeTimeInt(struct tm& AR_TimeStruct)*/ + + static inline time_t MakeTimeInt(int AI_Year, int AI_Month, int AI_Day, int AI_Hour=0, int AI_Min=0, int AI_Sec=0) + { + ::tm VO_TimeStr; ::memset(&VO_TimeStr, 0, sizeof(::tm)); + + VO_TimeStr.tm_year=AI_Year-1900 ; + VO_TimeStr.tm_mon =AI_Month-1 ; + VO_TimeStr.tm_mday=AI_Day ; + VO_TimeStr.tm_hour=AI_Hour ; + VO_TimeStr.tm_min =AI_Min ; + VO_TimeStr.tm_sec =AI_Sec ; + + return ::mktime(&VO_TimeStr); + + /*/////////////////////////////////////////////////////////////////// + + ■ MakeTimeInt(2010,2,32) 을 호출하면(2010 년 2월 32 일자로 호출하면) + 2010-03-04 00:00:00 에 해당하는 time_t 를 리턴한다. 따라서 이 함수 + 를 호출할 때 정확한 인수를 주는 것이 제일 좋지만, 차선책으로 인수가 + 지정하는 날짜와 이 함수가 리턴한 time_t 에 대한 날짜를 비교해 보는 + 것도 좋을 것 같다. + + -- 2010-03-01 18:21;00 + + ///////////////////////////////////////////////////////////////////*/ + }/* + static inline time_t MakeTimeInt(int AI_Year, int AI_Month, int AI_Day, int AI_Hour=0, int AI_Min=0, int AI_Sec=0)*/ + + static bool IsValidTime(time_t AI_Time, int AI_Year, int AI_Month, int AI_Day, int AI_Hour, int AI_Min, int AI_Sec, bool AB_IsLocalTime=true) + { + struct ::tm VO_TimeStr; const bool CB_IsOK = + SetTimeObj(AI_Time, VO_TimeStr, AB_IsLocalTime); + + if(CB_IsOK==false) return false; + + return AI_Year ==VO_TimeStr.tm_year+1900 && + AI_Month==VO_TimeStr.tm_mon +1 && + AI_Day ==VO_TimeStr.tm_mday && + AI_Hour ==VO_TimeStr.tm_hour && + AI_Min ==VO_TimeStr.tm_min && + AI_Sec ==VO_TimeStr.tm_sec ; + /////// + }/* + static bool IsValidTime(time_t AI_Time, int AI_Year, int AI_Month, int AI_Day, int AI_Hour, int AI_Min, int AI_Sec, bool AB_IsLocalTime=true)*/ + + static bool IsValidTime(int AI_Year, int AI_Month, int AI_Day, int AI_Hour, int AI_Min, int AI_Sec, bool AB_IsLocalTime=true) + { + return IsValidTime( + MakeTimeInt(AI_Year, AI_Month, AI_Day, AI_Hour, AI_Min, AI_Sec), + AI_Year , + AI_Month, + AI_Day , + AI_Hour , + AI_Min , + AI_Sec , + AB_IsLocalTime + /*/////////*/ ); /////////////////////////////////////////////////////////////// + }/* + static bool IsValidTime(int AI_Year, int AI_Month, int AI_Day, int AI_Hour, int AI_Min, int AI_Sec, bool AB_IsLocalTime=true)*/ + + + bool Plus (time_t AI_TimeAddVal ){ml_TimeSec+=AI_TimeAddVal ; return SetTimeObj();} + bool Minus(time_t AI_TimeMinusVal){ml_TimeSec-=AI_TimeMinusVal; return SetTimeObj();} + + ZCTime& operator+=(time_t AI_TimeVal){Plus (AI_TimeVal); return *this;} + ZCTime& operator-=(time_t AI_TimeVal){Minus(AI_TimeVal); return *this;} + + + char* GetTimeChars() + { + return ::asctime(&mo_TimeObj); + + // We can see "Mon Nov 20Sun Jun 6 12:30:34 1995\n\0 " format from the function + // A size of char array which thie function return is 26 + }/* + char* GetTimeChars()*/ + + inline int GetSysYear () const{return mo_TimeObj.tm_year ;} + inline int GetYear () const{return mo_TimeObj.tm_year + 1900 ;} + inline int GetSysMonth() const{return mo_TimeObj.tm_mon ;} + inline int GetMonth () const{return mo_TimeObj.tm_mon + 1 ;} + inline int GetDay () const{return mo_TimeObj.tm_mday ;} + inline int GetHour () const{return mo_TimeObj.tm_hour ;} + inline int GetMinute () const{return mo_TimeObj.tm_min ;} + inline int GetMin () const{return mo_TimeObj.tm_min ;} + inline int GetSecond () const{return mo_TimeObj.tm_sec ;} + inline int GetSec () const{return mo_TimeObj.tm_sec ;} + inline int GetYDay () const{return mo_TimeObj.tm_yday + 1 ;} + inline int GetSysYDay () const + { + // int tm_yday; // Day of year (0 - 365) + + return mo_TimeObj.tm_yday ; + }/* + inline int GetSysYDay() const*/ + + inline int GetWeekDay() const + { + // int tm_wday; // Day of week (0 - 6 : 0 = Sunday) + + return mo_TimeObj.tm_wday + 1 ; + }/* + inline int GetWeekDay() const*/ + + inline int GetSysWeekDay() const + { + // int tm_wday; // Day of week (0 - 6 : 0 = Sunday) + + return mo_TimeObj.tm_wday ; + }/* + inline int GetSysWeekDay() const*/ + + inline int GetWeekOfYear() const + { + // 그 해의 몇 번째 주인지를 판단한다. + // int tm_wday; // Day of week (0 - 6 : 0 = Sunday) + + if(mo_TimeObj.tm_yday<=mo_TimeObj.tm_wday) return 1; + + const int CI_DayCntOfWeek=7; + const int CI_DayCntAdded =2; + + return (mo_TimeObj.tm_yday - mo_TimeObj.tm_wday-1)/CI_DayCntOfWeek + CI_DayCntAdded ; + }/* + inline int GetWeekOfYear() const*/ + + inline char* GetDate(bool AB_DoHaveHypen=true) + { + // AB_DoHaveHypen=true 이면, 일자를 2007-01-01 형태로 반환한다. + // AB_DoHaveHypen=false 이면, 일자를 20070101 형태로 반환한다. + + if(mpc_TimeBuff==0) + { + mpc_TimeBuff=new char[ZCTime::ETimeBuffSize+1]; + + if(mpc_TimeBuff==0) + { + // Add Codes For Memory Over; + + return 0; + }/* + if(mpc_TimeBuff==0)*/ + }/* + if(mpc_TimeBuff==0)*/ + + mpc_TimeBuff[0] = + mpc_TimeBuff[ZCTime::ETimeBuffSize]=0 ; + + if(AB_DoHaveHypen) + { + (void)sprintf( mpc_TimeBuff , + "%d-%02d-%02d" , + GetYear(), GetMonth(), GetDay() + /*////////*/ ); + } + else + { + (void)sprintf( mpc_TimeBuff , + "%d%02d%02d" , + GetYear(), GetMonth(), GetDay() + /*////////*/ ); + }/* + else*/ + + return mpc_TimeBuff; + }/* + inline char* GetDate(bool AB_DoHaveHypen=true)*/ + + + /*/////////////////////////////////////////////////////////////////////////// + + ■ 일정 시간과의 차이를 초로 구한다. + 일별로 로그 파일을 남길 때, 일자가 언제 바뀌는데 알고 싶을 때 사용할 수 있다. + 특히 로그 쓰레드를 만들 때, 로그 쓰레드에서 어떤 신호를 받아 다른 날짜로 로그 + 파일명을 바꾸어야 한다면 이 로그 쓰레드의 날짜를 체크하는 타이머 쓰레드에서 + 이 값을 참고할 수 있다. + + -- 2009-05-19 14:03:00 + + ///////////////////////////////////////////////////////////////////////////*/ + + long GetDiffSec(int AI_Hour=24, int AI_Min=0, int AI_Sec=0) + { + return (AI_Hour*3600+AI_Min*60+AI_Sec) - (mo_TimeObj.tm_hour*3600 + mo_TimeObj.tm_min*60 + mo_TimeObj.tm_sec) ; + }/* + long GetDiffSec(int AI_Hour=24, int AI_Min=0, int AI_Sec=0)*/ + + bool GetDiffSec(time_t& ARRI_TimeGap, int AI_Year, int AI_Month, int AI_Day, int AI_Hour, int AI_Min, int AI_Sec) + { + time_t VI_TimeSec=ZNsMain::ZCTime::MakeTimeInt(AI_Year, AI_Month, AI_Day, AI_Hour, AI_Min, AI_Sec); + + if(VI_TimeSec<1) return false; *this+=VI_TimeSec; return true ; + }/* + bool GetDiffSec(time_t& ARRI_TimeGap, int AI_Year,int AI_Month,int AI_Day,int AI_Hour,int AI_Min,int AI_Sec)*/ + + static bool GetDiffSec( + time_t& ARRI_TimeGap, + int AI_Year1, int AI_Month1, int AI_Day1, int AI_Hour1, int AI_Min1, int AI_Sec1, + int AI_Year2 ,int AI_Month2, int AI_Day2, int AI_Hour2, int AI_Min2, int AI_Sec2 + /*//////////*/ ) + { + time_t VI_TimeSec1=ZNsMain::ZCTime::MakeTimeInt(AI_Year1, AI_Month1, AI_Day1, AI_Hour1, AI_Min1, AI_Sec1); + time_t VI_TimeSec2=ZNsMain::ZCTime::MakeTimeInt(AI_Year2, AI_Month2, AI_Day2, AI_Hour2, AI_Min2, AI_Sec2); + + if(VI_TimeSec1<0 || VI_TimeSec2<0) return false; + + ARRI_TimeGap=VI_TimeSec2-VI_TimeSec1; return true ; + }/* + static bool GetDiffSec( + time_t& ARRI_TimeGap, + int AI_Year1, int AI_Month1, int AI_Day1, int AI_Hour1, int AI_Min1, int AI_Sec1, + int AI_Year2 ,int AI_Month2, int AI_Day2, int AI_Hour2, int AI_Min2, int AI_Sec2 + ////////////// ) */ + + static inline long GetNowDiffSec(int AI_Hour=24, int AI_Min=0, int AI_Sec=0) + { + ZCTime VO_CTime; return VO_CTime.GetDiffSec(AI_Hour, AI_Min, AI_Sec); + }/* + static inline long GetNowDiffSec(int AI_Hour=24, int AI_Min=0, int AI_Sec=0)*/ + + + inline char* GetTimeStamp() + { + if(mpc_TimeBuff==0) + { + mpc_TimeBuff=new char[ZCTime::ETimeBuffSize+1]; + + if(mpc_TimeBuff==0) + { + // Add Codes For Memory Over; + + return 0; + }/* + if(mpc_TimeBuff==0)*/ + }/* + if(mpc_TimeBuff==0)*/ + + mpc_TimeBuff[0] = + mpc_TimeBuff[ZCTime::ETimeBuffSize]=0 ; + + (void)sprintf /////////////////////////// + ( + mpc_TimeBuff, + "%d-%02d-%02d %02d:%02d:%02d" , + GetYear(), GetMonth (), GetDay(), + GetHour(), GetMinute(), GetSec() + ); + ///////////////////////////////////////// + + return mpc_TimeBuff; + }/* + inline char* GetTimeStamp()*/ + inline char* GetTimeStamp2() + { + // GetTimeStamp() 와는 달리, 공백, '-', ':' 등을 없앤다. 2012-09-09 10:16:00 + + if(mpc_TimeBuff==0) + { + mpc_TimeBuff=new char[ZCTime::ETimeBuffSize+1]; + + if(mpc_TimeBuff==0) + { + // Add Codes For Memory Over; + + return 0; + }/* + if(mpc_TimeBuff==0)*/ + }/* + if(mpc_TimeBuff==0)*/ + + mpc_TimeBuff[0] = + mpc_TimeBuff[ZCTime::ETimeBuffSize]=0 ; + + (void)sprintf ///////////////////////////////// + ( + mpc_TimeBuff, "%d%02d%02d%02d%02d%02d", + GetYear() , GetMonth (), GetDay() , + GetHour() , GetMinute(), GetSec() + ); + /////////////////////////////////////////////// + + return mpc_TimeBuff; + }/* + inline char* GetTimeStamp2()*/ + + static inline char* GetNowTimeStamp(bool AB_IsLoaclTime=true) + { + struct tm VO_StTime; time_t VL_Time; time(&VL_Time); /*##############*/ + + if(SetTimeObj(VL_Time, RR(VO_StTime), AB_IsLoaclTime)==false) return 0; + + + const int CI_TimeBuffSize=30; static char VCA_TimeBuff[CI_TimeBuffSize]; + + (void)sprintf //////////////////////////////////////////////////////// + ( + VCA_TimeBuff , "%d-%02d-%02d %02d:%02d:%02d" , + VO_StTime.tm_year+1900, VO_StTime.tm_mon+1, VO_StTime.tm_mday, + VO_StTime.tm_hour , VO_StTime.tm_min , VO_StTime.tm_sec + ); + ////////////////////////////////////////////////////////////////////// + + return VCA_TimeBuff; + }/* + static inline char* GetNowTimeStamp(bool AB_IsLoaclTime=true)*/ + + inline static char* GetTimeChars(const time_t& AR_TimeVal) + { + struct tm VO_StTime; + + if(SetSystemTimeObj(AR_TimeVal, RR(VO_StTime))==false) return 0; + + return ::asctime(&VO_StTime); /*##############################*/ + }/* + inline static char* GetTimeChars(const time_t& AR_TimeVal)*/ + + inline static char* GetLocalTimeChars(const time_t& AR_TimeVal) + { + struct tm VO_StTime; + + if(SetLocalTimeObj(AR_TimeVal, RR(VO_StTime))==false) return 0; + + return ::asctime(&VO_StTime); /*#############################*/ + }/* + inline static char* GetLocalTimeChars(const time_t& AR_TimeVal)*/ + + static inline time_t GetNowSec() + { + return time((time_t*)0); // Get Sec Time after the standard time + }/* + static inline time_t GetNowSec()*/ + + static inline clock_t Clock() + { + return clock(); // _CRTIMP clock_t __cdecl clock(void); + }/* + static inline clock_t Clock()*/ + + static inline long GetSecFromClock(clock_t AI_ClockInt) + { + return AI_ClockInt / CLOCKS_PER_SEC ; + }/* + static inline long GetSecFromClock(clock_t AI_ClockInt)*/ + + + #if !defined(_WIN) // Is it better not to use this function ? + + + /*///////////////////////////////////////////////////////////////////////////////////////// + + ■ gcc 2.96 에서는 strptime 이 구현되지 않았을 수도 있다. + + static inline char* GetTimeChars(const char* APC_Buff, const char* APC_Format, struct tm* AP_StTime) + { + return ::strptime(APC_Buff,APC_Format,AP_StTime); + } + + /////////////////////////////////////////////////////////////////////////////////////////*/ + + + static string& GetUniqueID(string& ARR_CString) + { + static int SI_Count=0; + + const char* CPC_Gap="_" ; + char VCA_Buff[60] ; + + struct timeval TTimeVal ; + struct timezone TTimeZone ; + + gettimeofday(&TTimeVal,&TTimeZone); + + (void)::sprintf //////////////////////////// + ( + VCA_Buff, "%ld%s%ld%s%ld%s%ld%s%ld", + long(TTimeVal.tv_sec ) , CPC_Gap , + long(TTimeVal.tv_usec) , CPC_Gap , + long(getpid()) , CPC_Gap , + long(getppid()) , CPC_Gap , + long(++SI_Count) + ); + //////////////////////////////////////////// + + return ARR_CString=VCA_Buff ; + }/* + static string& GetUniqueID(string& ARR_CString)*/ + + + template static TTypString& GetUniqueIDObj(TTypString& ARR_CString) + { + static int SI_Count = 0 ; + + const char* CPC_Gap="_" ; + char VCA_Buff[60] ; + + struct timeval TTimeVal ; + struct timezone TTimeZone ; + + gettimeofday(&TTimeVal,&TTimeZone); + + (void)sprintf ///////////////////// + ( + VCA_Buff , + "%ld%s%ld%s%ld%s%ld%s%ld" , + TTimeVal.tv_sec , CPC_Gap , + TTimeVal.tv_usec, CPC_Gap , + getpid() , CPC_Gap , + getppid() , CPC_Gap , ++SI_Count + ); + /////////////////////////////////// + + return ARR_CString=VCA_Buff ; + }/* + template static TTypString& GetUniqueIDObj(TTypString& ARR_CString)*/ + + + #else // deinfed(_WIN) + + + static string& GetUniqueID(string& ARR_CString) + { + const int CI_BuffSize=100 ; + static int SI_Count =0 ; + const char* CPC_Gap ="_" ; + char VCA_Buff[CI_BuffSize] ; + + ::sprintf( VCA_Buff, + "%d%s%d%s%d" , + (long)GetNowSec(), // (long) 가 없으면 메모리 오류가 난다. + CPC_Gap , GetTickCount() , + CPC_Gap , (++SI_Count)+ ::GetCurrentProcessId() + /*////*/ ); + + return ARR_CString = VCA_Buff ; + + /*////////////////////////////////////////////////////////////// + + ■ sprintf + + ※ http://msdn.microsoft.com/en-us/library/ybk95axf.aspx In MSDN + + // crt_sprintf.c + // compile with: /W3 + // This program uses sprintf to format various + // data and place them in the string named buffer. + + #include + + int main( void ) + { + char buffer[200], s[] = "computer", c = 'l'; + int i = 35, j; + float fp = 1.7320534f; + + // Format and print various data: + j = sprintf( buffer, " String: %s\n", s ); // C4996 + j += sprintf( buffer + j, " Character: %c\n", c ); // C4996 + j += sprintf( buffer + j, " Integer: %d\n", i ); // C4996 + j += sprintf( buffer + j, " Real: %f\n", fp );// C4996 + // Note: sprintf is deprecated; consider using sprintf_s instead + + printf( "Output:\n%s\ncharacter count = %d\n", buffer, j ); + } + + ■ Windows C++ Safe String Functions + + ※ http://www.lingoport.com/gi/help/gihelp/unsafeMethod/winstrsafe.htm + + Strsafe.h function Replaces + + StringCchCat, StringCchCatEx strcat, wcscat, lstrcat, strcat, StrCatBuff, _tcscat, _ftcscat + StringCchCatN, StringCchCatNEx strncat, StrNCat + StringCchCopy, StringCchCopyEx strcpy, wcscpy, lstrcpy, strcpy, _tcscpy, _ftcscpy + StringCchCopyN, StringCchCopyNEx strncpy + StringCchGets, StringCchGetsEx gets, _getws, _getts + StringCchPrintf, StringCchPrintfEx sprintf, swprintf, wsprintf, wnsprintf, _stprintf, _snprintf, _snwprintf, _sntprintf + StringCchVPrintf, StringCchVPrintfEx vsprintf, vswprintf, wvsprintf, wvnsprintf, _vstprintf, _vsnprintf, _vsnwprintf, _vsntprintf + + StringCchLength, strlen, lstrlen + + ■ GetTickCount() + + Windows 가 부팅된 이후의 시간을 구하는데, 이전 GetTickCount() + 호출과의 시간 간격은 약 49.7 일 동안은 유효하다. + + //////////////////////////////////////////////////////////////*/ + }/* + static string& GetUniqueID(string& ARR_CString)*/ + + + template + static TTypString& GetUniqueIDObj(TTypString& ARR_CString) + { + static int SI_Count =0 ; + const int CI_BuffSize=100 ; + + ZTypChar VC_Buff[CI_BuffSize]; + ZTypCPCCh VP_GAP ="-" ; + + (void)::sprintf + ( + VC_Buff , "%d%s%d%s%d", + (long)GetNowSec() , VP_GAP , + ::GetTickCount() , VP_GAP , + (++SI_Count) + ::GetCurrentProcessId() + ); + /*###########*/ + + /*////////////////////////////////////////////////////////// + + ■ (long) 를 제거하면 VC++ 2008 에서 메모리 오류가 발생한다. + + -- 2008-09-07 02:27:00 + + //////////////////////////////////////////////////////////*/ + + return ARR_CString=VC_Buff ; + }/* + template + static TTypString& GetUniqueIDObj(TTypString& ARR_CString) */ + + + #endif //deinfed(_WIN) + + + static string& GetUniqueID() + { + static string VO_CStringObj; VO_CStringObj=""; return GetUniqueID(VO_CStringObj); + }/* + static string& GetUniqueID()*/ + + template static TTypString& GetUniqueIDObj() + { + static TTypString VO_CStringObj; VO_CStringObj=""; + + return GetUniqueIDObj(RR(VO_CStringObj)); + }/* + template static TTypString& GetUniqueIDObj()*/ + + + /*//////////////////////////////////////////////////////// + + clock + Calculates the wall-clock time used by the calling process. + + clock_t clock( void ); + Return Value + The elapsed wall-clock time since the start of the process (elapsed time in seconds times CLOCKS_PER_SEC). If the amount of elapsed time is unavailable, the function returns ?1, cast as a clock_t. + + Remarks + The clock function tells how much time the calling process has used. A timer tick is approximately equal to 1/CLOCKS_PER_SEC second. In versions of Microsoft C before 6.0, the CLOCKS_PER_SEC constant was called CLK_TCK. + + Requirements + Routine Required header Compatibility + clock ANSI, Win 98, Win Me, Win NT, Win 2000, Win XP + + For additional compatibility information, see Compatibility in the Introduction. + + Libraries + + All versions of the C run-time libraries. + + Example + CLOCK.C: This example prompts for how long + the program is to run and then continuously + displays the elapsed time for that period. + + #include + #include + #include + + void sleep( clock_t wait ); + + void main( void ) + { + long i = 600000L; + clock_t start, finish; + double duration; + + // Delay for a specified time. + printf( "Delay for three seconds\n" ); + sleep( (clock_t)3 * CLOCKS_PER_SEC ); + printf( "Done!\n" ); + + // Measure the duration of an event. + printf( "Time to do %ld empty loops is ", i ); + start = clock(); + + while( i-- ) + { + }; + + finish = clock(); + duration = (double)(finish - start) / CLOCKS_PER_SEC; + printf( "%2.1f seconds\n", duration ); + } + + // Pauses for a specified number of milliseconds. + + void sleep( clock_t wait ) + { + clock_t goal; + goal = wait + clock(); + while( goal > clock() ) + ; + } + + Output + Delay for three seconds + Done! + Time to do 600000 empty loops is 0.1 seconds + + //////////////////////////////////////////////*/ + + public: + };/* + class ZCTime*/ + + +#if defined(_WIN) + + + /*/////////////////////////////////////////////////////////// + + ■ class ZCStdTime 클래스는 해당 OS 에 고유한 함수를 사용하여, + 좀 더 multi-thread 에 안전하게 구현한다. + + -- 2012-03-23 14:42:00 + + 리눅스에서는 ZCTime 을 ZCStdTime 으로 typedef 해도 되는데, 현재 + gettimeofday() 를 이용해 좀 더 최적화되었다. -- 2018-06-25 09:38:00 + + ■ 현재 아래 멤버가 Unix 랑 호환되는 것으로 정했다. + + ZCStdTime::TypeIntTime : 시간을 표현하는 정수 자료형. + + ZCStdTime(bool AB_IsLocal=true) + + void InitLocalTimeObj () + void InitSystemTimeObj() + + GetSecResolution() + + GetTimeInt() : return os-dependent time value + GetTimeSec() + + AddTimeIntMilli() + AddTimeIntSec () + + int GetYear () + int GetMonth () + int GetDay () + int GetDayOfWeek() // sunday 가 0, monday 가 1. + int GetHour () + int GetMinute () + int GetSecond () + int GetMin () + int GetSec () + int GetMilliSec () + int GetMilli () + + + -- 2012-04-02 17:25:00 + + ■ -- In WinBase.h + + typedef struct _SYSTEMTIME { + WORD wYear ; + WORD wMonth ; + WORD wDayOfWeek ; + WORD wDay ; + WORD wHour ; + WORD wMinute ; + WORD wSecond ; + WORD wMilliseconds; + } SYSTEMTIME, *PSYSTEMTIME + + -- In WinDef.h + + typedef struct _FILETIME { + DWORD dwLowDateTime ; + DWORD dwHighDateTime; + } FILETIME, *PFILETIME, *LPFILETIME; + #define _FILETIME_ + + □ 1601 년 1월 1일 0시가 기준이다. + time() 은 1970 년 1월 1일 0시가 기준이다. + + □ FILETIME 타입은 그냥 간단하게 64비트 정수형으로 보면 되 + 는데 1601년 1월 1일 0시 0분 0초를 0으로 지정하며 1초에 + 10,000,000 이 늘어난다. 이를 두고 100 나노초의 해상도를 + 가진다고 이야기하는 것이다. 경과시간을 구할 때는 32비트 + 정수형 두개를 사용하지 않고 ULARGE_INTEGER 형에 대입한 + 후 QuadPart를 64비트 정수 연산을 이용한다. -- 2016-10-05 + + ☞ http://blog.naver.com/mysticodoi/140043721556 + + 아래 예제도 참고 -- 2018-06-21 17:08:00 + + ☞ https://support.microsoft.com/ko-kr/help/188768/info-working-with-the-filetime-structure + + #define _SECOND ((int64) 10000000) + #define _MINUTE (60 * _SECOND) + #define _HOUR (60 * _MINUTE) + #define _DAY (24 * _HOUR) + + ULONGLONG qwResult; + + // Copy the time into a quadword. + qwResult = (((ULONGLONG) ft.dwHighDateTime) << 32) + ft.dwLowDateTime; + + // Add 30 days. + qwResult += 30 * _DAY; + + // Copy the result back into the FILETIME structure. + ft.dwLowDateTime = (DWORD) (qwResult & 0xFFFFFFFF ); + ft.dwHighDateTime = (DWORD) (qwResult >> 32 ); + + □ -- + + ///////////////////////////////////////////////////////////*/ + + class ZCStdTime + { + public : + typedef ZTypUInt64 TypeIntTime; + private: + enum{ETimeBuffSize =30 }; + enum{ESecResolution=1000*10000}; // 1 초를 이루는 값으로 1000 만. + private: + char mca_TimeBuff[ETimeBuffSize]; + private: + bool mb_IsLocal ; + FILETIME mo_FILETIME ; + SYSTEMTIME mo_SYSTEMTIME; + public : + + static TypeIntTime GetSecResolution() + { + return (TypeIntTime)ESecResolution; + }/* + static TypeIntTime GetSecResolution()*/ + + public : + + ZCStdTime(bool AB_IsLoaclTime=true) + { + mb_IsLocal=AB_IsLoaclTime; + + if(AB_IsLoaclTime) + InitLocalTimeObj (); + else InitSystemTimeObj(); + }/* + ZCStdTime(bool AB_IsLoaclTime=true)*/ + + ZCStdTime(const ZCStdTime& rhs) + { + if(this==&rhs) return; + + mb_IsLocal =rhs.mb_IsLocal ; + mo_FILETIME =rhs.mo_FILETIME ; + mo_SYSTEMTIME=rhs.mo_SYSTEMTIME; + }/* + ZCStdTime(const ZCStdTime& rhs)*/ + + ~ZCStdTime() + { + }/* + ~ZCStdTime()*/ + + ZCStdTime& operator=(const ZCStdTime& rhs) + { + if(this==&rhs) return *this; + + mb_IsLocal =rhs.mb_IsLocal ; + mo_FILETIME =rhs.mo_FILETIME ; + mo_SYSTEMTIME=rhs.mo_SYSTEMTIME; + + return *this; + }/* + ZCStdTime& operator=(const ZCStdTime& rhs)*/ + + + bool InitLocalTimeObj() + { + ::GetLocalTime (&mo_SYSTEMTIME); return + ::SystemTimeToFileTime(&mo_SYSTEMTIME, &mo_FILETIME)==TRUE; + }/* + bool InitLocalTimeObj()*/ + + bool InitSystemTimeObj() + { + ::GetSystemTime (&mo_SYSTEMTIME); return + ::SystemTimeToFileTime(&mo_SYSTEMTIME, &mo_FILETIME)==TRUE; + }/* + bool InitSystemTimeObj()*/ + + bool InitTimeObj(bool AB_IsLoaclTime) + { + if(AB_IsLoaclTime) + return InitLocalTimeObj(); + else + return InitSystemTimeObj(); + //else + }/* + bool InitTimeObj(bool AB_IsLoaclTime)*/ + + bool InitTimeObj() + { + /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + ■ Windows 에서 CLogData.H 에서, 자꾸 mb_IsLocal 이 false 로 바뀌어 버린다. + 그래서 __USE_LOCAL_TIME_BY_FORCE__ 이 정의되어 있으면, 무조건 InitTimeObj + 에 false 를 전달한다. -- 2018-02-26 11:28:00 + >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ + #ifdef __USE_LOCAL_TIME_BY_FORCE__ + return InitTimeObj(true ); + #else + return InitTimeObj(mb_IsLocal); + #endif + }/* + bool InitTimeObj()*/ + + bool InitTimeObjFromDate( + int AI_Year , int AI_Month, int AI_Day , + int AI_Hour=0, int AI_Min=0, int AI_Sec=0, int AI_MiliSec=0) + { + mo_SYSTEMTIME.wYear =AI_Year ; + mo_SYSTEMTIME.wMonth =AI_Month ; + mo_SYSTEMTIME.wDay =AI_Day ; + mo_SYSTEMTIME.wHour =AI_Hour ; + mo_SYSTEMTIME.wMinute =AI_Min ; + mo_SYSTEMTIME.wSecond =AI_Sec ; + mo_SYSTEMTIME.wMilliseconds=AI_MiliSec; + mo_SYSTEMTIME.wDayOfWeek =0 ; + + if(::SystemTimeToFileTime(&mo_SYSTEMTIME, &mo_FILETIME)==TRUE) + { + // to set mo_SYSTEMTIME.wDayOfWeek to correct value + + ::FileTimeToSystemTime(&mo_FILETIME, &mo_SYSTEMTIME); return true; + }/* + if(::SystemTimeToFileTime(&mo_SYSTEMTIME, &mo_FILETIME)==TRUE)*/ + + return false; + }/* + bool InitTimeObjFromDate( + int AI_Year , int AI_Month, int AI_Day , + int AI_Hour=0, int AI_Min=0, int AI_Sec=0, int AI_MiliSec=0)*/ + + + TypeIntTime GetTimeInt() const + { + return (((TypeIntTime)mo_FILETIME.dwHighDateTime)<<32) + mo_FILETIME.dwLowDateTime ; + }/* + TypeIntTime GetTimeInt() const*/ + + TypeIntTime GetTimeSec() const + { + return GetTimeInt()/ESecResolution; + }/* + TypeIntTime GetTimeSec() const*/ + + + TypeIntTime AddTimeIntMilli(TypeIntTime AI_AddMilli) const{ + return GetTimeInt() + ( AI_AddMilli*(ESecResolution/1000) ) ;} + TypeIntTime AddTimeIntSec (TypeIntTime AI_AddSec ) const{ + return GetTimeInt() + ( AI_AddSec * ESecResolution ) ;} + + + inline TypeIntTime AddTimeIntMilliRev(TypeIntTime AI_AddMilli) const + { + // ESecResolution/1000 < 1 인 경우에는 1 milli 초를 표현할 수 없으니까, + // ESecResolution/1000 이상이면서 가장 가까운 배수로 보정(revise)하는 + // 것이다. 스케줄러에서 예약 시간을 등록할 때 필요하다. + // ZCStdTime 에는 ESecResolution/1000 < 1 인 경우가 없어서, 사실상 이 함 + // 수는 사용되지 않는다. + + return AddTimeIntMilli(AI_AddMilli); // 특별한 처리가 필요없다. + }/* + inline TypeIntTime AddTimeIntMilliRev(TypeIntTime AI_AddMilli) const*/ + + inline TypeIntTime AddTimeIntSecRev(TypeIntTime AI_AddSec) const + { + // ESecResolution < 1 인 경우에는 1 초를 표현할 수 없으니까, + // ESecResolution 이상이면서 가장 가까운 배수로 보정(revise)하는 + // 것이다. 스케줄러에서 예약 시간을 등록할 때 필요하다. + + return AddTimeIntSec(AI_AddSec); // 특별한 처리가 필요없다. + }/* + inline TypeIntTime AddTimeIntSecRev(TypeIntTime AI_AddSec) const*/ + + + int GetYear () const{return mo_SYSTEMTIME.wYear ;} + int GetMonth () const{return mo_SYSTEMTIME.wMonth ;} + int GetDay () const{return mo_SYSTEMTIME.wDay ;} + int GetDayOfWeek() const{return mo_SYSTEMTIME.wDayOfWeek ;} // sunday 가 0, monday 가 1. + int GetHour () const{return mo_SYSTEMTIME.wHour ;} + int GetMinute () const{return mo_SYSTEMTIME.wMinute ;} + int GetMin () const{return mo_SYSTEMTIME.wMinute ;} + int GetSecond () const{return mo_SYSTEMTIME.wSecond ;} + int GetSec () const{return mo_SYSTEMTIME.wSecond ;} + int GetMilliSec () const{return mo_SYSTEMTIME.wMilliseconds ;} + int GetMilli () const{return mo_SYSTEMTIME.wMilliseconds ;} + + bool Plus(TypeIntTime AL_TimeSec) + { + TypeIntTime VL_TimeInt=GetTimeInt()+AL_TimeSec*ESecResolution; + + mo_FILETIME.dwHighDateTime=(DWORD)(VL_TimeInt>>32 ); + mo_FILETIME.dwLowDateTime =(DWORD)(VL_TimeInt & 0xFFFFFFFF); + + return ::FileTimeToSystemTime(&mo_FILETIME, &mo_SYSTEMTIME)==TRUE; + }/* + bool Plus(TypeIntTime AL_TimeSec)*/ + + bool Minus(TypeIntTime AL_TimeSec) + { + TypeIntTime VL_TimeInt=GetTimeInt()-AL_TimeSec*ESecResolution; + + mo_FILETIME.dwHighDateTime=(DWORD)(VL_TimeInt>>32 ); + mo_FILETIME.dwLowDateTime =(DWORD)(VL_TimeInt & 0xFFFFFFFF); + + return ::FileTimeToSystemTime(&mo_FILETIME, &mo_SYSTEMTIME)==TRUE; + }/* + bool Minus(TypeIntTime AL_TimeSec)*/ + + char* GetDate(bool AB_DoIncludeSpace=true) + { + // AB_DoIncludeSpace==true 이면 일자를 2007-01-01 형태로 반환한다. + // AB_DoIncludeSpace==false 이면 일자를 20070101 형태로 반환한다. + + mca_TimeBuff[0] = + mca_TimeBuff[ZCStdTime::ETimeBuffSize]=0 ; + + if(AB_DoIncludeSpace==true) + { + (void)::sprintf(mca_TimeBuff , + "%d-%02d-%02d" , + GetYear(), GetMonth(), GetDay() + /*//////////*/ ); + } + else + { + (void)::sprintf(mca_TimeBuff , + "%d%02d%02d" , + GetYear(), GetMonth(), GetDay() + /*//////////*/ ); + }/* + else*/ + + return mca_TimeBuff; + }/* + char* GetDate(bool AB_DoIncludeSpace=true)*/ + + char* GetTimeStamp() + { + mca_TimeBuff[0] = + mca_TimeBuff[ZCStdTime::ETimeBuffSize]=0 ; + + (void)::sprintf(mca_TimeBuff, + "%d-%02d-%02d %02d:%02d:%02d", + GetYear(), GetMonth (), GetDay (), + GetHour(), GetMinute(), GetSecond() + /*//////////*/ ); + + return mca_TimeBuff; + }/* + char* GetTimeStamp()*/ + + public: + };/* + class ZCStdTime*/ + + + /*/////////////////////////////////////////////////////////////////////////////////////////// + + ■ class ZCTimeElapse + + 걸린 시간을 측정하는데, GetTickCount() 를 사용하고 있다. 좀 더 정확한 시간은 timeGetTime() + 이나 아래 함수를 사용해야 한다. + + QueryPerformanceCounter(StartTick); + QueryPerformanceFrequency(Freq); + + 또한 GetTickCount64() 하는 함수도 있는데, 게임 서버 같이, 장시간에 결쳐 운영되는 프로그램 + 에서 쓸 수 있겠다. + + ULONGLONG WINAPI GetTickCount64(void); + + -- 2013-08-11 01:17:00 + + ■ http://cafe446.daum.net/_c21_/bbs_search_read?grpid=1EeeD&fldid=5AuH&contentval=0000bzzzzzzzzzzzzzzzzzzzzzzzzz&q= + + [C언어 씨언어 알고니즘 정보보안전문가] - GetTickCount() - clock()보다 더 정확한 시간 재기. + + >저도 GetTickCount가 어떤건지, 며칠전에 알았습니다. + >저처럼 모르고있었던분들도 있을것 같아서, 한번 올립니다. + > + >GetTickCount가 뭔 CPU클럭인가 먼가 .. 여튼 그런걸 이용한다던데요.. + >여튼, 0.001초마다 이 카운트가 1씩 오르는건 정확합니다. + + 정확하지 않습니다. + 카운트가 1ms(0.001sec) 라는건 값을 반환할 때 사용하는 단위가 밀리세컨드라는 뜻일 뿐입니다. + 실제로 사용해보면 resolution(정밀도)은 15ms 정도에 불과합니다. (windows 2000 이상 기준) + + winmm.lib 에 들어있는 (헤더는 mmsystem.h) timeGetTime() 함수가 좀 더 정확합니다. + + 대신 timeBeginPeriod() 와 timeEndPeriod() 함수로 정밀도를 수동조절해야 그나마 높은 정밀도 + 가 나옵니다. 문제는 그렇게 해놓아도 종종 10ms 이상의 점핑현상이 나타난다는거.. + + 1ms 이상의 정밀도가 나오는 함수는 QueryPerformanceCounter() 이거 하나 뿐입니다. (수백만분 + 의 1초 수준의 정밀도가 나온다는군요) + + 이 함수의 문제는 하드웨어 사양에 따라 지원이 안되거나, 이상한 결과가 나올 수도 있다는 점.. + + 결론을 말하자면, 윈도우즈에서 1ms 정밀도에 안정성까지 있는 함수는 존재하지 않습니다. + + 저는 라이브러리 로딩할 때 QueryPerformanceCounter() 가 지원되는지를 한번 확인하고, 지원 안 + 된다면 그냥 GetTickCount()를 쓰되 오차를 적절히 보정해서 씁니다. + + 그러나 1/100초 정도의 정밀도로 충분하다면 GetTickCount() 를 쓰는게 좋습니다 + + -- 2013-08-11 01:17:00 + + ///////////////////////////////////////////////////////////////////////////////////////////*/ + + class ZCTimeElapse + { + public : + typedef ZTypInt64 TypeIntTime; + private: + TypeIntTime ml_InitMiliTime ; + public : + + ZCTimeElapse() + { + ml_InitMiliTime = ::GetTickCount(); + }/* + ZCTimeElapse()*/ + + void Init() + { + ml_InitMiliTime = ::GetTickCount(); + }/* + void Init()*/ + + TypeIntTime GetElapse() const + { + return ::GetTickCount()-ml_InitMiliTime; + }/* + TypeIntTime GetElapse() const*/ + + TypeIntTime GetElapseInit() // 시간 간격을 구하면서 동시에 초기화를 한다. + { + long VL_PrevTime=ml_InitMiliTime; + + ml_InitMiliTime = ::GetTickCount(); + + return ml_InitMiliTime-VL_PrevTime; + }/* + TypeIntTime GetElapseInit()*/ + + TypeIntTime GetTimeInt () const{return ml_InitMiliTime;} + TypeIntTime GetTimeMilli() const{return ml_InitMiliTime;} + + static TypeIntTime GetTimeIntNow () { return ::GetTickCount(); } + static TypeIntTime GetTimeMilliNow() { return ::GetTickCount(); } + + public: + };/* + class ZCTimeElapse*/ + + +#else // !defined(_WIN) + + + /*////////////////////////////////////////////////////////////// + + ■ ZCTime 에 동기화 처리가 되었기 때문에, Unix 에서는 ZCTime 을 + ZCStdTime 으로 typedef 해서 사용한다. + + -- 2012-04-03 12:45:00 + + 이제는 Unix 에서 gettimeofday() 를 이용한 좀 더 최적화된 ZCStdTime + 을 만들었다. -- 2018-06-22 14:47:00 + + ■ HP-UX 에서는 localtime_r, gmtime_r 을 사용하기 위해서는 + _REENTRANT 을 정의해야 하는 경우가 있다. + + -- 2012-04-08 18:43:00 + + //////////////////////////////////////////////////////////////*/ + + + class ZCStdTime + { + public : + typedef ZTypInt64 TypeIntTime; + private: + enum{ETimeBuffSize =30 }; + enum{ESecResolution=1000*1000 }; // 1 초를 이루는 값으로 100 만. + private: + char mca_TimeBuff[ETimeBuffSize]; + private: + bool mb_IsLocal; struct + timeval mo_TimeVal; struct + tm mo_TimeObj; + TypeIntTime mi_TimeSec; + public : + + static TypeIntTime GetSecResolution() + { + return (TypeIntTime)ESecResolution; + }/* + static TypeIntTime GetSecResolution()*/ + + public : + + ZCStdTime(bool AB_IsLoaclTime=true) + { + mb_IsLocal=AB_IsLoaclTime; + mi_TimeSec=0 ; + + if(AB_IsLoaclTime) + InitLocalTimeObj (); + else InitSystemTimeObj(); + }/* + ZCStdTime(bool AB_IsLoaclTime=true)*/ + + ZCStdTime(const ZCStdTime& rhs) + { + mb_IsLocal=rhs.mb_IsLocal; + mo_TimeVal=rhs.mo_TimeVal; + mo_TimeObj=rhs.mo_TimeObj; + mi_TimeSec=rhs.mi_TimeSec; + }/* + ZCStdTime(const ZCStdTime& rhs)*/ + + ~ZCStdTime() + { + }/* + ~ZCStdTime()*/ + + ZCStdTime& operator=(const ZCStdTime& rhs) + { + if(this==&rhs) return *this; + + mb_IsLocal=rhs.mb_IsLocal; + mo_TimeVal=rhs.mo_TimeVal; + mo_TimeObj=rhs.mo_TimeObj; + mi_TimeSec=rhs.mi_TimeSec; + + return *this; + }/* + ZCStdTime& operator=(const ZCStdTime& rhs)*/ + + + bool InitLocalTimeObj() + { + ::gettimeofday(&mo_TimeVal, NULL ); + ::localtime_r (&mo_TimeVal.tv_sec, &mo_TimeObj); return true; + }/* + bool InitLocalTimeObj()*/ + + bool InitSystemTimeObj() + { + ::gettimeofday(&mo_TimeVal, NULL ); + ::gmtime_r (&mo_TimeVal.tv_sec, &mo_TimeObj); return true; + }/* + bool InitSystemTimeObj()*/ + + bool InitTimeObj(bool AB_IsLoaclTime) + { + if(AB_IsLoaclTime) + return InitLocalTimeObj (); + else return InitSystemTimeObj(); + }/* + bool InitTimeObj(bool AB_IsLoaclTime)*/ + + bool InitTimeObj() + { + return InitTimeObj(mb_IsLocal); + }/* + bool InitTimeObj()*/ + + + bool InitLocalTimeObj(TypeIntTime AI_TimeInt) + { + if(::localtime_r(&AI_TimeInt, &mo_TimeObj)==0) + return false; + /*##########################################*/ + + mi_TimeSec = AI_TimeInt; + mo_TimeVal.tv_sec = AI_TimeInt; + mo_TimeVal.tv_usec= 0 ; return true; + }/* + bool InitLocalTimeObj()*/ + + bool InitSystemTimeObj(TypeIntTime AI_TimeInt) + { + if(::gmtime_r(&AI_TimeInt, &mo_TimeObj)==0) + return false; + /*#######################################*/ + + mi_TimeSec = AI_TimeInt; + mo_TimeVal.tv_sec = AI_TimeInt; + mo_TimeVal.tv_usec= 0 ; return true; + }/* + bool InitSystemTimeObj(TypeIntTime AI_TimeInt)*/ + + bool InitTimeObj(bool AB_IsLoaclTime, TypeIntTime AI_TimeInt) + { + if(AB_IsLoaclTime) + return InitLocalTimeObj (AI_TimeInt); + else return InitSystemTimeObj(AI_TimeInt); + }/* + bool InitTimeObj(bool AB_IsLoaclTime, TypeIntTime AI_TimeInt)*/ + + + bool InitTimeObjFromDate( + int AI_Year , int AI_Month, int AI_Day , + int AI_Hour=0, int AI_Min=0, int AI_Sec=0, int AI_MiliSec=0) + { + ::memset(&mo_TimeVal, 0, sizeof(::tm)); + + mo_TimeObj.tm_year=AI_Year-1900 ; + mo_TimeObj.tm_mon =AI_Month-1 ; + mo_TimeObj.tm_mday=AI_Day ; + mo_TimeObj.tm_hour=AI_Hour ; + mo_TimeObj.tm_min =AI_Min ; + mo_TimeObj.tm_sec =AI_Sec ; + + mi_TimeSec = ::mktime(&mo_TimeObj); + + if(mi_TimeSec<=0) return false; + + mo_TimeVal.tv_sec = mi_TimeSec ; + mo_TimeVal.tv_usec = AI_MiliSec*1000; + + return true; + }/* + bool InitTimeObjFromDate( + int AI_Year , int AI_Month, int AI_Day , + int AI_Hour=0, int AI_Min=0, int AI_Sec=0, int AI_MiliSec=0)*/ + + + TypeIntTime GetTimeInt() const + { + return (((TypeIntTime)mo_TimeVal.tv_sec)<<32) + mo_TimeVal.tv_usec ; + }/* + TypeIntTime GetTimeInt() const*/ + + TypeIntTime GetTimeSec() const + { + return mo_TimeVal.tv_sec ; + }/* + TypeIntTime GetTimeSec() const*/ + + + TypeIntTime AddTimeIntMilli(TypeIntTime AI_AddMilli) const{ + return GetTimeInt() + ( AI_AddMilli*(ESecResolution/1000) ) ;} + TypeIntTime AddTimeIntSec (TypeIntTime AI_AddSec ) const{ + return GetTimeInt() + ( AI_AddSec * ESecResolution ) ;} + + + inline TypeIntTime AddTimeIntMilliRev(TypeIntTime AI_AddMilli) const + { + // ESecResolution/1000 < 1 인 경우에는 1 milli 초를 표현할 수 없으니까, + // ESecResolution/1000 이상이면서 가장 가까운 배수로 보정(revise)하는 + // 것이다. 스케줄러에서 예약 시간을 등록할 때 필요하다. + + return AddTimeIntMilli(AI_AddMilli); // 특별한 처리가 필요없다. + }/* + inline TypeIntTime AddTimeIntMilliRev(TypeIntTime AI_AddMilli) const*/ + + inline TypeIntTime AddTimeIntSecRev(TypeIntTime AI_AddSec) const + { + // ESecResolution < 1 인 경우에는 1 초를 표현할 수 없으니까, + // ESecResolution 이상이면서 가장 가까운 배수로 보정(revise)하는 + // 것이다. 스케줄러에서 예약 시간을 등록할 때 필요하다. + + return AddTimeIntSec(AI_AddSec); // 특별한 처리가 필요없다. + }/* + inline TypeIntTime AddTimeIntSecRev(TypeIntTime AI_AddSec) const*/ + + + inline int GetSysYear () const{return mo_TimeObj.tm_year ;} + inline int GetYear () const{return mo_TimeObj.tm_year + 1900 ;} + inline int GetSysMonth() const{return mo_TimeObj.tm_mon ;} + inline int GetMonth () const{return mo_TimeObj.tm_mon + 1 ;} + inline int GetDay () const{return mo_TimeObj.tm_mday ;} + inline int GetHour () const{return mo_TimeObj.tm_hour ;} + inline int GetMinute () const{return mo_TimeObj.tm_min ;} + inline int GetMin () const{return mo_TimeObj.tm_min ;} + inline int GetSecond () const{return mo_TimeObj.tm_sec ;} + inline int GetSec () const{return mo_TimeObj.tm_sec ;} + inline int GetYDay () const{return mo_TimeObj.tm_yday + 1 ;} + inline int GetSysYDay () const + { + // int tm_yday; // Day of year (0 - 365) + + return mo_TimeObj.tm_yday ; + }/* + inline int GetSysYDay() const*/ + + inline int GetWeekDay() const + { + // int tm_wday; // Day of week (0 - 6 : 0 = Sunday) + + return mo_TimeObj.tm_wday + 1 ; + }/* + inline int GetWeekDay() const*/ + + inline int GetSysWeekDay() const + { + // int tm_wday; // Day of week (0 - 6 : 0 = Sunday) + + return mo_TimeObj.tm_wday ; + }/* + inline int GetSysWeekDay() const*/ + + inline int GetWeekOfYear() const + { + // 그 해의 몇 번째 주인지를 판단한다. + // int tm_wday; // Day of week (0 - 6 : 0 = Sunday) + + if(mo_TimeObj.tm_yday<=mo_TimeObj.tm_wday) return 1; + + const int CI_DayCntOfWeek=7; + const int CI_DayCntAdded =2; + + return (mo_TimeObj.tm_yday - mo_TimeObj.tm_wday-1)/CI_DayCntOfWeek + CI_DayCntAdded ; + }/* + inline int GetWeekOfYear() const*/ + + int GetMilliSec() const{return mo_TimeVal.tv_usec/1000;} + int GetMilli () const{return mo_TimeVal.tv_usec/1000;} + int GetMicroSec() const{return mo_TimeVal.tv_usec ;} + + + bool Plus(TypeIntTime AL_TimeSec) + { + return InitTimeObj(mb_IsLocal, mo_TimeVal.tv_sec+AL_TimeSec); + }/* + bool Plus(TypeIntTime AL_TimeSec)*/ + + bool Minus(TypeIntTime AL_TimeSec) + { + return InitTimeObj(mb_IsLocal, mo_TimeVal.tv_sec-AL_TimeSec); + }/* + bool Minus(TypeIntTime AL_TimeSec)*/ + + char* GetDate(bool AB_DoIncludeSpace=true) + { + // AB_DoIncludeSpace==true 이면 일자를 2007-01-01 형태로 반환한다. + // AB_DoIncludeSpace==false 이면 일자를 20070101 형태로 반환한다. + + mca_TimeBuff[0] = + mca_TimeBuff[ZCStdTime::ETimeBuffSize]=0 ; + + if(AB_DoIncludeSpace==true) + { + (void)::sprintf(mca_TimeBuff , + "%d-%02d-%02d" , + GetYear(),GetMonth(),GetDay() + /*//////////*/ ); + } + else + { + (void)::sprintf(mca_TimeBuff , + "%d%02d%02d" , + GetYear(),GetMonth(),GetDay() + /*//////////*/ ); + }/* + else*/ + + return mca_TimeBuff; + }/* + char* GetDate(bool AB_DoIncludeSpace=true)*/ + + char* GetTimeStamp() + { + mca_TimeBuff[0] = + mca_TimeBuff[ZCStdTime::ETimeBuffSize]=0 ; + + (void)::sprintf(mca_TimeBuff, + "%d-%02d-%02d %02d:%02d:%02d", + GetYear(), GetMonth (), GetDay (), + GetHour(), GetMinute(), GetSecond() + /*//////////*/ ); + + return mca_TimeBuff; + }/* + char* GetTimeStamp()*/ + + public: + };/* + class ZCStdTime*/ + + + /*////////////////////////////////////////////////////////////// + + ■ struct timeval + { + time_t tv_sec ; // seconds + suseconds_t tv_usec; // microseconds + }; + + //////////////////////////////////////////////////////////////*/ + + class ZCTimeElapse + { + public : + typedef ZTypInt64 TypeIntTime ; + private: + struct timeval mo_InitTimeVal; + public : + + ZCTimeElapse() + { + ::gettimeofday(&mo_InitTimeVal, NULL); + }/* + ZCTimeElapse()*/ + + void Init() + { + ::gettimeofday(&mo_InitTimeVal, NULL); + }/* + void Init()*/ + + ZTypInt64 GetElapse() const // 밀리 초로 반환한다. + { + struct timeval VO_TimeVal; ::gettimeofday(&VO_TimeVal, NULL); + + return + (VO_TimeVal.tv_sec - mo_InitTimeVal.tv_sec )*1000 + + (VO_TimeVal.tv_usec- mo_InitTimeVal.tv_usec)/1000 ; + }/* + ZTypInt64 GetElapse() const*/ + + ZTypInt64 GetElapseInit() // 시간 간격을 구하면서 동시에 초기화를 한다. + { + struct timeval VO_TimeVal; ::gettimeofday(&VO_TimeVal, NULL); + + long VL_MiliTime = + (VO_TimeVal.tv_sec - mo_InitTimeVal.tv_sec )*1000 + + (VO_TimeVal.tv_usec- mo_InitTimeVal.tv_usec)/1000 ; + + mo_InitTimeVal=VO_TimeVal; return VL_MiliTime; //////// + }/* + ZTypInt64 GetElapseInit()*/ + + TypeIntTime GetTimeInt() const + { + return (TypeIntTime)(mo_InitTimeVal.tv_sec<<32) + mo_InitTimeVal.tv_usec; + }/* + TypeIntTime GetTimeInt() const*/ + + TypeIntTime GetTimeMilli() const + { + return (TypeIntTime)(mo_InitTimeVal.tv_sec*1000) + mo_InitTimeVal.tv_usec/1000; + }/* + TypeIntTime GetTimeMilli() const*/ + + static TypeIntTime GetTimeIntNow() + { + struct timeval VO_TimeVal; ::gettimeofday(&VO_TimeVal, NULL); + + return (TypeIntTime)(VO_TimeVal.tv_sec<<32) + VO_TimeVal.tv_usec; + }/* + static TypeIntTime GetTimeIntNow()*/ + + static TypeIntTime GetTimeMilliNow() + { + // GetTimeIntNow() 을 milli 초로 환산한 것. + + struct timeval VO_TimeVal; ::gettimeofday(&VO_TimeVal, NULL); + + return (TypeIntTime)(VO_TimeVal.tv_sec )*1000 + (VO_TimeVal.tv_usec)/1000 ; + }/* + static TypeIntTime GetTimeMilliNow()*/ + + public: + };/* + class ZCTimeElapse*/ + + +#endif // !defined(_WIN) + + + /*///////////////////////////////////////////////////// + + Open a file. + + int _open( + const char *filename, + int oflag [, + int pmode] + ); + int _wopen( + const wchar_t *filename, + int oflag [, + int pmode] + ); + + Parameters + filename + Filename. + oflag + Type of operations allowed. + pmode + Permission mode. + Return Value + Each of these functions returns a file handle for the opened file. + A return value of ?1 indicates an error, + in which case errno is set to one of the following values: + + EACCES + Tried to open read-only file for writing, + or file's sharing mode does not allow specified operations, or given path is directory. + EEXIST + _O_CREAT and _O_EXCL flags specified, but filename already exists. + EINVAL + Invalid oflag or pmode argument. + EMFILE + No more file handles available (too many open files). + ENOENT + File or path not found. + + See _doserrno, errno, _sys_errlist, and _sys_nerr for more information on these, + and other, return codes. + + Remarks + + The _open function opens the file specified by filename and prepares the file + for reading or writing, + as specified by oflag. _wopen is a wide-character version of _open; + the filename argument to _wopen is a wide-character string. + _wopen and _open behave identically otherwise. + + Generic-Text Routine Mappings + + TCHAR.H routine _UNICODE & _MBCS not defined _MBCS defined _UNICODE defined + _topen _open _open _wopen + + oflag is an integer expression formed + from one or more of the following manifest constants or constant combinations + defined in FCNTL.H: + + _O_APPEND + Moves file pointer to end of file before every write operation. + _O_BINARY + Opens file in binary (untranslated) mode. (See fopen for a description of binary mode.) + _O_CREAT + Creates and opens new file for writing. Has no effect if file specified by filename exists. pmode argument is required when _O_CREAT is specified. + _O_CREAT | _O_SHORT_LIVED + Create file as temporary and if possible do not flush to disk. pmode argument is required when _O_CREAT is specified. + _O_CREAT | _O_TEMPORARY + Create file as temporary; file is deleted when last file handle is closed. pmode argument is required when _O_CREAT is specified. + _O_CREAT | _O_EXCL + Returns error value if file specified by filename exists. Applies only when used with _O_CREAT. + _O_RANDOM + Specifies that caching is optimized for, but not restricted to, random access from disk. + _O_RDONLY + Opens file for reading only; cannot be specified with _O_RDWR or _O_WRONLY. + _O_RDWR + Opens file for both reading and writing; you cannot specify this flag with _O_RDONLY or _O_WRONLY. + _O_SEQUENTIAL + Specifies that caching is optimized for, but not restricted to, sequential access from disk. + _O_TEXT + Opens file in text (translated) mode. (For more information, see Text and Binary Mode File I/O and fopen.) + _O_TRUNC + Opens file and truncates it to zero length; file must have write permission. You cannot specify this flag with _O_RDONLY. _O_TRUNC used with _O_CREAT opens an existing file or creates a new file. + Note The _O_TRUNC flag destroys the contents of the specified file. + _O_WRONLY + Opens file for writing only; cannot be specified with _O_RDONLY or _O_RDWR. + + To specify the file access mode, + you must specify either _O_RDONLY, _O_RDWR, or _O_WRONLY. + There is no default value for the access mode. + + When two or more manifest constants are used to form the oflag argument, + the constants are combined with the bitwise-OR operator ( | ). + See Text and Binary Mode File I/O for a discussion of binary and text modes. + + The pmode argument is required only when _O_CREAT is specified. + If the file already exists, pmode is ignored. + Otherwise, pmode specifies the file permission settings, + which are set when the new file is closed the first time. + _open applies the current file-permission mask to pmode before setting the permissions + (for more information, see _umask). + pmode is an integer expression containing one or both of the following manifest constants, + defined in SYS\STAT.H: + + #define _S_IREAD 0000400 // read permission, owner + #define _S_IWRITE 0000200 // write permission, owner + + _S_IREAD + Reading only permitted. + _S_IWRITE + Writing permitted (effectively permits reading and writing). + _S_IREAD | _S_IWRITE + Reading and writing permitted. + When both constants are given, they are joined with the bitwise-OR operator ( | ). + In Windows NT, all files are readable, so write-only permission is not available; + thus the modes _S_IWRITE and _S_IREAD | _S_IWRITE are equivalent. + + Requirements + Routine Required header Optional headers Compatibility + _open , , Win 98, Win Me, Win NT, Win 2000, Win XP + _wopen or , , Win NT, Win 2000, Win XP + + For additional compatibility information, see Compatibility in the Introduction. + + Libraries + + All versions of the C run-time libraries. + + Example + OPEN.C: This program uses _open to open a file + named OPEN.C for input and a file named OPEN.OUT + for output. The files are then closed. + + #include + #include + #include + #include + #include + + void main( void ) + { + int fh1, fh2; + + fh1 = _open( "OPEN.C", _O_RDONLY ); + if( fh1 == -1 ) + perror( "open failed on input file" ); + else + { + printf( "open succeeded on input file\n" ); + _close( fh1 ); + } + + fh2 = _open( "OPEN.OUT", _O_WRONLY | _O_CREAT, _S_IREAD | + _S_IWRITE ); + if( fh2 == -1 ) + perror( "Open failed on output file" ); + else + { + printf( "Open succeeded on output file\n" ); + _close( fh2 ); + } + } + + Output + Open succeeded on input file + Open succeeded on output file + + ///////////////////////////*/ + + + namespace ZNsConst + { + + namespace ZNsCFileMode + { + // These values are second parameters of CCFile::Open() function + + const char* const Read = "r" ; + const char* const ReadWrite = "r+"; + const char* const RWAppend = "a+"; + const char* const RWCut = "w" ; + const char* const WriteAppend= "a" ; + const char* const WriteCut = "w+"; + const char* const Binary = "b" ; + const char* const WriteBinany= "wb"; + }/* + namespace ZNsCFileMode*/ + + namespace ZNsCppFileMode + { + // These vales are used to be a second parmeter in fstream::open() function + + const unsigned int Read =std::ios::in ; + const unsigned int WriteCut =std::ios::out; // == std::ios::out | std::ios::trunc + const unsigned int Append =std::ios::out | std::ios::app ; + const unsigned int ReadWrite=std::ios::in | std::ios::out ; + const unsigned int RWCut =std::ios::in | std::ios::out | std::ios::trunc ; + + const unsigned int EndPos =std::ios::ate ; + // std::ios::ate mode move file pointer to file end + // Use this value with other mode value + }/* + namespace ZNsCppFileMode*/ + + namespace ZNsLlioMode // Low Level Input Output + { + const unsigned long Read =O_RDONLY; + const unsigned long Write =O_WRONLY; + const unsigned long ReadWrite=O_RDWR ; + const unsigned long RWMake =O_RDWR | O_CREAT ; + + const unsigned long Append =O_APPEND | O_WRONLY; + const unsigned long Trunc =O_TRUNC ; + const unsigned long Create =O_CREAT ; + const unsigned long OnlyExist =O_EXCL | O_CREAT ; + const unsigned long WriteMakeCut=O_WRONLY | O_CREAT | O_TRUNC ; + const unsigned long AppendMake =O_APPEND | O_WRONLY | O_CREAT ; + + // AppendMake : 덧붙이되 파일이 없으면 새로 만든다. + // O_EXCL : open only if file doesn't already exist + // O_EXCL is used with O_CREAT + }/* + namespace ZNsLlioMode*/ + + }/* + namespace ZNsConst*/ + + + /*///////////////////////// + + struct stat + { + _dev_t st_dev; + _ino_t st_ino; + unsigned short st_mode; + short st_nlink; + short st_uid; + short st_gid; + _dev_t st_rdev; + _off_t st_size; + time_t st_atime; + time_t st_mtime; + time_t st_ctime; + }; + + /////////////////////////*/ + + + class CFile + { + protected: + FILE* mp_HFile; + public : + + CFile() + { + mp_HFile=0; + }/* + CFile()*/ + + const FILE* GetFilePtr() + { + return mp_HFile; + }/* + const FILE* GetFilePtr()*/ + + bool Open(const char* APC_FileName, const char* APC_Mode=ZNsConst::ZNsCFileMode::ReadWrite) + { + return (mp_HFile=::fopen(APC_FileName, APC_Mode))!=0; + }/* + bool Open(const char* APC_FileName,const char* APC_Mode=ZNsConst::ZNsCFileMode::ReadWrite)*/ + + bool Close() + { + bool VB_IsOK=(::fclose(mp_HFile)==0); mp_HFile=0; return VB_IsOK; + }/* + bool Close()*/ + + size_t Read(void* AP_Buff, size_t AI_BlockSize, size_t AI_BlockCnt) + { + return ::fread(AP_Buff, AI_BlockSize, AI_BlockCnt, mp_HFile); + }/* + size_t Read(void* AP_Buff, size_t AI_BlockSize, size_t AI_BlockCnt)*/ + + size_t Read(void* AP_ReadBuff, size_t AI_ReadByte) + { + return ::fread(AP_ReadBuff, 1, AI_ReadByte, mp_HFile); + }/* + size_t Read(void* AP_ReadBuff, size_t AI_ReadByte)*/ + + size_t Write(const void* AP_Buff, size_t AI_BlockSize, size_t AI_BlockCnt) + { + return ::fwrite(AP_Buff, AI_BlockSize, AI_BlockCnt, mp_HFile); + }/* + size_t Write(const void* AP_Buff, size_t AI_BlockSize, size_t AI_BlockCnt)*/ + + size_t Write(const void* AP_WriteBuff, size_t AI_WriteByte) + { + return ::fwrite(AP_WriteBuff, 1, AI_WriteByte, mp_HFile); + }/* + size_t Write(const void* AP_WriteBuff, size_t AI_WriteByte)*/ + + size_t Write(const char* AP_Buff) + { + return ::fwrite(AP_Buff, 1, strlen(AP_Buff), mp_HFile); + }/* + size_t Write(const char* AP_Buff)*/ + + bool Flush() // 파일스트림의 모든 데이타를 즉시 저장한다. + { + return ::fflush(mp_HFile)==0; + }/* + bool Flush()*/ + + int Seek(long AL_Offset, int AI_Whence=SEEK_SET) // AI_Whence 는 SEEK_SET, SEEK_CUR, SEEK_END 중의 한 값 + { + return ::fseek(mp_HFile, AL_Offset, AI_Whence); + }/* + int Seek(long AL_Offset, int AI_Whence=SEEK_SET)*/ + + long Tell() + { + return ::ftell(mp_HFile); + }/* + long Tell()*/ + + int GetC() + { + return ::fgetc(mp_HFile); + }/* + int GetC()*/ + + int PutC(int AI_Char) + { + return ::fputc(AI_Char,mp_HFile); + }/* + int PutC(int AI_Char)*/ + + int PrintF(const char* APC_Format, ...) + { + va_list VP_VarParam; va_start( VP_VarParam, APC_Format); + + return vfprintf(mp_HFile, APC_Format, VP_VarParam); + }/* + int PrintF(const char* APC_Format, ...)*/ + + bool IsError() + { + return ::ferror(mp_HFile)!=0; + }/* + bool IsError()*/ + + bool IsEOF() + { + return ::feof(mp_HFile)!=0; + }/* + bool IsEOF()*/ + + public: + };/* + class CFile*/ + + + class ZCLLIO // Low Level Input Output + { + protected: + int mi_Handle; + public : + + ZCLLIO() + { + mi_Handle=-1; + }/* + ZCLLIO()*/ + + bool IsValid() const + { + return mi_Handle>=0; + }/* + bool IsValid() const*/ + + bool Open(ZTypCPCCh APC_Path, int AI_Mode=ZNsConst::ZNsLlioMode::Read, int AI_Perm=0) + { + // Mode value is one of many variables in namespace NsCLLio + // return -1 if it fails; + + return (mi_Handle= ::open(APC_Path, AI_Mode, AI_Perm)) != -1 ; + + /*//////////////////////////////////////////////////////////////////////////////////////////////////////// + + ■ cf) + fflush() returns 0 if the buffer was successfully flushed. + The value 0 is also returned in cases + in which the specified stream has no buffer or is open for reading only. + A return value of EOF indicates an error. + Note If fflush returns EOF, data may have been lost due to a write failure. + When setting up a critical error handler, + it is safest to turn buffering off with the setvbuf() function + or to use low-level I/O routines such as _open, _close, and _write instead of the stream I/O functions. + + ■ -- + + ////////////////////////////////////////////////////////////////////////////////////////////////////////*/ + }/* + bool Open(ZTypCPCCh APC_Path, int AI_Mode=ZNsConst::ZNsLlioMode::Read, int AI_Perm=0)*/ + + bool OpenRead (ZTypCPCCh APC_Path , int AI_Perm=0) // 읽기 + { return (mi_Handle= ::open( APC_Path , ZNsConst::ZNsLlioMode::Read , AI_Perm)) != -1 ; } + bool OpenWrite(ZTypCPCCh APC_Path , int AI_Perm=0) // 쓰기 + { return (mi_Handle= ::open( APC_Path , ZNsConst::ZNsLlioMode::Write , AI_Perm)) != -1 ; } + bool OpenRW (ZTypCPCCh APC_Path , int AI_Perm=0) // 읽기/쓰기 + { return (mi_Handle= ::open( APC_Path , ZNsConst::ZNsLlioMode::ReadWrite, AI_Perm)) != -1 ; } + bool OpenApp (ZTypCPCCh APC_Path , int AI_Perm=0) // 덧붙이기 + { return (mi_Handle= ::open( APC_Path , ZNsConst::ZNsLlioMode::Append , AI_Perm)) != -1 ; } + + + #ifndef S_IRWXU + #define S_IRWXU 0 + #endif + #ifndef S_IRUSR + #define S_IRUSR 0 + #endif + #ifndef S_IWUSR + #define S_IWUSR 0 + #endif + #ifndef S_IXUSR + #define S_IXUSR 0 + #endif + + #ifndef S_IRWXG + #define S_IRWXG 0 + #endif + #ifndef S_IRGRP + #define S_IRGRP 0 + #endif + #ifndef S_IWGRP + #define S_IWGRP 0 + #endif + #ifndef S_IXGRP + #define S_IXGRP 0 + #endif + + #ifndef S_IRWXO + #define S_IRWXO 0 + #endif + #ifndef S_IROTH + #define S_IROTH 0 + #endif + #ifndef S_IWOTH + #define S_IWOTH 0 + #endif + #ifndef S_IXOTH + #define S_IXOTH 0 + #endif + + /*############################################################################## + + □ unix open 함수의 주요 상수. + + S_IRWXU 00700 user (file owner) has read, write and execute permission + S_IRUSR 00400 user has read permission + S_IWUSR 00200 user has write permission + S_IXUSR 00100 user has execute permission + + S_IRWXG 00070 group has read, write and execute permission + S_IRGRP 00040 group has read permission + S_IWGRP 00020 group has write permission + S_IXGRP 00010 group has execute permission + + S_IRWXO 00007 others have read, write and execute permission + S_IROTH 00004 others have read permission + S_IWOTH 00002 others have write permission + S_IXOTH 00001 others have execute permission + + ##############################################################################*/ + + bool MakeCut(ZTypCPCCh APC_Path, int AI_Perm=(S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) + { return Open(APC_Path, ZNsConst::ZNsLlioMode::WriteMakeCut, AI_Perm); } + bool MakeRW (ZTypCPCCh APC_Path, int AI_Perm=(S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) + { return Open(APC_Path, ZNsConst::ZNsLlioMode::RWMake , AI_Perm); } + bool MakeApp(ZTypCPCCh APC_Path, int AI_Perm=(S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) + { return Open(APC_Path, ZNsConst::ZNsLlioMode::AppendMake , AI_Perm); } // 덧붙이되 없으면 새로 만듦. + + inline int GetHandle() const + { + return mi_Handle; + }/* + inline int GetHandle() const*/ + + off_t GetFileSize() + { + // typedef long _off_t; IN Windows + // typedef long off_t; IN Linux + + struct stat VO_FileStatus; + + if(fstat(mi_Handle, &VO_FileStatus)<0) + { return -1; } + + return VO_FileStatus.st_size; + }/* + off_t GetFileSize()*/ + + size_t Read(void* AP_Buffer, size_t AI_ByteSize) + { + return read(mi_Handle,AP_Buffer,AI_ByteSize); + + // typedef unsigned int size_t; + }/* + size_t Read(void* AP_Buffer, size_t AI_ByteSize)*/ + + size_t Write(const void* AP_Buffer, size_t AI_ByteSize) + { + // _CRTIMP int __cdecl write(int, const void *, unsigned int); // In Visual C++ 6.0 + + return write(mi_Handle,AP_Buffer,AI_ByteSize); + }/* + size_t Write(const void* AP_Buffer, size_t AI_ByteSize)*/ + + off_t Seek(off_t AI_Offset,int AI_Whence=SEEK_SET) const + { + // typedef long off_t; + // AI_Whence is one of SEEK_SET, SEEK_CUR, SEEK_END + + return ::lseek(mi_Handle,AI_Offset,AI_Whence); + + /* MSDN : _lseek() returns the offset, in bytes, of the new position from the beginning of the file. + _lseeki64 returns the offset in a 64-bit integer. + The function returns ?1L to indicate an error + and sets errno either to EBADF, meaning the file handle is invalid, + or to EINVAL, meaning the value for origin is invalid or the position specified by offset + is before the beginning of the file. + On devices incapable of seeking (such as terminals and printers), + the return value is undefined. */ + }/* + off_t Seek(off_t AI_Offset,int AI_Whence=SEEK_SET) const*/ + + + /*////////////////////////////////////////////////////////////////////////////////// + + ■ int _fstat ( int handle, struct _stat *buffer ); + __int64 _fstati64( int handle, struct _stat *buffer ); + + Function Required Header Compatibility + _fstat and Win 95, Win NT + _fstati64 and Win 95, Win NT + + Return Value + + _fstat and _fstati64 return 0 if the file-status information is obtained. + A return value of ?1 indicates an error, in which case errno is set to EBADF, + indicating an invalid file handle. + + When you declear struct stat even in a C++ file, To use struct keyword is better + + //////////////////////////////////////////////////////////////////////////////////*/ + + + bool GetFStat(struct stat& ARR_StatBuf) + { + return fstat(mi_Handle, &ARR_StatBuf)==0; + }/* + bool GetFStat(struct stat& ARR_StatBuf)*/ + + static bool GetFStat(ZTypCPCCh APC_Path, struct stat& ARR_StatBuf) + { + return stat(APC_Path, &ARR_StatBuf)==0; + }/* + static bool GetFStat(ZTypCPCCh APC_Path, struct stat& ARR_StatBuf)*/ + + + #if !defined(_WIN) + + + static bool GetLStat(ZTypCPCCh APC_Path, struct stat& ARR_StatBuf) + { + return lstat(APC_Path, &ARR_StatBuf)==0; + + // lstat() return information of link itself if Path is a link + }/* + static bool GetLStat(ZTypCPCCh Path, struct stat& ARR_StatBuf)*/ + + /*///////////////////////////////////////// + + #define S_ISBLK(m) (((m)&_IFMT) == _IFBLK) + #define S_ISCHR(m) (((m)&_IFMT) == _IFCHR) + #define S_ISDIR(m) (((m)&_IFMT) == _IFDIR) + #define S_ISFIFO(m) (((m)&_IFMT) == _IFIFO) + #define S_ISREG(m) (((m)&_IFMT) == _IFREG) + #define S_ISLNK(m) (((m)&_IFMT) == _IFLNK) + #define S_ISSOCK(m) (((m)&_IFMT) == _IFSOCK) + + /////////////////////////////////////////*/ + + + #endif //!defined(_WIN) + + + bool Close() + { + if(mi_Handle<0) return true; + + bool VB_Result=(::close(mi_Handle)==0); + + mi_Handle = -1; return VB_Result; + + // close() returns -1 if it fail + // close() returns 0 if it succeed + }/* + bool Close()*/ + + int SetDefaultMask(int AI_Mode) + { + /*/////////////////////////////////// + + int _umask( + int pmode + ); + + Sets the default file-permission mask. + + Parameter + pmode + Default permission setting. + Return Value + _umask returns the previous value of pmode. There is no error return. + + ///////////////////////////////////*/ + + return umask(AI_Mode); + }/* + int SetDefaultMask(int AI_Mode)*/ + + public: + };/* + class ZCLLIO*/ + + + //////////////// class ZCFileInfo //////////////// + + + class ZCFileInfo + { + protected: + struct stat mo_FileStatus; + public : + + bool GetStatus(ZTypCPCCh AP_File) + { + return stat(AP_File, &mo_FileStatus) != -1 ; + + /* Each of these functions returns 0 if the file-status information is obtained. + A return value of ?1 indicates an error, + in which case errno is set to ENOENT, + indicating that the filename or path could not be found. */ + }/* + bool GetStatus(ZTypCPCCh APC_Path)*/ + + bool GetStatus(int AI_FileHandle) + { + return fstat(AI_FileHandle, &mo_FileStatus) != -1; + }/* + bool GetStatus(int AI_FileHandle)*/ + + struct stat& GetStatusObj(){ return mo_FileStatus; } + + public: + };/* + class ZCFileInfo*/ + + + /*//////////////////////////////////////////////////////////////////////////// + + _fstat, _fstati64 + Get information about an open file. + + int _fstat( int handle, struct _stat *buffer ); + + __int64 _fstati64( int handle, struct _stat *buffer ); + + Function Required Header Compatibility + _fstat and Win 95, Win NT + _fstati64 and Win 95, Win NT + + For additional compatibility information, see Compatibility in the Introduction. + + Libraries + + LIBC.LIB Single thread static library, retail version + LIBCMT.LIB Multithread static library, retail version + MSVCRT.LIB Import library for MSVCRT.DLL, retail version + + Return Value + + _fstat and _fstati64 return 0 if the file-status information is obtained. + A return value of ?1 indicates an error, in which case errno is set to EBADF, + indicating an invalid file handle. + + Parameters + + handle + Handle of open file + buffer + Pointer to structure to store results + + Remarks + + The _fstat function obtains information about the open file associated with handle and + stores it in the structure pointed to by buffer. + The _stat structure, defined in SYS\STAT.H, contains the following fields: + + // typedef long time_t; + + st_atime + Time of last file access. + + st_ctime + Time of creation of file. + + st_dev + If a device, handle; otherwise 0. + + st_mode + Bit mask for file-mode information. The _S_IFCHR bit is set if handle refers to a device. The _S_IFREG bit is set if handle refers to an ordinary file. The read/write bits are set according to the file’s permission mode. _S_IFCHR and other constants are defined in SYS\STAT.H. + + st_mtime + Time of last modification of file. + + st_nlink + Always 1 on non-NTFS file systems. + + st_rdev + If a device, handle; otherwise 0. + + st_size + Size of the file in bytes. + + If handle refers to a device, the st_atime, + st_ctime, and st_mtime and st_size fields are not meaningful. + + Because STAT.H uses the _dev_t type, which is defined in TYPES.H, + you must include TYPES.H before STAT.H in your code. + + Example + + FSTAT.C: This program uses _fstat to report + the size of a file named F_STAT.OUT. + + #include + #include + #include + #include + #include + #include + #include + #include + + void main( void ) + { + struct _stat iov_base; + int fh, result; + char buffer[] = "A line to output"; + + if( (fh = _open( "f_stat.out", _O_CREAT | _O_WRONLY | + _O_TRUNC )) == -1 ) + _write( fh, buffer, strlen( buffer ) ); + + // Get data associated with "fh": + result = _fstat( fh, &iov_base ); + + // Check if statistics are valid: + + if( result != 0 ) + { + printf( "Bad file handle\n" ); + } + else + { + printf( "File size : %ld\n", iov_base.st_size ); + printf( "Time modified : %s", ctime( &iov_base.st_ctime ) ); + } + + _close( fh ); + } + + Output + + File size : 0 + Time modified : Tue Mar 21 15:23:08 1995 + + /////////////////////////////////////////////////////////////////*/ + + /*///////////////////////////////////////////////////////////////// + + #define _S_IREAD 0000400 // read permission, owner + #define _S_IWRITE 0000200 // write permission, owner + + #define _S_IFMT 0170000 // file type mask + #define _S_IFDIR 0040000 // directory + #define _S_IFCHR 0020000 // character special + #define _S_IFIFO 0010000 // pipe + #define _S_IFREG 0100000 // regular + #define _S_IEXEC 0000100 // execute/search permission, owner + + #define S_IFMT _S_IFMT + #define S_IFDIR _S_IFDIR + #define S_IFCHR _S_IFCHR + #define S_IFREG _S_IFREG + + /////////////////////////////////////////////////////////////////*/ + + + namespace ZNsFileStatMode + { + #ifndef S_IFIFO + #define S_IFIFO _S_IFIFO + #endif + const unsigned int File =S_IFMT ; + const unsigned int Directory =S_IFDIR; + const unsigned int CharDevice =S_IFCHR; + const unsigned int DefaultFile=S_IFREG; + const unsigned int Fifo =S_IFIFO; + //const unsigned int Execute =S_IEXEC; + }/* + namespace ZNsFileStatMode*/ + + + /*//////////////////////////////////////////////////////////////////////////////////// + + ■ WIN32_FIND_DATA + + typedef struct _WIN32_FIND_DATAA { + DWORD dwFileAttributes; + FILETIME ftCreationTime; + FILETIME ftLastAccessTime; + FILETIME ftLastWriteTime; + DWORD nFileSizeHigh; + DWORD nFileSizeLow; + DWORD dwReserved0; + DWORD dwReserved1; + _Field_z_ CHAR cFileName[ MAX_PATH ]; + _Field_z_ CHAR cAlternateFileName[ 14 ]; + #ifdef _MAC + DWORD dwFileType; + DWORD dwCreatorType; + WORD wFinderFlags; + #endif + } WIN32_FIND_DATAA, *PWIN32_FIND_DATAA, *LPWIN32_FIND_DATAA; + typedef struct _WIN32_FIND_DATAW { + DWORD dwFileAttributes; + FILETIME ftCreationTime; + FILETIME ftLastAccessTime; + FILETIME ftLastWriteTime; + DWORD nFileSizeHigh; + DWORD nFileSizeLow; + DWORD dwReserved0; + DWORD dwReserved1; + _Field_z_ WCHAR cFileName[ MAX_PATH ]; + _Field_z_ WCHAR cAlternateFileName[ 14 ]; + #ifdef _MAC + DWORD dwFileType; + DWORD dwCreatorType; + WORD wFinderFlags; + #endif + } WIN32_FIND_DATAW, *PWIN32_FIND_DATAW, *LPWIN32_FIND_DATAW; + #ifdef UNICODE + typedef WIN32_FIND_DATAW WIN32_FIND_DATA; + typedef PWIN32_FIND_DATAW PWIN32_FIND_DATA; + typedef LPWIN32_FIND_DATAW LPWIN32_FIND_DATA; + #else + typedef WIN32_FIND_DATAA WIN32_FIND_DATA; + typedef PWIN32_FIND_DATAA PWIN32_FIND_DATA; + typedef LPWIN32_FIND_DATAA LPWIN32_FIND_DATA; + #endif // UNICODE + + + typedef struct _WIN32_FIND_DATA + { + DWORD dwFileAttributes; + FILETIME ftCreationTime; + FILETIME ftLastAccessTime; + FILETIME ftLastWriteTime; + DWORD nFileSizeHigh; + DWORD nFileSizeLow; + DWORD dwOID; + TCHAR cFileName[MAX_PATH]; + } WIN32_FIND_DATA; + + Members + dwFileAttributes + + File attributes of the file found. + The following table shows the possible values for dwFileAttribute. Value Description + + FILE_ATTRIBUTE_ARCHIVE + Indicates that the file or directory is an archive file or directory. + Applications use this attribute to mark files for backup or removal. + FILE_ATTRIBUTE_COMPRESSED + Indicates that the file or directory is compressed. + For a file, this means that all of the data in the file is compressed. + For a directory, this means that compression is the default + for newly created files and subdirectories. + FILE_ATTRIBUTE_DIRECTORY + Indicates that the handle identifies a directory. + FILE_ATTRIBUTE_ENCRYPTED + Indicates that the file or directory is encrypted. + For a file, this means that all data streams are encrypted. For a directory, this means that encryption is the default for newly created files and subdirectories. + FILE_ATTRIBUTE_HIDDEN + Indicates that the file or directory is hidden. + It is not included in an ordinary directory listing. + FILE_ATTRIBUTE_INROM + Indicates that this file is an operating system file stored in ROM. + These files are read-only; they cannot be modified. + FILE_ATTRIBUTE_NORMAL + Indicates that the file or directory has no other attributes set. + This attribute is valid only if used alone. + FILE_ATTRIBUTE_READONLY + Indicates that the file or directory is read-only. + Applications can read the file but cannot write to it or delete it. + In the case of a directory, applications cannot delete it. + FILE_ATTRIBUTE_REPARSE_POINT + Indicates that the file has an associated reparse point. + FILE_ATTRIBUTE_ROMMODULE + Indicates that this file is an operating system file stored in ROM and executed directly from ROM, + rather than being first copied to RAM. + The CreateFile function cannot be used to access this file, + instead the LoadLibrary and CreateProcess functions must be used. + FILE_ATTRIBUTE_ROMSTATICREF + Indicates that the file is a DLL module that has an implicit reference + from at least one other file that is in the modules section of the image. + A file having this attribute cannot replace the functionality of the DLL with a RAM copy of the same DLL. + A file having this attribute must also have the FILE_ATTRIBUTE_INROM and FILE_ATTRIBUTE_ROMMODULE attributes. + FILE_ATTRIBUTE_SPARSE_FILE + Indicates that the file is a sparse file. + FILE_ATTRIBUTE_SYSTEM + Indicates that the file or directory is part of the operating system + or is used exclusively by the operating system. + FILE_ATTRIBUTE_TEMPORARY + Indicates that the file is being used for temporary storage. + File systems attempt to keep all of the data in memory for quicker access, + rather than flushing it back to mass storage. + A temporary file should be deleted by the application as soon as it is no longer needed. + + ftCreationTime + FILETIME structure containing the time the file was created. + FindFirstFile and FindNextFile report file times in Coordinated Universal Time (UTC) format. + These functions set the FILETIME members to zero + if the file system containing the file does not support this time member. + You can use the FileTimeToLocalFileTime function to convert from UTC to local time, + and then use the FileTimeToSystemTime function + to convert the local time to a SYSTEMTIME structure containing individual members + for the month, day, year, weekday, hour, minute, second, and millisecond. + ftLastAccessTime + FILETIME structure containing the time that the file was last accessed. + The time is in UTC format; the FILETIME members are zero + if the file system does not support this time member. + ftLastWriteTime + FILETIME structure containing the time that the file was last written to. + The time is in UTC format; the FILETIME members are zero + if the file system does not support this time member. + nFileSizeHigh + High-order DWORD value of the file size, in bytes. + This value is zero unless the file size is greater than MAXDWORD. + The size of the file is equal to (nFileSizeHigh * MAXDWORD) + nFileSizeLow. + nFileSizeLow + Low-order DWORD value of the file size, in bytes. + dwOID + Object identifier of the file. + cFileName + Null-terminated string that is the name of the file. + + ////////////////////////////////////////////////////////////////////////////////////*/ + + #ifndef MAX_PATH + #define MAX_PATH 512*2 + #endif + + #define _MAX_PATH2 MAX_PATH*3 + + #ifdef _WIN + typedef HANDLE TypeDirID; + #elif defined(__unix__) + typedef DIR* TypeDirID; + #else + typedef DIR* TypeDirID; + #endif + + + #if defined(_WIN) + + class ZCFileData : public WIN32_FIND_DATAA + { + public: + + bool IsDir() const + { + return (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)==FILE_ATTRIBUTE_DIRECTORY; + + // #define FILE_ATTRIBUTE_DIRECTORY 0x00000010 + }/* + bool IsDir() const*/ + + ZTypCPCh GetFileName() const + { + return this->cFileName; + }/* + ZTypCPCh GetFileName() const*/ + + public: + };/* + class ZCFileData*/ + + #else //!defined(_WIN) + + class ZCFileData : public stat + { + public: + + char cFileName[_MAX_PATH2]; + + inline bool IsDir() const + { return S_ISDIR(this->st_mode); } + + inline ZTypCPChar GetFileName() const + { return cFileName ; } + + public: + };/* + class ZCFileData*/ + + + #endif //!defined(_WIN) + + + /*////////////////////////////////////////////////////////////////////////////////////////////////////// + + HANDLE FindFirstFile(LPCTSTR lpFileName, LPWIN32_FIND_DATA lpFindFileData); + + #define MAX_PATH 260 + + Parameters + lpFileName + [in] Pointer to a null-terminated string that specifies a valid directory or path and file name, + which can contain wildcard characters (* and ?). + If the string ends with a wildcard, a period, or a directory name, + the user must have access to the root and all subdirectories on the path. + In the ANSI version of this function, the name is limited to MAX_PATH characters. + To extend this limit to 32,767 wide characters, + call the Unicode version of the function and prepend "\\?\" to the path. + For more information, see Naming a File. + + Windows Me/98/95: This string must not exceed MAX_PATH characters. + + lpFindFileData + [out] Pointer to the WIN32_FIND_DATA structure that receives information about the found file or subdirectory. + + Return Values + If the function succeeds, + the return value is a search handle used in a subsequent call to FindNextFile or FindClose. + If the function fails, + the return value is INVALID_HANDLE_VALUE. + To get extended error information, call GetLastError. + + Remarks + The FindFirstFile function opens a search handle + and returns information about the first file whose name matches the specified pattern. + It searches both the long and short file names. + After the search handle has been established, + use the FindNextFile function to search for other files that match the same pattern. + When the search handle is no longer needed, close it by using the FindClose function. + + In rare cases, + file attribute information on NTFS file systems may not be current at the time you call this function. + To obtain the current NTFS file attributes, call GetFileInformationByHandle. + + This function searches for files by name only; + it cannot be used for attribute-based searches. + You cannot use root directories as the lpFileName input string for FindFirstFile, + with or without a trailing backslash. + To examine files in a root directory, + use something like "C:\*" and step through the directory with FindNextFile. + To get the attributes of a root directory, use GetFileAttributes. + Prepending the string "\\?\" does not allow access to the root directory. + + Similarly, on network shares, you can use an lpFileName of the form "\\server\service\*" + but you cannot use an lpFileName that points to the share itself, such as "\\server\service". + + To examine any directory other than a root directory, + use an appropriate path to that directory, with no trailing backslash. + For example, an argument of "C:\windows" will return information about the directory "C:\windows", + not about any directory or file in "C:\windows". + An attempt to open a search with a trailing backslash will always fail. + + trail [treil] 【L 「(배를) 끌다」의 뜻에서】 n. + 1 a 끌고 간 자국, 지나간 자국, 흔적; 선적(船跡), 항적(航跡) + the ~ of a slug 달팽이의 지나간 자국 + hot[hard] on the ~ (of ···) (···의) 바로 뒤에 + b 냄새 자국 ((짐승의)), 실마리, 단서 ((수사상의)) + 2 《미캐나다》 (황야 등의) 밟아 다져진 길, (산속의) 작은 길, 오솔길, 산길 + 3 꼬리 ((유성의)); 길게 늘어진 자락 ((구름연기 등의)); 긴 옷자락; 늘어진 술머리카락 ((등)); (사람차 등의) 줄, 열; (땅을) 기는 덩굴[가지]; 예망(曳網)(=~ net) + 4 【군사】 세워총(의 자세) + 5 (사고재해 등의) 결과, 여파, 후유증 + at the ~ 【군사】 세워총의 자세로 + blaze a ~ to ···을 개척하다, 창시하다(pioneer) + hit the ~ 《속어》 여행 떠나다; 가버리다, 떠나다 + off the ~ (짐승의) 냄새 자국을 잃고; 실마리를 잃고 + on the ~ (of) ···을 추적하여; 냄새 자국[실마리]을 찾아내어 + vt. + 1 끌다; <옷자락 등을> 질질 끌다, 끌며 가다; <그물 등을> 끌다 + ~ one's skirt 치마를 질질 끌다 + 《~+목+전+명》 ~ a toy cart by[on] a piece of string 장난감 수레를 끈으로 끌다 + 《~+목+부》 He ~ed along his wounded leg. 그는 다친 다리를 끌며 걸었다 + 2 <구름연기 등을> 길게 나부끼게 하다; <노를> 젓지 않고 놓아 두다 + 3 <사람동물 등을> 추적하다, 미행하다 + 《~+목+전+명》 ~ a person to his house 집까지 ···을 뒤쫓다 + 4 《미구어》 (경주 등에서) ···의 뒤를 달리다; <가축을> 뒤쫓다; (긴 열을 지어) 뒤에 붙어서 가다; (시합에서) 지고 있다 + 5 《미》 <풀 등을> 밟아 길을 내다 + 6 <이야기 등을> 질질 끌다; 길게 발음하다 + 7 【군사】 세워총을 하다 + T~ arms! 세워총! + ~ one's coat 일부러 반발을 유발하다; 싸움을 걸다 + vi. + 1 끌다; <옷자락 등이> 질질 끌리다, <머리카락 등이> 늘어지다 + 《~+전+명》 Her long bridal gown was ~ing on[over] the church floor. 그녀의 긴 신부 의상이 교회의 마루에 질질 끌리고 있었다 + 2 <덩굴이> 기다 + 《~+전+명》 Ivy ~s over the house. 담쟁이덩굴이 집에 기어 오르고 있다 + 3 <구름연기가> 길게 나부끼다 + 《~+전+명》 Smoke ~ed from the chimney. 연기가 굴뚝에서 길게 나부꼈다 + 4 발을 질질 끌며 걷다 ((along)), 힘없이[느릿느릿] 걷다, 낙오하다 + 5 <소리가> 점점 사라지다[약해지다] ((off, away)) + 《~+부》 《~+전+명》 Her voice ~ed off[wy] into silence. 그녀의 목소리는 서서히 사라져 갔다 + 6 <이야기 등이> 질질 계속되다 ((on)) + 7 마지막으로 도착하다 ((in)) + ~ on <싫은 시간행사 등이> 길어지다( vi. 6) + + BOOL RemoveDirectory(LPCTSTR lpPathName); + + Parameters + lpPathName + [in] Pointer to a null-terminated string that specifies the path of the directory to be removed. + The path must specify an empty directory, + and the calling process must have delete access to the directory. + In the ANSI version of this function, the name is limited to MAX_PATH characters. + To extend this limit to 32,767 wide characters, + call the Unicode version of the function and prepend "\\?\" to the path. + For more information, see Naming a File. + + Windows Me/98/95: This string must not exceed MAX_PATH characters. + + Return Values + If the function succeeds, the return value is nonzero. + If the function fails, the return value is zero. To get extended error information, call GetLastError. + + BOOL DeleteFile( LPCTSTR lpFileName ); + + Parameters + lpFileName + [in] Pointer to a null-terminated string that specifies the file to be deleted. + In the ANSI version of this function, the name is limited to MAX_PATH characters. + To extend this limit to 32,767 wide characters, + call the Unicode version of the function and prepend "\\?\" to the path. + For more information, see Naming a File. + + Windows Me/98/95: This string must not exceed MAX_PATH characters. + + Return Values + If the function succeeds, the return value is nonzero. + If the function fails, the return value is zero. + To get extended error information, call GetLastError. + + int _rmdir (const char *dirname ); + int _wrmdir (const wchar_t *dirname ); + + Parameters + dirname + Path of directory to be removed. + Return Value + Each of these functions returns 0 + if the directory is successfully deleted. + A return value of ?1 indicates an error, and errno is set to one of the following values: + + ENOTEMPTY + Given path is not a directory; directory is not empty; + or directory is either current working directory or root directory. + ENOENT + Path is invalid. + EACCESS + A program has an open handle to the directory. + + //////////////////////////////////////////////////////////////////////////////////////////////////////*/ + + + namespace ZNsInterface + { + + class ZCViewDir + { + private: + int mi_Depth; + private: + + void PrintDepth() + { + for(int i=1; i<=mi_Depth; ++i) ::printf(" "); + }/* + void PrintDepth()*/ + + /*private:*/ + public : + + ZCViewDir() + { + mi_Depth=0; + }/* + ZCViewDir()*/ + + ZNsMain::ZNsEnum::ZERun OnFile(ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData) + { + printf("◇ "); PrintDepth(); + printf("OnFile:APC_NowPath=\"%s\", File=\"%s\"\n", APC_NowPath, AR_CFileData.GetFileName()); + + return ZNsMain::ZNsEnum::ZERun_OK; + }/* + ZNsMain::ZNsEnum::ZERun OnFile(ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData)*/ + + ZNsMain::ZNsEnum::ZERun OnDir(ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData) + { + printf("◆ OnDir:Dir=\"%s\"\n", AR_CFileData.GetFileName()); return ZNsMain::ZNsEnum::ZERun_OK; + }/* + ZNsMain::ZNsEnum::ZERun OnDir(ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData)*/ + + + template ZNsMain::ZNsEnum::ZERun + OnFile(ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData, TTypeHelp AR_CTypeHelp) + { + printf("◇ "); PrintDepth(); + printf("OnFile:APC_NowPath=\"%s\", File=\"%s\"\n", APC_NowPath, AR_CFileData.GetFileName()); + + return ZNsMain::ZNsEnum::ZERun_OK; + }/* + template ZNsMain::ZNsEnum::ZERun + OnFile(ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData, TTypeHelp AR_CTypeHelp) */ + + template ZNsMain::ZNsEnum::ZERun + OnDir(ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData, TTypeHelp AR_CTypeHelp) + { + printf("◆ OnDir:Dir=\"%s\"\n", AR_CFileData.GetFileName()); return ZNsMain::ZNsEnum::ZERun_OK; + }/* + template ZNsMain::ZNsEnum::ZERun + OnDir(ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData, TTypeHelp AR_CTypeHelp) */ + + ZNsMain::ZNsEnum::ZERun OnIntoDir(ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData) + { + printf("▶ "); PrintDepth(); + printf("OnIntoDir:APC_NowPath=\"%s\", cFileName=\"%s\"\n", APC_NowPath, AR_CFileData.GetFileName()); + + ++mi_Depth; return ZNsMain::ZNsEnum::ZERun_OK; + }/* + ZNsMain::ZNsEnum::ZERun OnIntoDir(ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData)*/ + + ZNsMain::ZNsEnum::ZERun OnOutOfDir(ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData) + { + --mi_Depth; + + printf("◀ "); PrintDepth(); + printf("OnOutOfDir:APC_NowPath=\"%s\", cFileName=\"%s\"\n", APC_NowPath, AR_CFileData.GetFileName()); + + return ZNsMain::ZNsEnum::ZERun_OK; + }/* + ZNsMain::ZNsEnum::ZERun OnOutOfDir(ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData)*/ + + + template ZNsMain::ZNsEnum::ZERun OnIntoDir( + ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData, TTypeHelp AR_CTypeHelp ) + { + printf("▶ "); PrintDepth(); + printf("OnIntoDir:APC_NowPath=\"%s\", cFileName=\"%s\"\n", APC_NowPath,AR_CFileData.GetFileName()); + + ++mi_Depth; return ZNsMain::ZNsEnum::ZERun_OK; + }/* + template ZNsMain::ZNsEnum::ZERun OnIntoDir + (ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData, TTypeHelp AR_CTypeHelp) */ + + template ZNsMain::ZNsEnum::ZERun OnOutOfDir( + ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData, TTypeHelp AR_CTypeHelp) + { + --mi_Depth; + + printf("◀ "); PrintDepth(); + printf("OnOutOfDir:APC_NowPath=\"%s\", cFileName=\"%s\"\n", APC_NowPath, AR_CFileData.GetFileName()); + + return ZNsMain::ZNsEnum::ZERun_OK; + }/* + template ZNsMain::ZNsEnum::ZERun OnOutOfDir( + ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData, TTypeHelp AR_CTypeHelp) */ + + public: + };/* + class ZCViewDir*/ + + + class ZCViewDirOfFileList + { + public : + + template _NP_ ZNsMain::ZNsEnum::ZERun + OnFile(ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData, TFileDataListRef ARR_CFileDataList) + { + ARR_CFileDataList.push_back(AR_CFileData); return ZNsMain::ZNsEnum::ZERun_OK; + }/* + template _NP_ ZNsMain::ZNsEnum::ZERun + OnFile(ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData, TFileDataListRef ARR_CFileDataList) */ + + template _NP_ ZNsMain::ZNsEnum::ZERun + OnIntoDir(ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData, TFileDataListRef ARR_CFileDataList) + { + return ZNsMain::ZNsEnum::ZERun_OK; + }/* + template _NP_ ZNsMain::ZNsEnum::ZERun + OnIntoDir(ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData, TFileDataListRef ARR_CFileDataList) */ + + template _NP_ ZNsMain::ZNsEnum::ZERun + OnOutOfDir(ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData, TFileDataListRef ARR_CFileDataList) + { + return ZNsMain::ZNsEnum::ZERun_OK; + }/* + template _NP_ ZNsMain::ZNsEnum::ZERun + OnOutOfDir(ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData, TFileDataListRef ARR_CFileDataList) */ + + public: + };/* + class ZCViewDirOfFileList*/ + + + /*///////////////////////////////////////////////////////////////////////////// + + ■ class ZCViewFileOfDir 는 특정 디렉토리에서 첫번째 깊이의 디렉토리만 저장한다. + + -- 2012-10-21 16:53:00 + + /////////////////////////////////////////////////////////////////////////////*/ + + class ZCViewFileOfDir + { + public: + + template ZNsMain::ZNsEnum::ZERun + OnFile(ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData, TDirNameListRef ARR_CDirNameList) + { + return ZNsMain::ZNsEnum::ZERun_OK; + }/* + template ZNsMain::ZNsEnum::ZERun + OnFile(ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData, TDirNameListRef ARR_CDirNameList) */ + + template ZNsMain::ZNsEnum::ZERun OnDir( + ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData, TDirNameListRef ARR_CDirNameList) + { + typedef typename ZNsMain::ZtCTypeData + ::TypeData::TypeData CStringData; + + CStringData VO_CStringPath; VO_CStringPath(APC_NowPath) + (ZNsMain::ZNsConst::CPC_DirDelimiter)(AR_CFileData.GetFileName()); /////// + + ARR_CDirNameList.push_back(VO_CStringPath); return ZNsMain::ZNsEnum::ZERun_OK; + }/* + template ZNsMain::ZNsEnum::ZERun OnDir( + ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData, TDirNameListRef ARR_CDirNameList) */ + + public: + };/* + class ZCViewFileOfDir*/ + + + class ZCViewFileDataList + { + public: + + template _NP_ ZNsMain::ZNsEnum::ZERun + OnFile(ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData, TFileDataListRef ARR_CFileList) + { + ARR_CFileList.push_back(AR_CFileData); return ZNsMain::ZNsEnum::ZERun_OK; + }/* + template _NP_ ZNsMain::ZNsEnum::ZERun + OnFile(ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData, TFileDataListRef ARR_CFileList) */ + + template _NP_ ZNsMain::ZNsEnum::ZERun + OnDir(ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData, TFileDataListRef ARR_CFileList) + { + return ZNsMain::ZNsEnum::ZERun_OK; + }/* + template _NP_ ZNsMain::ZNsEnum::ZERun + OnDir(ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData, TFileDataListRef ARR_CFileList) */ + + public: + };/* + class ZCViewFileDataList*/ + + }/* + namespace ZNsInterface*/ + + + class ZCDir + { + public: + + + class ZCExceptDir : public ZCExceptBase + { + protected: + std::string mo_CStrFileName; + std::string mo_CStrMessage ; + public : + + ZCExceptDir(const char* AP_FileName, const char* AP_Message=0) + { + if(AP_FileName!=0) mo_CStrFileName=AP_FileName; + if(AP_Message !=0) mo_CStrMessage =AP_Message ; + }/* + ZCExceptDir(const char* AP_FileName, const char* AP_Message=0)*/ + + std::string& GetFileName(){return mo_CStrFileName;} + std::string& GetMessage (){return mo_CStrMessage ;} + + public: + };/* + class ZCExceptDir + + + public:*/ + public: + + + inline static bool DoExist(const char* AP_FileName, int AI_Mode=0) + { + /* AI_Mode 가 0 이면 파일의 존재를 조사하며, + 2 이면 읽기, 4면 쓰기, 6 이면 읽기 쓰기 모두 가능한지 조사한다. + 요청한 액세스 타입이 맞으면 0, 그렇지 않으면 -1 을 리턴. */ + + return ::access(AP_FileName, AI_Mode)==0 ; + }/* + inline static bool DoExist(const char* AP_FileName, int AI_Mode=0)*/ + + inline static bool DoExist(const wchar_t* AP_FileName, int AI_Mode=0) + { + /* AI_Mode 가 0 이면 파일의 존재를 조사하며, + 2 이면 읽기, 4면 쓰기, 6 이면 읽기 쓰기 모두 가능한지 조사한다. + 요청한 액세스 타입이 맞으면 0, 그렇지 않으면 -1 을 리턴. */ + + char VCA_TempBuf[_MAX_PATH2]; + + ::wcstombs( + VCA_TempBuf, AP_FileName, ZNsMain::ZftLength(AP_FileName)); + + return ::access(VCA_TempBuf,AI_Mode)==0 ; + }/* + inline static bool DoExist(const wchar_t* AP_FileName, int AI_Mode=0)*/ + + + template static const TTypChar* + GetExtName(const TTypChar* APC_FileName, ZTypLength AI_Length) + { + // 파일의 확장자를 가져온다. + + if(AI_Length<1) return 0; + + for(int VI_Index=AI_Length-1; VI_Index>=0; --VI_Index) + { + if(APC_FileName[VI_Index]=='.') return APC_FileName+VI_Index+1 ; + }/* + for(int VI_Index=AI_Length-1; VI_Index>=0; --VI_Index)*/ + + return 0; + }/* + template static const TTypChar* + GetExtName(const TTypChar* APC_FileName, ZTypLength AI_Length)*/ + + template static const TTypChar* GetExtName + ( + const TTypChar* APC_FileName, + ZTypLength AI_Length , + ZTypLength& ARRI_LenExt + ) + ///////////////////////////////////////////////////////////// + { + if(AI_Length<1) return 0; + + for(int VI_Index=AI_Length-1; VI_Index>=0; --VI_Index) + { + if(APC_FileName[VI_Index]=='.') + { + ARRI_LenExt=AI_Length-(VI_Index+1); return APC_FileName+VI_Index+1 ; + }/* + if(APC_FileName[VI_Index]=='.')*/ + }/* + for(int VI_Index=AI_Length-1; VI_Index>=0; --VI_Index)*/ + + ARRI_LenExt=0; return 0; + }/* + template static const TTypChar* GetExtName + ( + const TTypChar* APC_FileName, + ZTypLength AI_Length , + ZTypLength& ARRI_LenExt + ) + ///////////////////////////////////////////////////////////*/ + + template /////////////// + static TString& GetExtName + ( + const TTypChar* APC_FileName , + ZTypLength AI_Length , + TString& ARR_CStringExt + ) + ///////////////////////////////////////////////////////////// + { + if(AI_Length<1) return ARR_CStringExt; + + + int VI_Index=AI_Length-1; + + for(; VI_Index>=0; --VI_Index) + { + if(APC_FileName[VI_Index]=='.') break; + }/* + for(; VI_Index>=0; --VI_Index)*/ + + if(VI_Index<0) return ARR_CStringExt; + + return ARR_CStringExt( + APC_FileName+VI_Index+1, AI_Length-(VI_Index+1)); + }/* + template /////////////// + static TString& GetExtName + ( + const TTypChar* APC_FileName , + ZTypLength AI_Length , + TString& ARR_CStringExt + ) + ///////////////////////////////////////////////////////////*/ + + + template static bool SetExtName( + const TTypChar* APC_FileName, ZTypLength AI_FileLen , + const TTypChar* APC_FileExt , ZTypLength AI_ExtLength, + TString& ARR_CStringFileNew + /*#########*/ ) /*#################################################*/ + { + // APC_FileName 의 확장자를 APC_FileExt 으로 바꾼 + // 새로운 파일명을 ARR_CStringFileNew 에 전달한다. + + ZTypLength VL_ExtPos=ZCMainChars::FindPosFromEnd( + APC_FileName, ".", + AI_FileLen ,(ZTypLength)1 + /*/////////*/ ); //////////////////////////////// + + if(VL_ExtPos<0 || VL_ExtPos==AI_FileLen-1) + { + ARR_CStringFileNew.append(APC_FileName, AI_FileLen); return false; + } + else if(VL_ExtPos==0) + { + ARR_CStringFileNew+="."; + ARR_CStringFileNew.append(APC_FileExt, AI_ExtLength); + + return true; + }/* + else if(VL_ExtPos==0)*/ + + ARR_CStringFileNew.append(APC_FileName, VL_ExtPos ); + ARR_CStringFileNew+="."; + ARR_CStringFileNew.append(APC_FileExt , AI_ExtLength); + + return true; + }/* + template static bool SetExtName( + const TTypChar* APC_FileName, ZTypLength AI_FileLen , + const TTypChar* APC_FileExt , ZTypLength AI_ExtLength, + TString& ARR_CStringFileNew + ############# ) ###################################################*/ + + + template static bool SetExtName( + const TString& AR_CStringFileNow, const TString& AR_CStringNewExt, TString& ARR_CStringFileNew) + { + return SetExtName( ///////////////////////////// + AR_CStringFileNow.c_str(), + AR_CStringFileNow.size() , + AR_CStringNewExt.c_str() , + AR_CStringNewExt.size() , + RR(ARR_CStringFileNew) + /*//////////*/ ); ////////////////////////////// + }/* + template static bool SetExtName( + const TString& AR_CStringFileNow, const TString& AR_CStringNewExt, TString& ARR_CStringFileNew) */ + + + template static bool SetFileName + ( + const TTypChar* APC_FileNow, ZTypLength AI_FileNowLen, + const TTypChar* APC_FileNew, ZTypLength AI_FileNewLen, + TString& ARR_CStringFileNew + ) + ///////////////////////////////////////////////////////////////////// + { + /* 파일 APC_FileNow 의 확장자를 뺀 부분을 APC_FileNew 으로 바꾼, + 새로운 파일명을 ARR_CStringFileNew 에 전달한다. */ + + ZTypLength VL_ExtPos=ZCMainChars::FindPos( ///////// + APC_FileNow ,".", + AI_FileNowLen,1 + /*/////////*/ ); ////////////////////////////////// + + if(VL_ExtPos<0) + { ARR_CStringFileNew.append(APC_FileNew, AI_FileNewLen); return false; } + else if(VL_ExtPos==0) + { ARR_CStringFileNew.append(APC_FileNow, AI_FileNowLen); return true ; } + /*else if(VL_ExtPos==0)*/ + + ARR_CStringFileNew.append(APC_FileNew, AI_FileNewLen); + ARR_CStringFileNew+="."; + + if(VL_ExtPos static bool SetFileName + ( + const TTypChar* APC_FileNow, ZTypLength AI_FileNowLen, + const TTypChar* APC_FileNew, ZTypLength AI_FileNewLen, + TString& ARR_CStringFileNew + ) + ///////////////////////////////////////////////////////////////////*/ + + + template static bool SetFileName( + const TString& AR_CStringFileNow, const TString& AR_CStringNewExt, TString& ARR_CStringFileNew) + { + return SetFileName( /////////////////////////// + AR_CStringFileNow.data(), + AR_CStringFileNow.size(), + AR_CStringNewExt .data(), + AR_CStringNewExt .size(), + RR(ARR_CStringFileNew) + /*//////////*/ ); ///////////////////////////// + }/* + template static bool SetFileName( + const TString& AR_CStringFileNow, const TString& AR_CStringNewExt, TString& ARR_CStringFileNew) */ + + + template static const TTypChar* GetFileNameInPath + ( + const TTypChar* APC_PathName, + ZTypLength AI_Length , + ZTypLength& ARRI_FileName + ) + //////////////////////////////////////////////////////////////////// + { + // 디렉토리명을 포함한 파일명 APC_PathName 에서 파일명 부분만 추출한다. + + if(AI_Length<1) return 0; + + using namespace ZNsMain::ZNsChars ; + using ZNsMain::ZNsConst::CPC_DirDelimiter ; + + ZTypLength VL_FindPos=ZtCMainChars::FindPosFromEnd + ( APC_PathName, CPC_DirDelimiter, AI_Length, 1 ) ; + + if(VL_FindPos<0) + { + ARRI_FileName=AI_Length; return APC_PathName; + } + ARRI_FileName=AI_Length-(VL_FindPos+1); + + return APC_PathName+VL_FindPos+1; + }/* + template + static const TTypChar* GetFileNameInPath /////////////////////// + ( + const TTypChar* APC_PathName, + ZTypLength AI_Length , + ZTypLength& ARRI_FileName + ) + //////////////////////////////////////////////////////////////////*/ + + template + static TString& GetFileNameInPath + (const TTypChar* APC_PathName, ZTypLength AI_Length, TString& ARR_FileNameCStr) + { + ZTypLength VL_Length= 0 ; + const char* VPC_File = GetFileNameInPath + ( APC_PathName, AI_Length, RR(VL_Length) ); + + if(VL_Length>0) + ARR_FileNameCStr(VPC_File, VL_Length); + + return ARR_FileNameCStr; + }/* + template + static TString& GetFileNameInPath + (const TTypChar* APC_PathName, ZTypLength AI_Length, TString& ARR_FileNameCStr)*/ + + template + static TString& GetFileNameInPath(const TChars& AR_PathName, TString& ARR_FileNameCStr) + { + return GetFileNameInPath(AR_PathName.data(), AR_PathName.size(), RR(ARR_FileNameCStr)); + }/* + template + static TString& GetFileNameInPath(const TChars& AR_PathName, TString& ARR_FileNameCStr) */ + + + static bool RmAnyDir /*###############################################################*/ + ( ZTypCPCh AP_DirName, void (*APF_ExceptHandle) + ( + ZTypCPCh AP_FileName, ZCFileData& AR_CFileData, ZTypCPCCh AP_Message + ) + ) + /*####################################################################################*/ + { + #if defined(_WIN) + + ZTypChar VCA_Search[_MAX_PATH2+1]={_T('0')}; + + ::strcpy(VCA_Search, AP_DirName ); + ::strcat(VCA_Search, "\\*.*" ); + + BOOL VB_IsSearched=TRUE ; + bool VB_RemoveFail=false; + + ZCFileData VO_CFileData ; HANDLE VH_File = + ::FindFirstFileA( VCA_Search, &VO_CFileData ) ; + + if(VH_File==INVALID_HANDLE_VALUE){ return false; } + + do ////// + { + // If the attribute of the file is FILE_ATTRIBUTE_READONLY, + // change the file attribute to FILE_ATTRIBUTE_NORNAL + + if( ::strcmp("." , VO_CFileData.cFileName)==0 || + ::strcmp("..", VO_CFileData.cFileName)==0 ) + { + continue; + } + /* + if( ::strcmp("." , VO_CFileData.cFileName)==0 || + ::strcmp("..", VO_CFileData.cFileName)==0 ) + */ + + strcpy(VCA_Search, AP_DirName); + strcat(VCA_Search, "\\" ); + strcat(VCA_Search, VO_CFileData.cFileName); + + if(VO_CFileData.dwFileAttributes & FILE_ATTRIBUTE_READONLY) + { ::SetFileAttributesA(VCA_Search, FILE_ATTRIBUTE_NORMAL); } + + if(VO_CFileData.IsDir()) // VO_CFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + if(RmAnyDir(VCA_Search, APF_ExceptHandle)==false) + { + APF_ExceptHandle( + VCA_Search, VO_CFileData, "RmAnyDir() return false"); + + VB_RemoveFail=true; break; + }/* + if(RmAnyDir(VCA_Search,APF_ExceptHandle)==false)*/ + } + else if(::DeleteFileA(VCA_Search)==FALSE) + { + APF_ExceptHandle( + VCA_Search, VO_CFileData, "DeleteFile() return false"); + + VB_RemoveFail=true; break; + }/* + else if(::DeleteFileA(VCA_Search)==FALSE)*/ + + VB_RemoveFail=false; + } + while(VB_IsSearched = ::FindNextFileA(VH_File, &VO_CFileData)); + + ::FindClose(VH_File); + + if(VB_RemoveFail==true) + { + return false; + } + if(::RemoveDirectoryA(AP_DirName)==FALSE) + { + if(APF_ExceptHandle!=0) + APF_ExceptHandle(AP_DirName, VO_CFileData, "Fail to RemoveDirectory"); + + return false; + } + else + { + return true; + }/* + else*/ + + #elif defined(_REENTRANT) // && !defined(_WIN) + + ZCFileData VO_CFileData; + dirent VO_DirEnt ; + dirent* VP_DirEnt=0 ; + TypeDirID VH_File = ::opendir(AP_DirName); + bool VB_RemoveFail= false ; + + if(VH_File==NULL) + { return false; } + + ::chdir(AP_DirName); + + /*////////////////////////////////////////////////////////////////// + + ■ In dirent.h + + #ifndef __USE_FILE_OFFSET64 + extern struct dirent *readdir (DIR *__dirp) __nonnull ((1)); + #else + # ifdef __REDIRECT + extern struct dirent *__REDIRECT (readdir, (DIR *__dirp), readdir64) + __nonnull ((1)); + # else + # define readdir readdir64 + # endif + #endif + + -- 2009-12-21 23:41:00 + + ■ 아래는 naver 에서 Visual C++ __REDIRECT 로 검색한 것. + + Visual C++의 __REDIRECT 매크로는 특정 함수 호출을 다른 함수로 리디렉션 + (재지정)하는 역할을 하며, 주로 Windows API에서 사용됩니다. 이 매크로는 + 함수 포인터를 통해 원래 함수의 동작을 다른 함수로 대체할 수 있도록 해 + 줍니다. + + __REDIRECT의 주요 특징 + + 함수 리디렉션: __REDIRECT는 호출되는 함수를 다른 함수로 변경할 수 있도 + 록 하여, 디버그/릴리즈 모드나 특정 플랫폼에서의 동작을 제어할 수 있습니 + 다. + + Windows API 호환성: 주로 Windows API에서 사용되며, 함수 포인터를 통해 + 원본 함수의 인자 변환 규칙을 유지하면서 다른 함수로 연결할 수 있습니다. + + 컴파일러 옵션: Visual C++ 컴파일러의 특정 옵션을 통해 정의되며, 함수의 + 반환 타입과 인자 변환 규칙을 지정할 수 있습니다. + + 사용 예시 및 유의점 + 디버그/릴리즈 모드 차이: __REDIRECT는 컴파일러 옵션에 따라 동작 방식이 + 달라질 수 있으므로, 개발 환경에 맞는 설정이 필요합니다. + + 호환성: 오래된 Windows 버전이나 타겟 플랫폼에서는 지원되지 않을 수 있 + 으니, 사용 전 호환성을 반드시 확인해야 합니다. + + __REDIRECT는 Windows API 개발에서 함수 우회, 디버그/릴리즈 모드 최적화 + 등에 널리 활용되는 매크로입니다 + + -- 2025-08-15 14:27 + + //////////////////////////////////////////////////////////////////*/ + + while(::readdir_r(VH_File, &VO_DirEnt, &VP_DirEnt)==0 && VP_DirEnt!=0) + { + const bool CB_IsNotValid = //////////////////// + ( + ::strcmp(".", VP_DirEnt->d_name)==0 || + ::strcmp("..", VP_DirEnt->d_name)==0 || + VO_DirEnt.d_ino==0 + ); + /////////////////////////////////////////////// + + if(CB_IsNotValid) continue; + + if(::lstat(VP_DirEnt->d_name, &VO_CFileData)<0) + { + APF_ExceptHandle( + VP_DirEnt->d_name, VO_CFileData, "lstat Error"); + + VB_RemoveFail=true; break; + }/* + if(::lstat(VP_DirEnt->d_name, &VO_CFileData)<0)*/ + + if(VO_CFileData.IsDir()) // S_ISDIR(VO_CFileData.st_mode)) + { + if(RmAnyDir(VP_DirEnt->d_name, APF_ExceptHandle)==false) + { + APF_ExceptHandle( + VP_DirEnt->d_name, VO_CFileData, "RmAnyDir() return false"); + + VB_RemoveFail=true; break; + }/* + if(RmAnyDir(VP_DirEnt->d_name, APF_ExceptHandle)==false)*/ + } + else + { + if(::unlink(VP_DirEnt->d_name)!=0) + { + APF_ExceptHandle( + VP_DirEnt->d_name, VO_CFileData, "DeleteFile() return false"); + + VB_RemoveFail=true; break; + }/* + if(::unlink(VP_DirEnt->d_name)!=0)*/ + }/* + else*/ + + VB_RemoveFail=false; + }/* + while(::readdir_r(VH_File, &VO_DirEnt, &VP_DirEnt)==0 && VP_DirEnt!=0)*/ + + ::chdir(".."); ::closedir(VH_File); + + if(VB_RemoveFail==true) return false; + + ::rmdir(AP_DirName); return true; + + //#elif defined(_REENTRANT) // && !defined(_WIN) + #else // !defined(_WIN) && !defined(_REENTRANT) + + ZCFileData VO_CFileData; + dirent* VP_DirEnt ; + TypeDirID VH_File = ::opendir(AP_DirName) ; + bool VB_RemoveFail= false ; + + if(VH_File==NULL) return false; + + ::chdir(AP_DirName); + + /*////////////////////////////////////////////////////////////////// + + ■ In dirent.h + + #ifndef __USE_FILE_OFFSET64 + extern struct dirent *readdir (DIR *__dirp) __nonnull ((1)); + #else + # ifdef __REDIRECT + extern struct dirent *__REDIRECT (readdir, (DIR *__dirp), readdir64) + __nonnull ((1)); + # else + # define readdir readdir64 + # endif + #endif + + -- 2009-12-21 23:41:00 + + //////////////////////////////////////////////////////////////////*/ + + while(VP_DirEnt = ::readdir(VH_File)) + { + const bool CB_IsNotValid = //////////////////// + ( + ::strcmp(".", VP_DirEnt->d_name)==0 || + ::strcmp("..", VP_DirEnt->d_name)==0 || + VP_DirEnt->d_ino==0 + ); + /////////////////////////////////////////////// + + if(CB_IsNotValid) continue; + + if(lstat(VP_DirEnt->d_name, &VO_CFileData)<0) + { + APF_ExceptHandle(VP_DirEnt->d_name, VO_CFileData, "lstat Error"); + + VB_RemoveFail=true; break; /*##################################*/ + }/* + if(lstat(VP_DirEnt->d_name, &VO_CFileData)<0)*/ + + if(VO_CFileData.IsDir()) // S_ISDIR(VO_CFileData.st_mode)) + { + if(RmAnyDir(VP_DirEnt->d_name, APF_ExceptHandle)==false) + { + APF_ExceptHandle(VP_DirEnt->d_name, VO_CFileData, "RmAnyDir return false"); + + VB_RemoveFail=true; break; /*############################################*/ + }/* + if(RmAnyDir(VP_DirEnt->d_name, APF_ExceptHandle)==false)*/ + } + else + { + ::unlink(VP_DirEnt->d_name); + }/* + else*/ + + VB_RemoveFail=false; + }/* + while(VP_DirEnt = ::readdir(VH_File))*/ + + ::chdir(".."); ::closedir(VH_File); + + if(VB_RemoveFail==true) return false; + + ::rmdir(AP_DirName); return true; + + #endif //!defined(_WIN) && !defined(_REENTRANT) + }/* + static bool RmAnyDir ################################################################@# + ( + ZTypCPCh AP_DirName , + void (*APF_ExceptHandle) + (ZTypCPCh AP_FileName, ZCFileData& AR_CFileData, ZTypCPCCh AP_Message) + ) + ######################################################################################*/ + + /*////////////////////////////////////////////////////////////////////////////////////// + + ■ int _mkdir (const char *dirname); + int _wmkdir (const wchar_t *dirname); + + Parameter + dirname + Path for new directory. + Return Value + Each of these functions returns the value 0 if the new directory was created. On an error the function returns ?1 and sets errno as follows: + + EEXIST + Directory was not created because dirname is the name of an existing file, directory, or device. + ENOENT + Path was not found. + + int _rmdir (const char *dirname ); + int _wrmdir (const wchar_t *dirname ); + Parameters + dirname + Path of directory to be removed. + Return Value + Each of these functions returns 0 if the directory is successfully deleted. A return value of ?1 indicates an error, and errno is set to one of the following values: + + ENOTEMPTY + Given path is not a directory; directory is not empty; or directory is either current working directory or root directory. + ENOENT + Path is invalid. + EACCESS + A program has an open handle to the directory. + See _doserrno, errno, _sys_errlist, and _sys_nerr for more information on these and other return codes. + + int _unlink( const char *filename ); + int _wunlink( const wchar_t *filename ); + + Routine Required Header Compatibility + _unlink and Win 95, Win NT + _wunlink or Win NT + + For additional compatibility information, + see Compatibility in the Introduction. + + Libraries + + LIBC.LIB Single thread static library, retail version + LIBCMT.LIB Multithread static library, retail version + MSVCRT.LIB Import library for MSVCRT.DLL, retail version + + Return Value + + Each of these functions returns 0 if successful. + Otherwise, the function returns ?1 and sets errno to EACCES, + which means the path specifies a read-only file, or to ENOENT, + which means the file or path is not found or the path specified a directory. + + //////////////////////////////////////////////////////////////////////////////////////*/ + + + // APC_DirPath 는 디렉토리 구분자로 끝나지 않게 하자. + + static ZNsMain::ZNsEnum::ZERun IterDirectory + ( + ZTypCPCh APC_DirPath, void* APC_VoidKey, + ZNsMain::ZNsEnum::ZERun (*APF_EachFile)(ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData, void* APC_VoidKey), + ZNsMain::ZNsEnum::ZERun (*APF_IntoDir )(ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData, void* APC_VoidKey)=0, + ZNsMain::ZNsEnum::ZERun (*APF_OutOfDir)(ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData, void* APC_VoidKey)=0 + ) + //////////////////////////////////////////// + { + ZNsMain::ZNsEnum::ZERun VE_ERun=ZNsMain::ZNsEnum::ZERun_OK; + + #if defined(_WIN) + + ZTypChar VCA_Search[_MAX_PATH2+1]={'0'}; + ::strcpy(VCA_Search, APC_DirPath); + ::strcat(VCA_Search, "\\*.*" ); + + ZCFileData VO_CFileData ; + BOOL VB_IsSearched= TRUE ; + HANDLE VH_File = + ::FindFirstFileA(VCA_Search, &VO_CFileData); + + if(VH_File==INVALID_HANDLE_VALUE) return ZNsMain::ZNsEnum::ZERun_OK; + + + while(VB_IsSearched) + { + if( VO_CFileData.IsDir() ) // VO_CFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + const bool CB_IsTrue = + ( + ::strcmp("." , VO_CFileData.cFileName)!=0 && + ::strcmp("..", VO_CFileData.cFileName)!=0 + ) ; + ////////////////////// + + if(CB_IsTrue) + { + ::strcpy(VCA_Search, APC_DirPath); + ::strcat(VCA_Search, "\\" ); + ::strcat(VCA_Search, VO_CFileData.cFileName); + + // VCA_Search is a directory name + + if(APF_IntoDir!=0) + { + if(APF_IntoDir(VCA_Search, VO_CFileData, APC_VoidKey)==ZNsMain::ZNsEnum::ZERun_NO) + { + VE_ERun=ZNsMain::ZNsEnum::ZERun_NO; break; + }/* + if(APF_IntoDir(VCA_Search, VO_CFileData, APC_VoidKey)==ZNsMain::ZNsEnum::ZERun_NO)*/ + }/* + if(APF_IntoDir!=0)*/ + + if(IterDirectory(VCA_Search, APC_VoidKey, APF_EachFile, APF_IntoDir, APF_OutOfDir)==ZNsMain::ZNsEnum::ZERun_NO) + { + VE_ERun=ZNsMain::ZNsEnum::ZERun_NO; break; + }/* + if(IterDirectory(VCA_Search, APC_VoidKey, APF_EachFile, APF_IntoDir, APF_OutOfDir)==ZNsMain::ZNsEnum::ZERun_NO)*/ + + if(APF_OutOfDir!=0) + { + if(APF_OutOfDir(VCA_Search, VO_CFileData, APC_VoidKey)==ZNsMain::ZNsEnum::ZERun_NO) + { + VE_ERun=ZNsMain::ZNsEnum::ZERun_NO; break; + }/* + if(APF_OutOfDir(VCA_Search, VO_CFileData, APC_VoidKey)==ZNsMain::ZNsEnum::ZERun_NO)*/ + }/* + if(APF_OutOfDir!=0)*/ + }/* + if(CB_IsTrue)*/ + } + else // !VO_CFileData.IsDir() + { + if(APF_EachFile(APC_DirPath, VO_CFileData, APC_VoidKey)==ZNsMain::ZNsEnum::ZERun_NO) + { + VE_ERun=ZNsMain::ZNsEnum::ZERun_NO; break; + }/* + if(APF_EachFile(APC_DirPath, VO_CFileData, APC_VoidKey)==ZNsMain::ZNsEnum::ZERun_NO)*/ + }/* + else // !VO_CFileData.IsDir()*/ + + VB_IsSearched = ::FindNextFileA(VH_File, &VO_CFileData); + }/* + while(VB_IsSearched)*/ + + ::FindClose(VH_File); + + #else //!defined(_WIN) + + ZCFileData VO_CFileData; + #ifdef _REENTRANT + dirent VO_DirEnt; + #endif + dirent* VP_DirEnt; + TypeDirID VH_File = ::opendir(APC_DirPath); + char VCA_Search[_MAX_PATH2+1]={'0'} ; + + if(VH_File==NULL) + return ZNsMain::ZNsEnum::ZERun_OK; + + #ifdef _REENTRANT + while(::readdir_r(VH_File, &VO_DirEnt, &VP_DirEnt)==0 && VP_DirEnt!=0) + #else + while(VP_DirEnt = ::readdir(VH_File)) + #endif + { + const bool CB_IsNotValid = + ( + ::strcmp(".", VP_DirEnt->d_name)==0 || + ::strcmp("..", VP_DirEnt->d_name)==0 + ); + ////////////////////////// + + if(CB_IsNotValid) continue; + + ::strcpy(VCA_Search, APC_DirPath); + + if(::strcmp(APC_DirPath, "/")!=0) + { ::strcat(VCA_Search, "/"); } // Not to append "/" at the tail of root directory name + + ::strcat(VCA_Search , VP_DirEnt->d_name); + ::strcpy(VO_CFileData.cFileName, VP_DirEnt->d_name); + + if(::lstat(VCA_Search,&VO_CFileData)<0) + { + throw ZCExceptDir + ( + VP_DirEnt->d_name, "Fatal Error In " + "ZCDir::IterDirectory() : Can't know the file info" + ); + ///////////////// + + return ZNsMain::ZNsEnum::ZERun_NO; + }/* + if(::lstat(VCA_Search,&VO_CFileData)<0)*/ + + if(VO_CFileData.IsDir()) // S_ISDIR(VO_CFileData.st_mode)) + { + if(APF_IntoDir!=0) + { + if(APF_IntoDir(VCA_Search, VO_CFileData, APC_VoidKey)==ZNsMain::ZNsEnum::ZERun_NO) + { + VE_ERun=ZNsMain::ZNsEnum::ZERun_NO; break; + }/* + if(APF_IntoDir(VCA_Search, VO_CFileData, APC_VoidKey)==ZNsMain::ZNsEnum::ZERun_NO)*/ + }/* + if(APF_IntoDir!=0)*/ + + if(IterDirectory(VCA_Search, APC_VoidKey, APF_EachFile, APF_IntoDir, APF_OutOfDir)==ZNsMain::ZNsEnum::ZERun_NO) + { + VE_ERun=ZNsMain::ZNsEnum::ZERun_NO; break; + }/* + if(IterDirectory(VCA_Search, APC_VoidKey, APF_EachFile, APF_IntoDir, APF_OutOfDir)==ZNsMain::ZNsEnum::ZERun_NO)*/ + + if(APF_OutOfDir!=0) + { + if(APF_OutOfDir(VCA_Search,VO_CFileData, APC_VoidKey)==ZNsMain::ZNsEnum::ZERun_NO) + { + VE_ERun=ZNsMain::ZNsEnum::ZERun_NO; break; + }/* + if(APF_OutOfDir(VCA_Search,VO_CFileData, APC_VoidKey)==ZNsMain::ZNsEnum::ZERun_NO)*/ + }/* + if(APF_OutOfDir!=0)*/ + } + else // !VO_CFileData.IsDir() + { + if(APF_EachFile(APC_DirPath, VO_CFileData, APC_VoidKey)==ZNsMain::ZNsEnum::ZERun_NO) + { + VE_ERun=ZNsMain::ZNsEnum::ZERun_NO; break; + }/* + if(APF_EachFile(APC_DirPath, VO_CFileData, APC_VoidKey)==ZNsMain::ZNsEnum::ZERun_NO)*/ + }/* + else // !VO_CFileData.IsDir()*/ + }/* + while(VP_DirEnt = ::readdir(VH_File))*/ + + ::closedir(VH_File); + + #endif //!defined(_WIN) + + return VE_ERun; + }/* + static ZNsMain::ZNsEnum::ZERun IterDirectory + ( + ZTypCPCh APC_DirPath, void* APC_VoidKey, + ZNsMain::ZNsEnum::ZERun (*APF_EachFile)(ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData, void* APC_VoidKey), + ZNsMain::ZNsEnum::ZERun (*APF_IntoDir )(ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData, void* APC_VoidKey)=0, + ZNsMain::ZNsEnum::ZERun (*APF_OutOfDir)(ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData, void* APC_VoidKey)=0 + ) + //////////////////////////////////////////*/ + + + /*///////////////////////////////////////////////////////////////////// + + ■ AR_CViewDir 는 ZNsMain::ZNsEnum::ZERun 을 리턴하는 아래 3 벰버를 가져야 한다. + AR_CViewDir.OnFile (ZTypCPCh APC_NowPath,ZCFileData& AR_CFileData) + AR_CViewDir.OnIntoDir (ZTypCPCh APC_NowPath,ZCFileData& AR_CFileData) + AR_CViewDir.OnOutOfDir(ZTypCPCh APC_NowPath,ZCFileData& AR_CFileData) + + TViewDir 은 ZNsMain::ZNsIFace::ZCViewDir 형. + + ■ APC_DirPath 는 디렉토리 구분자로 끝나지 않게 하자. + + ■ IterDirEx(~) 함수가 디렉토리와 파일을 찾아내는 Logic 을 담당한다면 + TViewDir 은 찾아낸 데이타에 대한 일종의 View 를 담당한다. + + ■ 예제 -- 2025-08-11 10:19 + + #include + #include "ZCppMain/ZMainHeadEx.H" + + int main() + { + ZNsMain::ZNsIFace::ZCViewDir VO_CViewDir; + ZNsMain::ZCDir::IterDirEx("..", VO_CViewDir); + + return 0; + } + + /////////////////////////////////////////////////////////////////////*/ + + template static ZNsMain::ZNsEnum::ZERun + IterDirEx(ZTypCPCh APC_DirPath, TViewDir AR_CViewDir) + { + typedef typename ZNsMain:: + ZtCTypeData::TypeData TypeViewDir ; + + TypeViewDir& VR_CViewDir = ZNsMain:: + ZtCTypeData::GetObjRef(AR_CViewDir); + + + ZNsMain::ZNsEnum::ZERun VE_ERun=ZNsMain::ZNsEnum::ZERun_OK; + + #if defined(_WIN) + + ZTypChar VCA_Search[_MAX_PATH2+1]={'0'}; + ::strcpy(VCA_Search, APC_DirPath); + ::strcat(VCA_Search, "\\*.*" ); + + ZCFileData VO_CFileData ; + BOOL VB_IsSearched= TRUE ; + HANDLE VH_File = + ::FindFirstFileA(VCA_Search, &VO_CFileData); + + if(VH_File==INVALID_HANDLE_VALUE) + { return ZNsMain::ZNsEnum::ZERun_OK; } + + while(VB_IsSearched) + { + if( VO_CFileData.IsDir() ) // VO_CFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + const bool CB_IsTrue = + ( + ::strcmp("." , VO_CFileData.cFileName)!=0 && + ::strcmp("..", VO_CFileData.cFileName)!=0 + ); + ////////////////////// + + if(CB_IsTrue) + { + strcpy(VCA_Search, APC_DirPath); + strcat(VCA_Search, "\\" ); + strcat(VCA_Search, VO_CFileData.cFileName); + + // VCA_Search is a directory name + + if(VR_CViewDir.OnIntoDir (VCA_Search, VO_CFileData)==ZNsMain::ZNsEnum::ZERun_NO) + { + VE_ERun=ZNsMain::ZNsEnum::ZERun_NO; break; + } + if(IterDirEx (VCA_Search, AR_CViewDir )==ZNsMain::ZNsEnum::ZERun_NO) + { + VE_ERun=ZNsMain::ZNsEnum::ZERun_NO; break; + } + if(VR_CViewDir.OnOutOfDir(VCA_Search, VO_CFileData)==ZNsMain::ZNsEnum::ZERun_NO) + { + VE_ERun=ZNsMain::ZNsEnum::ZERun_NO; break; + }/* + if(VR_CViewDir.OnOutOfDir(VCA_Search, VO_CFileData)==ZNsMain::ZNsEnum::ZERun_NO)*/ + }/* + if(CB_IsTrue)*/ + } + else + { + if(VR_CViewDir.OnFile(APC_DirPath, VO_CFileData)==ZNsMain::ZNsEnum::ZERun_NO) + { + VE_ERun=ZNsMain::ZNsEnum::ZERun_NO; break; + }/* + if(VR_CViewDir.OnFile(APC_DirPath, VO_CFileData)==ZNsMain::ZNsEnum::ZERun_NO)*/ + }/* + else*/ + + VB_IsSearched=::FindNextFile(VH_File, &VO_CFileData); + }/* + while(VB_IsSearched)*/ + + ::FindClose(VH_File); + + #else //!defined(_WIN) + + ZCFileData VO_CFileData; + #ifdef _REENTRANT + dirent VO_DirEnt; + #endif + dirent* VP_DirEnt; + TypeDirID VH_File = ::opendir(APC_DirPath); + char VCA_Search[_MAX_PATH2+1]={'0'} ; + + if(VH_File==NULL) + return ZNsMain::ZNsEnum::ZERun_OK; + + #ifdef _REENTRANT + while(::readdir_r(VH_File, &VO_DirEnt, &VP_DirEnt)==0 && VP_DirEnt!=0) + #else + while(VP_DirEnt=::readdir(VH_File)) + #endif + { + const bool CB_IsNotValid=( + ::strcmp(".", VP_DirEnt->d_name)==0 || + ::strcmp("..", VP_DirEnt->d_name)==0 + /*//////////*/ ); + + if(CB_IsNotValid) continue; + + ::strcpy(VCA_Search, APC_DirPath); + + if(::strcmp(APC_DirPath, "/")!=0) + { ::strcat(VCA_Search, "/"); } // Not to append "/" at the tail of root directory name + + ::strcat(VCA_Search , VP_DirEnt->d_name); + ::strcpy(VO_CFileData.cFileName, VP_DirEnt->d_name); + + if(::lstat(VCA_Search,&VO_CFileData)<0) + { + throw ZCExceptDir + ( + VP_DirEnt->d_name, "Fatal Error In " + "ZCDir::IterDirEx() : Can't know the file info" + ); + ///////////////// + + return ZNsMain::ZNsEnum::ZERun_NO; + }/* + if(::lstat(VCA_Search,&VO_CFileData)<0)*/ + + if(VO_CFileData.IsDir()) // S_ISDIR(VO_CFileData.st_mode)) + { + if(VR_CViewDir.OnIntoDir (VCA_Search, VO_CFileData)==ZNsMain::ZNsEnum::ZERun_NO) + { + VE_ERun=ZNsMain::ZNsEnum::ZERun_NO; break; + } + if(IterDirEx (VCA_Search, AR_CViewDir )==ZNsMain::ZNsEnum::ZERun_NO) + { + VE_ERun=ZNsMain::ZNsEnum::ZERun_NO; break; + } + if(VR_CViewDir.OnOutOfDir(VCA_Search, VO_CFileData)==ZNsMain::ZNsEnum::ZERun_NO) + { + VE_ERun=ZNsMain::ZNsEnum::ZERun_NO; break; + }/* + if(VR_CViewDir.OnOutOfDir(VCA_Search, VO_CFileData)==ZNsMain::ZNsEnum::ZERun_NO)*/ + } + else + { + if(VR_CViewDir.OnFile(APC_DirPath, VO_CFileData)==ZNsMain::ZNsEnum::ZERun_NO) + { + VE_ERun=ZNsMain::ZNsEnum::ZERun_NO; break; + }/* + if(VR_CViewDir.OnFile(APC_DirPath, VO_CFileData)==ZNsMain::ZNsEnum::ZERun_NO)*/ + }/* + else*/ + }/* + while(VP_DirEnt=::readdir(VH_File))*/ + + ::closedir(VH_File); + + #endif //!defined(_WIN) + + return VE_ERun; + }/* + template static ZNsMain::ZNsEnum::ZERun + IterDirEx(ZTypCPCh APC_DirPath, TViewDir AR_CViewDir) */ + + /*////////////////////////////////////////////////////////////////////////////////////////////////////// + + ■ AR_CViewDir 는 ZNsMain::ZNsEnum::ZERun 을 리턴하는 아래 3 벰버를 가져야 한다. + + AR_CViewDir.OnFile (ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData, TTypeHelp AR_CTypeHelp) + AR_CViewDir.OnIntoDir (ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData, TTypeHelp AR_CTypeHelp) + AR_CViewDir.OnOutOfDir(ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData, TTypeHelp AR_CTypeHelp) + + -- 2012-05-23 02:24:00 + + //////////////////////////////////////////////////////////////////////////////////////////////////////*/ + + template + static ZNsMain::ZNsEnum::ZERun IterDirEx( + ZTypCPCh APC_DirPath, TViewDir AR_CViewDir, TTypeHelp AR_CTypeHelp) + { + using ZNsMain::ZNsEnum::ZERun ; + using ZNsMain::ZNsEnum::ZERun_OK; + using ZNsMain::ZNsEnum::ZERun_NO; + + typedef typename ZNsMain:: + ZtCTypeData::TypeData TypeViewDir ; + + TypeViewDir& VR_CViewDir = ZNsMain:: + ZtCTypeData::GetObjRef(AR_CViewDir); + ZERun VE_ERun = ZERun_OK; + + #if defined(_WIN) + + ZTypChar VCA_Search[_MAX_PATH2+1]={'0'}; + ::strcpy(VCA_Search, APC_DirPath); + ::strcat(VCA_Search, "\\*.*" ); + + ZCFileData VO_CFileData ; + BOOL VB_IsSearched= TRUE ; + HANDLE VH_File = + ::FindFirstFileA(VCA_Search, &VO_CFileData); + + if(VH_File==INVALID_HANDLE_VALUE) return ZERun_OK; + + while(VB_IsSearched) + { + if( VO_CFileData.IsDir() ) // VO_CFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + const bool CB_IsTrue = + ( + ::strcmp("." , VO_CFileData.cFileName)!=0 && + ::strcmp("..", VO_CFileData.cFileName)!=0 + ) ; + ////////////////////// + + if(CB_IsTrue) + { + strcpy(VCA_Search, APC_DirPath); + strcat(VCA_Search, "\\" ); + strcat(VCA_Search, VO_CFileData.cFileName); + + // VCA_Search is a directory name + + if(VR_CViewDir.template OnIntoDir (VCA_Search, VO_CFileData, AR_CTypeHelp)==ZERun_NO) + { VE_ERun=ZERun_NO; break; } + if(IterDirEx (VCA_Search, AR_CViewDir , AR_CTypeHelp)==ZERun_NO) + { VE_ERun=ZERun_NO; break; } + if(VR_CViewDir.template OnOutOfDir(VCA_Search, VO_CFileData, AR_CTypeHelp)==ZERun_NO) + { VE_ERun=ZERun_NO; break; }/* + if(VR_CViewDir.template OnOutOfDir(VCA_Search, VO_CFileData, AR_CTypeHelp)==ZERun_NO)*/ + }/* + if(CB_IsTrue)*/ + } + else + { + if(AR_CViewDir.template OnFile + (APC_DirPath, VO_CFileData, AR_CTypeHelp)==ZERun_NO) + { + VE_ERun=ZERun_NO; break; + }/* + if(AR_CViewDir.template OnFile + (APC_DirPath, VO_CFileData, AR_CTypeHelp)==ZERun_NO)*/ + }/* + else*/ + + VB_IsSearched = ::FindNextFile(VH_File, &VO_CFileData); + }/* + while(VB_IsSearched)*/ + + ::FindClose(VH_File); + + #else //!defined(_WIN) + + ZCFileData VO_CFileData; + #ifdef _REENTRANT + dirent VO_DirEnt; + #endif + dirent* VP_DirEnt; + TypeDirID VH_File= ::opendir(APC_DirPath); + char VCA_Search[_MAX_PATH2+1]={'0'} ; + + if(VH_File==NULL) return ZERun_OK; + + #ifdef _REENTRANT + while(::readdir_r(VH_File, &VO_DirEnt, &VP_DirEnt)==0 && VP_DirEnt!=0) + #else + while(VP_DirEnt= ::readdir(VH_File)) + #endif + { + const bool CB_IsNotValid = + ( + ::strcmp(".", VP_DirEnt->d_name)==0 || + ::strcmp("..", VP_DirEnt->d_name)==0 + ); + ////////////////////////// + + if(CB_IsNotValid) continue; + + ::strcpy(VCA_Search, APC_DirPath); + + if(::strcmp(APC_DirPath,"/")!=0) + { ::strcat(VCA_Search, "/"); } // Not to append "/" at the tail of root directory name + + ::strcat(VCA_Search , VP_DirEnt->d_name); + ::strcpy(VO_CFileData.cFileName, VP_DirEnt->d_name); + + if(::lstat(VCA_Search,&VO_CFileData)<0) + { + throw ZCExceptDir + ( + VP_DirEnt->d_name, "Fatal Error In " + "ZCDir::IterDirEx() : Can't know the file info" + ); + ///////////////// + + return ZERun_NO ; + }/* + if(::lstat(VCA_Search,&VO_CFileData)<0)*/ + + if(VO_CFileData.IsDir()) // S_ISDIR(VO_CFileData.st_mode)) + { + if(VR_CViewDir.template OnIntoDir (VCA_Search, VO_CFileData, AR_CTypeHelp)==ZERun_NO) + { VE_ERun=ZERun_NO; break; } + if(IterDirEx (VCA_Search, AR_CViewDir , AR_CTypeHelp)==ZERun_NO) + { VE_ERun=ZERun_NO; break; } + if(VR_CViewDir.template OnOutOfDir(VCA_Search, VO_CFileData, AR_CTypeHelp)==ZERun_NO) + { VE_ERun=ZERun_NO; break; }/* + if(VR_CViewDir.template OnOutOfDir(VCA_Search, VO_CFileData, AR_CTypeHelp)==ZERun_NO)*/ + } + else + { + if(VR_CViewDir.template OnFile + (APC_DirPath, VO_CFileData, AR_CTypeHelp)==ZERun_NO) + { + VE_ERun=ZERun_NO; break; + }/* + if(VR_CViewDir.template OnFile + (APC_DirPath, VO_CFileData, AR_CTypeHelp)==ZERun_NO)*/ + }/* + else*/ + }/* + #ifdef _REENTRANT + while(::readdir_r(VH_File, &VO_DirEnt, &VP_DirEnt)==0 && VP_DirEnt!=0) + #else + while(VP_DirEnt= ::readdir(VH_File)) + #endif + */ + + ::closedir(VH_File); + + #endif //!defined(_WIN) + + return VE_ERun; + }/* + template + static ZNsMain::ZNsEnum::ZERun IterDirEx( + ZTypCPCh APC_DirPath, TViewDir AR_CViewDir, TTypeHelp AR_CTypeHelp) */ + + + // APC_DirPath 는 디렉토리 구분자로 끝나지 않게 하자. + + static ZNsMain::ZNsEnum::ZERun IterFile + ( + ZTypCPCh APC_DirPath, void* APC_VoidKey, + ZNsMain::ZNsEnum::ZERun (*APF_EachFile)(ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData, void* APC_VoidKey), + ZNsMain::ZNsEnum::ZERun (*APF_EachDir )(ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData, void* APC_VoidKey)=0 + ) + /////////////////////////////////////// + { + ZNsMain::ZNsEnum::ZERun VE_ERun=ZNsMain::ZNsEnum::ZERun_OK; + + #if defined(_WIN) + + ZTypChar VCA_Search[_MAX_PATH2+1]={'0'}; + + ::strcpy(VCA_Search, APC_DirPath); + ::strcat(VCA_Search, "\\*.*" ); + + ZCFileData VO_CFileData ; + BOOL VB_IsSearched = TRUE ; + HANDLE VH_File = + ::FindFirstFileA(VCA_Search, &VO_CFileData); + + if(VH_File==INVALID_HANDLE_VALUE) + return ZNsMain::ZNsEnum::ZERun_OK; + + while(VB_IsSearched) + { + if(VO_CFileData.IsDir()) // (VO_CFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + { + const bool CB_Istrue = + ( + ::strcmp("." , VO_CFileData.cFileName)!=0 && + ::strcmp("..", VO_CFileData.cFileName)!=0 + ); + ////////////////////// + + if(CB_Istrue) + { + if(APF_EachDir!=0) + { + if(APF_EachDir(APC_DirPath, VO_CFileData, APC_VoidKey)==ZNsMain::ZNsEnum::ZERun_NO) + { + VE_ERun=ZNsMain::ZNsEnum::ZERun_NO; break; + }/* + if(APF_EachDir(APC_DirPath, VO_CFileData, APC_VoidKey)==ZNsMain::ZNsEnum::ZERun_NO)*/ + }/* + if(APF_EachDir!=0)*/ + }/* + if(CB_Istrue)*/ + } + else // !VO_CFileData.IsDir() + { + if(APF_EachFile(APC_DirPath, VO_CFileData, APC_VoidKey)==ZNsMain::ZNsEnum::ZERun_NO) + { + VE_ERun=ZNsMain::ZNsEnum::ZERun_NO; break; + }/* + if(APF_EachFile(APC_DirPath, VO_CFileData, APC_VoidKey)==ZNsMain::ZNsEnum::ZERun_NO)*/ + }/* + else // !VO_CFileData.IsDir()*/ + + VB_IsSearched = ::FindNextFileA(VH_File, &VO_CFileData); + }/* + while(VB_IsSearched)*/ + + ::FindClose(VH_File); + + #else // !defined(_WIN) + + ZCFileData VO_CFileData; + #ifdef _REENTRANT + dirent VO_DirEnt; + #endif + dirent* VP_DirEnt; + TypeDirID VH_File= ::opendir(APC_DirPath); + char VCA_Search[_MAX_PATH2+1]={_T('0')}; + + if(VH_File==NULL) + return ZNsMain::ZNsEnum::ZERun_OK; + + #ifdef _REENTRANT + while(::readdir_r(VH_File, &VO_DirEnt, &VP_DirEnt)==0 && VP_DirEnt!=0) + #else + while(VP_DirEnt= ::readdir(VH_File)) + #endif + { + const bool CB_IsNotValid=( + ::strcmp(".", VP_DirEnt->d_name)==0 || + ::strcmp("..", VP_DirEnt->d_name)==0 + /*//////////*/ ); + + if(CB_IsNotValid) continue; + + ::strcpy(VCA_Search,APC_DirPath); + + if(::strcmp(APC_DirPath, "/")!=0) + { ::strcat(VCA_Search, "/"); } + + ::strcat(VCA_Search , VP_DirEnt->d_name); + ::strcpy(VO_CFileData.cFileName, VP_DirEnt->d_name); + + if(::lstat(VCA_Search,&VO_CFileData)<0) + { + throw ZCExceptDir + ( + VP_DirEnt->d_name, "Fatal Error " + "In ZCDir::IterFile() : Can't know the file info" + ); + ///////////////// + + return ZNsMain::ZNsEnum::ZERun_NO; + }/* + if(::lstat(VCA_Search,&VO_CFileData)<0)*/ + + if( VO_CFileData.IsDir() ) + { + if(APF_EachDir(APC_DirPath, VO_CFileData, APC_VoidKey)==ZNsMain::ZNsEnum::ZERun_NO) + { + VE_ERun=ZNsMain::ZNsEnum::ZERun_NO; break; + }/* + if(APF_EachDir(APC_DirPath, VO_CFileData, APC_VoidKey)==ZNsMain::ZNsEnum::ZERun_NO)*/ + } + else + { + if(APF_EachFile(APC_DirPath, VO_CFileData, APC_VoidKey)==ZNsMain::ZNsEnum::ZERun_NO) + { + VE_ERun=ZNsMain::ZNsEnum::ZERun_NO; break; + }/* + if(APF_EachFile(APC_DirPath, VO_CFileData, APC_VoidKey)==ZNsMain::ZNsEnum::ZERun_NO)*/ + }/* + else*/ + }/* + while((VP_DirEnt= ::readdir(VH_File))!=0)*/ + + ::closedir(VH_File); + + #endif // !defined(_WIN) + + return VE_ERun; + }/* + static ZNsMain::ZNsEnum::ZERun IterFile + ( + ZTypCPCh APC_DirPath, void* APC_VoidKey, + ZNsMain::ZNsEnum::ZERun (*APF_EachFile)(ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData, void* APC_VoidKey), + ZNsMain::ZNsEnum::ZERun (*APF_EachDir )(ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData, void* APC_VoidKey)=0 + ) + /////////////////////////////////////*/ + + + /*//////////////////////////////////////////////////// + + ■ TViewFile 은 ZNsMain::ZNsEnum::ZERun 을 리턴하는 아래 멤버를 갖는다. + + OnDir (ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData) + OnFile(ZTypCPCh APC_NowPath, ZCFileData& AR_CFileData) + + ■ APC_DirPath 는 디렉토리 구분자로 끝나지 않게 하자. + + ////////////////////////////////////////////////////*/ + + template static ZNsMain::ZNsEnum:: + ZERun IterFileEx(ZTypCPCh APC_DirPath, TViewFile AR_CViewFile) + { + typedef typename ZNsMain:: + ZtCTypeData::TypeData TypeViewFile ; + + TypeViewFile& VR_CViewFile = ZNsMain:: + ZtCTypeData::GetObjRef(AR_CViewFile); + + + ZNsMain::ZNsEnum::ZERun VE_ERun=ZNsMain::ZNsEnum::ZERun_OK; + + #if defined(_WIN) + + ZTypChar VCA_Search[_MAX_PATH2+1]={'0'}; + + ::strcpy(VCA_Search, APC_DirPath) ; + ::strcat(VCA_Search, "\\*.*" ) ; + + ZCFileData VO_CFileData ; + BOOL VB_IsSearched = TRUE ; + HANDLE VH_File = + ::FindFirstFileA(VCA_Search, &VO_CFileData); + + if(VH_File==INVALID_HANDLE_VALUE) return ZNsMain::ZNsEnum::ZERun_OK; + + while(VB_IsSearched) + { + if(VO_CFileData.IsDir()) // (VO_CFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + { + const bool CB_IsTrue = + ( + ::strcmp("." , VO_CFileData.cFileName)!=0 && + ::strcmp("..", VO_CFileData.cFileName)!=0 + ); + ////////////////////// + + if(CB_IsTrue) + { + if(VR_CViewFile.OnDir(APC_DirPath, VO_CFileData)==ZNsMain::ZNsEnum::ZERun_NO) + { + VE_ERun=ZNsMain::ZNsEnum::ZERun_NO; break; + }/* + if(VR_CViewFile.OnDir(APC_DirPath, VO_CFileData)==ZNsMain::ZNsEnum::ZERun_NO)*/ + }/* + if(CB_IsTrue)*/ + } + else // !VO_CFileData.IsDir() + { + if(VR_CViewFile.OnFile(APC_DirPath, VO_CFileData)==ZNsMain::ZNsEnum::ZERun_NO) + { + VE_ERun=ZNsMain::ZNsEnum::ZERun_NO; break; + }/* + if(VR_CViewFile.OnFile(APC_DirPath, VO_CFileData)==ZNsMain::ZNsEnum::ZERun_NO)*/ + }/* + else // !VO_CFileData.IsDir()*/ + + VB_IsSearched = ::FindNextFile(VH_File, &VO_CFileData); + }/* + while(VB_IsSearched)*/ + + ::FindClose(VH_File); + + #else // !defined(_WIN) + + ZCFileData VO_CFileData; + #ifdef _REENTRANT + dirent VO_DirEnt; + #endif + dirent* VP_DirEnt; + TypeDirID VH_File= ::opendir(APC_DirPath); + char VCA_Search[_MAX_PATH2+1]={_T('0')}; + + if(VH_File==NULL) + return ZNsMain::ZNsEnum::ZERun_OK; + + #ifdef _REENTRANT + while(::readdir_r(VH_File, &VO_DirEnt, &VP_DirEnt)==0 && VP_DirEnt!=0) + #else + while(VP_DirEnt= ::readdir(VH_File)) + #endif + { + const bool CB_IsNotValid=( + ::strcmp("." , VP_DirEnt->d_name)==0 || + ::strcmp("..", VP_DirEnt->d_name)==0 + /*//////////*/ ); + + if(CB_IsNotValid) continue; + + ::strcpy(VCA_Search,APC_DirPath); + + if(::strcmp(APC_DirPath, "/")!=0) + { ::strcat(VCA_Search, "/"); } + + ::strcat(VCA_Search , VP_DirEnt->d_name); + ::strcpy(VO_CFileData.cFileName, VP_DirEnt->d_name); + + if(::lstat(VCA_Search,&VO_CFileData)<0) + { + throw ZCExceptDir + ( + VP_DirEnt->d_name, "Fatal Error In " + "ZCDir::IterFile() : Can't know the file info" + ); + ///////////////// + + return ZNsMain::ZNsEnum::ZERun_NO; + }/* + if(::lstat(VCA_Search,&VO_CFileData)<0)*/ + + if( VO_CFileData.IsDir() ) + { + if(VR_CViewFile.OnDir (APC_DirPath, VO_CFileData)==ZNsMain::ZNsEnum::ZERun_NO) + { + VE_ERun=ZNsMain::ZNsEnum::ZERun_NO; break; + }/* + if(VR_CViewFile.OnDir (APC_DirPath, VO_CFileData)==ZNsMain::ZNsEnum::ZERun_NO)*/ + } + else + { + if(VR_CViewFile.OnFile(APC_DirPath, VO_CFileData)==ZNsMain::ZNsEnum::ZERun_NO) + { + VE_ERun=ZNsMain::ZNsEnum::ZERun_NO; break; + }/* + if(VR_CViewFile.OnFile(APC_DirPath, VO_CFileData)==ZNsMain::ZNsEnum::ZERun_NO)*/ + }/* + else*/ + }/* + while((VP_DirEnt=::readdir(VH_File))!=0)*/ + + ::closedir(VH_File); + + #endif //!defined(_WIN) + + return VE_ERun; + }/* + template static ZNsMain::ZNsEnum:: + ZERun IterFileEx(ZTypCPCh APC_DirPath, TViewFile AR_CViewFile) */ + + template + static ZNsMain::ZNsEnum::ZERun IterFileEx + (ZTypCPCh APC_DirPath, TViewFile AR_CViewFile, TTypeHelp AR_CTypeHelp) + { + typedef typename ZNsMain:: + ZtCTypeData::TypeData TypeViewFile; + TypeViewFile& VR_CViewFile = + ZNsMain::ZtCTypeData::GetObjRef(AR_CViewFile); + + ZNsMain::ZNsEnum::ZERun VE_ERun= ZNsMain::ZNsEnum::ZERun_OK ; + + if(APC_DirPath==0) return ZNsMain::ZNsEnum::ZERun_OK; + + #if defined(_WIN) + + ZTypChar VCA_Search[_MAX_PATH2+1]={_T('0')}; + + ::strcpy(VCA_Search, APC_DirPath); + ::strcat(VCA_Search, "\\*.*" ); + + ZCFileData VO_CFileData ; + HANDLE VH_File = + ::FindFirstFile(VCA_Search, &VO_CFileData); + BOOL VB_IsSearched = TRUE ; + + if(VH_File==INVALID_HANDLE_VALUE) + return ZNsMain::ZNsEnum::ZERun_OK ; + + while(VB_IsSearched) + { + if(VO_CFileData.IsDir()) // (VO_CFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + { + const bool CB_IsTrue = + ( + ::strcmp("." , VO_CFileData.cFileName)!=0 && + ::strcmp("..", VO_CFileData.cFileName)!=0 + ); + ////////////////////// + + if(CB_IsTrue) + { + if(VR_CViewFile.template OnDir + (APC_DirPath, VO_CFileData, AR_CTypeHelp)==ZNsMain::ZNsEnum::ZERun_NO) + { + VE_ERun=ZNsMain::ZNsEnum::ZERun_NO; break; + }/* + if(VR_CViewFile.template OnDir + (APC_DirPath, VO_CFileData, AR_CTypeHelp)==ZNsMain::ZNsEnum::ZERun_NO)*/ + }/* + if(CB_IsTrue)*/ + } + else + { + if(VR_CViewFile.template OnFile + (APC_DirPath, VO_CFileData, AR_CTypeHelp)==ZNsMain::ZNsEnum::ZERun_NO) + { + VE_ERun=ZNsMain::ZNsEnum::ZERun_NO; break; + }/* + if(VR_CViewFile.template OnFile + (APC_DirPath, VO_CFileData, AR_CTypeHelp)==ZNsMain::ZNsEnum::ZERun_NO)*/ + }/* + else*/ + + VB_IsSearched = ::FindNextFile(VH_File, &VO_CFileData); + }/* + while(VB_IsSearched)*/ + + ::FindClose(VH_File); + + #else // !defined(_WIN) + + ZCFileData VO_CFileData; + #ifdef _REENTRANT + dirent VO_DirEnt; + #endif + dirent* VP_DirEnt; + TypeDirID VH_File= ::opendir(APC_DirPath); + char VCA_Search[_MAX_PATH2+1]={_T('0')}; + + if(VH_File==NULL) return ZNsMain::ZNsEnum::ZERun_OK; + + #ifdef _REENTRANT + while(::readdir_r(VH_File, &VO_DirEnt, &VP_DirEnt)==0 && VP_DirEnt!=0) + #else + while(VP_DirEnt = ::readdir(VH_File)) + #endif + { + const bool CB_IsNotValid = + ( + ::strcmp(".", VP_DirEnt->d_name)==0 || + ::strcmp("..", VP_DirEnt->d_name)==0 + ); + ////////////////////////// + + if(CB_IsNotValid) continue; + + ::strcpy(VCA_Search,APC_DirPath); + + if(::strcmp(APC_DirPath, "/")!=0) + { ::strcat(VCA_Search, "/"); } + + ::strcat(VCA_Search , VP_DirEnt->d_name); + ::strcpy(VO_CFileData.cFileName, VP_DirEnt->d_name); + + if(::lstat(VCA_Search,&VO_CFileData)<0) + { + throw ZCExceptDir + ( + VP_DirEnt->d_name, "Fatal Error In " + "ZCDir::IterFile() : Can't know the file info" + ); + ///////////////// + + return ZNsMain::ZNsEnum::ZERun_NO; + }/* + if(::lstat(VCA_Search,&VO_CFileData)<0)*/ + + if( VO_CFileData.IsDir() ) + { + if(VR_CViewFile.template OnDir + (APC_DirPath, VO_CFileData, AR_CTypeHelp)==ZNsMain::ZNsEnum::ZERun_NO) + { + VE_ERun=ZNsMain::ZNsEnum::ZERun_NO; break; + }/* + if(VR_CViewFile.template OnDir + (APC_DirPath, VO_CFileData, AR_CTypeHelp)==ZNsMain::ZNsEnum::ZERun_NO)*/ + } + else + { + if(VR_CViewFile.template OnFile + (APC_DirPath, VO_CFileData, AR_CTypeHelp)==ZNsMain::ZNsEnum::ZERun_NO) + { + VE_ERun=ZNsMain::ZNsEnum::ZERun_NO; break; + }/* + if(VR_CViewFile.template OnFile + (APC_DirPath, VO_CFileData, AR_CTypeHelp)==ZNsMain::ZNsEnum::ZERun_NO)*/ + }/* + else*/ + }/* + while((VP_DirEnt = ::readdir(VH_File))!=0)*/ + + ::closedir(VH_File); + + #endif // !defined(_WIN) + + return VE_ERun; + }/* + template + static ZNsMain::ZNsEnum::ZERun IterFileEx + (ZTypCPCh APC_DirPath, TViewFile AR_CViewFile, TTypeHelp AR_CTypeHelp)*/ + + + template // TFileDataList 은 std::ZCFileData 의 리스트. + static void GetCFileDataList(ZTypCPCh APC_DirPath, TFileDataList& AR_TFileDataList) + { + /* APC_DirPath 디렉토리에 있는 파일만을 AR_TFileDataList 에 저장한다. 즉 + APC_DirPath 의 하위 디렉토리로 찾아 들어가지 않는다. */ + + typedef ZNsMain::ZNsIFace::ZCViewFileDataList ZCViewFileDataList; + + ZCViewFileDataList VO_CViewFileDataList; //////////////////////// + + IterFileEx( ///////////////// + APC_DirPath , + VO_CViewFileDataList, + AR_TFileDataList + /*/////////*/ ); //////////////////////////////////////////////// + }/* + template + static void GetCFileDataList(ZTypCPCh APC_DirPath, TFileDataList& AR_TFileDataList) */ + + template // TFileDataList 은 ZCFileData 의 리스트. + static void GetCFileDataListRecur(ZTypCPCh APC_DirPath, TFileDataList& AR_TFileDataList) + { + /* APC_DirPath 디렉토리와 그 하위 디렉토리에 있는 + 모든 파일을 AR_TFileDataList 에 저장한다. */ + + typedef ZNsMain::ZNsIFace::ZCViewDirOfFileList ZCViewDirOfFileList; + + ZCViewDirOfFileList VO_CViewDirOfFileList; //////////////////////// + + IterDirEx( /////////////////// + APC_DirPath , + VO_CViewDirOfFileList, + AR_TFileDataList + /*/////////*/ ); ////////////////////////////////////////////////// + }/* + template + static void GetCFileDataListRecur(ZTypCPCh APC_DirPath, TFileDataList& AR_TFileDataList) */ + + + template // TDirNameList 은 문자열 리스트. + static void GetDirNameList(ZTypCPCh APC_DirPath, TDirNameList& ARR_CDirNameList) + { + /* APC_DirPath 의 바로 밑에 있는 하위 디렉토리만 찾는다. + 즉 재귀적으로 하위 디렉토리를 찾지 않는다. */ + + typedef ZNsMain::ZNsIFace::ZCViewFileOfDir ZCViewFileOfDir; + + ZCViewFileOfDir VO_CViewDirList; ////////////////////////// + + IterFileEx( /////////////// + APC_DirPath , + VO_CViewDirList, + ARR_CDirNameList + /*/////////*/ ); ////////////////////////////////////////// + }/* + template + static void GetDirNameList(ZTypCPCh APC_DirPath, TDirNameList& ARR_CDirNameList) */ + + + #ifdef _WIN + + + // 비어있는 디렉토리를 삭제 + + static bool RemoveEmptyDir(ZTypCPCh APC_PathName) + { + return ::RemoveDirectoryA(APC_PathName)==TRUE ; + }/* + static bool RemoveEmptyDir(ZTypCPCh APC_PathName)*/ + + static bool MakeDir(ZTypCPCh APC_PathName, LPSECURITY_ATTRIBUTES lpSecurityAttributes=NULL) + { + return ::CreateDirectoryA(APC_PathName, lpSecurityAttributes)==TRUE ; + }/* + static bool MakeDir(ZTypCPCh APC_PathName, LPSECURITY_ATTRIBUTES lpSecurityAttributes=NULL)*/ + + template static bool GetNowDir( + TString& ARR_CStringDir, bool AB_DoKeepPrev=false) + { + // 디렉토리명이 _MAX_DIR 을 넘을 수 있다. 그래서 넉넉하게 곱하기 4 를 한다. + + if(false==AB_DoKeepPrev) + { + const int CI_BuffSize = _MAX_DIR*4 ; + + ARR_CStringDir.resize(CI_BuffSize+1, ' '); + + // ::GetCurrentDirectory() 는 완전 경로를 얻고 그 길이를 반환한다. + + long VL_Length = ::GetCurrentDirectoryA + ( CI_BuffSize, (ZTypPCh)ARR_CStringDir.data() ); + + if(VL_Length<1){ return false; } ////// + + ARR_CStringDir.resize(VL_Length, ' '); return true ; + }/* + if(false==AB_DoKeepPrev)*/ + + + ZTypLength VL_PrevSize = ARR_CStringDir.size() ; + const int CI_BuffSize = VL_PrevSize+_MAX_DIR*4 ; + ARR_CStringDir.resize(CI_BuffSize+1, ' ') ; + ZTypPChar VP_CopyStart = + (ZTypPChar)ARR_CStringDir.data()+VL_PrevSize ; + + // ::GetCurrentDirectory() 는 완전 경로를 얻고 그 길이를 반환한다. + + long VL_Length = + ::GetCurrentDirectoryA(CI_BuffSize, VP_CopyStart); + + if(VL_Length<1) return false; ////////// + + ARR_CStringDir. + resize(VL_PrevSize+VL_Length, ' ' ); + return true ; + }/* + template static bool GetNowDir( + TString& ARR_CStringDir, bool AB_DoKeepPrev=false) */ + + static bool ChangeDir(ZTypCPCh APC_DirName) + { + return ::SetCurrentDirectoryA(APC_DirName)==TRUE ; + }/* + static bool ChangeDir(ZTypCPCh APC_DirName)*/ + + #else //!defined(_WIN) + + static bool RemoveEmptyDir(const char* APC_PathName) + { + return ::rmdir(APC_PathName)==0 ; // 비어있는 디렉토리를 삭제 + }/* + static bool RemoveEmptyDir(const char* APC_PathName)*/ + + static bool MakeDir(const char* APC_PathName, mode_t mode=0744) + { + return ::mkdir(APC_PathName, mode)==0 ; + }/* + static bool MakeDir(const char* APC_PathName, mode_t mode=0744)*/ + + template static bool GetNowDir( + TString& ARR_CStringDir, bool AB_DoKeepPrev=false) + { + if(false==AB_DoKeepPrev) + { + const int CI_BuffSize = _MAX_DIR*4 ; + + ARR_CStringDir.resize(CI_BuffSize+1, ' '); + + char* VP_NowDir = + ::getcwd((char*)ARR_CStringDir.data(), CI_BuffSize); + + if(VP_NowDir==0) return false; ARR_CStringDir. + + resize(ZNsMain::ZftLength(VP_NowDir), ' '); return true; + }/* + if(false==AB_DoKeepPrev)*/ + + + ZTypLength VL_PrevSize = ARR_CStringDir.size() ; + const int CI_BuffSize = VL_PrevSize+_MAX_DIR*4 ; + ARR_CStringDir.resize(CI_BuffSize+1, ' ') ; + ZTypPChar VP_CopyStart = + (ZTypPChar)ARR_CStringDir.data()+VL_PrevSize ; + + char* VP_NowDir = ::getcwd(VP_CopyStart, CI_BuffSize); + + if(VP_NowDir==0) return false; //////////////////// + + ARR_CStringDir. + resize( VL_PrevSize+ZftLength(VP_NowDir), ' '); + return true ; + }/* + template static bool GetNowDir( + TString& ARR_CStringDir, bool AB_DoKeepPrev=false) */ + + static bool ChangeDir(const char* APC_DirName) + { + return ::chdir(APC_DirName)==0 ; + }/* + static bool ChangeDir(const char* APC_DirName)*/ + + #endif //!defined(_WIN) + + + /*///////////////////////////////////////////////////////////////////////////////////// + + ■ 절대 경로 AP_AbsPath 에 대해서, 기준 경로 AP_StdPath 에 로부터의 상대 경로를 구한다. + 즉 현재 디렉토리 위치가 기준 경로 AP_StdPath 라 가정했을 때, 이 경로에서 절대 경로 + AP_AbsPath 에 이르는 상대 경로를 구하는 것이다. + + 두 경로 모두 디렉토리 구분자로 끝나는 것이 일관성이 있어서 좋을 것 같다. 이렇게 하면 + AP_StdPath 와 GetRelativePath() 함수로 얻어진 상대 경로를 더하면, 바로 AP_AbsPath 경 + 로에 이를 수 있다. + + ■ 기준경로 AP_StdPath 도 절대경로로 입력받는다. + + ■ 반환 경로에는 디렉토리 구분자가 붙는다. + + ■ 경로명에 디렉토리 구분자가 연이어 존재해서는 안된다. + 이에 대한 에러 처리는 넣지 않았다. + + ■ 예제 코드 + + const char* CPC_AbsPath="C:\\Windows\\A\\B\\"; + const char* CPC_StdPath="C:\\Windows\\A\\C\\D\\"; + + std::string VO_CStringRelativePath; + + std::ZCDir::GetRelativePath + ( + CPC_AbsPath, strlen(CPC_AbsPath), + CPC_StdPath, strlen(CPC_StdPath), RR(VO_CStringRelativePath) + ); + + cout<<"RelativePath="< static TString& GetRelativePath + ( + const TTypChar* AP_AbsPath, ZTypLength AI_AbsPathLen, + const TTypChar* AP_StdPath, ZTypLength AI_StdPathLen, + TString& ARR_CStrRelativePath + ) + /*#########################################################################*/ + { + /* 맨 끝에 디렉토리 구분자가 있다면, 길이를 1 줄이는 것으로 무효화시킨다. */ + + const bool CB_IsTrue = ( /*###########################*/ + AI_AbsPathLen>0 && + ( + AP_AbsPath[AI_AbsPathLen-1]=='\\' || + AP_AbsPath[AI_AbsPathLen-1]=='/' + ) + /*########*/ ); /*####################################*/ + + if(CB_IsTrue){ --AI_AbsPathLen; } + + const bool CB_IsTrue2 = ( /*##########################*/ + AI_StdPathLen>0 && + ( + AP_StdPath[AI_StdPathLen-1]=='\\' || + AP_StdPath[AI_StdPathLen-1]=='/' + ) + /*#########*/); /*####################################*/ + + if(CB_IsTrue2){ --AI_StdPathLen; } + + if(AI_AbsPathLen<1) + { + return ARR_CStrRelativePath="" ; + } + if(AI_StdPathLen<1) + { + ARR_CStrRelativePath=""; + ARR_CStrRelativePath.append(AP_AbsPath, AI_AbsPathLen); + + #ifdef _WIN + ARR_CStrRelativePath+="\\"; + #else + ARR_CStrRelativePath+="/"; + #endif + + return ARR_CStrRelativePath; + }/* + if(AI_StdPathLen<1)*/ + + ZTypLength VI_MinLoop = + ( AI_AbsPathLen>=AI_StdPathLen ? AI_StdPathLen : AI_AbsPathLen ) ; + + const char* VP_AbsPath=AP_AbsPath ; + const char* VP_StdPath=AP_StdPath ; + char VC_Temp = char(0) ; + + ZTypLength VI_EqualCnt = 0; // 앞에서부터 일치하는 문자열 갯수 + ZTypLength VI_LastDirPos=-1; // 앞에서부터 일치하는 문자열 중 마지막 디렉토리 구분자의 위치 + + while(VI_EqualCnt static TString& GetRelativePath + ( + const TTypChar* AP_AbsPath, ZTypLength AI_AbsPathLen, + const TTypChar* AP_StdPath, ZTypLength AI_StdPathLen, + TString& ARR_CStrRelativePath + ) + ###########################################################################*/ + + template /*###########################*/ + static TString& GetRelativePath + ( + const TTypChar* AP_AbsPath, + const TTypChar* AP_StdPath, + TString& ARR_CStrRelativePath + ) + /*#########################################################################*/ + { + using ZNsMain::ZftLength ; + + return GetRelativePath( /////////////////////////// + AP_AbsPath , + ZftLength(AP_AbsPath) , + AP_StdPath , + ZftLength(AP_StdPath) , + RR(ARR_CStrRelativePath) + /*/////////*/ ); ////////////////////////////////// + }/* + template ############################### + static TString& GetRelativePath + ( + const TTypChar* AP_AbsPath, + const TTypChar* AP_StdPath, + TString& ARR_CStrRelativePath + ) + ###########################################################################*/ + + static std::string GetRelativePath( + const char* AP_AbsPath, ZTypLength AI_AbsPathLen, const char* AP_StdPath, ZTypLength AI_StdPathLen) + { + static std::string SO_CStrRelativePath; + + return GetRelativePath( /////////////////////////// + AP_AbsPath , AI_AbsPathLen , + AP_StdPath , AI_StdPathLen , + RR(SO_CStrRelativePath) + /*/////////*/ ); ////////////////////////////////// + }/* + static std::string GetRelativePath( + const char* AP_AbsPath, ZTypLength AI_AbsPathLen, const char* AP_StdPath, ZTypLength AI_StdPathLen) */ + + static std::string GetRelativePath(const char* AP_AbsPath, const char* AP_StdPath) + { + using ZNsMain::ZftLength; static std::string SO_CStrRelativePath; + + return GetRelativePath /////////////////////////////// + ( + AP_AbsPath , ZftLength(AP_AbsPath) , + AP_StdPath , ZftLength(AP_StdPath) , + RR(SO_CStrRelativePath) + ); + /////////////////////////////////////////////////////// + }/* + static std::string GetRelativePath(const char* AP_AbsPath, const char* AP_StdPath) */ + + #if defined(_WIN) + + static bool DeleteFile(ZTypCPCh APC_FileName) + { + return ::DeleteFileA(APC_FileName)==TRUE; + }/* + static bool DeleteFile(ZTypCPCh APC_FileName)*/ + + static bool MoveFile(ZTypCPCh APC_FileNow, ZTypCPCh APC_FileNew) + { + return ::MoveFileA(APC_FileNow, APC_FileNew)==TRUE; + }/* + static bool MoveFile(ZTypCPCh APC_FileNow, ZTypCPCh APC_FileNew)*/ + + #else //!defined(_WIN) + + static bool DeleteFile(const char* APC_FileName) + { + return ::unlink(APC_FileName)==0; + }/* + static bool DeleteFile(const char* APC_FileName)*/ + + static bool MoveFile(const char* APC_FileNow, const char* APC_FileNew) + { + return ::rename(APC_FileNow, APC_FileNew)==0; + }/* + static bool MoveFile(const char* APC_FileNow, const char* APC_FileNew)*/ + + #endif // !defined(_WIN) + + + public: + };/* + class ZCDir*/ + +#ifdef _WIN + static int GetLastErrorNo(){return ::WSAGetLastError();} +#else + static int GetLastErrorNo(){return errno ;} +#endif + + +#ifdef __linux__ + + + /* 비동기 입출력은 완료시 콜백할 수 있는 윈도우 쪽이 편한 듯 하다. + 리눅스도 signal 을 등록하면 물론 가능하다. cf) lio_listio() */ + + + /*////////////////////////////////////////////////////////////// + + struct aiocb + { + int aio_fildes; // File desriptor. + int aio_lio_opcode; // Operation to be performed. + int aio_reqprio; // Request priority offset. + volatile void *aio_buf; // Location of buffer. + size_t aio_nbytes; // Length of transfer. + struct sigevent aio_sigevent; // Signal number and value. + + Internal members. + + struct aiocb *__next_prio; + int __abs_prio; + int __policy; + int __error_code; + __ssize_t __return_value; + + #ifndef __USE_FILE_OFFSET64 + __off_t aio_offset; // File offset. + char __pad[sizeof (__off64_t) - sizeof (__off_t)]; + #else + __off64_t aio_offset; // File offset. + #endif + char __unused[32]; + }; + + //////////////////////////////////////////////////////////////*/ + + + class ZCAsynIO : public aiocb + { + public : + + ZCAsynIO() + { + ::memset(this, 0, sizeof(aiocb)); + }/* + ZCAsynIO()*/ + + void SetHandle(int AI_FileHandle) + { + this->aio_fildes=AI_FileHandle; + }/* + void SetHandle(int AI_FileHandle)*/ + + void Init(int AI_FileHandle, std::LLong ALL_Offset=0) + { + this->aio_fildes=AI_FileHandle; + this->aio_offset=ALL_Offset ; + }/* + void Init(int AI_FileHandle, std::LLong ALL_Offset=0)*/ + + int Read(volatile char* AP_Buffer, int AI_BufSize) + { + this->aio_buf =AP_Buffer ; + this->aio_nbytes=AI_BufSize ; + + return ::aio_read(this); + }/* + int Read(volatile char* AP_Buffer, int AI_BufSize)*/ + + int Write(volatile char* AP_Buffer, int AI_BufSize) + { + this->aio_buf =AP_Buffer ; + this->aio_nbytes=AI_BufSize ; + + return ::aio_write(this); + }/* + int Write(volatile char* AP_Buffer, int AI_BufSize)*/ + + int GetErrCode() + { + return ::aio_error(this); + }/* + int GetErrCode()*/ + + + /*///////////////////////////////////////////////////////////////////// + + ■ aio_return(struct aiocb*) + + RETURN VALUE + + If the asynchronous I/O operation has completed, this function returns + the value that would have been returned in case of a synchronous read, + write, or fsync request. Otherwise the return value is undefined. On + error, the error value is returned. + + /////////////////////////////////////////////////////////////////////*/ + + + ssize_t GetFinishResult() + { + return ::aio_return(this) ; + }/* + ssize_t GetFinishResult()*/ + + + // Windows 와 호환을 위해... + + void GetFinishResult(ssize_t& ARRI_FinishCode) + { + ARRI_FinishCode = ::aio_return(this) ; + }/* + void GetFinishResult(ssize_t& ARRI_FinishCode)*/ + + + /*///////////////////////////////////////////////////////////////////////// + + ■ aio_cancel(int fd,struct aiocb*) + + RETURN VALUE + + This function returns AIO_CANCELED if all requests were successfully + cancelled. It returns AIO_NOTCANCELED when at least one of the requests + specified was not cancelled because it was in progress. In this case + one may check the status of individual requests using aio_error(3). + This function returns AIO_ALLDONE when all requests had been completed + already before this call. When some error occurs, -1 is returned, and + errno is set appropriately. + + ■ Return values of cancelation function. + + enum + { + AIO_CANCELED, + #define AIO_CANCELED AIO_CANCELED + AIO_NOTCANCELED, + #define AIO_NOTCANCELED AIO_NOTCANCELED + AIO_ALLDONE + #define AIO_ALLDONE AIO_ALLDONE + }; + + /////////////////////////////////////////////////////////////////////////*/ + + int Cancel() + { + return ::aio_cancel(this->aio_fildes, this) ; + }/* + int Cancel()*/ + + int Cancel(int AI_FileDesc) + { + return ::aio_cancel(AI_FileDesc, this) ; + }/* + int Cancel(int AI_FileDesc)*/ + + + /*///////////////////////////////////////////////////////////////////////// + + ■ aio_fsync(int op,struct aiocb*); + + ** DESCRIPTION + + The aio_fsync function does a sync on all outstanding asynchronous I/O + operations associated with aiocbp->aio_fildes. + + More precisely, if op is O_SYNC, then all currently queued I/O opera- + tions shall be completed as if by a call of fsync(2), and if op is + O_DSYNC, this call is the asynchronous analog of fdatasync(2). Note + that this is a request only - this call does not wait for I/O comple- + tion. + + Apart from aio_fildes the only field in the structure pointed to by + aiocbp that is used by this call is the aio_sigevent field (a struct + sigevent) that indicates the desired type of asynchronous notification + at completion. All other fields are ignored. + + ** RETURN VALUE + + On success (the sync request was successfully queued) this function + returns 0. On error -1 is returned, and errno is set appropriately. + + + ** Operation codes for `aio_lio_opcode'. + + enum + { + LIO_READ, + #define LIO_READ LIO_READ + LIO_WRITE, + #define LIO_WRITE LIO_WRITE + LIO_NOP + #define LIO_NOP LIO_NOP + }; + + /////////////////////////////////////////////////////////////////////////*/ + + + bool FSync(int AI_Operation) + { + return ::aio_fsync(AI_Operation, this)==0 ; + }/* + bool FSync(int AI_Operation)*/ + + + /*///////////////////////////////////////////////////////////////////////// + + ■ int aio_suspend(const struct aiocb * const cblist[],int n, const struct timespec *timeout); + + ** DESCRIPTION + + The aio_suspend function suspends the calling process until at least + one of the asynchronous I/O requests in the list cblist of length n + have completed, a signal is delivered, or timeout is not NULL and the + time interval it indicates has passed. + + Each item in the list must either be NULL (and then is ignored), or a + pointer to a control block on which I/O was initiated using + aio_read(3), aio_write(3), or lio_listio(3). + + If CLOCK_MONOTONIC is supported, this clock is used to measure the + timeout interval. + + ** RETURN VALUE + + If this function returns after completion of one of the indicated + requests, it returns 0. Otherwise it returns -1 and sets errno appro- + priately. + + /////////////////////////////////////////////////////////////////////////*/ + + bool Suspend(const struct timespec* AP_TimeOut) + { + aiocb* VP_AIOCB[1]; VP_AIOCB[0]=this; + + return ::aio_suspend(VP_AIOCB, 1/*VP_AIOCB 원소수*/, AP_TimeOut)==0 ; + }/* + bool Suspend(const struct timespec* AP_TimeOut)*/ + + static bool Suspend(const struct aiocb* const APA_AIOCB[], int AI_Size, const struct timespec* AP_TimeOut) + { + return ::aio_suspend(APA_AIOCB, AI_Size, AP_TimeOut)==0 ; + }/* + static bool Suspend(const struct aiocb* const APA_AIOCB[], int AI_Size, const struct timespec* AP_TimeOut)*/ + + + /*//////////////////////////////////////////////////////////////////////////// + + ■ 윈도우의 WaitForMultipleObjects() 과 비슷한 POSIX 함수는 lio_listio() 이다. + + DWORD WaitForMultipleObjects + ( + DWORD nCount, + CONST HANDLE* lpHandles, + BOOL fWaitAll, + DWORD dwMilliseconds + ); + + DWORD WaitForSingleObject( HANDLE hHandle, DWORD dwMilliseconds ); + + enum + { + LIO_WAIT, + #define LIO_WAIT LIO_WAIT + LIO_NOWAIT + #define LIO_NOWAIT LIO_NOWAIT + }; + + + int lio_listio + ( + int mode, + struct aiocb *restrict const list[restrict], + int nent, + struct sigevent *restrict sig + ); + + ////////////////////////////////////////////////////////////////////////////*/ + + + public: + };/* + class ZCAsynIO : public aiocb*/ + + +#elif defined(_WIN) + + + /*////////////////////////////////////////////////////////////////////////////// + + typedef struct _OVERLAPPED + { + ULONG_PTR Internal; + ULONG_PTR InternalHigh; + union + { + struct + { + DWORD Offset; + DWORD OffsetHigh; + }; + + PVOID Pointer; + }; HANDLE hEvent; + } OVERLAPPED, *LPOVERLAPPED; + + Internal + Reserved for operating system use. + This member, which specifies a system-dependent status, + is valid when the GetOverlappedResult function returns + without setting the extended error information to ERROR_IO_PENDING. + + InternalHigh + Reserved for operating system use. + This member, which specifies the length of the data transferred, + is valid when the GetOverlappedResult function returns TRUE. + + Offset + File position at which to start the transfer. + The file position is a byte offset from the start of the file. + The calling process must set this member before calling the ReadFile or WriteFile function. + This member is used only when the device is a file. Otherwise, this member must be zero. + + OffsetHigh + High-order word of the file position at which to start the transfer. + This member is used only when the device is a file. + Otherwise, this member must be zero. + + Pointer + Reserved for system use; do not use. + + hEvent + Handle to an event that will be set to the signaled state + when the operation has been completed. + The calling process must set this member either to zero or a valid event handle + before calling any overlapped functions. + To create an event object, + use the CreateEvent function. + This function returns a handle that can be used to synchronize simultaneous I/O requests for a device. + Functions such as ReadFile and WriteFile set this handle to the nonsignaled state + before they begin an I/O operation. + When the operation has completed, the handle is set to the signaled state. + + Functions such as GetOverlappedResult and the wait functions reset auto-reset events to the nonsignaled state. + Therefore, if you use an auto-reset event, + your application can hang if you wait for the operation to complete then call GetOverlappedResult + + + BOOL ReadFileEx + ( + HANDLE hFile, + LPVOID lpBuffer, + DWORD nNumberOfBytesToRead, + LPOVERLAPPED lpOverlapped, + LPOVERLAPPED_COMPLETION_ROUTINE APF_CompletionRoutine + ); + + BOOL WriteFileEx + ( + HANDLE hFile, + LPCVOID lpBuffer, + DWORD nNumberOfBytesToWrite, + LPOVERLAPPED lpOverlapped, + LPOVERLAPPED_COMPLETION_ROUTINE APF_CompletionRoutine + ); + + VOID CALLBACK FileIOCompletionRoutine + ( + DWORD dwErrorCode, + DWORD dwNumberOfBytesTransfered, + LPOVERLAPPED lpOverlapped + ); + + //////////////////////////////////////////////////////////////////////////////*/ + + + class ZCAsynIO : public OVERLAPPED + { + private: + HANDLE mh_Handle; + public : + + ZCAsynIO(HANDLE AH_FileHandle=INVALID_HANDLE_VALUE, DWORD AI_Offset=0, DWORD AI_OffseHigh=0, HANDLE AH_Event=NULL) + { + this->mh_Handle =AH_FileHandle; + this->Offset =AI_Offset ; + this->OffsetHigh=AI_OffseHigh ; + this->hEvent =AH_Event ; + }/* + ZCAsynIO(HANDLE AH_FileHandle=INVALID_HANDLE_VALUE, DWORD AI_Offset=0, DWORD AI_OffseHigh=0, HANDLE AH_Event=NULL)*/ + + void SetHandle(HANDLE AH_FileHandle) + { + mh_Handle=AH_FileHandle ; + }/* + void SetHandle(AH_FileHandle)*/ + + void Init(HANDLE AH_FileHandle, DWORD AI_Offset=0, DWORD AI_OffseHigh=0, HANDLE AH_Event=NULL) + { + this->mh_Handle =AH_FileHandle; + this->Offset =AI_Offset ; + this->OffsetHigh=AI_OffseHigh ; + this->hEvent =AH_Event ; + }/* + void Init(HANDLE AH_FileHandle, DWORD AI_Offset=0, DWORD AI_OffseHigh=0, HANDLE AH_Event=NULL)*/ + + DWORD Read(LPVOID AP_Buffer, DWORD AI_BufferSize) + { + DWORD VDW_ReadSize=0; ::ReadFile( ////////// + mh_Handle , + AP_Buffer , + AI_BufferSize , + &VDW_ReadSize , + this + /*/////////*/ ); /////////////////////////// + + return VDW_ReadSize; + }/* + DWORD Read(LPVOID AP_Buffer, DWORD AI_BufferSize)*/ + + BOOL Read(LPVOID AP_Buffer, DWORD AI_BufferSize, DWORD& ARR_ReadSize) + { + return ::ReadFile(mh_Handle, AP_Buffer, AI_BufferSize, &ARR_ReadSize, this); + }/* + BOOL Read(LPVOID AP_Buffer, DWORD AI_BufferSize, DWORD& ARR_ReadSize)*/ + + BOOL Read(LPVOID AP_Buffer, DWORD AI_BufferSize, LPOVERLAPPED_COMPLETION_ROUTINE APF_CompletionRoutine) + { + return ::ReadFileEx(mh_Handle,AP_Buffer, AI_BufferSize, this, APF_CompletionRoutine); + }/* + BOOL Read(LPVOID AP_Buffer, DWORD AI_BufferSize, LPOVERLAPPED_COMPLETION_ROUTINE APF_CompletionRoutine)*/ + + DWORD Write(LPVOID AP_Buffer, DWORD AI_BufferSize) + { + DWORD VDW_WriteSize=0; ::WriteFile( + mh_Handle , + AP_Buffer , + AI_BufferSize , + &VDW_WriteSize , + this + /*/////////*/ ); ////////////////// + + return VDW_WriteSize; + }/* + DWORD Write(LPVOID AP_Buffer, DWORD AI_BufferSize)*/ + + BOOL Write(LPVOID AP_Buffer, DWORD AI_BufferSize, DWORD& ARR_WriteSize) + { + return ::WriteFile(mh_Handle,AP_Buffer, AI_BufferSize, &ARR_WriteSize,this); + }/* + BOOL Write(LPVOID AP_Buffer, DWORD AI_BufferSize, DWORD& ARR_WriteSize)*/ + + BOOL Write(LPVOID AP_Buffer, DWORD AI_BufferSize, LPOVERLAPPED_COMPLETION_ROUTINE APF_CompletionRoutine) + { + return ::WriteFileEx(mh_Handle, AP_Buffer, AI_BufferSize, this, APF_CompletionRoutine); + }/* + BOOL Write(LPVOID AP_Buffer, DWORD AI_BufferSize, LPOVERLAPPED_COMPLETION_ROUTINE APF_CompletionRoutine)*/ + + BOOL Cancel() + { + return ::CancelIo(mh_Handle); + }/* + BOOL Cancel()*/ + + BOOL GetFinishResult(DWORD& ARRI_FinishCode, BOOL AB_Wait=FALSE) + { + return ::GetOverlappedResult(mh_Handle, this, &ARRI_FinishCode, AB_Wait); + }/* + BOOL GetFinishResult(DWORD& ARRI_FinishCode, BOOL AB_Wait=FALSE)*/ + + DWORD GetFinishResult(BOOL AB_Wait=FALSE) + { + /*////////////////////////////////////////////////////////////////////////////// + + ■ 이 object 로 비동기 입출력을 한 상태에서 현재 입출력 상태를 알기 위해 + 이 멤버를 호출하면 물론 안된다. 그때는 + + DWORD GetFinishResult(OVERLAPPED& ARR_OverLapped,BOOL AB_Wait=FALSE) + + 을 호출해야 한다. 즉 다른 OVERLAPPED object 로 입출력 상태를 통보받아야 한다. + + //////////////////////////////////////////////////////////////////////////////*/ + + DWORD VDW_FinishCode; ::GetOverlappedResult( + mh_Handle , + this , + &VDW_FinishCode , + AB_Wait + /*//////////*/ ); ////////////////////////// + + return VDW_FinishCode; + }/* + DWORD GetFinishResult(BOOL AB_Wait=FALSE)*/ + + DWORD GetFinishResult(OVERLAPPED& ARR_OverLapped, BOOL AB_Wait=FALSE) + { + DWORD VDW_FinishCode; ::GetOverlappedResult( + mh_Handle , + &ARR_OverLapped , + &VDW_FinishCode , + AB_Wait + /*/////////*/ ); /////////////////////////// + + return VDW_FinishCode; + }/* + DWORD GetFinishResult(OVERLAPPED& ARR_OverLapped, BOOL AB_Wait=FALSE)*/ + + public: + };/* + class ZCAsynIO : public OVERLAPPED*/ + + + /*//////////////////////////////////////////////////////////////////////////////////////////////////// + + ■ IOCP 지원정보 + + Client : Requires Windows Vista, Windows XP, or Windows 2000 Professional. + Server : Requires Windows Server 2008, Windows Server 2003, or Windows 2000 Server. + Header : Declared in WinBase.h; include Windows.h. + + Library Use Kernel32.lib. + + DLL Requires Kernel32.dll. + + ※ window95, window98 에서는 지원되지 않는다. + + ■ 관련함수 + + HANDLE CreateIoCompletionPort + ( + HANDLE FileHandle , + HANDLE ExistingCompletionPort , + ULONG_PTR CompletionKey , + DWORD NumberOfConcurrentThreads + ); + + □ 인수 + + ※ FileHandle + + [in] Handle to a file opened for overlapped I/O completion. + You must specify the FILE_FLAG_OVERLAPPED flag + when using the CreateFile function to obtain the handle. + If FileHandle specifies INVALID_HANDLE_VALUE, + CreateIoCompletionPort creates an I/O completion port + without associating it with a file. In this case, + the ExistingCompletionPort parameter must be NULL and the CompletionKey parameter is ignored. + + ※ ExistingCompletionPort + + [in] Handle to the I/O completion port. + If this parameter specifies an existing completion port, + the function associates it with the file specified by the FileHandle parameter. + The function returns the handle of the existing completion port; + it does not create a new I/O completion port. + + If this parameter is NULL, + the function creates a new I/O completion port and associates it with the file specified by FileHandle. + The function returns the handle to the new I/O completion port. + + -- 이 인수가 NULL 이면 새로운 완료 포트를 만든다. + + ※ CompletionKey + + [in] Per-file completion key that is included in every I/O completion packet for the specified file. + + ※ NumberOfConcurrentThreads + + [in] Maximum number of threads that the operating system can allow + to concurrently process I/O completion packets for the I/O completion port. + This parameter is ignored if the ExistingCompletionPort parameter is not NULL. + If this parameter is zero, the system allows as many concurrently running threads + as there are processors in the system. + + □ Return Values + + If the function succeeds, + the return value is the handle to the I/O completion port + that is associated with the specified file. + + If the function fails, the return value is NULL. + To get extended error information, call GetLastError. + + + BOOL GetQueuedCompletionStatus + ( + HANDLE CompletionPort , + LPDWORD lpNumberOfBytes , + PULONG_PTR lpCompletionKey , + LPOVERLAPPED* lpOverlapped , + DWORD dwMilliseconds + ); + + □ Return Value + + If the function dequeues a completion packet for a successful I/O operation + from the completion port, the return value is nonzero. + The function stores information in the variables pointed to + by the lpNumberOfBytes, lpCompletionKey, and lpOverlapped parameters. + + If *lpOverlapped is NULL and the function does not dequeue a completion packet + from the completion port, the return value is zero. + The function does not store information in the variables pointed to + by the lpNumberOfBytes and lpCompletionKey parameters. + To get extended error information, call GetLastError. + If the function did not dequeue a completion packet because the wait timed out, + GetLastError returns WAIT_TIMEOUT. + + -- *lpOverlapped 가 NULL 이고 즉 OVERLAPPED* 형 인수가 NULL 로 설정되고 완료 포트로부터 완료패 + -- 킷을 가져오지 않는다면 반환값은 zero 이다. 이때 lpNumberOfBytes 와 lpCompletionKey 인수에 + -- 값이 설정되지 않는다. 상세한 에러 정보는 GetLastError() 를 호출할 것. 이 함수가 타임아웃으로 + -- 인해 완료패킷을 가져오지 않았다면 GetLastError() 은 WAIT_TIMEOUT 을 반환한다. + + If *lpOverlapped is not NULL and the function dequeues a completion packet + for a failed I/O operation from the completion port, the return value is zero. + The function stores information in the variables pointed to + by lpNumberOfBytes, lpCompletionKey, and lpOverlapped. + To get extended error information, call GetLastError + + -- *lpOverlapped 가 NULL 이 아니고 즉 OVERLAPPED* 형 인수가 NULL 이 아닌 값으로 설정되고 완료 포 + -- 트로부터 완료패킷을 가져왔다면 반환값은 zero 이다. 이때 lpNumberOfBytes, lpCompletionKey, + -- lpOverlapped 인수에 유효한 값이 설정된다. + + + BOOL PostQueuedCompletionStatus( + HANDLE CompletionPort, + DWORD dwNumberOfBytesTransferred, // can be 0 + ULONG_PTR dwCompletionKey, + LPOVERLAPPED lpOverlapped // can be null + ); + + typedef _W64 unsigned long ULONG_PTR, *PULONG_PTR; + + The PostQueuedCompletionStatus function posts an I/O completion packet to an I/O completion port. + + -- 완료된 입출력 정보를 IOCP Queue 에 직접 전달하기 위해 사용하는 API. 이 함수를 호출하면 + -- GetQueuedCompletionStatus 함수에서 받게 된다. IOCP가 반드시 파일이나, 네트웍의 전송으로만 사용 + -- 되어야 할 필요는 없다. 스레드간의 통신에서도 CompletionKey 값을 주고받는 것으로 대체할 수도 있 + -- 다 + + □ Parameters + + CompletionPort + [in] Handle to an I/O completion port to which the I/O completion packet is to be posted. + dwNumberOfBytesTransferred + [in] Value to be returned through the lpNumberOfBytesTransferred parameter + of the GetQueuedCompletionStatus function. + dwCompletionKey + [in] Value to be returned through the lpCompletionKey parameter + of the GetQueuedCompletionStatus function. + lpOverlapped + [in] Value to be returned through the lpOverlapped parameter + of the GetQueuedCompletionStatus function. + + ※ dwNumberOfBytesTransferred can be 0 + ※ lpOverlapped can be null + + □ Return Value + + If the function succeeds, the return value is nonzero. + If the function fails, the return value is zero. + To get extended error information, call GetLastError. + + □ Remarks + + The I/O completion packet will satisfy an outstanding call + to the GetQueuedCompletionStatus function. + This function returns with the three values passed as the second, third, and fourth parameters + of the call to PostQueuedCompletionStatus. + The system does not use or validate these values. + In particular, the lpOverlapped parameter need not point to an OVERLAPPED structure. + + ■ -- + + ////////////////////////////////////////////////////////////////////////////////////////////////////*/ + + + class CWinIOCP + { + protected: + HANDLE mh_IOCP; + public : + + CWinIOCP() + { + mh_IOCP=0; + }/* + CWinIOCP()*/ + + ~CWinIOCP(){Close();} + + bool Create(DWORD AI_ThreadCnt=0) + { + return (mh_IOCP=::CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, AI_ThreadCnt))!=NULL; + }/* + bool Create(DWORD AI_ThreadCnt=0)*/ + + bool AddHandle(HANDLE AH_FileHandle, ULONG_PTR APL_Key, DWORD AI_ThreadCnt=0) + { + return ::CreateIoCompletionPort(AH_FileHandle, mh_IOCP, APL_Key, AI_ThreadCnt)!=NULL; + }/* + bool AddHandle(HANDLE AH_FileHandle,ULONG_PTR APL_Key, DWORD AI_ThreadCnt=0)*/ + + bool GetStatus(LPDWORD APL_NumberOfBytes, PULONG_PTR APL_CompletionKey, LPOVERLAPPED* APP_Overlapped, DWORD AI_Milliseconds=INFINITE) + { + return ::GetQueuedCompletionStatus(mh_IOCP, APL_NumberOfBytes, APL_CompletionKey, APP_Overlapped, AI_Milliseconds)==TRUE; + }/* + bool GetStatus(LPDWORD APL_NumberOfBytes, PULONG_PTR APL_CompletionKey, LPOVERLAPPED* APP_Overlapped, DWORD AI_Milliseconds=INFINITE)*/ + + bool GetStatus(LPDWORD APL_NumberOfBytes, PULONG_PTR APL_CompletionKey, LPOVERLAPPED& APRR_Overlapped, DWORD AI_Milliseconds=INFINITE) + { + return ::GetQueuedCompletionStatus(mh_IOCP, APL_NumberOfBytes, APL_CompletionKey, &APRR_Overlapped, AI_Milliseconds)==TRUE; + }/* + bool GetStatus(LPDWORD APL_NumberOfBytes, PULONG_PTR APL_CompletionKey, LPOVERLAPPED& APRR_Overlapped, DWORD AI_Milliseconds=INFINITE)*/ + + #if defined(__VISUAL_CPP_VER__) && __VISUAL_CPP_VER__>=200800 + + bool GetStatusEx(OVERLAPPED_ENTRY* AP_OvlpEntry, ULONG AI_EntryCnt, ULONG& ALRR_FetchEntry, DWORD AI_Milliseconds=INFINITE, BOOL AB_Alertable=TRUE) + { + return ::GetQueuedCompletionStatusEx(mh_IOCP, AP_OvlpEntry, AI_EntryCnt, &ALRR_FetchEntry, AI_Milliseconds, AB_Alertable)==TRUE; + }/* + bool GetStatusEx(OVERLAPPED_ENTRY* AP_OvlpEntry, ULONG AI_EntryCnt, ULONG& ALRR_FetchEntry, DWORD AI_Milliseconds=INFINITE, BOOL AB_Alertable=TRUE)*/ + + #endif //defined(__VISUAL_CPP_VER__) && __VISUAL_CPP_VER__>=200800 + + bool PostStatus(DWORD ADW_NumberOfBytes, ULONG_PTR APL_CompletionKey, LPOVERLAPPED AP_Overlapped=NULL) + { + return ::PostQueuedCompletionStatus(mh_IOCP, ADW_NumberOfBytes, APL_CompletionKey, AP_Overlapped)==TRUE; + }/* + bool PostStatus(DWORD ADW_NumberOfBytes, ULONG_PTR APL_CompletionKey, LPOVERLAPPED AP_Overlapped=NULL)*/ + + bool Close() + { + if(mh_IOCP==0) return true; + + bool VB_IsOK = + ::CloseHandle(mh_IOCP)==TRUE ; + + mh_IOCP=0; return VB_IsOK; + }/* + bool Close()*/ + + HANDLE GetHandle() + { + return mh_IOCP; + }/* + HANDLE GetHandle()*/ + + public: + };/* + class CWinIOCP*/ + + +#endif //defined(_WIN) + + +#ifndef _WIN + + + /*//////////////////////////////////////////////////////// + + ■ RLIMIT_CPU // 초 단위의 CPU 시간 + RLIMIT_FSIZE // 최대 파일 크기 + RLIMIT_DATA // 최대 데이타 크기 + RLIMIT_STACK // 최대 스택 크기 + RLIMIT_CORE // 최대 코어 파일 크기 + RLIMIT_RSS // 최대 거주 집합 크기 + RLIMIT_NPROC // 최대 프로세스 수 + RLIMIT_NOFILE // 최대 열 수 있는 파일의 수 + RLIMIT_MEMLOCK // 최대 잠긴 기억 장소 주소 공간 + RLIMIT_AS // 주소 공간(가상 메모리) 제한값 + + 만일 RLIM_INFINITY 로 설정되었다면 자원은 무제한이다. + RLIMIT_OFILE는 RLIMIT_NOFILE에대한 BSD 이름이다. + + ■ rlimit 구조체는 다음과 같다: + + struct rlimit + { + rlim_t rlim_cur; + rlim_t rlim_max; + }; + + ■ -- 2010-02-10 22:43:00 + + ■ http://carenam.egloos.com/9515070 + + ulimit -c 해서 core file size가 0 으로 되어 있다면 core file 이 생성되지 않음(linux 최초 기본값). + + Core file size 변경 방법입니다. + + 방법1: ulimit -c unlimited <-- 한시적인 적용 (rebooting 후 해제 됨) + 방법2: /etc/profile 파일 변경 <-- rebooting 후에도 설정 유지 됨 + + # No core files by default + ulimit -S -c 0 > /dev/null 2>&1 부분을 아래와 같이 수정 + ulimit -S -c unlimited > /dev/null 2>&1 + # source /etc/profile <-- /etc/profile을 수정 하였으므로 설정 값 적용. + + /etc/security/limits.conf 파일 변경 + * soft core -1 추가 + * hard core -1 추가 ( -1은 무한 의미 ) + + ulimit -a 또는 ulimit -c 로 확인 <-- core file 생성 적용 여부 확인 (unlimited 또는 설정파일 크기) + + -- 2010-05-19 23:12:00 + + ////////////////////////////////////////////////////////*/ + + template class CResrcLimit_T : public rlimit + { + public: + + TLimitSize GetCurSize() const + { + return this->rlim_cur; + }/* + TLimitSize GetCurSize() const*/ + + TLimitSize GetMaxSize() const + { + return this->rlim_max; + }/* + TLimitSize GetMaxSize() const*/ + + void SetCurSize(TLimitSize AI_LimitSize) + { + this->rlim_cur=AI_LimitSize; + }/* + void SetCurSize(TLimitSize AI_LimitSize)*/ + + void SetMaxSize(TLimitSize AI_LimitSize) + { + this->rlim_max=AI_LimitSize; + }/* + void SetMaxSize(TLimitSize AI_LimitSize)*/ + + void SetSize(TLimitSize AI_CurSize, TLimitSize AI_MaxSize) + { + this->rlim_cur=AI_CurSize; + this->rlim_max=AI_MaxSize; + }/* + void SetSize(TLimitSize AI_CurSize, TLimitSize AI_MaxSize)*/ + + bool GetInfo(int AI_Resource) + { + ::getrlimit(AI_Resource, this)==0; + }/* + bool GetInfo(int AI_Resource)*/ + + void SetInfo(int AI_Resource) + { + ::setrlimit(AI_Resource, this)==0; + }/* + void SetInfo(int AI_Resource)*/ + + public: + };/* + template class CResrcLimit_T : public rlimit */ + + + /*/////////////////////////////////////// + + ■ struct iovec + { + void* iov_base; // Starting address + size_t iov_len ; // Number of bytes + }; + + ■ -- 2010-04-17 20:15:00 + + ///////////////////////////////////////*/ + + + template class ZtCIOBuffVec + { + public : + enum{EInvalidPos=-1 }; + enum{EVecSize =TVecSize}; + public : + typedef ::iovec StIOBuff; + protected: + ::iovec mo_IOBuff[TVecSize]; + ZTypLength mi_HeadPos ; // TVecSize 에서 유효한 처음 위치 + ZTypLength mi_TailPos ; // TVecSize 에서 유효한 마지막 위치 + ZTypLength ml_AllLen ; // 전체 버퍼 길이 + public : + + static char* GetCharsInVec ( StIOBuff& AR_StIOBuff){return (char*) AR_StIOBuff.iov_base;} + static const char* GetCharsInVec (const StIOBuff& AR_StIOBuff){return (const char*)AR_StIOBuff.iov_base;} + static size_t GetLengthInVec(const StIOBuff& AR_StIOBuff){return AR_StIOBuff.iov_len ;} + + static void InitStIOBuff(StIOBuff& ARR_StIOBuff) + { + ARR_StIOBuff.iov_base=0; + ARR_StIOBuff.iov_len =0; + }/* + static void InitStIOBuff(StIOBuff& ARR_StIOBuff)*/ + + /*public:*/ + public: + + ZtCIOBuffVec() + { + Init(); + }/* + ZtCIOBuffVec()*/ + + void Init() + { + mi_HeadPos=EInvalidPos; + mi_TailPos=EInvalidPos; + ml_AllLen =0 ; + }/* + void Init()*/ + + ZTypLength GetSize() const + { + return mi_HeadPos<=EInvalidPos ? 0 : (mi_TailPos-mi_HeadPos+1) ; + }/* + ZTypLength GetSize() const*/ + + ZTypLength GetAllLength() const + { + return ml_AllLen; + }/* + ZTypLength GetAllLength() const*/ + + bool IsFull() const + { + return GetSize()==EVecSize; + }/* + bool IsFull() const*/ + + StIOBuff& operator[](ZTypLength AI_Index) + { + return mo_IOBuff[AI_Index]; + }/* + StIOBuff& operator[](ZTypLength AI_Index)*/ + + const StIOBuff& operator[](ZTypLength AI_Index) const + { + return mo_IOBuff[AI_Index]; + }/* + const StIOBuff& operator[](ZTypLength AI_Index) const*/ + + bool IsEqual(ZTypLength AI_BuffIndex, char* APC_Buff, ZTypLength AI_Length) + { + // AI_BuffIndex 번 원소가 APC_Buff, AI_Length 인지 확인하는 함수. + // 주로 DEBUG 목적으로 설계한 함수이다. + + if(AI_BuffIndex<0 || AI_BuffIndex>=EVecSize) + { return false; } + + return GetCharsInVec (mo_IOBuff[AI_BuffIndex])==APC_Buff && + GetLengthInVec(mo_IOBuff[AI_BuffIndex])==AI_Length ; + ////// + }/* + bool IsEqual(ZTypLength AI_BuffIndex, char* APC_Buff, ZTypLength AI_Length)*/ + + bool AddBuff(char* APC_Buff, ZTypLength AI_Length) + { + if(AI_Length<1 || mi_TailPos+1>=TVecSize) + { return false; } + + if(mi_HeadPos<=EInvalidPos) + { mi_HeadPos=0; } + + mo_IOBuff[++mi_TailPos].iov_base=APC_Buff ; + mo_IOBuff[ mi_TailPos].iov_len =AI_Length; + + ml_AllLen+=AI_Length; return true; + }/* + bool AddBuff(char* APC_Buff, ZTypLength AI_Length)*/ + + template bool AddBuffCStr(TString& AR_CString) + { + return AddBuff(AR_CString.data(), AR_CString.size()); + }/* + template bool AddBuffCStr(TString& AR_CString)*/ + + int MinusLength(ZTypLength AL_Length, ZTypLength* APL_LastInvalidByte=0) + { + /*////////////////////////////////////////////////////////////////////// + + ■ mo_WSABuff 의 유효버퍼에서 AL_Length 만큼 처리가 된 것으로 셋팅한다. + + ■ int VI_EmptyBuffCnt(처리 후 비어 있게 되는 버퍼 갯수)를 반환한다. + + ■ long* APL_LastInvalidByte 에 유효한 mo_IOBuff 중 마지막 원소에서 무효 + 화되는 바이트 길이를 전달한다. + + //////////////////////////////////////////////////////////////////////*/ + + if(AL_Length<1 ) return 0 ; + if(ml_AllLen=std::IntI(VP_IOBuff->iov_len)) + { + AL_Length -= VP_IOBuff->iov_len; + ml_AllLen -= VP_IOBuff->iov_len; + + ++VI_EmptyBuffCnt; + + if(++mi_HeadPos>mi_TailPos) + { + Init(); return VI_EmptyBuffCnt; + } + if(AL_Length<=0) + { + return VI_EmptyBuffCnt; + }/* + if(AL_Length<=0)*/ + } + else // AL_Lengthiov_len) + { + if(APL_LastInvalidByte!=0) + *APL_LastInvalidByte=AL_Length; + + VP_IOBuff->iov_base = (char*)(VP_IOBuff->iov_base)+AL_Length; + VP_IOBuff->iov_len -= AL_Length; + ml_AllLen -= AL_Length; + + return VI_EmptyBuffCnt; + }/* + else // AL_Lengthiov_len)*/ + + ++VP_IOBuff; + }/* + for(int i=mi_HeadPos; i<=mi_TailPos; ++i)*/ + + return VI_EmptyBuffCnt; + }/* + int MinusLength(ZTypLength AL_Length, ZTypLength* APL_LastInvalidByte=0)*/ + + StIOBuff* GetHeadBuffPtr() + { + return mi_HeadPos<=EInvalidPos ? 0 : mo_IOBuff+mi_HeadPos ; + }/* + StIOBuff* GetHeadBuffPtr()*/ + + void MoveFirst() + { + if(mi_HeadPos<1) return; + + int VI_Index=0 ; + int i =mi_HeadPos; + + int VI_ValidBuffCnt=GetSize(); + + for(; i<=mi_TailPos; ++i) + { + mo_IOBuff[VI_Index++]=mo_IOBuff[i]; + }/* + for(; i<=mi_TailPos; ++i)*/ + + // mi_HeadPos 개 만큼을 앞으로 이동시켰으므로 + // 이 다음 유효하지 않은 mi_HeadPos 개 StIOBuff 버퍼를 초기화한다. + + for(i=0; i void SetInfoCStr( + TString& ARR_CStringInfo, const char* APC_Indent="") + { + // 이 함수는 주로 DEBUG 를 위해 설계하였다. + + ARR_CStringInfo(APC_Indent)("All Buffer Cnt=")(EVecSize) ("\r\n"); + ARR_CStringInfo(APC_Indent)("Use Buffer Cnt=")(GetSize()) ("\r\n"); + ARR_CStringInfo(APC_Indent)("All Byte Cnt=")(GetAllLength())("\r\n"); + ARR_CStringInfo(APC_Indent)("HeadPos=")(mi_HeadPos)(", TailPos=")(mi_TailPos)("\r\n"); + + if(mi_HeadPos<=EInvalidPos) return; + + for(int i=mi_HeadPos; i<=mi_TailPos; ++i) + { + ARR_CStringInfo(APC_Indent)("i=")(i)(" : Length=")(GetLengthInVec(mo_IOBuff[i]))("\r\n"); + ARR_CStringInfo(APC_Indent)(" Data=\"")(GetCharsInVec(mo_IOBuff[i]),GetLengthInVec(mo_IOBuff[i]))("\"\r\n"); + }/* + for(int i=mi_HeadPos; i<=mi_TailPos; ++i)*/ + }/* + template void SetInfoCStr( + TString& ARR_CStringInfo, const char* APC_Indent="") */ + + public: + };/* + template class ZtCIOBuffVec*/ + + + template<> class ZtCIOBuffVec<0> + { + public: + enum{EInvalidPos=-1}; + enum{EVecSize = 0}; + public: + typedef ::iovec StIOBuff; + public: + + ZtCIOBuffVec(){} + + void Init(){} + + int GetSize() const {return 0;} + + bool AddBuff( + char* APC_Buff, ZTypLength AI_Length){return false;} + + void MinusLength(long AL_Length){} + + StIOBuff* GetHeadBuffPtr(){return 0;} + + void MoveFirst(){} + + public: + };/* + template<> class ZtCIOBuffVec<0>*/ + + +#endif //!_WIN + +}/* +namespace std */ + + +/*/////////////////////////////////////////////////////////////////////////////////////// + +■ ZCDir 클래스에서 사용된 readdir() 함수를 _REENTRANT 매크로가 정의되어 있는 경우, + readdir_r() 을 사용하는 것으로 바꾸었다. man 페이지에서는 readdir_r() 대신에 + getdents() 을 사용할 것을 권고하고 있으나, freebsd 에서는 인수가 약간 다르고, + 실제 테스트에 자꾸 core dump 가 발생하여 readdir_r() 을 사용하는 것으로 하였다. + + int getdents(unsigned int fd, struct dirent* dirp, unsigned int count ); // In Linux + int getdents(int fd , char *buf , int nbytes); // In FreeBSD + int getdents(int fildes , struct dirent *buf , size_t nbyte ); // In solaris + + OS 별로 선언이 다른 것이 지저분해 보인다. + + -- 2012-05-07 01:19:00 + + 그리고 getdents() 보다 readdir_r() 을 사용한 것이 결국 좋았다. AIX(115.21.49.210)에서 + 확인 결과, getdents() 는 없어도 readdir_r() 은 있었다. 즉 readdir_r() 이 좀 더 많은 OS + 에서 지원된다고 봐도 된다. (2012-05-07 01:27:00) + +///////////////////////////////////////////////////////////////////////////////////////*/ + + +#endif //__ZCPPMAIIN__MAINHEAD_EX_H__ diff --git a/ZCppMain/ZMainXhtml.H b/ZCppMain/ZMainXhtml.H new file mode 100644 index 0000000..82b1707 --- /dev/null +++ b/ZCppMain/ZMainXhtml.H @@ -0,0 +1,38 @@ + + +#ifndef __ZCPPMAIIN__ZMAINXHTML_H__ +#define __ZCPPMAIIN__ZMAINXHTML_H__ + + +namespace ZNsMain +{ + + template TStringData& ZftConvertXhtml(TStringData& ARR_CString) + { + /* Ÿ ״ Ŭ̾Ʈ ϸ + HTML ±׿ ȥ ִµ ̸ ϱ + ڵѴ. + */ + return ARR_CString. + Replace("&" ,"&" ). Replace("<" ,"<" ). + Replace(">" ,">" ). Replace(" " ," " ). + Replace("\n","
" ); + }/* + template static TStringData& ConvertXhtml(TStringData& ARR_CString) */ + + template TStringData& ZftConvertXhtmlAtt(TStringData& ARR_CString) + { + // X(H)TML Ӽ ִ ڵѴ. + + return ARR_CString. + Replace("&" ,"&" ). Replace("<" ,"<" ). + Replace(">" ,">" ). Replace("\"",""" ). + Replace("\r"," " ). Replace("\n"," " ); + }/* + template TStringData& ZftConvertXhtmlAtt(TStringData& ARR_CString) */ + +}/* +namespace ZNsMain*/ + + +#endif // __ZCPPMAIIN__ZMAINXHTML_H__ diff --git a/ZCppMain/ZtCArray.H b/ZCppMain/ZtCArray.H index 8fab347..3cca7d7 100644 --- a/ZCppMain/ZtCArray.H +++ b/ZCppMain/ZtCArray.H @@ -1,7 +1,7 @@ + - -#ifndef __ZTCARRAY_H__ -#define __ZTCARRAY_H__ +#ifndef __ZCPPMAIIN__ZTCARRAY_H__ +#define __ZCPPMAIIN__ZTCARRAY_H__ #include "ZCppMain/ZMainHead.H" @@ -10,15 +10,17 @@ namespace ZNsMain { - template< typename Type , - typename TypeArg=const Type&, + template< typename TType , + typename TTypArg=const TType&, typename TSize =long > - class ZtCArray ///////////////////////// + class ZtCArray ////////////////////////// { public: + typedef TType Type ; + typedef TType TypeData; + typedef TTypArg TypeArg ; typedef TSize TypeSize; - typedef Type TypeData; typedef ZtCArray ZCArray ; public: class ZCIterator; @@ -428,9 +430,8 @@ namespace ZNsMain ++VP_TypeArr; - /* ZtCTypeData 으로 인해서, AO_Functor 이 함수일 때 뿐이 아니라, - operator() 연산자를 가진 object 포인터일 때도 사용할 수 있게 되었다. - */ + /* ZtCTypeData 으로 인해서, AO_Functor 이 함수일 때뿐이 아니라, + operator() 연산자를 가진 object 포인터일 때도 사용할 수 있게 되었다. */ }/* __for0(TypeSize, i, ml_UseSize)*/ }/* @@ -459,10 +460,87 @@ namespace ZNsMain 형태를 사용하면 좋을 것 같다. -- 2014-06-16 23:11:00 - ZCCheckRef::PassData() 으로 인해, 인수를 ZtCRef 클래스를 이용해 인수를 참조 - 로 넘길 수 있게 되었다. -- 2021-03-10 16:56 + ZCCheckRef::PassData() 으로 인해, 인수를 ZtCRef 클래스를 이용해 인수를 참조 + 로 넘길 수 있게 되었다. -- 2021-03-10 16:56 - 이제는 ZtCRef 과 ZCCheckRef 클래스 템플릿을 사용하면 된다. -- 2021-03-11 11:00 + 이제는 ZtCRef 과 ZCCheckRef 클래스 템플릿을 사용하면 된다. -- 2021-03-11 11:00 + + 이제는 ZftMCR() 과 ZftMCP() 을 사용하면 된다. -- 2025-08-07 17:55 + + ■ 예제1 -- 2025-08-07 17:35 + + #include + + #include "ZCppMain/ZtCArray.H" + + + using namespace std ; + using namespace ZNsMain; + + int main() + { + ZtCArray myArray; + + myArray.AddTail(10); + myArray.AddTail(20); + myArray.AddTail(30); + myArray.AddTail(40); + + class CHelpObj + { + public: + + CHelpObj() + { + } + + CHelpObj(const CHelpObj& rhs) + { + cout<<"* CHelpObj(const CHelpObj& rhs)"<::GetObjRef(AO_Functor) - ( - *VP_TypeArr, ZCCheckRef::PassData(AO_TypeHelp) - ); + ( + *VP_TypeArr, ZCCheckRef::PassData(AO_TypeHelp) + ); ++VP_TypeArr; /////////////////////////////////////// }/* __for0(TypeSize, i, ml_UseSize)*/ @@ -486,8 +564,7 @@ namespace ZNsMain template - void IterElement(TFunctor AO_Functor, - TTypeHelp1 AO_TypeHelp1, TTypeHelp2 AO_TypeHelp2) + void IterElement(TFunctor AO_Functor, TTypeHelp1 AO_TypeHelp1, TTypeHelp2 AO_TypeHelp2) { /*///////////////////////////////////////////////////////////////////////////// @@ -531,8 +608,7 @@ namespace ZNsMain __for0(TypeSize, i, ml_UseSize)*/ }/* template - void IterElement(TFunctor AO_Functor, - TTypeHelp1 AO_TypeHelp1, TTypeHelp2 AO_TypeHelp2)*/ + void IterElement(TFunctor AO_Functor, TTypeHelp1 AO_TypeHelp1, TTypeHelp2 AO_TypeHelp2)*/ /*/////////////////////////////////////////////////////////////////////////// @@ -540,32 +616,92 @@ namespace ZNsMain ■ IterElement() 예제. #include - #include "ZCArray.H" + #include "ZCppMain/ZtCArray.H" + using namespace std ; using namespace ZNsMain; + int main() { - std:: ZtCArray myArray; + typedef ZtCArray CArray ; + typedef CArray::IterEasy IterEasy; - myArray.AddTail(10); - myArray.AddTail(20); - myArray.AddTail(30); - myArray.AddTail(40); + + CArray VO_Array; + + VO_Array.AddTail(10); + VO_Array.AddTail(20); + VO_Array.AddTail(30); + VO_Array.AddTail(40); + + class CHelpObj + { + public: + + CHelpObj() + { + } + + CHelpObj(const CHelpObj& rhs) + { + cout<<"* CHelpObj(const CHelpObj& rhs)"< + class ZtCLoadDataBlock; /////////////////// + + + namespace ZNsInterface + { + + template class ZtCChildLoadDataBlock + { + public : + + template< typename TyDerive , //////////////// + typename TyString , + bool TyBoIncMark + > + friend class ZtCLoadDataBlock; ///////////////// + + public : + typedef typename TStringData::TypeData TypeChar; + protected: + + ZERun ExecBlockIn(const TStringData& AR_CStringData) + { + cout<<"Search Data Block IN =>\""< ZERun ExecBlockIn + (const TStringData& AR_CStringData, THelpObj AO_HelpObj) + { + cout<<"Help:Search Data Block IN =>\""< ZERun ExecBlockIn + (const TStringData& AR_CStringData, THelpObj AO_HelpObj)*/ + + + ZERun ExecBlockOut(const TypeChar* AP_Data, ZTypLength AL_Length) + { + if(AL_Length>0) + cout<<"Search Data Block OUT=>\"" ; + else cout<<"Search Data Block OUT=>\"NULL"; + + for(ZTypLength i=0; i ZERun ExecBlockOut + (const TypeChar* AP_Data, ZTypLength AL_Length, THelpObj AO_HelpObj) + { + if(AL_Length>0) + cout<<"Help:Search Data Block OUT=>\"" ; + else cout<<"Help:Search Data Block OUT=>\"NULL"; + + for(ZTypLength i=0; i ZERun ExecBlockOut ZERun ExecBlockOut + (const TypeChar* AP_Data, ZTypLength AL_Length, THelpObj AO_HelpObj)*/ + + protected: + };/* + template class ZtCChildLoadDataBlock */ + + }/* + namespace ZNsInterface*/ + + + /* 찾은 2 개 문자열 사이에 있는 문자열 블럭에 대하여 특정한 처리를 해준다. + 찾은 2 개 문자열 사이에 아무 문자열이 없더라도 지정된 함수를 호출한다. */ + + template< typename TDerive , // ZNsIFace::ZtCChildLoadDataBlock<> + typename TStringData, + bool TBooIncMark =false + > + class ZtCLoadDataBlock //////////////// + { + public : + typedef TStringData ZCStringData; + typedef typename ZCStringData::ZCMainChars ZCMainChars ; + typedef typename ZCStringData::TypeChar TypeChar ; + typedef typename ZCStringData::TypeLength TypeLength ; + public : + typedef TStringData TypeData; + protected: + + TStringData mo_StartMarkCStr; + TStringData mo_CloseMarkCStr; + TStringData mo_MarkBuffCStr ; // FindPosReady() 함수를 위한 버퍼 + TStringData mo_BlockBuffCStr; // mo_StartMarkCStr, mo_CloseMarkCStr 사이에 있는 데이타는 여기에 쌓아둔다. + bool mb_DoFindStart ; // mo_StartMarkCStr 을 찾은 상태라면 true + + #define __GET_CHILD_OBJ__ (static_cast(*this)) + + /*protected:*/ + public : + + _NP_ ZERun OnMeetNormal(const TypeChar* APC_Data, TypeLength AL_Length) + { + if(mb_DoFindStart==true) + { + if(TBooIncMark==true && mo_BlockBuffCStr.size()<1) + { mo_BlockBuffCStr.append(mo_StartMarkCStr); } + + mo_BlockBuffCStr.append(APC_Data, AL_Length); + + return ZERun_OK; //////////////////////////// + }/* + if(mb_DoFindStart==true)*/ + + return __GET_CHILD_OBJ__.ExecBlockOut(APC_Data, AL_Length); + }/* + _NP_ ZERun OnMeetNormal(const TypeChar* APC_Data, TypeLength AL_Length)*/ + + template _NP_ ZERun OnMeetNormal( + const TypeChar* APC_Data, TypeLength AL_Length, THelpType AO_CHelpType) + { + typedef ZNsMain::ZtCCheckRef ZCCheckRef; + + if(mb_DoFindStart==true) + { + if(TBooIncMark==true && mo_BlockBuffCStr.size()<1) + { mo_BlockBuffCStr.append(mo_StartMarkCStr); } + + mo_BlockBuffCStr.append(APC_Data, AL_Length); + + return ZERun_OK; //////////////////////////// + }/* + if(mb_DoFindStart==true)*/ + + return __GET_CHILD_OBJ__.ExecBlockOut + ( + APC_Data, AL_Length, ZCCheckRef::PassData(AO_CHelpType) + ); + ///////////////////////////////////// + }/* + template _NP_ ZERun OnMeetNormal( + const TypeChar* APC_Data, TypeLength AL_Length, THelpType AO_CHelpType) */ + + _NP_ ZERun OnMeetReady + ( + const TypeChar* APC_Data, TypeLength AL_Length, ZERun AE_ERun + ) + /*##################*/ + { + if(AE_ERun==ZERun_OK) return ZERun_OK; + + if(mb_DoFindStart==true) + { + /*////////////////////////////////////////////////////////////////////////////////////////////////// + + ■ mo_StartMarkCStr 은 이미 찾은 상태에서 mo_CloseMarkCStr 을 찾았기 때문에 이 함수가 호출된 것이다. + 이때는 mo_CloseMarkCStr 을 찾기 전까지 모아 두었던 데이타 mo_BlockBuffCStr 을 출력하고 내용을 비 + 운다. 이 함수 수행이 끝나면 바로 mb_DoFindStart 는 false 가 된다. + + //////////////////////////////////////////////////////////////////////////////////////////////////*/ + + if(TBooIncMark==true) mo_BlockBuffCStr.append(mo_CloseMarkCStr); + + if(__GET_CHILD_OBJ__.ExecBlockIn(mo_BlockBuffCStr)==ZERun_NO) + { + mo_BlockBuffCStr=""; return ZERun_NO; + }/* + if(__GET_CHILD_OBJ__.ExecBlockIn(mo_BlockBuffCStr)==ZERun_NO)*/ + + mo_BlockBuffCStr=""; + }/* + if(mb_DoFindStart==true)*/ + + return ZERun_OK; + }/* + _NP_ ZERun OnMeetReady + ( + const TypeChar* APC_Data, TypeLength AL_Length, ZERun AE_ERun + ) + ####################*/ + + + template _NP_ ZERun OnMeetReady + ( + const TypeChar* APC_Data, TypeLength AL_Length, + ZERun AE_ERun , THelpType AO_CHelpType + ) + /*###############################################*/ + { + typedef ZNsMain:: + ZtCCheckRef ZCCheckRef; + + if(AE_ERun==ZERun_OK) return ZERun_OK; + + if(mb_DoFindStart==true) + { + /*////////////////////////////////////////////////////////////////////////////////////////////////// + + ■ mo_StartMarkCStr 은 이미 찾은 상태에서 mo_CloseMarkCStr 을 찾았기 때문에 이 함수가 호출된 것이다. + 이때는 mo_CloseMarkCStr 을 찾기 전까지 모아 두었던 데이타 mo_BlockBuffCStr 을 출력하고 내용을 비 + 운다. 이 함수 수행이 끝나면 바로 mb_DoFindStart 는 false 가 된다. + + //////////////////////////////////////////////////////////////////////////////////////////////////*/ + + if(TBooIncMark==true) + { mo_BlockBuffCStr.append(mo_CloseMarkCStr); } + + if ( __GET_CHILD_OBJ__.ExecBlockIn + ( + mo_BlockBuffCStr, ZCCheckRef::PassData(AO_CHelpType) + ) + ==ZERun_NO + ) + /////////////////////////////////// + { + mo_BlockBuffCStr=""; return ZERun_NO; + } + /////////////////////////////////// + + mo_BlockBuffCStr = ""; + }/* + if(mb_DoFindStart==true)*/ + + return ZERun_OK; + }/* + template _NP_ ZERun OnMeetReady + ( + const TypeChar* APC_Data, TypeLength AL_Length, + ZERun AE_ERun , THelpType AO_CHelpType + ) + #################################################*/ + + /*public:*/ + public: + + ZtCLoadDataBlock() + { + mb_DoFindStart=false; + }/* + ZtCLoadDataBlock()*/ + + ~ZtCLoadDataBlock() + { + }/* + ~ZtCLoadDataBlock()*/ + + TStringData& GetStartMark(){return mo_StartMarkCStr;} + TStringData& GetCloseMark(){return mo_CloseMarkCStr;} + TStringData& GetMarkBuff (){return mo_MarkBuffCStr ;} + + ZERun LoadData(const TypeChar* APC_Data, TypeLength AL_Length) + { + bool VB_IsOK =false ; + TypeLength VL_StartPos=0 ; + ZERun VE_ERun =ZERun_OK ; + + do //// + { + if(mb_DoFindStart==false) + { + VB_IsOK = ZCMainChars::template + FindPosReady + ( + *this , + APC_Data , + mo_StartMarkCStr.data() , + AL_Length , + mo_StartMarkCStr.size() , + RR(mo_MarkBuffCStr) , + RR(VL_StartPos) , + RR(VE_ERun) + ); + //////////////////////////////////////////////// + + if(VB_IsOK==true) mb_DoFindStart=true; + } + else // mb_DoFindStart==true + { + VB_IsOK=ZCMainChars::template + FindPosReady + ( + *this , + APC_Data , + mo_CloseMarkCStr.data() , + AL_Length , + mo_CloseMarkCStr.size() , + RR(mo_MarkBuffCStr) , + RR(VL_StartPos) , + RR(VE_ERun) + ); + //////////////////////////////////////////////// + + if(VB_IsOK==true) mb_DoFindStart=false; + }/* + else // mb_DoFindStart==true */ + } + while(VB_IsOK==true && VE_ERun==ZERun_OK); + + return VE_ERun; ////////////////////////// + }/* + ZERun LoadData(const TypeChar* APC_Data, TypeLength AL_Length)*/ + + ZERun LoadData(const TStringData& AR_CStringData) + { + return LoadData(AR_CStringData.data(), AR_CStringData.size()); + }/* + ZERun LoadData(const TStringData& AR_CStringData)*/ + + + template ZERun LoadData( + const TStringData& AR_CStringData, THelpType AO_CHelpType) + { + return LoadData /////////////// + ( + AR_CStringData.data(), AR_CStringData.size(), AO_CHelpType + ); + ////////////////////////////////////////// + }/* + template ZERun LoadData( + const TStringData& AR_CStringData, THelpType AO_CHelpType) */ + + template ZERun LoadData( + const TypeChar* APC_Data, TypeLength AL_Length, THelpType AO_CHelpType) + { + typedef ZNsMain:: + ZtCCheckRef ZCCheckRef; + typedef ZCCheckRef::TypeData TypeObject; + + bool VB_IsOK =false ; + ZTypLength VL_StartPos=0 ; + ZERun VE_ERun =ZERun_OK ; + + do //// + { + if(mb_DoFindStart==false) + { + VB_IsOK = ZCMainChars::template FindPosReady + + ( + *this + , ZCCheckRef::PassData(AO_CHelpType) + , APC_Data + , mo_StartMarkCStr.data() + , AL_Length + , mo_StartMarkCStr.size() + , RR(mo_MarkBuffCStr) + , RR(VL_StartPos ) + , RR(VE_ERun ) + ); + //////////////////////////////////////////////// + + if(VB_IsOK==true) mb_DoFindStart=true; + } + else // mb_DoFindStart==true + { + VB_IsOK = ZCMainChars::template FindPosReady + + ( + *this + , ZCCheckRef::PassData(AO_CHelpType) + , APC_Data + , mo_CloseMarkCStr.data() + , AL_Length + , mo_CloseMarkCStr.size() + , RR(mo_MarkBuffCStr) + , RR(VL_StartPos ) + , RR(VE_ERun ) + ); + //////////////////////////////////////////////// + + if(VB_IsOK==true) mb_DoFindStart=false; + }/* + else // mb_DoFindStart==true*/ + } + while(VB_IsOK==true && VE_ERun==ZERun_OK); + + return VE_ERun; ////////////////////////////////////// + }/* + template ZERun LoadData( + const TypeChar* APC_Data, TypeLength AL_Length, THelpType AO_CHelpType) */ + + + void InitBuff() + { + mb_DoFindStart =false; + + mo_MarkBuffCStr =""; + mo_BlockBuffCStr=""; + }/* + void InitBuff()*/ + + void FiniBuff() + { + if(mb_DoFindStart==true ) __GET_CHILD_OBJ__. + ExecBlockOut(mo_StartMarkCStr.data(), mo_StartMarkCStr.size()); + if(mo_BlockBuffCStr.size()>0) __GET_CHILD_OBJ__. + ExecBlockOut(mo_BlockBuffCStr.data(), mo_MarkBuffCStr.size()); + if(mo_MarkBuffCStr .size()>0) __GET_CHILD_OBJ__. + ExecBlockOut(mo_MarkBuffCStr. data(), mo_MarkBuffCStr. size()); + }/* + void FiniBuff()*/ + + template void FiniBuff(THelpType AO_CHelpType) + { + typedef ZNsMain::ZtCCheckRef ZCCheckRef; + + if(mb_DoFindStart==true ) __GET_CHILD_OBJ__.ExecBlockOut + (mo_StartMarkCStr.data(), mo_StartMarkCStr.size(), ZCCheckRef::PassData(AO_CHelpType)); + if(mo_BlockBuffCStr.size()>0) __GET_CHILD_OBJ__.ExecBlockOut + (mo_BlockBuffCStr.data(), mo_BlockBuffCStr.size(), ZCCheckRef::PassData(AO_CHelpType)); + if(mo_MarkBuffCStr .size()>0) __GET_CHILD_OBJ__.ExecBlockOut + (mo_MarkBuffCStr. data(), mo_MarkBuffCStr. size(), ZCCheckRef::PassData(AO_CHelpType)); + }/* + template void FiniBuff(THelpType AO_CHelpType) */ + + + #undef __GET_CHILD_OBJ__ + + + public: + };/* + template< typename TDerive , + typename TStringData , + bool TBooIncMark =false + > + class ZtCLoadDataBlock //////////////*/ + + + + namespace ZNsType + { + + template< typename TStringData , + typename TTypeBase = ZNsIFace:: + ZtCChildLoadDataBlock, + bool TBooIncMark=false + > + class ZtCTypeLoadDataBlock ////////////////////////////////////////////////// + { + public: + + class ZCLoadDataBlock : + public TTypeBase, public ZNsMain::ZtCLoadDataBlock + < + ZCLoadDataBlock, TStringData, TBooIncMark + > + /////////////////////////////////////////////////////// + { };/* + class CTypeLoadDataBlock ////////////////////////////*/ + + typedef TStringData ZCStringData; + typedef typename ZCStringData::ZCMainChars ZCMainChars ; + typedef typename ZCStringData::TypeChar TypeChar ; + typedef typename ZCStringData::TypeLength TypeLength ; + typedef ZCLoadDataBlock TypeMain ; + + public: + };/* + template< typename TStringData , + typename TTypeBase =ZNsIFace:: + ZtCChildLoadDataBlock, + bool TBooIncMark=false + > + class ZtCTypeLoadDataBlock ////////////////////////////////////////////////*/ + + }/* + namespace ZNsType*/ + + + namespace ZNsExam + { + + /*////////////////////////////////////////////////// + + ■ ZCMainChars::FindPosReady<>(~) 함수를 이용한 예제. + + //////////////////////////////////////////////////*/ + + + template class ZtCExamReadyExec + { + public : + typedef ZNsMain::ZCMainChars ZCMainChars; + protected: + TStringData mo_StartMarkCStr ; + TStringData mo_CloseMarkCStr ; + TStringData mo_MarkBuffCStr ; + TStringData mo_BuffMarkExCStr; + TStringData mo_BlockBuffCStr ; // mo_StartMarkCStr, mo_CloseMarkCStr 사이에 있는 데이타는 여기에 쌓아둔다. + bool mb_DoFindStart ; // mo_StartMarkCStr 을 찾을 상태라면 true + public : + + ZtCExamReadyExec() + { + mo_StartMarkCStr="{◆◆◆◆◆{"; + mo_CloseMarkCStr="}◆◆◆◆◆}"; + mb_DoFindStart =false; + }/* + ZtCExamReadyExec()*/ + + ~ZtCExamReadyExec() + { + ShowMarkBuff(); + }/* + ~ZtCExamReadyExec()*/ + + TStringData& GetStartMark(){return mo_StartMarkCStr;} + TStringData& GetCloseMark(){return mo_CloseMarkCStr;} + + const TStringData& GetStartMark() const {return mo_StartMarkCStr;} + const TStringData& GetCloseMark() const {return mo_CloseMarkCStr;} + + ZERun OnMeetNormal(const char* APC_Data, ZTypLength AL_Length) + { + if(mb_DoFindStart==true) + mo_BlockBuffCStr.append(APC_Data, AL_Length); + else + { TStringData VO_CString(APC_Data, AL_Length); + + cout<<"OnMeetNormal ="< ZERun OnMeetNormal + (const char* APC_Data, ZTypLength AL_Length, THelpType AO_CHelpType) + { + if(mb_DoFindStart==true) + mo_BlockBuffCStr.append(APC_Data, AL_Length); + else + { TStringData VO_CString(APC_Data, AL_Length); + + cout<<"THelpType ☞ "< ZERun OnMeetReady + (const char* APC_Data, ZTypLength AL_Length, ZERun AE_ERun, THelpType AO_CHelpType) + { + if(AE_ERun==ZERun_OK) + { + mo_BuffMarkExCStr.append(APC_Data,AL_Length); return ZERun_OK; + }/* + if(AE_ERun==ZERun_OK)*/ + + if(mb_DoFindStart==true) + { + cout<<"♣♣Body♣♣ ="< ZERun OnMeetReady + (const char* APC_Data, ZTypLength AL_Length, ZERun AE_ERun, THelpType AO_CHelpType) */ + + void LoadData(const char* APC_Data, ZTypLength AL_Length) + { + bool VB_IsOK =false ; + ZTypLength VL_StartPos=0 ; + ZERun VE_ERun =ZERun_OK ; + + do //// + { + if(mb_DoFindStart==false) + { + VB_IsOK=ZCMainChars::FindPosReady + + ( + *this + , APC_Data + , mo_StartMarkCStr.data() + , AL_Length + , mo_StartMarkCStr.size() + , RR(mo_MarkBuffCStr) + , RR(VL_StartPos) + , RR(VE_ERun) + ); + ////////////////////////////////////////// + + if(VB_IsOK==true) mb_DoFindStart=true; + } + else // mb_DoFindStart==true + { + VB_IsOK=ZCMainChars::FindPosReady + + ( + *this + , APC_Data + , mo_CloseMarkCStr.data() + , AL_Length + , mo_CloseMarkCStr.size() + , RR(mo_MarkBuffCStr) + , RR(VL_StartPos) + , RR(VE_ERun) + ); + ////////////////////////////////////////// + + if(VB_IsOK==true) mb_DoFindStart=false; + }/* + else // mb_DoFindStart==true*/ + } + while(VB_IsOK==true); + }/* + void LoadData(const char* APC_Data, ZTypLength AL_Length)*/ + + template void LoadData( + const char* APC_Data, ZTypLength AL_Length, THelpType AO_CHelpType) + { + typedef ZNsMain::ZtCCheckRef ZCCheckRef; + typedef typename ZCCheckRef::TypeData TypeObject; + + bool VB_IsOK =false ; + ZTypLength VL_StartPos=0 ; + ZERun VE_ERun =ZERun_OK ; + + do //// + { + if(mb_DoFindStart==false) + { + VB_IsOK = ZCMainChars::FindPosReady + + ( + *this + , ZCCheckRef::PassData(AO_CHelpType) + , APC_Data + , mo_StartMarkCStr.data() + , AL_Length + , mo_StartMarkCStr.size() + , RR(mo_MarkBuffCStr) + , RR(VL_StartPos) + , RR(VE_ERun) + ); + ///////////////////////////////////////////////////// + + if(VB_IsOK==true) mb_DoFindStart=true; + } + else // mb_DoFindStart==true + { + VB_IsOK = ZCMainChars::FindPosReady + + ( + *this + , ZCCheckRef::PassData(AO_CHelpType) + , APC_Data + , mo_CloseMarkCStr.data() + , AL_Length + , mo_CloseMarkCStr.size() + , RR(mo_MarkBuffCStr) + , RR(VL_StartPos) + , RR(VE_ERun) + ); + ////////////////////////////////////////////// + + if(VB_IsOK==true) mb_DoFindStart=false; + }/* + else // mb_DoFindStart==true */ + } + while(VB_IsOK==true); + }/* + template void LoadData( + const char* APC_Data, ZTypLength AL_Length, THelpType AO_CHelpType) */ + + void ShowMarkBuff() + { + if(mo_MarkBuffCStr.size()>0) + cout<<"MarkBuff=" < class ZtCExamReadyExec*/ + + + + typedef ZNsMain::ZtCStringBase ZCStringBase; + + + class ZCLoadDataBlock1 : public ZNsMain:: + ZtCLoadDataBlock + { + protected: + + friend class ZNsMain::ZtCLoadDataBlock; + + /*////////////////////////////////////////////////////////////////////// + + ■ ZNsMain::ZtCLoadDataBlock 을 TypeBase + 로 typedef 하고 friend class TypeBase 라 하면 g++ 에서는 컴파일이 안 + 된다. + + CLoadDataBlock_test.cpp:26: error: + using typedef-name `std::CLoadDataBlock::TypeBase' after `class' + + Visual C++ 2008 에서는 컴파일되는데, 이점은 Visual C++ 쪽이 좀 더 합 + 리적인 것 같다. + + -- 2008-12-10 21:14:00 + + //////////////////////////////////////////////////////////////////////*/ + + protected: + + ZERun ExecBlockIn(const ZCStringBase& AR_CString) + { + cout<<"▷ Search Data Block IN =>\""< ZERun ExecBlockIn + (const ZCStringBase& AR_CStringData, THelpObj AO_HelpObj) + { + cout<<"Help:Search Data Block IN =>\""< ZERun ExecBlockIn + (const ZCStringBase& AR_CStringData, THelpObj AO_HelpObj)*/ + + + ZERun ExecBlockOut(const char* AP_Data, long AL_Length) + { + if(AL_Length>0) + cout<<"▷ Search Data Block OUT=>\"" ; + else cout<<"▷ Search Data Block OUT=>\"NULL"; + + for(long i=0;i ZERun ExecBlockOut + (const TypeChar* AP_Data, ZTypLength AL_Length, THelpObj AO_HelpObj) + { + if(AL_Length>0) + cout<<"▷ Help:Search Data Block OUT=>\"" ; + else cout<<"▷ Help:Search Data Block OUT=>\"NULL"; + + for(long i=0;i ZERun ExecBlockOut ZERun ExecBlockOut + (const TypeChar* AP_Data, ZTypLength AL_Length, THelpObj AO_HelpObj)*/ + + protected: + };/* + class ZCLoadDataBlock1 : public ZNsMain:: + ZtCLoadDataBlock*/ + + + class ZCLoadDataBlock2 : public ZNsMain:: + ZtCLoadDataBlock + { + protected: + + friend class ZNsMain::ZtCLoadDataBlock; + + /*////////////////////////////////////////////////////////////////////// + + ■ ZNsMain::ZtCLoadDataBlock 을 TypeBase + 로 typedef 하고 friend class TypeBase 라 하면 g++ 에서는 컴파일이 안 + 된다. + + CLoadDataBlock_test.cpp:26: error: + using typedef-name `std::CLoadDataBlock::TypeBase' after `class' + + Visual C++ 2008 에서는 컴파일되는데, 이점은 Visual C++ 쪽이 좀 더 합 + 리적인 것 같다. + + -- 2008-12-10 21:14:00 + + //////////////////////////////////////////////////////////////////////*/ + + protected: + + ZERun ExecBlockIn(const ZCStringBase& AR_CString) + { + cout<<"▷ Search2 Data Block IN =>\""< ZERun ExecBlockIn + (const ZCStringBase& AR_CStringData, THelpObj& AO_HelpObj) + { + cout<<"Help2:Search2 Data Block IN =>\""< ZERun ExecBlockIn + (const ZCStringBase& AR_CStringData, THelpObj& AO_HelpObj)*/ + + + ZERun ExecBlockOut(const char* AP_Data, long AL_Length) + { + if(AL_Length>0) + cout<<"▷ Search2 Data Block OUT=>\"" ; + else cout<<"▷ Search2 Data Block OUT=>\"NULL"; + + for(long i=0;i ZERun ExecBlockOut + (const TypeChar* AP_Data, ZTypLength AL_Length, THelpObj& AO_HelpObj) + { + if(AL_Length>0) + cout<<"▷ Help2:Search2 Data Block OUT=>\"" ; + else cout<<"▷ Help2:Search2 Data Block OUT=>\"NULL"; + + for(long i=0;i ZERun ExecBlockOut ZERun ExecBlockOut + (const TypeChar* AP_Data, ZTypLength AL_Length, THelpObj& AO_HelpObj)*/ + + protected: + };/* + class ZCLoadDataBlock2 : public ZNsMain:: + ZtCLoadDataBlock*/ + + + template class ZtCExamLoadDataBlock + { + public: + + class ZCHelpObj + { + public: + ZCHelpObj(){} + ZCHelpObj(const ZCHelpObj& rhs) + { cout<<""; } + ZCHelpObj& operator =(const ZCHelpObj& rhs) + { cout<<"" ; } + public: + }; + /////////////// + + public: + + static int Main(int AI_ArgCnt=0, const char* APA_ArgVal[]=0) + { + ZNsExam::ZCLoadDataBlock1 VO_CLoadDataBlock1; + ZNsExam::ZCLoadDataBlock2 VO_CLoadDataBlock2; + + ZCHelpObj VO_CHelpObj ; + ///////////////////////////////////////////// + + ZCStringBase VO_CStringBase1 + ( + "{{}}{{body2}}{{}}{{body4-sauron}}" + "{bad5}}{{body6}}{{body7}" + ); + ZCStringBase VO_CStringBase2 + ( + "}}" + ); + ///////////////////////////////////////////// + + VO_CLoadDataBlock1.GetStartMark()="{{"; + VO_CLoadDataBlock1.GetCloseMark()="}}"; + VO_CLoadDataBlock2.GetStartMark()="{{"; + VO_CLoadDataBlock2.GetCloseMark()="}}"; + + VO_CLoadDataBlock1.LoadData(VO_CStringBase1, VO_CHelpObj); + VO_CLoadDataBlock1.LoadData(VO_CStringBase2, VO_CHelpObj); + + VO_CLoadDataBlock1.InitBuff(); cout< class ZtCExamLoadDataBlock*/ + + }/* + namespace ZNsExam*/ + + + + namespace ZNsInterface + { + + template class ZtCParentLoadDataBlockArr + { + public: + typedef typename TStringData::TypeData TypeChar; + public: + + ZERun ExecBlockIn(const TypeChar* AP_Data, ZTypLength AL_Length, int AI_SearchArrNum) + { + cout<<"Search Data Block IN : " + "AI_SearchArrNum="<\""; + + for(ZTypLength i=0;i0) + cout<<"Search Data Block Match : AI_SearchArrNum="<\"" ; + else cout<<"Search Data Block Match : AI_SearchArrNum="<\"NULL"; + + for(ZTypLength i=0;i ZERun ExecBlockIn( + const TypeChar* AP_Data, ZTypLength AL_Length, int AI_SearchArrNum, THelpType AO_HelpType) + { + cout<<"Search Data Block IN : AI_SearchArrNum="<< + AI_SearchArrNum <<", THelpType=" << + typeid(THelpType).name()<<", Data=>\"" ; + + for(ZTypLength i=0; i ZERun ExecBlockIn( + const TypeChar* AP_Data, ZTypLength AL_Length, int AI_SearchArrNum, THelpType AO_HelpType) */ + + template ZERun ExecBlockMatch( + const TypeChar* AP_Data, ZTypLength AL_Length, int AI_SearchArrNum, THelpType AO_HelpType) + { + if(AL_Length>0) + cout<<"Search Data Block Match : AI_SearchArrNum="<\""; + else cout<<"Search Data Block Match : AI_SearchArrNum="<\"NULL"; + + for(ZTypLength i=0; i ZERun ExecBlockMatch( + const TypeChar* AP_Data, ZTypLength AL_Length, int AI_SearchArrNum, THelpType AO_HelpType) */ + + public: + };/* + template class ZtCParentLoadDataBlockArr */ + + }/* + namespace ZNsInterface*/ + + + /*/////////////////////////////////////////////////////////////////////////////// + + ■ 찾는 데이타를 문자열 배열로 구성해서, 이 배열의 각 원소의 문자열을 찾을 때마다 + 그 이전에 찾은 문자열 사이의 데이타에 대하여, '어떤 처리'를 해준다. 결국 '어떤 + 처리'의 대상이 되려면 그 이전에 찾은 문자열이 있어야 한다. + + ///////////////////////////////////////////////////////////////////////////////*/ + + template< typename TDerive , + typename TStringData, + typename TStringArr=ZNsMain::ZtCArray + > + class ZtCLoadDataBlockArr /*############################*/ + { + public : + typedef TStringData TypeString; // 이 public 영역은 외부 참고용 type 정의다. + typedef TStringArr TypeData ; + typedef TStringArr TypeArray ; + public : + typedef typename TStringData::TypeChar TypeChar ; + typedef typename TStringData::TypeLength TypeLength ; + typedef typename TStringData::ZCMainChars ZCMainChars; + protected: + typedef TStringData ZCStringData; + typedef TStringArr CStringArr ; + protected: + CStringArr mo_CArrSearch ; // 이 배열에 있는 값을 순서대로 찾는다. + ZCStringData* mp_CSearchNow ; // mo_CArrSearch 의 특정 원소를 가리킨다. + ZCStringData mo_CStringBuff; + TypeLength mi_NowArrPos ; // mp_CSearchNow 이 mo_CArrSearch 에서 가리키는 번호, 유효한 번호이면 1 부터 시작 + protected: + + TDerive& GetParentObj() + { + return (static_cast(*this)); + }/* + TDerive& GetParentObj()*/ + + /*protected:*/ + public : + + ZtCLoadDataBlockArr() + { + mp_CSearchNow=0; + mi_NowArrPos =0; + }/* + ZtCLoadDataBlockArr()*/ + + void clear() + { + mp_CSearchNow=0; + mi_NowArrPos =0; + mo_CArrSearch.clear(); + mo_CStringBuff=""; + }/* + void clear()*/ + + void ClearCursor() + { + mp_CSearchNow=0; + mi_NowArrPos =0; + mo_CStringBuff=""; + }/* + void ClearCursor()*/ + + void ClearSearch() + { + mo_CArrSearch.clear(); + }/* + void ClearSearch()*/ + + CStringArr& GetSeachCStrArr() + { + return mo_CArrSearch; + }/* + CStringArr& GetSeachCStrArr()*/ + + const CStringArr& GetSeachCStrArr() const + { + return mo_CArrSearch; + }/* + const CStringArr& GetSeachCStrArr() const*/ + + void AddSearchData(const ZCStringData& AR_CStringData) + { + mo_CArrSearch.push_back(AR_CStringData); + }/* + void AddSearchData(const ZCStringData& AR_CStringData)*/ + + + TypeLength GetNowArrPos() const + { + return mi_NowArrPos; + }/* + TypeLength GetNowArrPos() const*/ + + void SetNowArrPos(int AI_NewArrPos=1) + { + if(AI_NewArrPos>0 && AI_NewArrPos<=mo_CArrSearch.size()) + { mi_NowArrPos=AI_NewArrPos; } + }/* + void SetNowArrPos(int AI_NewArrPos=1)*/ + + + void LoadData(const TypeChar* APC_Origin, TypeLength AL_Length) + { + if(AL_Length<1 || mo_CArrSearch.size()<1) + { + return; + } + if(mi_NowArrPos<1) + { + mi_NowArrPos =1; + mp_CSearchNow=&mo_CArrSearch[0]; + } + if(mp_CSearchNow->size()<1) + { + return; + }/* + if(mp_CSearchNow->size()<1)*/ + + const TypeChar* VPC_Origin=APC_Origin; + + TypeLength VL_StartPos =0; + TypeLength VL_ValidReady=0; + TypeLength VL_ValidLen =0; + bool VB_IsOK =true; + + do //// + { + VPC_Origin=APC_Origin+VL_StartPos; + + VB_IsOK=ZCMainChars::FindPosReadyValid( ////////////////// + APC_Origin , + mp_CSearchNow->data(), + AL_Length , + mp_CSearchNow->size(), + RR(mo_CStringBuff) , + RR(VL_StartPos) , + RR(VL_ValidReady) , + RR(VL_ValidLen) + /*/////////*/ ); //////////////////////////////////////// + + if(VL_ValidReady>0) + { + ZERun CE_ERun=GetParentObj().ExecBlockIn( + mo_CStringBuff.data(), + VL_ValidReady , + mi_NowArrPos + /*/////////*/ ); //////////////////////////////////// + + if(CE_ERun==ZERun_NO) return; + } + if(VL_ValidLen>0) + { + ZERun CE_ERun=GetParentObj().ExecBlockIn( + VPC_Origin , + VL_ValidLen , + mi_NowArrPos + /*//////////*/ ); /////////////////////////////////// + + if(CE_ERun==ZERun_NO) return; + }/* + if(VL_ValidLen>0)*/ + + if(VB_IsOK==false) return; + + ZERun CE_ERun=GetParentObj().ExecBlockMatch( + mp_CSearchNow->data() , + mp_CSearchNow->size() , + mi_NowArrPos + /*//////////*/ ); ////////////////////////////////////// + + if(CE_ERun==ZERun_NO) + { return; } + if(++mi_NowArrPos>mo_CArrSearch.size()) + { mi_NowArrPos=1; } + + mp_CSearchNow=&mo_CArrSearch[mi_NowArrPos-1]; + } + while(true); + }/* + void LoadData(const TypeChar* APC_Origin, TypeLength AL_Length)*/ + + void LoadData(ZCStringData& AR_CStringData) + { + LoadData(AR_CStringData.data(), AR_CStringData.size()); + }/* + void LoadData(ZCStringData& AR_CStringData)*/ + + + template void LoadData( + const TypeChar* APC_Origin, TypeLength AL_Length, THelpType AO_HelpType) + { + typedef ZNsMain:: + ZtCCheckRef ZCCheckRef ; + + + if(AL_Length<1 || mo_CArrSearch.size()<1) + { + return; + } + if(mi_NowArrPos<1) + { + mi_NowArrPos =1; + mp_CSearchNow=&mo_CArrSearch[0]; + } + if(mp_CSearchNow->size()<1) + { + return; + }/* + if(mp_CSearchNow->size()<1)*/ + + const TypeChar* VPC_Origin =APC_Origin; + TypeLength VL_StartPos =0 ; + TypeLength VL_ValidReady=0 ; + TypeLength VL_ValidLen =0 ; + bool VB_IsOK =true ; + + do //// + { + VPC_Origin=APC_Origin+VL_StartPos; + + VB_IsOK=ZCMainChars::FindPosReadyValid( //////////////////////// + APC_Origin , + mp_CSearchNow->data(), + AL_Length , + mp_CSearchNow->size(), + RR(mo_CStringBuff) , + RR(VL_StartPos) , + RR(VL_ValidReady) , + RR(VL_ValidLen) + /*/////////*/ ); ////////////////////////////////////////////// + + if(VL_ValidReady>0) + { + const ZERun CE_ERun=GetParentObj().ExecBlockIn + ( + mo_CStringBuff.data(), VL_ValidReady , + mi_NowArrPos , ZCCheckRef::PassData(AO_HelpType) + ); + ////////////////////////////////////////////// + + if(CE_ERun==ZERun_NO) return; + } + if(VL_ValidLen>0) + { + const ZERun CE_ERun=GetParentObj().ExecBlockIn + ( + VPC_Origin , VL_ValidLen , + mi_NowArrPos, ZCCheckRef::PassData(AO_HelpType) + ); + ////////////////////////////////////////////// + + if(CE_ERun==ZERun_NO) return; + }/* + if(VL_ValidLen>0)*/ + + if(VB_IsOK==false) return; + + const ZERun CE_ERun=GetParentObj().ExecBlockMatch + ( + mp_CSearchNow->data(), mp_CSearchNow->size(), + mi_NowArrPos , ZCCheckRef::PassData(AO_HelpType) + ); + ///////////////////////////////////////////////// + + if(CE_ERun==ZERun_NO) + {return ;} + if(++mi_NowArrPos>mo_CArrSearch.size()) + {mi_NowArrPos=1;} + + mp_CSearchNow = &mo_CArrSearch[mi_NowArrPos-1]; + } + while(true); + }/* + template void LoadData( + const TypeChar* APC_Origin, TypeLength AL_Length, THelpType AO_HelpType) */ + + template + void LoadData(ZCStringData& AR_CStringData, THelpType AO_HelpType) + { + LoadData(AR_CStringData.data(), AR_CStringData.size(), AO_HelpType); + }/* + template + LoadData(ZCStringData& AR_CStringData, THelpType AO_HelpType) */ + + void LoadData() + { + // mo_CStringBuff 에 남아 있는 마지막 데이타를 처리한다. + + if(mo_CStringBuff.size()>0) + { + GetParentObj().ExecBlockIn( /////////////// + mo_CStringBuff.data(), + mo_CStringBuff.size(), + mi_NowArrPos + /*//////////*/ ); ///////////////////////// + + mo_CStringBuff = ""; + }/* + if(mo_CStringBuff.size()>0)*/ + }/* + void LoadData()*/ + + template void LoadDataHelp(THelpType AO_HelpType) + { + typedef ZNsMain::ZtCCheckRef ZCCheckRef; + + if(mo_CStringBuff.size()>0) + { + GetParentObj().ExecBlockIn ////////////// + ( + mo_CStringBuff.data(), + mo_CStringBuff.size(), + mi_NowArrPos , + ZCCheckRef::PassData(AO_HelpType) + ); + ///////////////////////////////////////// + + mo_CStringBuff = ""; + }/* + if(mo_CStringBuff.size()>0)*/ + }/* + template void LoadDataHelp(THelpType AO_HelpType) */ + + public: + };/* + template< typename TDerive , + typename TStringData, + typename TStringArr =ZNsMain::ZtCArray + > + class ZtCLoadDataBlockArr */ + + + /*//////////////////////////////////////////////////////////////////////////////////// + + ■ ZtCLoadDataBlockArr<> class template 선언에 아래와 같이 멤버함수 템플릿이 있을 경우 + + template + void LoadData(TStringData& AR_CStringData) + { + LoadData(AR_CStringData.data(),AR_CStringData.size()); + } + + + 아래 멤버 템플릿 함수 특수화가 컴파일 안된다. + + template<> + + template< typename TDerive , + typename TStringData, + typename TStringArr + > + void ZtCLoadDataBlockArr::LoadData(const char* APC_Origin) + { + this->LoadData(APC_Origin,ZNsMain::GetLength(APC_Origin)); + } + + ※ 아래 처럼 CLoadDataBlockArr 이 템플릿이 아닌 클래스라면 컴파일된다. + + template<> + void CLoadDataBlockArr::LoadData(const char* APC_Origin) + { + this->LoadData(APC_Origin,ZNsMain::GetLength(APC_Origin)); + } + + ////////////////////////////////////////////////////////////////////////////////////*/ + + + + namespace ZNsType + { + + template< typename TStringData, + typename TTypeBase=ZNsIFace::ZtCParentLoadDataBlockArr + > + class CTypeLoadDataBlockArr_T //////////////////////////////////////////////// + { + public: + + class ZCLoadDataBlock : + public TTypeBase, public ZNsMain::ZtCLoadDataBlockArr + < + ZCLoadDataBlock, TStringData, ZNsMain::ZtCArray + > + ////////////////////////////////////////////////////////// + { + public: + + public: + };/* + class ZCLoadDataBlock*/ + + typedef TStringData ZCStringData; + typedef typename ZCStringData::ZCMainChars ZCMainChars ; + typedef typename ZCStringData::TypeChar TypeChar ; + typedef typename ZCStringData::TypeLength TypeLength ; + typedef ZCLoadDataBlock TypeMain ; + + public: + };/* + template< typename TStringData, + typename TTypeBase=ZNsIFace::ZtCParentLoadDataBlockArr + > + class CTypeLoadDataBlockArr_T //////////////////////////////////////////////*/ + + }/* + namespace ZNsType*/ + + + template< typename TDerive, + typename TStringData + > + class ZtCLoadDataBlockOne; + + + namespace ZNsInterface + { + + template class ZtCChildLoadDataBlockOne + { + public : + template< typename TTDerive, /*#################*/ + typename TTStringData + > + friend class ZtCLoadDataBlockOne; /*##############*/ + public : + typedef typename TStringData::TypeChar TypeChar ; + typedef typename TStringData::TypeLength TypeLength ; + typedef typename TStringData::ZCMainChars ZCMainChars; + /*public :*/ + + private: + + ZERun ExecBlockIn(const TypeChar* AP_Data, TypeLength AL_Length) + { + cout<<"Search Data Block IN : Data=>"; + + for(ZTypLength i=0; i0) + cout<<"Search Data Block Match : Data=>"; + else + cout<<"Search Data Block Match : Data=>NULL"; + //else + + for(ZTypLength i=0; i ZERun ExecBlockIn( + const TypeChar* AP_Data, TypeLength AL_Length, THelpType AO_HelpType) + { + cout<<"Search Data Block IN : THelpType="<"; + + for(TypeLength i=0; i ZERun ExecBlockIn( + const TypeChar* AP_Data, TypeLength AL_Length, THelpType AO_HelpType)*/ + + template ZERun ExecBlockMatch( + const TypeChar* AP_Data, TypeLength AL_Length, THelpType AO_HelpType) + { + if(AL_Length>0) + cout<<"Search Data Block Match : THelpType="<"; + else + cout<<"Search Data Block Match : THelpType="<NULL"; + //else + + for(ZTypLength i=0; i ZERun ExecBlockMatch( + const TypeChar* AP_Data, TypeLength AL_Length, THelpType AO_HelpType)*/ + + private: + };/* + template class ZtCChildLoadDataBlockOne */ + + }/* + namespace ZNsInterface*/ + + + /* ZtCLoadDataBlockArr<> 클래스 템플릿에서 한 개의 + 문자열만 찾는 경우를 최적화한 클래스 템플릿이다. */ + + template< typename TDerive, typename TStringData + > + class ZtCLoadDataBlockOne //////////////////////// + { + public : + typedef TStringData ZCStringData; + public : + typedef typename ZCStringData::TypeChar TypeChar ; + typedef typename ZCStringData::TypeLength TypeLength ; + typedef typename ZCStringData::ZCMainChars ZCMainChars ; + protected: + ZCStringData mo_CStrSearch ; // 찾아야 하는 값 + ZCStringData mo_CStringBuff; + protected: + + TDerive& GetParentObj() + { + return (static_cast(*this)); + }/* + TDerive& GetParentObj()*/ + + /*protected:*/ + public : + + ZtCLoadDataBlockOne() + { + }/* + ZtCLoadDataBlockOne()*/ + + void clear() + { + mo_CStrSearch =""; + mo_CStringBuff=""; + }/* + void clear()*/ + + ZCStringData& GetSearchCString() + { + return mo_CStrSearch; + }/* + ZCStringData& GetSearchCString()*/ + + const ZCStringData& GetSearchCString() const + { + return mo_CStrSearch; + }/* + const ZCStringData& GetSearchCString() const*/ + + void SetSearchCString(const TypeChar* APC_Search, TypeLength AL_Length) + { + mo_CStrSearch=""; mo_CStrSearch.append(APC_Search, AL_Length); + }/* + void SetSearchCString(const TypeChar* APC_Search, TypeLength AL_Length)*/ + + void SetSearchCString(const ZCStringData& AR_CStrSearch) + { + mo_CStrSearch=AR_CStrSearch; + }/* + void SetSearchCString(const ZCStringData& AR_CStrSearch)*/ + + void AddSearchData(const ZCStringData& AR_CStrSearch) // for ZtCLoadDataBlockArr 와의 호환을 위해... + { + mo_CStrSearch=AR_CStrSearch; + }/* + void AddSearchData(const ZCStringData& AR_CStrSearch)*/ + + void AddSearchData(const TypeChar* APC_Search, TypeLength AL_Length) // for ZtCLoadDataBlockArr<> 와의 호환을 위해... + { + mo_CStrSearch=""; mo_CStrSearch.append(APC_Search, AL_Length); + }/* + void AddSearchData(const TypeChar* APC_Search, TypeLength AL_Length)*/ + + + void LoadData(const TypeChar* APC_Origin, TypeLength AL_Length) + { + if(AL_Length<1 || mo_CStrSearch.size()<1) return; + + const TypeChar* VPC_Origin=APC_Origin; + + TypeLength VL_StartPos =0; + TypeLength VL_ValidReady=0; + TypeLength VL_ValidLen =0; + bool VB_IsOK =true; + + do //// + { + VPC_Origin=APC_Origin+VL_StartPos; + + VB_IsOK=ZCMainChars::FindPosReadyValid( //////////////////////// + APC_Origin , + mo_CStrSearch.data() , + AL_Length , + mo_CStrSearch.size() , + RR(mo_CStringBuff) , + RR(VL_StartPos) , + RR(VL_ValidReady) , + RR(VL_ValidLen) + /*/////////*/ ); ////////////////////////////////////////////// + + if(VL_ValidReady>0) + { + const ZERun CE_ERun=GetParentObj().ExecBlockIn( + mo_CStringBuff.data(), + VL_ValidReady + /*/////////*/ ); ////////////////////////////////////////// + + if(CE_ERun==ZERun_NO) return; + } + if(VL_ValidLen>0) + { + const ZERun CE_ERun=GetParentObj().ExecBlockIn( + VPC_Origin , + VL_ValidLen + /*//////////*/ ); ///////////////////////////////////////// + + if(CE_ERun==ZERun_NO) return; + }/* + if(VL_ValidLen>0)*/ + + if(VB_IsOK==false) return; + + const ZERun CE_ERun=GetParentObj().ExecBlockMatch( + mo_CStrSearch.data(), + mo_CStrSearch.size() + /*//////////*/ ); //////////////////////////////////////////// + + if(CE_ERun==ZERun_NO) return; + } + while(true); + }/* + void LoadData(const TypeChar* APC_Origin, TypeLength AL_Length)*/ + + void LoadData(const ZCStringData& AR_CStringData) + { + LoadData(AR_CStringData.data(), AR_CStringData.size()); + }/* + void LoadData(const ZCStringData& AR_CStringData)*/ + + + template void LoadData( + const TypeChar* APC_Origin, TypeLength AL_Length, THelpType AO_HelpType) + { + typedef ZNsMain::ZtCCheckRef ZCCheckRef; + + if(AL_Length<1 || mo_CStrSearch.size()<1) return ; + + const TypeChar* VPC_Origin=APC_Origin; + + TypeLength VL_StartPos =0; + TypeLength VL_ValidReady=0; + TypeLength VL_ValidLen =0; + bool VB_IsOK =true; + + do //// + { + VPC_Origin=APC_Origin+VL_StartPos; + + VB_IsOK=ZCMainChars::FindPosReadyValid( //////////////////////// + APC_Origin , + mo_CStrSearch.data() , + AL_Length , + mo_CStrSearch.size() , + RR(mo_CStringBuff) , + RR(VL_StartPos) , + RR(VL_ValidReady) , + RR(VL_ValidLen) + /*/////////*/ ); ////////////////////////////////////////////// + + if(VL_ValidReady>0) + { + const ZERun CE_ERun=GetParentObj().ExecBlockIn + ( + mo_CStringBuff.data(), VL_ValidReady, + ZCCheckRef::PassData(AO_HelpType) + ); + ////////////////////////////////////////////// + + if(CE_ERun==ZERun_NO) return; + } + if(VL_ValidLen>0) + { + const ZERun CE_ERun=GetParentObj().ExecBlockIn + ( + VPC_Origin , VL_ValidLen , + ZCCheckRef::PassData(AO_HelpType) + ); + ////////////////////////////////////////////// + + if(CE_ERun==ZERun_NO) return; + }/* + if(VL_ValidLen>0)*/ + + if(VB_IsOK==false) return; + + const ZERun CE_ERun = GetParentObj().ExecBlockMatch + ( + mo_CStrSearch.data(), mo_CStrSearch.size(), + ZCCheckRef::PassData(AO_HelpType) + ); + /////////////////////////////////////////////////// + + if(CE_ERun==ZERun_NO) return; + } + while(true); + }/* + template void LoadData( + const TypeChar* APC_Origin, TypeLength AL_Length, THelpType AO_HelpType) */ + + template + void LoadData(const ZCStringData& AR_CStringData, THelpType AO_HelpType) + { + LoadData(AR_CStringData.data(), AR_CStringData.size(), AO_HelpType); + }/* + template + LoadData(const ZCStringData& AR_CStringData, THelpType AO_HelpType) */ + + void LoadData() + { + // mo_CStringBuff 에 남아 있는 마지막 데이타를 처리한다. + + if(mo_CStringBuff.size()>0) + { + GetParentObj().ExecBlockIn + (mo_CStringBuff.data(), mo_CStringBuff.size()); + + mo_CStringBuff=""; + }/* + if(mo_CStringBuff.size()>0)*/ + }/* + void LoadData()*/ + + template void LoadDataHelp(THelpType AO_HelpType) + { + typedef ZNsMain::ZtCCheckRef ZCCheckRef; + + if(mo_CStringBuff.size()>0) + { + GetParentObj().ExecBlockIn //////////////////// + ( + mo_CStringBuff.data(), + mo_CStringBuff.size(), + ZCCheckRef::PassData(AO_HelpType) + ); + /////////////////////////////////////////////// + + mo_CStringBuff = "" ; + }/* + if(mo_CStringBuff.size()>0)*/ + }/* + template void LoadDataHelp(THelpType AO_HelpType) */ + + public: + };/* + template< typename TDerive, typename TStringData + > + class ZtCLoadDataBlockOne //////////////////////*/ + + + namespace ZNsType + { + + /*////////////////////////////////////////////////////////////////////////////////////// + + ■ class ZtCLoadDataBlockOne<> 이 상속을 해서 사용해야 한다면, + class ZtCTypeLoadDataBlockOne<>::TypeMain 은 기초 클래스를 지정해서 사용한다. + + -- 2011-12-18 14:35:00 + + //////////////////////////////////////////////////////////////////////////////////////*/ + + template< typename TStringData , + typename TTypeBase=ZNsIFace:: + ZtCChildLoadDataBlockOne + > + class ZtCTypeLoadDataBlockOne /////////////////////////////////////////////// + { + public: + + class ZCLoadDataBlock : + public TTypeBase , + public ZNsMain::ZtCLoadDataBlockOne + < + ZCLoadDataBlock, TStringData + /*//////////*/ > + { + public: + typedef TStringData ZCStringData; + typedef typename ZCStringData::ZCMainChars ZCMainChars ; + typedef typename ZCStringData::TypeChar TypeChar ; + typedef typename ZCStringData::TypeLength TypeLength ; + public: + };/* + class ZCLoadDataBlock : + public TTypeBase, + public ZNsMain::ZtCLoadDataBlockOne + < + ZCLoadDataBlock, TStringData + ////////////// > */ + + typedef TStringData ZCStringData; + typedef typename ZCStringData::ZCMainChars ZCMainChars ; + typedef typename ZCStringData::TypeChar TypeChar ; + typedef typename ZCStringData::TypeLength TypeLength ; + typedef ZCLoadDataBlock TypeMain ; + + public: + };/* + template< typename TStringData, + typename TTypeBase=ZNsIFace::ZtCChildLoadDataBlockOne + > + class ZtCTypeLoadDataBlockOne /////////////////////////////////////////////*/ + + }/* + namespace ZNsType*/ + +}/* +namespace ZNsMain*/ + + +#endif //__NSMAIN_CLOADDATABLOCK_H__ diff --git a/ZCppMain/ZtCMainChars.H b/ZCppMain/ZtCMainChars.H new file mode 100644 index 0000000..cb176df --- /dev/null +++ b/ZCppMain/ZtCMainChars.H @@ -0,0 +1,7212 @@ + + +#ifndef __ZCPPMAIIN__ZTCMAINCHARS_H__ +#define __ZCPPMAIIN__ZTCMAINCHARS_H__ + + +#include "ZCppMain/ZMainHead.H" + + +namespace ZNsMain +{ + + namespace ZNsChars + { + + typedef ZNsMain::IterEasyID IterEasyID ; + typedef ZNsMain::IterEasyIDc IterEasyIDc; + + + namespace ZNsEnum + { + + typedef ZNsMain::ZNsEnum::ZERun ZERun ; + typedef ZNsMain::ZNsEnum::ZERunEx ZERunEx; + + + enum ZESearchMax + { + ZESearchMax_Over, + ZESearchMax_Stop + };/* + enum ZESearchMax*/ + + /*//////////////////////////////////////////////////////////////////////////// + + ESearchMaxFind ZtCMainChars<>::GetLength_Repeat_Find() Լ, + ִ ߰ Ƚ(AI_RepeatMax) ȿ , AI_RepeatMax ŭ ߰ + ڿ ȸ , ȸ (׷ ش + ڿ ٽ ߰ϸ, AI_RepeatMax+1 ߰ ǰ, ̰ ǿ + ʴ Ǵؾ Ѵ) Ѵ. + + -- 2011-07-16 03:49:00 + + ////////////////////////////////////////////////////////////////////////////*/ + + + /*////////////////////////////////////////////////////// + + ش ǥİ ġϴ ڿ ġ + ZERegMatch_MoveNot ̸ ̵ ʴ´. + ZERegMatch_MovePos ̸ ̵Ų. + + //////////////////////////////////////////////////////*/ + + enum ZERegMatch + { + ZERegMatch_MoveNot, + ZERegMatch_MovePos + };/* + enum ZERegMatch*/ + + + /*////////////////////////////////////////////////////// + + ش ǥİ ġϴ ڿ , ġ + ZERegMatchSavePos_Not ̸ ʴ´. + ZERegMatchSavePos_Yes ̸ Ѵ. + + //////////////////////////////////////////////////////*/ + + enum ZERegMatchSavePos + { + ZERegMatchSavePos_Not, + ZERegMatchSavePos_Yes + };/* + enum ZERegMatchSavePos*/ + + + enum ZERegFlag + { + ZERegFlag_Nothing , + ZERegFlag_Permit , // ã ڿ ߿ ϳ ġؾ ... + ZERegFlag_PermitRange , // ã ڿ ... + ZERegFlag_PermitChar , // ã ڿ ߿ ϳ ġؾ ... + ZERegFlag_PermitCharRange , // ã ڿ 2 ڴ Ÿµ, ڰ ־... + ZERegFlag_NoPermit , // ã ڿ ϰ ΰ ġ ʾƾ ... + ZERegFlag_NoPermitRange , // ã ڿ ... + ZERegFlag_NoPermitChar , // ã ڿ ڿ ġ ʾƾ ... + ZERegFlag_NoPermitCharRange, // ã ڿ 2 ڴ ʴ Ÿµ, ۿ ڰ ־... + ZERegFlag_Find , // ã ڿ ߿ ϳ ġϸ ̱ ؿ´. + ZERegFlag_FindChar , // ã ڿ ߿ ϳ ġϸ ̱ ؿ´. + ZERegFlag_FindSerial , // ã ڿ ãƾ Ѵ. + ZERegFlag_FindSerialChar , // ã ڿ ڸ ãƾ Ѵ. + ZERegFlag_FindEscape , // ã ڿ ߿ ϳ ġϰ escape ڿ ̱ Ѵ. + ZERegFlag_StartFind , // ã ڿ , 1 Һ ϰ, 2 Һ ã Ѵ. + ZERegFlag_StartFindChar , // ZERegFlag_FindSerialChar ϳ, 1 ڷ ؾ ϴ ٸ. + + ZERegFlag_BlockStart , // 'ȸ Block' κ + ZERegFlag_BlockClose // 'ȸ Block' κ + };/* + enum ZERegFlag*/ + + + /*//////////////////////////////////////////////////////////////////////////// + + enum ZERegErr class ZtCSearchCChars ϴ ڵ. + + ZERegErr_CharCount : ã + + ZtCSearchCChars::mi_SearchCharMin + ZtCSearchCChars::mi_SearchCharMax ̿ ʴ. + + ZERegErr_CharSum : + + ZtCSearchCChars ̳(ַ 迭) μ ޾Ƽ, + ؼ ZtCSearchCChars ġϴ ڸ ã , + ġϴ ڸ Ư (ַ ) ϰ Ǵµ, ã + , + + ZtCSearchCChars::mi_SearchSumMin + ZtCSearchCChars::mi_SearchSumMax ̿ ̴. + + -- + + ȸ Block + + ڿ Ư ã , ã object + 迭̳ tree · ϰ Ǵµ, ̶ ã ó ҿ + 'ȸ Block'̶ Ѵ. Ư tree + ο Ʈ ְ, ο 'ȸ Block' ߻ϴ + ϱ ʿ ̴. + + -- 2013-06-25 23:37:00 + + ////////////////////////////////////////////////////////////////////////////*/ + + enum ZERegErr // ǥ ڵ. + { + ZERegErr_None , // . + ZERegErr_CharCount, // ã . + ZERegErr_CharSum // ã . + };/* + enum ZERegErr*/ + + enum ZETypeCharTmplChain + { + ZETypeCharTmplChain_No , + ZETypeCharTmplChain_Char , + ZETypeCharTmplChain_Char2 + };/* + enum ZETypeCharTmplChain*/ + + }/* + namespace ZNsEnum*/ + + + namespace ZNsInterface + { + + template class ZtCStackOfTmplChain + { + private: + TTypeLength ml_SearchSum; + public : + + ZtCStackOfTmplChain() + { + ml_SearchSum=0; + }/* + ZtCStackOfTmplChain()*/ + + TTypeLength GetSearchSum() const{return ml_SearchSum;} + + void SetSearchSum(TTypeLength AI_Length){ml_SearchSum =AI_Length;} + void AddSearchSum(TTypeLength AL_Length){ml_SearchSum+=AL_Length;} + + public : + };/* + template class ZtCStackOfTmplChain */ + + }/* + namespace ZNsInterface*/ + + namespace ZNsIFace + { + // ̸ ZNsInterface ª ZNsIFace ε ǥ ϰ Ѵ. + + using namespace ZNsInterface; + }/* + namespace ZNsIFace*/ + + + namespace ZNsType + { + + // 쿡 TTypeChar short int int ִ. + + template< typename TTypeChar =char, + typename TTypeLength=ZTypLength // signed ̾ Ѵ. + > + class ZtCTypeChars /*////////////////////*/ + { + public: + typedef TTypeChar TypeChar ; + typedef TTypeLength TypeLength; // signed ̾ Ѵ. + public: + typedef const TypeChar TypeCharC ; + typedef const TypeChar* TypeCharCP; + public: + + static TypeChar GetCharOfAnsi(char AC_AnsiChar) + { + return AC_AnsiChar; + }/* + static TypeChar GetCharOfAnsi(char AC_AnsiChar)*/ + + static bool IsAnsiChars(TypeCharC* APC_Char,TypeLength AI_Length) + { + // Ansi 7bit ̸ true . + // AI_Length<1 쿡 true + + while(--AI_Length>=0) + { + if((*APC_Char++)<0) return false; + }/* + while(--AI_Length>=0)*/ + + return true; + }/* + static bool IsAnsiChars(TypeCharC* APC_Char,TypeLength AI_Length)*/ + + static TypeLength GetLength(TypeCharC* APC_TypeChar) + { + if(APC_TypeChar==0) return 0; TypeLength VL_Length=0; + + while(*(APC_TypeChar+VL_Length)!=ZtCTypeChars::GetCharOfAnsi('\0')) + { + ++VL_Length; + }/* + while(*(APC_TypeChar+VL_Length)!=ZtCTypeChars::GetCharOfAnsi('\0'))*/ + + return VL_Length; + }/* + static TypeLength GetLength(TypeCharC* APC_TypeChar) + + + public:*/ + public: + + + class ZCChars + { + public : + template friend class ZtCMainChars; + public : + typedef ZtCTypeChars ZCTypeChars; + typedef TTypeChar TypeChar ; + typedef TTypeLength TypeLength ; + public: + typedef const TTypeChar TypeCharC ; + typedef const TTypeChar* TypeCharCP ; + private: + TypeChar* mp_TypeChar ; + TypeLength ml_TypeLength; + public : + + ZCChars() + { + mp_TypeChar =0; + ml_TypeLength=0; + }/* + ZCChars()*/ + + ZCChars(TypeCharC* APC_TypeChar) + { + mp_TypeChar =const_cast (APC_TypeChar); + ml_TypeLength=ZtCTypeChars::GetLength(mp_TypeChar ); + }/* + ZCChars(TypeCharC* APC_TypeChar)*/ + + ZCChars(TypeCharC* APC_TypeChar, TypeLength AL_Length) + { + mp_TypeChar = const_cast + (APC_TypeChar) ; + ml_TypeLength=AL_Length ; + }/* + ZCChars(TypeCharC* APC_TypeChar, TypeLength AL_Length)*/ + + void Init(TypeCharC* APC_TypeChar=0, TypeLength AL_Length=0) + { + mp_TypeChar =const_cast + (APC_TypeChar) ; + ml_TypeLength=AL_Length ; + }/* + void Init(TypeCharC* APC_TypeChar=0, TypeLength AL_Length=0)*/ + + void InitData(TypeCharC* APC_TypeChar) + { + mp_TypeChar=const_cast(APC_TypeChar); + }/* + void InitData(TypeCharC* APC_TypeChar)*/ + + void InitLength(TypeLength AL_Length) + { + ml_TypeLength=AL_Length; + }/* + void InitLength(TypeLength AL_Length)*/ + + TypeChar* data() + { + return mp_TypeChar; + }/* + TypeChar* data()*/ + + TypeCharC* data() const + { + return mp_TypeChar; + }/* + TypeCharC* data() const*/ + + TypeLength size() const + { + return ml_TypeLength; + }/* + TypeLength size() const*/ + + ZCChars& operator+=(TypeLength AI_MovePos) + { + return MoveChar(AI_MovePos); + }/* + ZCChars& operator+=(TypeLength AI_MovePos)*/ + + int operator-(const ZCChars& rhs) const + { + // ڿ 0 + // ڿ ũ 0 ū  + // ڿ ũ 0  ȯ + + TypeCharC* VP_Left = mp_TypeChar; + TypeCharC* VP_Right=rhs.mp_TypeChar; + + #if(_CODE_OLD_) + TypeChar VC_Minus=0; + #else + int VI_Minus=0; // ϴ 'char int Ȯ忡 ڵ' . + #endif + TypeLength VL_Index=0; + TypeLength VL_Loop =(ml_TypeLength<=rhs.ml_TypeLength ? ml_TypeLength : rhs.ml_TypeLength) ; + + while(VL_Index (const ZCChars& rhs) const{return (*this)-rhs > 0 ;} + bool operator< (const ZCChars& rhs) const{return (*this)-rhs < 0 ;} + bool operator>=(const ZCChars& rhs) const{return (*this)-rhs >= 0 ;} + bool operator<=(const ZCChars& rhs) const{return (*this)-rhs <= 0 ;} + + ZCChars& MoveChar(TypeLength AI_MovePos) + { + mp_TypeChar +=AI_MovePos; + ml_TypeLength-=AI_MovePos; + + return *this; + }/* + ZCChars& MoveChar(TypeLength AI_MovePos)*/ + + + ZTypIntI GetInt(bool AB_IsBigEndian=true) const + { + const ZTypIntI CI_IntByte = sizeof(ZTypIntI); + const ZTypIntI CI_SearchSize = + (ml_TypeLength=0; --i) + { + VI_Result += (ZTypIntI)(ZTypUChar)(mp_TypeChar[i]) * VI_TempInt ; + VI_TempInt*= 256 ; + }/* + for(ZTypIntI i=CI_SearchSize-1; i>=0; --i)*/ + + return VI_Result; + }/* + if(AB_IsBigEndian)*/ + + for(ZTypIntI i=0; i=0; --i) + { + VI_Result += (ZTypIntI)(ZTypUChar)(mp_TypeChar[i]) * VI_TempInt ; + VI_TempInt*= 256 ; + }/* + for(ZTypIntI i=CI_SearchSize-1; i>=0; --i)*/ + + return VI_Result; + }/* + if(AB_IsBigEndian)*/ + + for(ZTypIntI i=0; i=0; --i) + { + VI_Result += (ZTypIntI)(ZTypUChar)(mp_TypeChar[i]) * VI_TempInt ; + VI_TempInt*= 256 ; + }/* + for(ZTypIntI i=CI_SearchSize-1; i>=0; --i)*/ + + return VI_Result; + }/* + if(AB_IsBigEndian)*/ + + for(ZTypIntI i=0; i TypeInt GetIntType(bool AB_IsBigEndian=true) const + { + const ZTypIntI CI_IntByte = sizeof(TypeInt); + const ZTypIntI CI_SearchSize = + (ml_TypeLength=0; --i) + { + VI_Result += (ZTypIntI)(ZTypUChar)(mp_TypeChar[i]) * VI_TempInt ; + VI_TempInt*= 256 ; + }/* + for(ZTypIntI i=CI_SearchSize-1; i>=0; --i)*/ + + return VI_Result; + }/* + if(AB_IsBigEndian)*/ + + for(ZTypIntI i=0; i TypeInt GetIntType(bool AB_IsBigEndian=true) const*/ + + public: + };/* + class ZCChars*/ + + + static TypeChar GetUpperChar(TypeChar AC_TypeChar) + { + const int CI_Distance='a'-'A'; return + + (AC_TypeChar>='a' && AC_TypeChar<='z') ? + AC_TypeChar-CI_Distance : AC_TypeChar ; + }/* + static TypeChar GetUpperChar(TypeChar AC_TypeChar)*/ + + static TypeChar GetLowerChar(TypeChar AC_TypeChar) + { + const int CI_Distance='a'-'A'; return + + (AC_TypeChar>='A' && AC_TypeChar<='Z') ? + AC_TypeChar-CI_Distance : AC_TypeChar ; + }/* + static TypeChar GetLowerChar(TypeChar AC_TypeChar)*/ + + + public: + };/* + template< typename TTypeChar =char, + typename TTypeLength=ZTypLength + > + class ZtCTypeChars //////////////////////*/ + + }/* + namespace ZNsType*/ + + + + template< typename TTypeChars=ZNsType::ZtCTypeChars + > + class ZtCMainChars //////////////////////////////////////// + { + public: + typedef TTypeChars ZCTypeChars; + typedef ZtCMainChars ZCMainChars; + typedef typename ZCTypeChars::ZCChars ZCChars ; + typedef typename ZCTypeChars::TypeChar TypeChar ; + typedef typename ZCTypeChars::TypeLength TypeLength ; + public: + typedef const TypeChar TypeCharC ; + typedef const TypeChar* TypeCharCP; + public: + + + static int Minus(const ZCChars& AR_CChars1, const ZCChars& AR_CChars2) + { + return ZtCMainChars::Minus( + AR_CChars1.data, AR_CChars2.data(), AR_CChars1.size(), AR_CChars2.size()); + }/* + static int Minus(const ZCChars& AR_CChars1, const ZCChars& AR_CChars2)*/ + + static int Minus( + const TypeChar* APC_Left , const TypeChar* APC_Right, + TypeLength AL_LeftLength, TypeLength AL_RightLength ) + { + // ڿ 0 + // ڿ ũ 0 ū  + // ڿ ũ 0  ȯ + + if(AL_LeftLength<1 || AL_RightLength<1) + { + return AL_LeftLength - AL_RightLength; + }/* + if(AL_LeftLength<1 || AL_RightLength<1)*/ + + const TypeChar* VP_Left =APC_Left ; + const TypeChar* VP_Right=APC_Right; + + TypeLength VL_Index=0; + TypeLength VL_Loop = + (AL_LeftLength<=AL_RightLength ? AL_LeftLength : AL_RightLength) ; + + #if(_CODE_OLD_) + + TypeChar VC_Minus=0; + + while(VL_Index0) + { + // ڸ i . + + for(TypeLength t=i; t0)*/ + + VPC_Char = APC_Char+(ARRL_Length-1); // Ų. + + for(i=ARRL_Length-1; i>=0; --i) + { + const bool CB_IsTrue = ( ////////////////////////////////////////// + (VC_Char=*VPC_Char--)!=' ' && + VC_Char!=ZCTypeChars::GetCharOfAnsi('\t') && + VC_Char!=ZCTypeChars::GetCharOfAnsi('\r') && + VC_Char!=ZCTypeChars::GetCharOfAnsi('\n') && + VC_Char!=ZCTypeChars::GetCharOfAnsi('\0') + /*/////////*/ ); ////////////////////////////////////////////////// + + if(CB_IsTrue) break; APC_Char[--ARRL_Length] = ZCTypeChars::GetCharOfAnsi('\0'); + }/* + for(i=ARRL_Length-1; i>=0; --i)*/ + + return APC_Char; + }/* + static TypeChar* Trim(TypeChar* APC_Char,TypeLength& ARRL_Length)*/ + + static ZCChars& Trim(ZCChars& ARR_CChars) + { + ZtCMainChars::Trim(ARR_CChars.mp_TypeChar, RR(ARR_CChars.ml_TypeLength)); return ARR_CChars; + }/* + static ZCChars& Trim(ZCChars& ARR_CChars)*/ + + + template static int GetStartCStrObjNum( + TypeCharC* APC_Origin, TypeLength AL_OriginLength, TStringArray& ARA_SearchArray) + { + long VL_ArrSize=ARA_SearchArray.size(); if(AL_OriginLength<1) return 0; + + IterEasyIDc CI_IterEasyID(ARA_SearchArray.GetHeadIterEasyID()); + + __for1(TypeLength, i, VL_ArrSize) + { + const bool CB_IsOK= ZtCMainChars::DoStart( + APC_Origin , ARA_SearchArray.ItD(CI_IterEasyID).data(), + AL_OriginLength, ARA_SearchArray.ItD(CI_IterEasyID).size() + /*//////////*/ ); + + if(CB_IsOK) return i; ARA_SearchArray.MoveNextIter(RR(CI_IterEasyID)); + }/* + __for1(TypeLength, i, VL_ArrSize)*/ + + return 0; + }/* + template static int GetStartCStrObjNum( + TypeCharC* APC_Origin, TypeLength AL_OriginLength, TStringArray& ARA_SearchArray) */ + + template + static TypeLength GetStartCStrObjNum(const TTyChars& AR_CCharsOrigin, TStringArray& ARA_SearchArray) + { + return ZtCMainChars::GetStartCStrObjNum(AR_CCharsOrigin.data(), AR_CCharsOrigin.size(), ARA_SearchArray); + }/* + template + static TypeLength GetStartCStrObjNum(const TTyChars& AR_CCharsOrigin, TStringArray& ARA_SearchArray) */ + + + template + static TypeLength GetStartCStrObjNum2( /*###############*/ + TypeCharC* APC_Origin , TypeLength AL_OriginLength, + TStringArray& ARA_SearchArray, TString*& APR_CStringStart + /*#####*/ ) /*##########################################*/ + { + APR_CStringStart=0; long VL_ArrSize=ARA_SearchArray.size(); + + if(AL_OriginLength<1) return 0; //////////////////////////// + + + IterEasyIDc CI_IterEasyID(ARA_SearchArray.GetHeadIterEasyID()); + + /* ݺ const_iterator ڵϸ APR_CStringStart + Լ ܺο const TString* VP_CStringData · Ǿ Ѵ. */ + + for(TypeLength i=1; i<=VL_ArrSize; ++i) + { + const bool CB_IsOK=ZtCMainChars::DoStart( + APC_Origin , ARA_SearchArray.ItD(CI_IterEasyID).data(), + AL_OriginLength, ARA_SearchArray.ItD(CI_IterEasyID).size() + /*//////////*/ ); + + if(CB_IsOK) + { + APR_CStringStart=&(ARA_SearchArray.ItD(CI_IterEasyID)); return i; + }/* + if(CB_IsOK)*/ + + ARA_SearchArray.MoveNextIter(RR(CI_IterEasyID)); + }/* + for(TypeLength i=1; i<=VL_ArrSize; ++i)*/ + + return 0; + }/* + template + static TypeLength GetStartCStrObjNum2( + TypeCharC* APC_Origin , TypeLength AL_OriginLength, + TStringArray& ARA_SearchArray, TString*& APR_CStringStart ) */ + + template static TypeLength + GetStartCStrObjNum2(const TTyChars& AR_CCharsOrigin, TStringArray& ARA_SearchArray, TString*& APR_CStringStart) + { + return ZtCMainChars::GetStartCStrObjNum2( + AR_CCharsOrigin.data(), AR_CCharsOrigin.size(), ARA_SearchArray, RR(APR_CStringStart)); + }/* + template static TypeLength + GetStartCStrObjNum2(const TTyChars& AR_CCharsOrigin, TStringArray& ARA_SearchArray, TString*& APR_CStringStart)*/ + + + /*////////////////////////////////////////////////////////////////// + + Ʒ typename TTyChars ڸ ø Լ TTyChars ڸ + , ZCChars Ŭ data(), size() Ŭ ִ. + + -- 2011-07-13 05:39:00 + + //////////////////////////////////////////////////////////////////*/ + + template static bool DoStart(const TTyChars& AR_CCharsOrigin, const TTyChars& AR_CCharsSearch) + { + return ZtCMainChars::DoStart(AR_CCharsOrigin.data(), AR_CCharsSearch.data(), AR_CCharsOrigin.size(), AR_CCharsSearch.size()); + }/* + template static bool DoStart(const TTyChars& AR_CCharsOrigin, const TTyChars& AR_CCharsSearch) */ + + static bool DoStart( + TypeCharC* APC_Origin, TypeCharC* APC_Search, TypeLength AL_OriginLength, TypeLength AL_SearchLength) + { + if(AL_OriginLength<1 || AL_SearchLength<1 || AL_OriginLength static bool DoClose(const TTyChars& AR_CCharsOrigin, const TTyChars& AR_CCharsSearch) + { + return ZtCMainChars::DoClose(AR_CCharsOrigin.data(), AR_CCharsSearch.data(), AR_CCharsOrigin.size(), AR_CCharsSearch.size()); + }/* + template static bool DoClose(const TTyChars& AR_CCharsOrigin, const TTyChars& AR_CCharsSearch) */ + + static bool DoClose( + TypeCharC* APC_Origin, TypeCharC* APC_Search, TypeLength AL_OriginLength, TypeLength AL_SearchLength) + { + const bool CB_IsBad = ( + AL_OriginLength<1 || AL_SearchLength<1 || AL_OriginLength static bool DoEndLinear( + const TTyChars& AR_CCharsOrigin1, const TTyChars& AR_CCharsOrigin2, const TTyChars& AR_CCharsSearch) + { + return ZtCMainChars::DoEndLinear( + AR_CCharsOrigin1.data(), AR_CCharsOrigin2.data(), AR_CCharsSearch.data(), + AR_CCharsOrigin1.size(), AR_CCharsOrigin2.size(), AR_CCharsSearch.size() ); + }/* + template static bool DoEndLinear( + const TTyChars& AR_CCharsOrigin1, const TTyChars& AR_CCharsOrigin2, const TTyChars& AR_CCharsSearch) */ + + static bool DoEndLinear( + TypeCharC* APC_Origin1 , TypeCharC* APC_Origin2 , TypeCharC* APC_Search, + TypeLength AL_OriginLength1, TypeLength AL_OriginLength2, TypeLength AL_SearchLength ) + { + /* APC_Origin1 APC_Origin2 ӵ ڿ , + ü ڿ APC_Search true ȯѴ. */ + + const bool CB_IsBad = ( + AL_SearchLength<1 || AL_OriginLength1+AL_OriginLength2AL_SearchLength + + APC_Origin1, APC_Origin2 ABCDEFGH IJKLMNOPQRSTU + APC_Search LMNOPQRSTU + + 2 : AL_OriginLength2<=AL_SearchLength + + APC_Origin1, APC_Origin2 ABCDEFGH IJKLMNOPQRSTU + APC_Search GHIJKLMNOPQRSTU + + -- 2011-03-09 09:49:00 + + /////////////////////////////////////////////////////*/ + + TypeCharC* VPC_OrginStart =APC_Origin2+AL_OriginLength2; + TypeCharC* VPC_SearchStart=APC_Search +AL_SearchLength ; + TypeLength VI_CompareCnt =( + AL_OriginLength2>AL_SearchLength ? AL_SearchLength : AL_OriginLength2); + + for(TypeLength i=0; i=AL_SearchLength) return true ; + if(AL_OriginLength1+VI_CompareCnt< AL_SearchLength) return false; + + VI_CompareCnt =AL_SearchLength-VI_CompareCnt; + VPC_OrginStart=APC_Origin1+AL_OriginLength1; + + for(TypeLength i=0; iAL_OriginLen) return false; + + return ZtCMainChars::DoStart(APC_Origin,APC_Search,AL_OriginLen,AL_SearchLen) && + ZtCMainChars::DoClose(APC_Origin,APC_Search,AL_OriginLen,AL_SearchLen) ; + }/* + bool DoWrap(TypeCharC* APC_Origin, TypeCharC* APC_Search, TypeLength AL_OriginLen, TypeLength AL_SearchLen) */ + + + template static TypeLength FindPos( + const TTyChars& AR_CCharsOrigin, const TTyChars& AR_CCharsSearch, TypeLength AL_StartPos=0) + { + return ZtCMainChars::FindPos( + AR_CCharsOrigin.data(), AR_CCharsSearch.data(), + AR_CCharsOrigin.size(), AR_CCharsSearch.size(), AL_StartPos); + }/* + template static TypeLength FindPos( + const TTyChars& AR_CCharsOrigin, const TTyChars& AR_CCharsSearch, TypeLength AL_StartPos=0) */ + + static TypeLength FindPos( + TypeCharC* APC_Origin , TypeCharC* APC_Search , + TypeLength AL_OriginLength, TypeLength AL_SearchLength, TypeLength AL_StartPos=0) + { + const bool CB_IsBad = ( + AL_OriginLength<1 || AL_SearchLength<1 || AL_StartPos<0 || AL_StartPos>=AL_OriginLength ); + + if(CB_IsBad) return -1; + + TypeLength VL_Loop=AL_OriginLength-AL_SearchLength; + TypeLength i =AL_StartPos; + TypeLength j =0 ; + + /*////////////////////////////////////////////////////// + + Ʒ while ڵ忡 + + if(j<1) ++i; else i+=j; + + κ ָ . + ӵ N ڸ ãƾ ϴµ, M( static TypeLength FindPosLen( + const TTyChars& AR_CCharsOrigin, const TTyChars& AR_CCharsSearch, TypeLength& ARRL_MatchLen, TypeLength AL_StartPos=0) + { + return ZtCMainChars::FindPosLen( + AR_CCharsOrigin.data(), AR_CCharsSearch.data(), + AR_CCharsOrigin.size(), AR_CCharsSearch.size(), RR(ARRL_MatchLen), AL_StartPos); + }/* + template static TypeLength FindPosLen( + const TTyChars& AR_CCharsOrigin, const TTyChars& AR_CCharsSearch, TypeLength& ARRL_MatchLen, TypeLength AL_StartPos=0) */ + + static TypeLength FindPosLen( //////////////////////////////////// + TypeCharC* APC_Origin , + TypeCharC* APC_Search , + TypeLength AL_OriginLength , + TypeLength AL_SearchLength , + TypeLength& ARRL_MatchLen , + TypeLength AL_StartPos=0 + /*////////*/ ) /*//////////////////////////////////////////////*/ + { + const bool CB_IsBad = + (AL_OriginLength<1 || AL_SearchLength<1 || AL_StartPos<0 || AL_StartPos>=AL_OriginLength ); + + if(CB_IsBad) return -1; + + + TypeLength VL_Loop=AL_OriginLength-AL_SearchLength; + TypeLength i =AL_StartPos; + TypeLength j =0 ; + + while(i<=VL_Loop) + { + for(j=0; j static TypeLength FindPosEsc( + const TTyChars& AR_CCharsOrigin, const TTyChars& AR_CCharsSearch, const TTyChars& AR_CCharsEscape, TypeLength AL_StartPos=0) + { + return ZtCMainChars::FindPosEsc( + AR_CCharsOrigin.data(), AR_CCharsSearch.data(), AR_CCharsEscape.data(), + AR_CCharsOrigin.size(), AR_CCharsSearch.size(), AR_CCharsEscape.size(), AL_StartPos); + }/* + template static TypeLength FindPosEsc( + const TTyChars& AR_CCharsOrigin, const TTyChars& AR_CCharsSearch, const TTyChars& AR_CCharsEscape, TypeLength AL_StartPos=0) */ + + + /* APC_Search ڿ ãµ APC_WrapStart Ѵٸ APC_WrapClose + ã ٷ APC_Search ־ ġ ȯѴ. */ + + static TypeLength FindPosEscWrap( //////////////////////////////// + TypeCharC* APC_Origin , + TypeCharC* APC_Search , + TypeCharC* APC_Escape , + TypeCharC* APC_WrapStart , + TypeCharC* APC_WrapClose , + TypeLength AL_OriginLen , + TypeLength AL_SearchLen , + TypeLength AL_EscapeLen , + TypeLength AL_WrapStartLen , + TypeLength AL_WrapCloseLen , + TypeLength AL_StartPos=0 + /*//////////*/ ) ///////////////////////////////////////////////*/ + { + const bool CB_IsBad = + (AL_OriginLen<1 || AL_SearchLen<1 || AL_OriginLen static TypeLength FindPosEscWrap( ////// + const TTyChars& AR_CCharsOrigin , + const TTyChars& AR_CCharsSearch , + const TTyChars& AR_CCharsEscape , + const TTyChars& AR_CCharsWrapStart, + const TTyChars& AR_CCharsWrapClose, + TypeLength AL_StartPos=0 + /*//////////*/ ) ///////////////////////////////////////////////*/ + { + return ZtCMainChars::FindPosEscWrap( + AR_CCharsOrigin.data(), AR_CCharsSearch.data(), AR_CCharsEscape.data(), AR_CCharsWrapStart.data(), AR_CCharsWrapClose.data(), + AR_CCharsOrigin.size(), AR_CCharsSearch.size(), AR_CCharsEscape.size(), AR_CCharsWrapStart.size(), AR_CCharsWrapClose.size(), AL_StartPos + /*/////////*/ ); + }/* + template static TypeLength FindPosEscWrap( ////// + const TTyChars& AR_CCharsOrigin , + const TTyChars& AR_CCharsSearch , + const TTyChars& AR_CCharsEscape , + const TTyChars& AR_CCharsWrapStart, + const TTyChars& AR_CCharsWrapClose, + TypeLength AL_StartPos=0 + ////////////// ) ///////////////////////////////////////////////*/ + + + /*//////////////////////////////////////////////////////////////// + + FindPosEscWrap() ׽Ʈ. + + typedef std::NsChars::ZNsType::ZtCTypeChars ZCTypeChars; + typedef std::NsChars::ZtCMainChars ZCMainChars; + + std::string CStrOrigin("{{ABC\\}}\"}},ABC"); + std::string CStrSearch(","); + std::string CStrEscape("\\"); + std::string CStrWrapStart("{{"); + std::string CStrWrapClose("}}"); + + cout<<"FindPosEscWrap="<"); + VO_Vec.push_back("<"); + + cout<<"pos="<=0) + { + TypeLength j; + + for(j=0; j=0)*/ + + return -1; + }/* + static TypeLength FindPosFromEnd( + TypeCharC* APC_Origin, TypeCharC* APC_Search, TypeLength AL_OriginLen, TypeLength AL_SearchLen)*/ + + template + static TypeLength FindPosFromEnd(const TTyChars& AR_CCharsOrigin, const TTyChars& AR_CCharsSearch) + { + return ZCMainChars::FindPosFromEnd(AR_CCharsOrigin.data(), AR_CCharsSearch.data(), AR_CCharsOrigin.size(), AR_CCharsSearch.size()); + }/* + template + static TypeLength FindPosFromEnd(const TTyChars& AR_CCharsOrigin, const TTyChars& AR_CCharsSearch) */ + + + template + static TypeLength GetMatchLenFromEnd(const TTyChars& AR_CCharsOrigin, const TTyChars& AR_CCharsSearch) + { + return ZtCMainChars::GetMatchLenFromEnd(AR_CCharsOrigin.data(), AR_CCharsSearch.data(), AR_CCharsOrigin.size(), AR_CCharsSearch.size()); + }/* + template + static TypeLength GetMatchLenFromEnd(const TTyChars& AR_CCharsOrigin, const TTyChars& AR_CCharsSearch) */ + + static TypeLength GetMatchLenFromEnd( + TypeCharC* APC_Origin, TypeCharC* APC_Search, TypeLength AL_OriginLength, TypeLength AL_SearchLength) + { + if(AL_OriginLength<1 || AL_SearchLength<1) return 0; + + TypeLength VL_LoopCnt = + (AL_SearchLength>AL_OriginLength ? AL_OriginLength : AL_SearchLength); + + TypeCharC* VP_OriTemp= + (AL_SearchLength>AL_OriginLength ? APC_Origin : APC_Origin+(AL_OriginLength-AL_SearchLength) ); + + TypeCharC* VP_OriTempIn; TypeCharC* VP_SeaTemp=APC_Search; + + TypeLength i=0; TypeLength j=0; + + for(i=VL_LoopCnt; i>0; --i) + { + VP_OriTempIn=VP_OriTemp++; + VP_SeaTemp =APC_Search ; + + for(j=0; j=i) return i; + }/* + for(i=VL_LoopCnt; i>0; --i)*/ + + return 0; + }/* + static TypeLength GetMatchLenFromEnd( + TypeCharC* APC_Origin, TypeCharC* APC_Search, TypeLength AL_OriginLength, TypeLength AL_SearchLength)*/ + + + /* տ δ ڿ APC_WrapStart APC_WrapClose ̿ ִ ڿ n ȸ + ݺ ü ̸ ´. APC_WrapStart APC_WrapClose ̸ Ѵ. + + APC_WrapStart APC_WrapClose " + "ABC""AAABBDD"ABC ڿ ؼ "ABC""AAABBDD" ̸ ȯѴ. */ + + static TypeLength GetWrapLen( //////////////////////////////////// + TypeCharC* APC_OriginChar , + TypeCharC* APC_WrapStart , + TypeCharC* APC_WrapClose , + TypeLength AL_OriginLen , + TypeLength AL_WrapStartLen , + TypeLength AL_WrapCloseLen + /*//////////*/ ) ///////////////////////////////////////////////*/ + { + if(AL_OriginLen<1) return 0; + + TypeLength VL_SearchPos=0; + TypeLength VL_SearchLen=0; + TypeLength VL_FindPos =0; + + do //// + { + const bool CB_DoStart = ZtCMainChars::DoStart( + APC_OriginChar+VL_SearchPos, APC_WrapStart, AL_OriginLen-VL_SearchPos, AL_WrapStartLen); + + if(CB_DoStart==false) return VL_SearchLen; + + // APC_WrapStart ϴ + + VL_SearchPos+=AL_WrapStartLen; + VL_SearchLen+=AL_WrapStartLen; + + VL_FindPos=ZtCMainChars::FindPos( + APC_OriginChar, APC_WrapClose, AL_OriginLen, AL_WrapStartLen, VL_SearchPos); + + if(VL_FindPos<0) + { + // APC_WrapCloase ã . + + return VL_SearchLen-AL_WrapStartLen; + }/* + if(VL_FindPos<0)*/ + + VL_SearchPos=VL_FindPos+AL_WrapCloseLen; + VL_SearchLen=VL_FindPos+AL_WrapCloseLen; + } + while(VL_SearchLen static TypeLength GetWrapLen( + const TTyChars& AR_CCharsOrigin, const TTyChars& AR_CCharsWrapStart, const TTyChars& AR_CCharsWrapClose) + { + return ZtCMainChars::GetWrapLen( + AR_CCharsOrigin.data(), AR_CCharsWrapStart.data(), AR_CCharsWrapClose.data(), AR_CCharsOrigin.size(), AR_CCharsWrapStart.size(), AR_CCharsWrapClose.size()); + }/* + template static TypeLength GetWrapLen( + const TTyChars& AR_CCharsOrigin, const TTyChars& AR_CCharsWrapStart, const TTyChars& AR_CCharsWrapClose)*/ + + + static TypeLength FindPosLinear( ///////////////////////////////// + TypeCharC* APC_Origin1 , + TypeCharC* APC_Origin2 , + TypeCharC* APC_Search , + TypeLength AL_OriginLen1 , + TypeLength AL_OriginLen2 , + TypeLength AL_SearchLength , + TypeLength& ARRL_SearchedPos1 , + TypeLength& ARRL_SearchedPos2 , + TypeLength& ARRL_SearchedLen1 , + TypeLength& ARRL_SearchedLen2 + /*//////////*/ ) ///////////////////////////////////////////////*/ + { + /* APC_Origin1 APC_Origin2 ̾ ڿ + APC_Search ġ Ѵ. + APC_Origin1 ߰ߵ ġ ARRL_SearchedPos1 + APC_Origin2 ߰ߵ ġ ARRL_SearchedPos2 Ѵ. + APC_Origin1 ߰ߵ ̴ ARRL_SearchedLen1 + APC_Origin2 ߰ߵ ̴ ARRL_SearchedLen2 Ѵ. */ + + ARRL_SearchedPos1=-1; + ARRL_SearchedPos2=-1; + ARRL_SearchedLen1= 0; + ARRL_SearchedLen2= 0; + + if(AL_SearchLength<1) return -1; + + TypeLength VL_MatchLen= 0; + TypeLength VL_FindPos =-1; + + /* APC_Origin1 ִ AL_SearchLength ڿ Ѵ. */ + + if(APC_Origin1=0) + { + ARRL_SearchedLen1=AL_SearchLength; return ARRL_SearchedPos1=VL_FindPos ; + }/* + if(VL_FindPos>=0)*/ + + + if(VL_MatchLen>0) + { + if(AL_SearchLength-VL_MatchLen>AL_OriginLen2) + return -1; + //endif + + bool VB_IsOK=ZtCMainChars::DoStart( + APC_Origin2 , + APC_Search +VL_MatchLen, + AL_OriginLen2 , + AL_SearchLength-VL_MatchLen + /*/////////*/ ); + + if(VB_IsOK==true) + { + ARRL_SearchedPos1=AL_OriginLen1-VL_MatchLen; + ARRL_SearchedPos2=0 ; + ARRL_SearchedLen1=VL_MatchLen; + ARRL_SearchedLen2=AL_SearchLength-VL_MatchLen; + + return 0; + }/* + if(VB_IsOK==true)*/ + }/* + if(VL_MatchLen>0)*/ + + + ARRL_SearchedPos2=ZtCMainChars::FindPos( + APC_Origin2 , + APC_Search , + AL_OriginLen2 , + AL_SearchLength , + 0 + /*/////////*/ ); /////////////////////// + + if(ARRL_SearchedPos2>=0) + ARRL_SearchedLen2=AL_SearchLength; + + return ARRL_SearchedPos2; + }/* + static TypeLength FindPosLinear( ///////////////////////////////// + TypeCharC* APC_Origin1 , + TypeCharC* APC_Origin2 , + TypeCharC* APC_Search , + TypeLength AL_OriginLen1 , + TypeLength AL_OriginLen2 , + TypeLength AL_SearchLength , + TypeLength& ARRL_SearchedPos1 , + TypeLength& ARRL_SearchedPos2 , + TypeLength& ARRL_SearchedLen1 , + TypeLength& ARRL_SearchedLen2 + ////////////// ) ///////////////////////////////////////////////*/ + + template + static TypeLength FindPosLinear( ///////////////////////////////// + const TTyChars& AR_CCharsOrigin1 , + const TTyChars& AR_CCharsOrigin2 , + const TTyChars& AR_CCharsSearch , + TypeLength& ARRL_SearchedPos1, + TypeLength& ARRL_SearchedPos2, + TypeLength& ARRL_SearchedLen1, + TypeLength& ARRL_SearchedLen2 + /*//////////*/ ) ///////////////////////////////////////////////*/ + { + return ZtCMainChars::FindPosLinear( + AR_CCharsOrigin1.data(), AR_CCharsOrigin2.data(), AR_CCharsSearch.data(), + AR_CCharsOrigin1.size(), AR_CCharsOrigin2.size(), AR_CCharsSearch.size(), + RR(ARRL_SearchedPos1) , RR(ARRL_SearchedPos2) , RR(ARRL_SearchedLen1) , RR(ARRL_SearchedLen2) + /*//////////*/ ); + }/* + template + static TypeLength FindPosLinear( ///////////////////////////////// + const TTyChars& AR_CCharsOrigin1 , + const TTyChars& AR_CCharsOrigin2 , + const TTyChars& AR_CCharsSearch , + TypeLength& ARRL_SearchedPos1, + TypeLength& ARRL_SearchedPos2, + TypeLength& ARRL_SearchedLen1, + TypeLength& ARRL_SearchedLen2 + ////////////// ) ///////////////////////////////////////////////*/ + + + /*//////////////////////////////////////////////////////////////////////////////////////////// + + template + bool FindPosReady( + TReadyExec AR_CReadyExec , + const ZCChars& AR_CCharsOrigin , + const ZCChars& AR_CCharsSearch , + TString& ARR_CStrReadyBuff, + TypeLength& ARRL_StartPos , // AR_CCharsOrigin.data() offset ̴. + ZNsEnum::ZERun& ARRE_ERun + ///////////// ) + +  ڿ ã ϴ Ÿ ִµ, ڿ ʹ  ϴ , + ڿ ݾ о ã ڿ Ž ʿ䰡 ִ. ü Ʒ ڿ . + + abc_BOUND1_defg_BOUND2_hijkmln_BO_BOUND3_opqrstuvwxyz + + ڿ ã ڿ BOUND1, BOUND2, BOUND3 ̸ ڿ ã +  ڷῡ Ͽ Ư ó ϰ ϴ ̴. + + ó abc_BOU оٰ ġ. ׷ ó ãƾ ϴ ڿ BOUND1 Ƿ, abc_BOU + Ͽ  ó ִ. ׷ abc_BOU ڿ ã ڿ պκ + (BOU) ϰ Ƿ, κ abc_ ؼ ó ־ Ѵ( εϴ + ڿ ND1 ִ ̴.) ׸ BOU ۿ ´. + + 2 ° ND1_de оٸ, ۿ ã ڿ BOUND1 ߿ BOU ۿ ̹ Ƿ + ND1_de , BOU ڿ ã ڿ ND1 ãƺ. ׷ BOUND1 ã ǰ, + Ÿ _de ´. Ÿ . ۵ . Ÿ _de 2 ° ã + ڿ BOUND2 ʰų, ã ڿ κ ڿ ڷ + ʾҴ. ׷ _de ؼ Ƚϰ(?) ó ش. + + 3 ° fg_BOUND2_hijkmln_BO о. 2 ° ã ڿ BOUND2 ã ȴ. ׷ + ڿ fg_ ؼ ó ְ 3 ° ã ڿ BOUND3 ã´. BOUND3 . ׷ BOUND3 + κ BO Ƿ, BO ( εϴ ڿ UND3 ֱ + ) ڿ _hijkmln_ ؼ ó ش. BO ۿ ´. + + 4 ° _BOUND3_opqrstuvwxyz о. ۿ ִ BO ϸ BO_BOUND3_opqrstuvwxyz + ȴ. ⼭ BOUND3 ã ǰ ۿ ִ Ÿ BO _ ؼ ó ָ + ȴ. BOUND3 Ÿ _opqrstuvwxyz ó ָ ȴ. + + ˰ FindPosReady(~) ̴. + + FindPosReady() о ڿ AR_CCharsSearch.data() Ͽ AR_CCharsOrigin.data() ã´. + ã о ڿ ã ڿ Ƿ, ϴ AR_CCharsOrigin.data() + ڿ AR_CCharsSearch.data() պκа ġϴ ڸ ARR_CStrReadyBuff Ѵ. ( ڵ + ã ڿ Ϻ ִ.) + + TReadyExec Ʒ ϸ ִ. + + std::ZNsEnum::ZERun TReadyExec::OnMeetNormal(TypeCharC*,TypeLength); + std::ZNsEnum::ZERun TReadyExec::OnMeetReady (TypeCharC*,TypeLength,std::ZNsEnum::ZERun); + + ã ڿ ARR_CStrReadyBuff AR_CCharsOrigin.data() ÿ ִµ, ã ڿ + ã + + OnMeetReady() 3 μ ZNsMain::ZNsEnum::ZERun_NO ̰ + ã 3 μ ZNsMain::ZNsEnum::ZERun_OK ̴. + + μ TString& ARR_CStrReadyBuff ȭ ִ ִ. + + ////////////////////////////////////////////////////////////////////////////////////////////*/ + + template< + typename TReadyExec, typename TTyChars, typename TString> + static bool FindPosReady( + TReadyExec AR_CReadyExec , + const TTyChars& AR_CCharsOrigin , + const TTyChars& AR_CCharsSearch , + TString& ARR_CStrReadyBuff, + TypeLength& ARRL_StartPos , // AR_CCharsOrigin.data() offset ̴. + ZNsEnum::ZERun& ARRE_ERun + /*//////////*/ ) ////////////////////////////////////////*/ + { + /*########################################################################################### + + ARR_CStrReadyBuff AR_CCharsSearch.data() պκа ġϴ ڿ ִ. + ٸ Ÿ ʵ ؾ Ѵ. + + ARRL_StartPos Լ true ȯ + ( AR_CCharsSearch.data() ã) AR_CCharsOrigin.data() ٽ ȸ ؾ + ϴ ġ õȴ. ׷ ȸÿ AR_CCharsOrigin.data()+ARRL_StartPos + ȸϸ ȴ. + + ###########################################################################################*/ + + ZCChars VO_CCharsOrigin(AR_CCharsOrigin.data(), AR_CCharsOrigin.size()); + + VO_CCharsOrigin += ARRL_StartPos; + + if(VO_CCharsOrigin.size()<1 || AR_CCharsSearch.size()<1) + { return false; } + //////////////////////////////////////////////////////// + + TypeLength VL_ReadyBuffSize=ARR_CStrReadyBuff.size(); + TypeLength VL_MatchLen =0; + + if(VL_ReadyBuffSize+VO_CCharsOrigin.size()0) + { + ARRE_ERun=AR_CReadyExec. + OnMeetNormal(ARR_CStrReadyBuff.data(), VL_ReadyBuffSize); + ARR_CStrReadyBuff=""; + + if(ARRE_ERun==ZNsMain::ZNsEnum::ZERun_NO) return false; + }/* + if(VL_ReadyBuffSize>0)*/ + + VL_MatchLen=ZtCMainChars::GetMatchLenFromEnd( + VO_CCharsOrigin.data(), + AR_CCharsSearch.data(), + VO_CCharsOrigin.size(), + VO_CCharsOrigin.size() + /*/////////*/ ); //////////////////////////// + + TypeLength VL_ValidLen=VO_CCharsOrigin.size()-VL_MatchLen; + + if(VL_MatchLen>0) + ARR_CStrReadyBuff.append(VO_CCharsOrigin.data()+VL_ValidLen, VL_MatchLen); + if(VL_ValidLen>0) + ARRE_ERun=AR_CReadyExec.OnMeetNormal(VO_CCharsOrigin.data(), VL_ValidLen); + //endif + + return false; + }/* + if(VL_ReadyBuffSize+AR_CCharsOrigin.size()0) + { + ARRE_ERun=AR_CReadyExec.OnMeetReady( /////////// + ARR_CStrReadyBuff.data(), + VL_ReadyBuffSize , + ZNsMain::ZNsEnum::ZERun_OK + /*/////////*/ ); /////////////////////////////// + + if(ARRE_ERun==ZNsMain::ZNsEnum::ZERun_NO) return true; + }/* + if(VL_ReadyBuffSize>0)*/ + + ARRE_ERun=AR_CReadyExec.OnMeetReady( + VO_CCharsOrigin.data(), VL_ReadyLen, ZNsMain::ZNsEnum::ZERun_NO); + + ARRL_StartPos +=VL_ReadyLen; + ARR_CStrReadyBuff="" ; return true; + }/* + if(VB_IsOK==true)*/ + + + if(VL_ReadyBuffSize>0) + { + ARRE_ERun=AR_CReadyExec.OnMeetNormal( + ARR_CStrReadyBuff.data(), VL_ReadyBuffSize); + ARR_CStrReadyBuff=""; + + if(ARRE_ERun==ZNsMain::ZNsEnum::ZERun_NO) return false; + }/* + if(VL_ReadyBuffSize>0)*/ + + VL_MatchLen=0; TypeLength VL_FindPos=ZtCMainChars::FindPosLen( + VO_CCharsOrigin.data(), + AR_CCharsSearch.data(), + VO_CCharsOrigin.size(), + AR_CCharsSearch.size(), + RR(VL_MatchLen) + /*/////////*/ ); ///////////////////////////////////////////// + + if(VL_FindPos<0) + { + ARRL_StartPos = -1; + ARRE_ERun=AR_CReadyExec.OnMeetNormal( + VO_CCharsOrigin.data(), VO_CCharsOrigin.size()-VL_MatchLen ); + ARR_CStrReadyBuff.append( + VO_CCharsOrigin.data()+VO_CCharsOrigin.size()-VL_MatchLen, VL_MatchLen ); + + return false; + }/* + if(VL_FindPos<0)*/ + + if(VL_FindPos>0) + { + ARRE_ERun=AR_CReadyExec. + OnMeetNormal(VO_CCharsOrigin.data(), VL_FindPos); + + if(ARRE_ERun==ZNsMain::ZNsEnum::ZERun_NO) return true; + }/* + if(VL_FindPos>0)*/ + + ARRE_ERun =AR_CReadyExec.OnMeetReady( + VO_CCharsOrigin.data()+VL_FindPos, AR_CCharsSearch.size(), ZNsMain::ZNsEnum::ZERun_NO); + ARRL_StartPos+=(VL_FindPos+AR_CCharsSearch.size()); + + return true; + }/* + template< + typename TReadyExec, typename TTyChars, typename TString> + static bool FindPosReady( + TReadyExec AR_CReadyExec , + const TTyChars& AR_CCharsOrigin , + const TTyChars& AR_CCharsSearch , + TString& ARR_CStrReadyBuff, + TypeLength& ARRL_StartPos , // AR_CCharsOrigin.data() offset ̴. + ZNsEnum::ZERun& ARRE_ERun + ////////////// ) ////////////////////////////////////////*/ + + template< + typename TReadyExec, typename TStringData> ////////////// + static bool FindPosReady( + TReadyExec AR_CReadyExec , + TypeCharC* AP_OriginData , + TypeCharC* AP_SearchData , + TypeLength AL_OriginLen , + TypeLength AL_SearchLen , + TStringData& ARR_CStrReadyBuff, + TypeLength& ARRL_StartPos , // AP_OriginData offset ̴. + ZNsEnum::ZERun& ARRE_ERun + /*//////////*/ ) //////////////////////////////////////////*/ + { + return FindPosReady( + AR_CReadyExec , + ZCChars(AP_OriginData, AL_OriginLen), + ZCChars(AP_SearchData, AL_SearchLen), + ARR_CStrReadyBuff , + ARRL_StartPos , // AP_OriginData offset ̴. + ARRE_ERun + /*/////*/ ); ///////////////////////////////////////// + }/* + template< + typename TReadyExec, typename TStringData> ////////////// + static bool FindPosReady( + TReadyExec AR_CReadyExec , + TypeCharC* AP_OriginData , + TypeCharC* AP_SearchData , + TypeLength AL_OriginLen , + TypeLength AL_SearchLen , + TStringData& ARR_CStrReadyBuff, + TypeLength& ARRL_StartPos , // AP_OriginData offset ̴. + ZNsEnum::ZERun& ARRE_ERun + ////////////// ) //////////////////////////////////////////*/ + + + /*//////////////////////////////////////////////////////////////////////////////// + + Call Back Լ TReadyExec::OnMeetNormal() ̳ TReadyExec::OnMeetReady() + ڼ ֵ AO_CHelpType μ ߰ Լ + Ѵ. ƴ ѱ ִ(THelpType AO_CHelpType). + THelpType ũⰡ ū object ͳ, ͸ object + ؼ Ѱܾ Ѵ. + + ////////////////////////////////////////////////////////////////////////////////*/ + + template< typename TReadyExec , typename TTyChars, + typename TStringData, typename THelpType> //////////// + static bool FindPosReady( + TReadyExec AR_CReadyExec , + THelpType AO_CHelpType , + const TTyChars& AR_CCharsOrigin , + const TTyChars& AR_CCharsSearch , + TStringData& ARR_CStrReadyBuff, + TypeLength& ARRL_StartPos , // AR_CCharsOrigin.data() offset ̴. + ZNsEnum::ZERun& ARRE_ERun + /*//////////*/ ) ///////////////////////////////////////////////*/ + { + /*######################################################################################## + + ARR_CStrReadyBuff AR_CCharsSearch.data() պκа ġϴ ڿ ִ. + ٸ Ÿ ʵ ؾ Ѵ. + + ARRL_StartPos Լ true ȯ ( AR_CCharsSearch.data() ã) + AR_CCharsOrigin.data() ٽ ȸ ؾ ϴ ġ õȴ. ׷ + ȸÿ AR_CCharsOrigin.data()+ARRL_StartPos ȸϸ ȴ. + + ########################################################################################*/ + + typedef ZNsMain::ZtCCheckRef ZCCheckRef ; + typedef ZCCheckRef::TypeData TypeObject ; + + ZCChars VO_CCharsOrigin( + AR_CCharsOrigin.data(), AR_CCharsOrigin.size() ) ; + + VO_CCharsOrigin += ARRL_StartPos ; + + if(VO_CCharsOrigin.size()<1 || AR_CCharsSearch.size()<1) + { return false; } + + TypeLength VL_ReadyBuffSize=ARR_CStrReadyBuff.size(); + TypeLength VL_MatchLen =0; + + if(VL_ReadyBuffSize+AR_CCharsOrigin.size()0) + { + ARRE_ERun= AR_CReadyExec.template OnMeetNormal + ( + ARR_CStrReadyBuff.data(), + VL_ReadyBuffSize , + ZCCheckRef::PassData(AO_CHelpType) + ); + ARR_CStrReadyBuff = ""; ////////////////////////////////// + + if(ARRE_ERun==ZNsMain::ZNsEnum::ZERun_NO) return false; + }/* + if(VL_ReadyBuffSize>0)*/ + + VL_MatchLen=ZtCMainChars::GetMatchLenFromEnd( + VO_CCharsOrigin.data(), + AR_CCharsSearch.data(), + VO_CCharsOrigin.size(), + VO_CCharsOrigin.size() + /*/////////*/ ); //////////////////////////// + + TypeLength VL_ValidLen=VO_CCharsOrigin.size()-VL_MatchLen; + + if(VL_MatchLen>0) + { + ARR_CStrReadyBuff.append(VO_CCharsOrigin.data()+VL_ValidLen, VL_MatchLen); + } + if(VL_ValidLen>0) + { + ARRE_ERun=AR_CReadyExec.template OnMeetNormal + ( + VO_CCharsOrigin.data(), + VL_ValidLen , + ZCCheckRef::PassData(AO_CHelpType) + ); + ///////////////////////////////////////////////////////// + }/* + if(VL_ValidLen>0)*/ + + return false; + }/* + if(VL_ReadyBuffSize+AR_CCharsOrigin.size()0) + { + ARRE_ERun=AR_CReadyExec.template OnMeetReady + ( + ARR_CStrReadyBuff.data() , VL_ReadyBuffSize, + ZNsMain::ZNsEnum::ZERun_OK, ZCCheckRef::PassData(AO_CHelpType) + ); + //////////////////////////////////////////////////////// + + if(ARRE_ERun==ZNsMain::ZNsEnum::ZERun_NO) return true; + } + //if(VL_ReadyBuffSize>0) + + ARRE_ERun=AR_CReadyExec.template OnMeetReady + ( + VO_CCharsOrigin.data() , VL_ReadyLen , + ZNsMain::ZNsEnum::ZERun_NO, ZCCheckRef::PassData(AO_CHelpType) + ); + //////////////////////////////////////////////////////// + + ARRL_StartPos +=VL_ReadyLen; + ARR_CStrReadyBuff=""; + + return true; + }/* + if(VB_IsOK==true)*/ + + + if(VL_ReadyBuffSize>0) + { + ARRE_ERun=AR_CReadyExec.template OnMeetNormal + ( + ARR_CStrReadyBuff.data(), + VL_ReadyBuffSize , + ZCCheckRef::PassData(AO_CHelpType) + ); + ///////////////////////////////////////////////////////// + + ARR_CStrReadyBuff = ""; + + if(ARRE_ERun==ZNsMain::ZNsEnum::ZERun_NO) + { return false; } + }/* + if(VL_ReadyBuffSize>0)*/ + + VL_MatchLen=0; TypeLength VL_FindPos=ZtCMainChars::FindPosLen( + VO_CCharsOrigin.data(), + AR_CCharsSearch.data(), + VO_CCharsOrigin.size(), + AR_CCharsSearch.size(), + RR(VL_MatchLen) + /*/////////*/ ); ///////////////////////////////////////////// + + if(VL_FindPos<0) + { + ARRL_StartPos=-1; + ARRE_ERun=AR_CReadyExec.template OnMeetNormal + ( + VO_CCharsOrigin.data() , + VO_CCharsOrigin.size()-VL_MatchLen, + ZCCheckRef::PassData(AO_CHelpType) + ); + ///////////////////////////////////////////////////////// + ARR_CStrReadyBuff.append + ( + VO_CCharsOrigin.data() + + VO_CCharsOrigin.size() - VL_MatchLen, + VL_MatchLen + ); + //////////////////////// + + return false; + }/* + if(VL_FindPos<0)*/ + + if(VL_FindPos>0) + { + ARRE_ERun=AR_CReadyExec.template OnMeetNormal + ( + VO_CCharsOrigin.data(), + VL_FindPos , + ZCCheckRef::PassData(AO_CHelpType) + ); + ///////////////////////////////////////////////////////// + + if(ARRE_ERun==ZNsMain::ZNsEnum::ZERun_NO) return true; + }/* + if(VL_FindPos>0)*/ + + ARRE_ERun=AR_CReadyExec.template OnMeetReady + ( + VO_CCharsOrigin.data()+VL_FindPos, AR_CCharsSearch.size(), + ZNsMain::ZNsEnum::ZERun_NO , ZCCheckRef::PassData(AO_CHelpType) + ); + ARRL_StartPos+=(VL_FindPos+AR_CCharsSearch.size()); return true; + }/* + template< typename TReadyExec , typename TTyChars, + typename TStringData, typename THelpType> //////////// + static bool FindPosReady( + TReadyExec AR_CReadyExec , + THelpType AO_CHelpType , + const TTyChars& AR_CCharsOrigin , + const TTyChars& AR_CCharsSearch , + TStringData& ARR_CStrReadyBuff, + TypeLength& ARRL_StartPos , // AR_CCharsOrigin.data() offset ̴. + ZNsEnum::ZERun& ARRE_ERun + ////////////// ) ///////////////////////////////////////////////*/ + + template + + static bool FindPosReady + ( + TReadyExec AR_CReadyExec , + THelpType AO_CHelpType , + TypeCharC* AP_OriginData , + TypeCharC* AP_SearchData , + TypeLength AL_OriginLen , + TypeLength AL_SearchLen , + TStringData& ARR_CStrReadyBuff, + TypeLength& ARRL_StartPos , // AP_OriginData offset ̴. + ZNsEnum::ZERun& ARRE_ERun + ) + /////////////////////////////////////////////////////////////////*/ + { + typedef ZNsMain::ZtCCheckRef ZCCheckRef ; + typedef ZCCheckRef::TypeData TypeObject ; + + return FindPosReady( + AR_CReadyExec , + ZCCheckRef::PassData(AO_CHelpType) , + ZCChars(AP_OriginData, AL_OriginLen), + ZCChars(AP_SearchData, AL_SearchLen), + ARR_CStrReadyBuff , + ARRL_StartPos , // AP_OriginData offset ̴. + ARRE_ERun + /*/////*/ ); ///////////////////////////////////////////////////// + }/* + template + + static bool FindPosReady + ( + TReadyExec AR_CReadyExec , + THelpType AO_CHelpType , + TypeCharC* AP_OriginData , + TypeCharC* AP_SearchData , + TypeLength AL_OriginLen , + TypeLength AL_SearchLen , + TStringData& ARR_CStrReadyBuff, + TypeLength& ARRL_StartPos , // AP_OriginData offset ̴. + ZNsEnum::ZERun& ARRE_ERun + ) + ///////////////////////////////////////////////////////////////////*/ + + + template ////////////////// + static bool FindPosReadyValid( + const TTyChars& AR_CCharsOrigin , + const TTyChars& AR_CCharsSearch , + TStringData& ARR_CStrReadyBuff, + TypeLength& ARRL_StartPos , + TypeLength& ARRL_ValidReady , // ARR_CStrReadyBuff ȿ + TypeLength& ARRL_ValidLen + /*//////////*/ ) /////////////////////////////////////////////////*/ + { + // ARRL_ValidReady 0 ̳ ARR_CStrReadyBuff.size() ̴. + + if(ARRL_StartPos<0) ARRL_StartPos=0; + + ZCChars VO_CCharsOrigin( + AR_CCharsOrigin.data(), AR_CCharsOrigin.size()); + + VO_CCharsOrigin+=ARRL_StartPos; + + /*///////////////////////////////////////////////////////////////////////////////////////// + + FindPosReady() Լ ϴµ, AR_CReadyExec μ + FindPosReady() VL_ValidLen ǹ̸ ̸ + μ ARRL_ValidLen Ѵ. + + ARRL_ValidLen + AR_CCharsOrigin.data() ߿ ã ڿ Ե ʴ ̸ Ÿ, + AR_CCharsOrigin.data() տ ڿ  ó ȴ. + + ARR_CStrReadyBuff ڿ AR_CCharsSearch.data() match Ǵ ڿ  + ARR_CStrReadyBuff ã Ϻΰ ƴ϶  ó Ǵ , + ARR_CStrReadyBuff ̸ μ ARRL_ValidReady Ѵ. + ARR_CStrReadyBuff AR_CCharsSearch.data() Ϻκ̹Ƿ + ARRL_ValidLen Ÿ óϱ ռ, AR_CCharsSearch.data() ARRL_ValidReady ŭ + Ÿ ó ־ Ѵ. + + ARRL_ValidReady 0 ̳ ARR_CStrReadyBuff.size() ̴. + + /////////////////////////////////////////////////////////////////////////////////////////*/ + + if(VO_CCharsOrigin.size()<1 || AR_CCharsSearch.size()<1) + { + ARRL_StartPos =-1; + ARRL_ValidReady = 0; + ARRL_ValidLen = 0; + + return false; + }/* + if(VO_CCharsOrigin.size()<1 || AR_CCharsSearch.size()<1)*/ + + TypeLength VL_ReadyBuffSize=ARR_CStrReadyBuff.size(); + TypeLength VL_MatchLen =0; + + if(VL_ReadyBuffSize+VO_CCharsOrigin.size()0) ARR_CStrReadyBuff. + append(VO_CCharsOrigin.data()+ARRL_ValidLen, VL_MatchLen); + + return false; + }/* + if(VL_ReadyBuffSize+AR_CCharsOrigin.size() ////////////////// + static bool FindPosReadyValid( + const TTyChars& AR_CCharsOrigin , + const TTyChars& AR_CCharsSearch , + TStringData& ARR_CStrReadyBuff, + TypeLength& ARRL_StartPos , + TypeLength& ARRL_ValidReady , // ARR_CStrReadyBuff ȿ + TypeLength& ARRL_ValidLen + ////////////// ) /////////////////////////////////////////////////*/ + + + template + static bool FindPosReadyValid( /////////////////////////////////// + TypeCharC* AP_CharOrigin , + TypeCharC* AP_CharSearch , + TypeLength AL_OriginLen , + TypeLength AL_SearchLen , + TString& ARR_CStrReadyBuff, + TypeLength& ARRL_StartPos , + TypeLength& ARRL_ValidReady , // ARR_CStrReadyBuff ȿ + TypeLength& ARRL_ValidLen + /*//////////*/ ) ///////////////////////////////////////////////*/ + { + return FindPosReadyValid( ///////////////////////////////// + ZCChars(AP_CharOrigin, AL_OriginLen), + ZCChars(AP_CharSearch, AL_SearchLen), + RR(ARR_CStrReadyBuff) , + ARRL_StartPos , + ARRL_ValidReady , + ARRL_ValidLen + /*/////////*/ ); ////////////////////////////////////////// + }/* + template + static bool FindPosReadyValid( /////////////////////////////////// + TypeCharC* AP_CharOrigin , + TypeCharC* AP_CharSearch , + TypeLength AL_OriginLen , + TypeLength AL_SearchLen , + TString& ARR_CStrReadyBuff, + TypeLength& ARRL_StartPos , + TypeLength& ARRL_ValidReady , // ARR_CStrReadyBuff ȿ + TypeLength& ARRL_ValidLen + ////////////// ) ///////////////////////////////////////////////*/ + + + 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 static TypeLength GetFindCnt( + const TTyChars& AR_CCharsOrigin, const TTyChars& APC_CCharsSearch) + { + return ZtCMainChars::GetFindCnt( + AR_CCharsOrigin.data(), APC_CCharsSearch.data(), + AR_CCharsOrigin.size(), APC_CCharsSearch.size() ) ; + }/* + template static TypeLength GetFindCnt( + const TTyChars& AR_CCharsOrigin, const TTyChars& APC_CCharsSearch) */ + + + /*////////////////////////////////////////////////////////////////////////////// + + APC_Origin APC_Search+AL_SearchOffset ϴ ǴѴ. + AL_OriginLen static TypeLength GetStartLength( + const TTyChars& AR_CCharsOrigin, const TTyChars& AR_CCharsSearch, TypeLength AL_SearchOffset=0) + { + return ZtCMainChars::GetStartLength( + AR_CCharsOrigin.data(), AR_CCharsSearch.data(), AR_CCharsOrigin.size(), AR_CCharsSearch.size(), AL_SearchOffset); + }/* + template static TypeLength GetStartLength( + const TTyChars& AR_CCharsOrigin, const TTyChars& AR_CCharsSearch, TypeLength AL_SearchOffset=0) */ + + + template static void SplitEach( /////////////// + TFunctor AR_TFunctor , + TypeCharC* APC_OriginChar , + TypeCharC* APC_SearchChar , + TypeLength AL_OriginLen , + TypeLength AL_SearchLen , + bool AB_DoExecNull=true // ڷ ߸ ڿ ̰ 0 쿡 ũ͸ Ѵ. + /*//////////*/ ) ///////////////////////////////////////////////*/ + { + if(AL_OriginLen<1 || AL_OriginLenVL_CopyStartPos) + { + AR_TFunctor( + APC_OriginChar+VL_CopyStartPos, VL_Index-VL_CopyStartPos, ++VI_SearchCount) ; + } + else if(AB_DoExecNull==true) + { + AR_TFunctor(0, 0, ++VI_SearchCount) ; + }/* + else if(AB_DoExecNull==true)*/ + + VL_CopyStartPos=VL_Index+=AL_SearchLen; + }/* + while(VL_Index<=VL_Loop)*/ + + + if(VL_CopyStartPos>=AL_OriginLen) return; + + if(VI_SearchCount==0 && VL_CopyStartPos==0) + { + AR_TFunctor(APC_OriginChar, AL_OriginLen, ++VI_SearchCount) ; + } + else + { + AR_TFunctor( + APC_OriginChar+VL_CopyStartPos, AL_OriginLen-VL_CopyStartPos, ++VI_SearchCount) ; + }/* + else*/ + }/* + template static void SplitEach( /////////////// + TFunctor AR_TFunctor , + TypeCharC* APC_OriginChar , + TypeCharC* APC_SearchChar , + TypeLength AL_OriginLen , + TypeLength AL_SearchLen , + bool AB_DoExecNull=true + ////////////// ) ///////////////////////////////////////////////*/ + + template static void SplitEach( + TFunctor AR_TFunctor, const TTyChars& AR_CCharsOrigin , const TTyChars& AR_CCharsSearch, bool AB_DoExecNull=true) + { + ZtCMainChars::template SplitEach( + AR_TFunctor, + AR_CCharsOrigin.data(), AR_CCharsSearch.data(), + AR_CCharsOrigin.size(), AR_CCharsSearch.size(), + AB_DoExecNull + /*/////////*/ ); ////////////////////////////////////////////// + }/* + template static void SplitEach( + TFunctor AR_TFunctor, const TTyChars& AR_CCharsOrigin , const TTyChars& AR_CCharsSearch, bool AB_DoExecNull=true) */ + + + template static bool SplitTwo( ///////////////// + TypeCharC* APC_OriginChar , + TypeCharC* APC_SearchChar , + TypeLength AL_OriginLen , + TypeLength AL_SearchLen , + TString& ARR_CString1 , + TString& ARR_CString2 + /*//////////*/ ) ///////////////////////////////////////////////*/ + { + TypeLength VL_FindPos=ZtCMainChars:: + FindPos(APC_OriginChar, APC_SearchChar, AL_OriginLen, AL_SearchLen); + + if(VL_FindPos<0) return false; + + ARR_CString1(APC_OriginChar, VL_FindPos); + ARR_CString2( + APC_OriginChar+VL_FindPos+AL_SearchLen, + AL_OriginLen -VL_FindPos-AL_SearchLen ); + + return true; + }/* + template static bool SplitTwo( ///////////////// + TypeCharC* APC_OriginChar , + TypeCharC* APC_SearchChar , + TypeLength AL_OriginLen , + TypeLength AL_SearchLen , + TString& ARR_CString1 , + TString& ARR_CString2 + ////////////// ) ///////////////////////////////////////////////*/ + + template static bool SplitTwo( + const TTyChars& AR_CCharsOrigin, const TTyChars& AR_CCharsSearch, TString& ARR_CString1, TString& ARR_CString2) + { + return ZtCMainChars::SplitTwo( + AR_CCharsOrigin.data(), AR_CCharsSearch.data(), AR_CCharsOrigin.size(), AR_CCharsSearch.size(), RR(ARR_CString1), RR(ARR_CString2)); + }/* + template static bool SplitTwo( + const TTyChars& AR_CCharsOrigin, const TTyChars& AR_CCharsSearch, TString& ARR_CString1, TString& ARR_CString2) */ + + + template 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==true ̸ йڿ ϳ ã + ü ڿ APC_OriginChar ARR_SaveList ʰ Ѵ. + + ӵ APC_SearchChar ̿ ٸ ڰ  + ִ TString object ARR_SaveList Ѵ. + + //////////////////////////////////////////////////////////////////////////*/ + + if(AL_OriginLen<1 || AL_OriginLenVL_CopyStartPos) + { + if(AB_DoAppendEachLink==true) + { + ((CStringData&)ARR_SaveList). + append(APC_OriginChar+VL_CopyStartPos, VL_Index-VL_CopyStartPos) ; + } + else + { + ((CStringData&)ARR_SaveList).Invalidate(). + append(APC_OriginChar+VL_CopyStartPos, VL_Index-VL_CopyStartPos) ; + }/* + else*/ + } + else if(AB_DoAppendEmpty==true) + { + (CStringData&)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_CopyStartPos>=AL_OriginLen)*/ + + + if(VL_PrevSize 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 TTyChars, typename TStringList> + static TStringList& SplitToList( + TStringList& ARR_SaveList , + const TTyChars& AR_CCharsOrigin , + const TTyChars& AR_CCharsSearch , + bool AB_DoEndWhenNoMatch=true , + bool AB_DoAppendEachLink=false, + bool AB_DoAppendEmpty =false + /*/////////////*/ ) + { + return ZtCMainChars::SplitToList( + RR(ARR_SaveList), + AR_CCharsOrigin.data(), AR_CCharsSearch.data(), + AR_CCharsOrigin.size(), AR_CCharsSearch.size(), + AB_DoEndWhenNoMatch , AB_DoAppendEachLink , AB_DoAppendEmpty + /*//////////*/ ); + }/* + template< + typename TTyChars, typename TStringList> + static TStringList& SplitToList( + TStringList& ARR_SaveList , + const TTyChars& AR_CCharsOrigin , + const TTyChars& AR_CCharsSearch , + bool AB_DoEndWhenNoMatch=true , + bool AB_DoAppendEachLink=false, + bool AB_DoAppendEmpty =false + ///////////////// ) */ + + + /*////////////////////////////////////////////////////////////////////////// + + APC_SearchChar APC_OriginChar ڸµ ڸ ڿ + յڿ APC_EscapeChar ִ. + APC_EscapeChar δ ڿ ȿ APC_SearchChar  ִ. + APC_EscapeChar δ ڿ ȿ APC_EscapeChar ڿ ¦ ; Ѵ. + APC_SearchChar "," ̰ APC_EscapeChar "\"" ̶ + ڿ 1,2,"My, Data=""Love""",10 Ʒ 4 . + + 1 + 2 + My, Data=""Love"" + 10 + + -- + + //////////////////////////////////////////////////////////////////////*/ + + template + static TStringList& SplitToListWrap( ///////////////////////////// + TStringList& ARR_SaveList , + TypeCharC* APC_OriginChar , + TypeCharC* APC_SearchChar , + TypeCharC* APC_WrapStart , + TypeCharC* APC_WrapClose , + TypeLength AL_OriginLen , + TypeLength AL_SearchLen , + TypeLength AL_WrapStartLen , + TypeLength AL_WrapCloseLen , + bool AB_DoEndWhenNoMatch=true , + bool AB_DoAppendEachLink=false + /*//////////*/ ) ///////////////////////////////////////////////*/ + { + // AB_DoEndWhenNoMatch==true ̸ ڿ ϳ ã + // ü ڿ APC_OriginChar ARR_SaveList ʰ Ѵ. + + if(AL_WrapStartLen<1 && AL_WrapCloseLen<1) + { + ZtCMainChars::SplitToList( + ARR_SaveList , + APC_OriginChar , + APC_SearchChar , + AL_OriginLen , + AL_SearchLen , + AB_DoEndWhenNoMatch , + AB_DoAppendEachLink + /*/////////*/ ); + + return ARR_SaveList; + } + if(AL_OriginLen<1 || AL_OriginLen0 && ( VL_PrevSizeGetData(). + append(APC_OriginChar+VL_SearchPos, VL_SearchLen) ; + } + else + { + ARR_SaveList.AddTailDefault()->GetData().Invalidate(). + append(APC_OriginChar+VL_SearchPos, VL_SearchLen) ; + }/* + else*/ + }/* + if(VL_SearchLen>0 && ( VL_PrevSize0) + { + if(AB_DoAppendEachLink==true) + { + ARR_SaveList.AddTailDefault()->GetData(). + append(APC_OriginChar+VL_SearchPos, VL_SearchLen) ; + } + else + { + ARR_SaveList.AddTailDefault()->GetData().Invalidate(). + append(APC_OriginChar+VL_SearchPos, VL_SearchLen) ; + }/* + else*/ + }/* + if(VL_SearchLen>0)*/ + + VL_SearchLen=0; + VL_SearchPos=VL_FindPos+AL_SearchLen; + }/* + while(VL_SearchPos + static TStringList& SplitToListWrap( ///////////////////////////// + TStringList& ARR_SaveList , + TypeCharC* APC_OriginChar , + TypeCharC* APC_SearchChar , + TypeCharC* APC_WrapStart , + TypeCharC* APC_WrapClose , + TypeLength AL_OriginLen , + TypeLength AL_SearchLen , + TypeLength AL_WrapStartLen , + TypeLength AL_WrapCloseLen , + bool AB_DoEndWhenNoMatch=true , + bool AB_DoAppendEachLink=false + ////////////// ) ///////////////////////////////////////////////*/ + + template ////////////////// + static TStringList& SplitToListWrap( + TStringList& ARR_SaveList , + const TTyChars& AR_CCharsOrigin , + const TTyChars& AR_CCharsSearch , + const TTyChars& AR_CCharsWrapStart, + const TTyChars& AR_CCharsWrapClose, + bool AB_DoEndWhenNoMatch=true , + bool AB_DoAppendEachLink=false + /*//////////*/ ) ///////////////////////////////////////////////*/ + { + return ZtCMainChars::SplitToListWrap( + ARR_SaveList, + AR_CCharsOrigin.data(), AR_CCharsSearch.data(), AR_CCharsWrapStart.data(), AR_CCharsWrapClose.data(), + AR_CCharsOrigin.size(), AR_CCharsSearch.size(), AR_CCharsWrapStart.size(), AR_CCharsWrapClose.size(), + AB_DoEndWhenNoMatch, AB_DoAppendEachLink + /*//////////*/ ); + }/* + template ////////////////// + static TStringList& SplitToListWrap( + TStringList& ARR_SaveList , + const TTyChars& AR_CCharsOrigin , + const TTyChars& AR_CCharsSearch , + const TTyChars& AR_CCharsWrapStart, + const TTyChars& AR_CCharsWrapClose, + bool AB_DoEndWhenNoMatch=true , + bool AB_DoAppendEachLink=false + ////////////// ) ///////////////////////////////////////////////*/ + + + template //////////// + static TStringList& SplitToListWrap2( + TStringList& ARR_CStrListSave, + TypeCharC* APC_Origin , + TypeCharC* APC_Escape , + TypeCharC* APC_WrapStart , + TypeCharC* APC_WrapClose , + TypeLength AL_OriginLen , + TypeLength AL_EscapeLen , + TypeLength AL_WrapStartLen , + TypeLength AL_WrapCloseLen , + TStringArray& ARA_SearchArray + /*//////////*/ ) ///////////////////////////////////////////////*/ + { + typedef typename TStringList::TypeData CStringData; + + CStringData* VP_CStringStart=0; + + long VL_SearchPos= 0 ; + long VL_FindPos =-1 ; + long VL_PrevSize =ARR_CStrListSave.size(); + + while(VL_SearchPosVL_PrevSize) + { + ARR_CStrListSave.AddTailDefault()->GetData(). + append(APC_Origin+VL_SearchPos, AL_OriginLen-VL_SearchPos) ; + }/* + if(ARR_CStrListSave.size()>VL_PrevSize)*/ + + return ARR_CStrListSave; + }/* + if(VL_FindPos<0)*/ + + if(VL_FindPos>0) + { + ARR_CStrListSave.AddTailDefault()->GetData()(APC_Origin+VL_SearchPos, VL_FindPos); + ARR_CStrListSave.AddTailDefault()->GetData()=(*VP_CStringStart); + }/* + if(VL_FindPos>0)*/ + + VL_SearchPos+=VL_FindPos+VP_CStringStart->size(); + }/* + while(VL_SearchPos //////////// + static TStringList& SplitToListWrap2( + TStringList& ARR_CStrListSave, + TypeCharC* APC_Origin , + TypeCharC* APC_Escape , + TypeCharC* APC_WrapStart , + TypeCharC* APC_WrapClose , + TypeLength AL_OriginLen , + TypeLength AL_EscapeLen , + TypeLength AL_WrapStartLen , + TypeLength AL_WrapCloseLen , + TStringArray& ARA_SearchArray + ////////////// ) ///////////////////////////////////////////////*/ + + template + TStringList& SplitToListWrap2( + TStringList& ARR_CStrListSave , + const TTyChars& AR_CCharsOrigin , + const TTyChars& AR_CCharsEscape , + const TTyChars& AR_CCharsWrapStart, + const TTyChars& AR_CCharsWrapClose, + TStringArray& ARA_SearchArray + /*//////////*/ ) ///////////////////////////////////////////////////*/ + { + return ZtCMainChars::SplitToListWrap2( + RR(ARR_CStrListSave), + AR_CCharsOrigin.data(), AR_CCharsEscape.data(), AR_CCharsWrapStart.data(), AR_CCharsWrapClose.data(), + AR_CCharsOrigin.size(), AR_CCharsEscape.size(), AR_CCharsWrapStart.size(), AR_CCharsWrapClose.size(), + ARA_SearchArray + /*//////////*/ ); + }/* + template + TStringList& SplitToListWrap2( + TStringList& ARR_CStrListSave , + const TTyChars& AR_CCharsOrigin , + const TTyChars& AR_CCharsEscape , + const TTyChars& AR_CCharsWrapStart, + const TTyChars& AR_CCharsWrapClose, + TStringArray& ARA_SearchArray + ////////////// ) ///////////////////////////////////////////////////*/ + + + /* APC_OriginChar APC_Search ã ã + TSearchInfoList ԷѴ. TSearchPosList ̴̳. */ + + template static void MakeInfoList( + TypeCharC* APC_OriginChar, + TypeCharC* APC_Search , + TypeLength AL_OriginLen , + TypeLength AL_SearchLen , + TypeLength AL_StartPos , + TSearchPosList& ARR_InfoList + /*//////////*/ ) ////////////////////////////////////////*/ + { + if(AL_OriginLen<1 || AL_SearchLen<1 || AL_OriginLen static void MakeInfoList( + TypeCharC* APC_OriginChar, + TypeCharC* APC_Search , + TypeLength AL_OriginLen , + TypeLength AL_SearchLen , + TypeLength AL_StartPos , + TSearchPosList& ARR_InfoList + ////////////// ) ////////////////////////////////////////*/ + + template static void MakeInfoList + ( + const TTyChars& AR_CCharsOrigin, const TTyChars& AR_CCharsSearch, + TypeLength AL_StartPos , TSearchPosList& ARR_InfoList + ) + ///////////////////////////////////////////////////////////////////////////// + { + ZtCMainChars::MakeInfoList( + AR_CCharsOrigin.data(), AR_CCharsSearch.data(), + AR_CCharsOrigin.size(), AR_CCharsSearch.size(), + AL_StartPos, RR(ARR_InfoList) + /*//////////*/ ); + }/* + template static void MakeInfoList + ( + const TTyChars& AR_CCharsOrigin, const TTyChars& AR_CCharsSearch, + TypeLength AL_StartPos , TSearchPosList& ARR_InfoList + ) + ///////////////////////////////////////////////////////////////////////////*/ + + + /*///////////////////////////////////////////////////////////////////////// + + TSearchInfo Ŭ (const TypeChar* StartPos, long Pos, long Length) + μ ڸ Ѵ. + + void MakeInfoList Լʹ ޸ APC_Search ڿ + ڿ Ʈ ´. + + /////////////////////////////////////////////////////////////////////////*/ + + template static void MakeSplitInfoList( + TypeCharC* APC_OriginChar, + TypeCharC* APC_Search , + TypeLength AL_OriginLen , + TypeLength AL_SearchLen , + TypeLength AL_StartPos , + TSearchInfoList& ARR_InfoList + /*//////////*/ ) //////////////////////////////////////////////*/ + { + typedef typename TSearchInfoList::TypeData ZCSearchInfo; + + if(AL_OriginLen<1 || AL_SearchLen<1) return ; + + TypeCharC* VP_Origin=APC_OriginChar ; + + TypeLength i =AL_StartPos; + TypeLength VL_PrevPos=AL_StartPos; + TypeLength VL_Loop =AL_OriginLen-AL_SearchLen ; + + while(i<=VL_Loop) + { + TypeLength j=0; + + for(; j0) + { + ZCSearchInfo VO_CSearchInfo( + VP_Origin+VL_PrevPos, VL_PrevPos, i-VL_PrevPos); + + ARR_InfoList.push_back(VO_CSearchInfo); + }/* + if(i-VL_PrevPos>0)*/ + + VL_PrevPos = i += AL_SearchLen ; + }/* + while(i<=VL_Loop)*/ + + if(VL_PrevPos static void MakeSplitInfoList( + TypeCharC* APC_OriginChar, + TypeCharC* APC_Search , + TypeLength AL_OriginLen , + TypeLength AL_SearchLen , + TypeLength AL_StartPos , + TSearchInfoList& ARR_InfoList + ////////////// ) //////////////////////////////////////////////*/ + + template static void MakeSplitInfoList + ( + const TTyChars& AR_CCharsOrigin, const TTyChars& AR_CCharsSearch, + TypeLength AL_StartPos , TSearchInfoList& ARR_InfoList + ) + { + ZtCMainChars::MakeSplitInfoList( + AR_CCharsOrigin.data(), AR_CCharsSearch.data(), + AR_CCharsOrigin.size(), AR_CCharsSearch.size(), + AL_StartPos, RR(ARR_InfoList) + /*//////////*/ ); + }/* + template static void MakeSplitInfoList + ( + const TTyChars& AR_CCharsOrigin, const TTyChars& AR_CCharsSearch, + TypeLength AL_StartPos , TSearchInfoList& ARR_InfoList + ) + /////////////////////////////////////////////////////////////////////////////////*/ + + + // APC_Search ڿ ãƼ, ڿ ̱ Ѵ. + + static TypeLength GetLength_Find( + TypeCharC* APC_Origin, TypeLength AL_OriginLen, + TypeCharC* APC_Search, TypeLength AL_SearchLen + /*//////////*/ ) + { + if(AL_OriginLen<1 || AL_SearchLen<1 || AL_OriginLen=AL_SearchLen + + TypeLength j=0; + TypeLength VL_MaxLoop=AL_OriginLen-AL_SearchLen; + TypeCharC* VP_Origin =APC_Origin; + TypeCharC* VP_Left ; + TypeCharC* VP_Right; + + for(TypeLength i=0; i<=VL_MaxLoop; ++i) + { + VP_Left =VP_Origin; + VP_Right=APC_Search ; + + for(j=0; j=AL_SearchLen) return i+AL_SearchLen; + + ++VP_Origin; ///////////////////////////// + }/* + for(TypeLength i=0; i<=VL_MaxLoop; ++i)*/ + + return 0; + }/* + static TypeLength GetLength_Find( + TypeCharC* APC_Origin, TypeLength AL_OriginLen, + TypeCharC* APC_Search, TypeLength AL_SearchLen + ////////////// ) */ + + template static TypeLength + GetLength_Find(const TTyChars& CCharsOrigin, const TTyChars& CCharsSearch) + { + return ZtCMainChars::GetLength_Find( + CCharsOrigin.data(), CCharsOrigin.size(), + CCharsSearch.data(), CCharsSearch.size() + /*//////////*/ ); + }/* + template static TypeLength + GetLength_Find(const TTyChars& CCharsOrigin, const TTyChars& CCharsSearch) */ + + + /* ARA_SearchArray ڿ ã ϹǷ, + ãƾ ϴ ڿ ARA_SearchArray տ ִ . */ + + template static TypeLength GetLength_Find2( + TypeCharC* APC_Origin, TypeLength AL_OriginLen, const TStringArray& ARA_SearchArray) + { + TypeLength VL_ArrSize=ARA_SearchArray.size(); + TypeLength VL_NowSize; + + if(VL_ArrSize<1) return 0; + + + IterEasyIDc CI_IterEasyID(ARA_SearchArray.GetHeadIterEasyID()); + + for(TypeLength i=0; i0) return VL_NowSize; + + ARA_SearchArray.MoveNextIter(RR(CI_IterEasyID)); + }/* + for(TypeLength i=0; i static TypeLength GetLength_Find2( + TypeCharC* APC_Origin, TypeLength AL_OriginLen, const TStringArray& ARA_SearchArray) */ + + template + static TypeLength GetLength_Find2(const TTyChars& AR_CCharsOrigin, const TStringArray& ARA_SearchArray) + { + return ZtCMainChars::GetLength_Find2(AR_CCharsOrigin.data(), AR_CCharsOrigin.size(), ARA_SearchArray); + }/* + template + static TypeLength GetLength_Find2(const TTyChars& AR_CCharsOrigin, const TStringArray& ARA_SearchArray) */ + + + // APC_Search ڿ ߿ ϳ ġϸ ̱ ؿ´. + + static TypeLength GetLength_FindChar( + TypeCharC* APC_Origin, TypeLength AL_OriginLen, + TypeCharC* APC_Search, TypeLength AL_SearchLen + /*//////////*/ ) + { + if(AL_OriginLen<1 || AL_SearchLen<1) return 0; + + TypeLength j =0 ; + TypeCharC* VP_Origin =APC_Origin; + TypeCharC* VP_Left ; + TypeCharC* VP_Right; + + for(TypeLength i=0; i + static TypeLength GetLength_FindChar(const TTyChars& CCharsOrigin, const TTyChars& CCharsSearch) + { + return ZtCMainChars::GetLength_FindChar( + CCharsOrigin.data(), CCharsOrigin.size(), + CCharsSearch.data(), CCharsSearch.size() + /*//////////*/ ); + }/* + template + static TypeLength GetLength_FindChar(const TTyChars& CCharsOrigin, const TTyChars& CCharsSearch) */ + + template static TypeLength GetLength_FindChar2( + TypeCharC* APC_Origin, TypeLength AL_OriginLen, const TStringArray& ARA_SearchArray) + { + TypeLength VL_ArrSize=ARA_SearchArray.size(); + TypeLength VL_NowSize=0; + TypeLength VL_SumSize=0; + + if(VL_ArrSize<1) return 0; + + + IterEasyIDc CI_IterEasyID(ARA_SearchArray.GetHeadIterEasyID()); + + for(TypeLength i=0; i static TypeLength GetLength_FindChar2( + TypeCharC* APC_Origin, TypeLength AL_OriginLen, const TStringArray& ARA_SearchArray) */ + + template + static TypeLength GetLength_FindChar2(const TTyChars& AR_CCharsOrigin, const TStringArray& ARA_SearchArray) + { + return ZtCMainChars::GetLength_FindChar2(AR_CCharsOrigin.data(), AR_CCharsOrigin.size(), ARA_SearchArray); + }/* + template + static TypeLength GetLength_FindChar2(const TTyChars& AR_CCharsOrigin, const TStringArray& ARA_SearchArray) */ + + + /* APC_Search ڿ ãƼ, ڿ ̱ Ѵ. + ã ڿ տ APC_Escape ڿ Ѵ. */ + + static TypeLength GetLength_FindEscape( + TypeCharC* APC_Origin, TypeLength AL_OriginLen, + TypeCharC* APC_Search, TypeLength AL_SearchLen, + TypeCharC* APC_Escape, TypeLength AL_EscapeLen + /*//////////*/ ) + { + if(AL_EscapeLen<1) return ZtCMainChars:: + GetLength_Find(APC_Origin, AL_OriginLen, APC_Search,AL_SearchLen); + + if(AL_OriginLen<1 || AL_SearchLen<1 || AL_OriginLen static TypeLength GetLength_FindEscape( + const TTyChars& AR_CCharsOrigin, const TTyChars& AR_CCharsSearch, const TTyChars& AR_CCharsEscape) + { + return ZtCMainChars::GetLength_FindEscape( + AR_CCharsOrigin.data(), AR_CCharsOrigin.size(), + AR_CCharsSearch.data(), AR_CCharsSearch.size(), + AR_CCharsEscape.data(), AR_CCharsEscape.size() + /*//////////*/ ) ; + }/* + template static TypeLength GetLength_FindEscape( + const TTyChars& AR_CCharsOrigin, const TTyChars& AR_CCharsSearch, const TTyChars& AR_CCharsEscape) */ + + + template static TypeLength GetLength_FindEscape2( + TypeCharC* APC_Origin, TypeLength AL_OriginLen, const TStringArray& ARA_SearchArray) + { + /* ARA_SearchArray ù° Ҹ escape ڿ . + ARA_SearchArray 迭 2 ̻̾ Ѵ. */ + + const int CI_MinArrSize=2; + + TypeLength VL_ArrSize=ARA_SearchArray.size(); + TypeLength VL_NowSize; + + if(VL_ArrSize0) return VL_NowSize; + + ARA_SearchArray.MoveNextIter(RR(CI_IterEasyID)); + }/* + for(TypeLength i=1; i static TypeLength GetLength_FindEscape2( + TypeCharC* APC_Origin, TypeLength AL_OriginLen, const TStringArray& ARA_SearchArray) */ + + template + static TypeLength GetLength_FindEscape2(const TTyChars& AR_CCharsOrigin, const TStringArray& ARA_SearchArray) + { + return ZtCMainChars::GetLength_FindEscape2(AR_CCharsOrigin.data(), AR_CCharsOrigin.size(), ARA_SearchArray); + }/* + template + static TypeLength GetLength_FindEscape2(const TTyChars& AR_CCharsOrigin, const TStringArray& ARA_SearchArray) */ + + + template static TypeLength GetLength_FindSerial( + TypeCharC* APC_Origin, TypeLength AL_Length, const TStringArray& ARA_SearchArray) + { + /*////////////////////////////////////////////////// + + ZtCMainChars::GetLength_Find() Լ ̿Ͽ, + ARA_SearchArray 1 Һ ã´. + + -- 2011-08-09 03:44:00 + + //////////////////////////////////////////////////*/ + + TypeLength VL_ArrSize=ARA_SearchArray.size(); + TypeLength VL_NowSize=0; + TypeLength VL_SumSize=0; + + if(VL_ArrSize<1) return 0; + + + IterEasyIDc CI_IterEasyID(ARA_SearchArray.GetHeadIterEasyID()); + + for(TypeLength i=0; i static TypeLength GetLength_FindSerial( + TypeCharC* APC_Origin, TypeLength AL_Length, const TStringArray& ARA_SearchArray) */ + + template + static TypeLength GetLength_FindSerial(const TTyChars& AR_CCharsOrigin, const TStringArray& ARA_SearchArray) + { + return ZtCMainChars::GetLength_FindSerial(AR_CCharsOrigin.data(), AR_CCharsOrigin.size(), ARA_SearchArray); + }/* + template + static TypeLength GetLength_FindSerial(const TTyChars& AR_CCharsOrigin, const TStringArray& ARA_SearchArray) */ + + + static TypeLength GetLength_FindSerialChar( + TypeCharC* APC_Origin, TypeLength AL_OriginLen, + TypeCharC* APC_Search, TypeLength AL_SearchLen + /*//////////*/ ) + { + // APC_Search ڰ APC_Origin ־ Ѵ. + + if(AL_OriginLen<1 || AL_SearchLen<1 || AL_OriginLen + static TypeLength GetLength_FindSerialChar(const TTyChars& CCharsOrigin, const TTyChars& CCharsSearch) + { + return ZtCMainChars::GetLength_FindSerialChar( + CCharsOrigin.data(), CCharsOrigin.size(), + CCharsSearch.data(), CCharsSearch.size() + /*//////////*/ ); + }/* + template + static TypeLength GetLength_FindSerialChar(const TTyChars& CCharsOrigin, const TTyChars& CCharsSearch) */ + + template static TypeLength GetLength_FindSerialChar2( + TypeCharC* APC_Origin, TypeLength AL_OriginLen, const TStringArray& ARA_SearchArray) + { + TypeLength VL_ArrSize=ARA_SearchArray.size(); + TypeLength VL_NowSize=0; + TypeLength VL_SumSize=0; + + if(VL_ArrSize<1) return 0; + + + IterEasyIDc CI_IterEasyID(ARA_SearchArray.GetHeadIterEasyID()); + + for(TypeLength i=0; i static TypeLength GetLength_FindSerialChar2( + TypeCharC* APC_Origin, TypeLength AL_OriginLen, const TStringArray& ARA_SearchArray) */ + + template + static TypeLength GetLength_FindSerialChar2(const TTyChars& AR_CCharsOrigin, const TStringArray& ARA_SearchArray) + { + return ZtCMainChars::GetLength_FindSerialChar2(AR_CCharsOrigin.data(), AR_CCharsOrigin.size(), ARA_SearchArray); + }/* + template + static TypeLength GetLength_FindSerialChar2(const TTyChars& AR_CCharsOrigin, const TStringArray& ARA_SearchArray) */ + + + template static TypeLength GetLength_StartFind( + TypeCharC* APC_Origin, TypeLength AL_Length, const TStringArray& ARA_SearchArray) + { + /*////////////////////////////////////////////////// + + ARA_SearchArray 1 Һ ϸ, ʹ + ZtCMainChars::GetLength_Find() Լ ̿Ͽ, + ARA_SearchArray 2 Һ ã´. + + -- 2011-08-09 04:19:00 + + //////////////////////////////////////////////////*/ + + TypeLength VL_ArrSize=ARA_SearchArray.size(); + TypeLength VL_NowSize=0; + TypeLength VL_SumSize=0; + + if(VL_ArrSize<2) return 0; + + + IterEasyIDc CI_IterEasyID(ARA_SearchArray.GetHeadIterEasyID()); + + const bool CB_IsOK=ZtCMainChars::DoStart( + APC_Origin, ARA_SearchArray.ItD(CI_IterEasyID).data(), + AL_Length , ARA_SearchArray.ItD(CI_IterEasyID).size() + /*/////////*/ ); + + if(!CB_IsOK) return 0; + + + VL_SumSize=ARA_SearchArray.ItD(CI_IterEasyID).size(); + + ARA_SearchArray.MoveNextIter(RR(CI_IterEasyID)); + + for(TypeLength i=1; i static TypeLength GetLength_StartFind( + TypeCharC* APC_Origin, TypeLength AL_Length, const TStringArray& ARA_SearchArray) */ + + template + static TypeLength GetLength_StartFind(const TTyChars& AR_CCharsOrigin, const TStringArray& ARA_SearchArray) + { + return ZtCMainChars::GetLength_StartFind(AR_CCharsOrigin.data(), AR_CCharsOrigin.size(), ARA_SearchArray); + }/* + template + static TypeLength GetLength_StartFind(const TTyChars& AR_CCharsOrigin, const TStringArray& ARA_SearchArray) */ + + + // GetLength_FindSerialChar() ϳ, 1 1 ڷ ؾ ϴ ٸ. + + static TypeLength GetLength_StartFindChar( + TypeCharC* APC_Origin, TypeLength AL_OriginLen, + TypeCharC* APC_Search, TypeLength AL_SearchLen + /*//////////*/ ) + { + // APC_Search ڰ APC_Origin ־ Ѵ. + + const bool CB_IsBad = + ( + AL_OriginLen<1 || AL_SearchLen<1 || + AL_OriginLen static TypeLength + GetLength_StartFindChar(const TTyChars& CCharsOrigin, const TTyChars& CCharsSearch) + { + return ZtCMainChars::GetLength_StartFindChar( + CCharsOrigin.data(), CCharsOrigin.size(), + CCharsSearch.data(), CCharsSearch.size() + /*//////////*/ ); + }/* + template static TypeLength + GetLength_StartFindChar(const TTyChars& CCharsOrigin, const TTyChars& CCharsSearch) */ + + template static TypeLength GetLength_StartFindChar2( + TypeCharC* APC_Origin, TypeLength AL_OriginLen, const TStringArray& ARA_SearchArray) + { + TypeLength VL_ArrSize=ARA_SearchArray.size(); + TypeLength VL_NowSize=0; + TypeLength VL_SumSize=0; + + if(VL_ArrSize<1) return 0; + + + IterEasyIDc CI_IterEasyID(ARA_SearchArray.GetHeadIterEasyID()); + + for(TypeLength i=0; i static TypeLength GetLength_StartFindChar2( + TypeCharC* APC_Origin, TypeLength AL_OriginLen, const TStringArray& ARA_SearchArray) */ + + template + static TypeLength GetLength_StartFindChar2(const TTyChars& AR_CCharsOrigin, const TStringArray& ARA_SearchArray) + { + return ZtCMainChars::GetLength_FindSerialChar2(AR_CCharsOrigin.data(), AR_CCharsOrigin.size(), ARA_SearchArray); + }/* + template + static TypeLength GetLength_StartFindChar2(const TTyChars& AR_CCharsOrigin, const TStringArray& ARA_SearchArray) */ + + + template static TypeLength GetLength_Permit( + TypeCharC* APC_Origin, TypeLength AL_Length, const TStringArray& ARA_SearchArray) + { + TypeLength VL_ArrSize=ARA_SearchArray.size(); + + if(AL_Length<1 || VL_ArrSize<1) return 0; + + + IterEasyIDc CI_IterEasyID(ARA_SearchArray.GetHeadIterEasyID()); + + for(TypeLength i=0; i static TypeLength GetLength_Permit( + TypeCharC* APC_Origin, TypeLength AL_Length, const TStringArray& ARA_SearchArray) */ + + template + static TypeLength GetLength_Permit(const TTyChars& AR_CCharsOrigin, const TStringArray& ARA_SearchArray) + { + return ZtCMainChars::GetLength_Permit(AR_CCharsOrigin.data(), AR_CCharsOrigin.size(), ARA_SearchArray) ; + }/* + template + static TypeLength GetLength_Permit(const TTyChars& AR_CCharsOrigin, const TStringArray& ARA_SearchArray) */ + + + /*////////////////////////////////////////////////////////////////////// + + TStringArray 迭(Ȥ  containter) Ȧ ° ̻̰ + Ÿ Ѵ. TStringArray 迭Ҽ/2 + ȯѴ. + + ã Ÿ ̴ ̰ ȯѴ.  Ÿ + "ab" "def" ̿ ִٸ ã ̴ "ab" ߾ 2 + Ѵ. + + //////////////////////////////////////////////////////////////////////*/ + + template static TypeLength GetLength_PermitRange( + TypeCharC* APC_Origin, TypeLength AL_Length, const TStringArray& ARA_SearchArray) + { + TypeLength VL_ArrSize=ARA_SearchArray.size()/2; + TypeLength VL_NowSize=0; + TypeLength VL_Result =0; + TypeLength i =0; + + if(AL_Length<1 || VL_ArrSize<1) return 0; + + + IterEasyIDc CI_IterEasyID(ARA_SearchArray.GetHeadIterEasyID()); + + for(; i0) + { + VL_NowSize = ARA_SearchArray.ItD(CI_IterEasyID).size()>AL_Length ? + AL_Length : ARA_SearchArray.ItD(CI_IterEasyID).size() ; + + if (VL_Result==0 ) VL_Result=VL_NowSize; + else if(VL_Result> VL_NowSize) VL_Result=VL_NowSize; + + if(ZtCMainChars::Minus(APC_Origin, ARA_SearchArray.ItD(CI_IterEasyID).data(), VL_NowSize, ARA_SearchArray.ItD(CI_IterEasyID).size())<0) + { + ARA_SearchArray.MoveNextIter(RR(CI_IterEasyID)); + ARA_SearchArray.MoveNextIter(RR(CI_IterEasyID)); + + continue; // ּ ٸ + }/* + if(ZtCMainChars::Minus(APC_Origin, ARA_SearchArray.ItD(CI_IterEasyID).data(), VL_NowSize, ARA_SearchArray.ItD(CI_IterEasyID).size())<0)*/ + }/* + if(ARA_SearchArray.ItD(CI_IterEasyID).size()>0)*/ + + ARA_SearchArray.MoveNextIter(RR(CI_IterEasyID)); + + if(ARA_SearchArray.ItD(CI_IterEasyID).size()>0) + { + VL_NowSize = ARA_SearchArray.ItD(CI_IterEasyID).size()>AL_Length ? + AL_Length : ARA_SearchArray.ItD(CI_IterEasyID).size() ; + + if(VL_Result>VL_NowSize) VL_Result=VL_NowSize; + + if(ZtCMainChars::Minus(APC_Origin, ARA_SearchArray.ItD(CI_IterEasyID).data(), VL_NowSize, ARA_SearchArray.ItD(CI_IterEasyID).size())>0) + { + ARA_SearchArray.MoveNextIter(RR(CI_IterEasyID)); continue; // ִ ٸ + }/* + if(ZtCMainChars::Minus(APC_Origin, ARA_SearchArray.ItD(CI_IterEasyID).data(), VL_NowSize, ARA_SearchArray.ItD(CI_IterEasyID).size())>0)*/ + + break; + }/* + if(ARA_SearchArray.ItD(CI_IterEasyID).size()>0)*/ + + ARA_SearchArray.MoveNextIter(RR(CI_IterEasyID)); + }/* + for(; i=VL_ArrSize) return 0; return VL_Result; + }/* + template static TypeLength GetLength_PermitRange( + TypeCharC* APC_Origin, TypeLength AL_Length, const TStringArray& ARA_SearchArray) */ + + template + static TypeLength GetLength_PermitRange(const TTyChars& AR_CChars, const TStringArray& ARA_SearchArray) + { + return ZtCMainChars::GetLength_PermitRange(AR_CChars.data(), AR_CChars.size(), ARA_SearchArray); + }/* + template + static TypeLength GetLength_PermitRange(const TTyChars& AR_CChars, const TStringArray& ARA_SearchArray) */ + + + static TypeLength GetLength_PermitChar( + TypeCharC* APC_Origin, TypeLength AL_Length, TypeCharC* APC_Permit, TypeLength AL_PermitLength) + { + if(AL_Length<1 || AL_PermitLength<1) return 0; + + TypeCharC* VPC_Origin=APC_Origin; + TypeCharC* VPC_Permit=APC_Permit; + + TypeLength VL_SearchLen=0; + TypeLength j =0; + + for(TypeLength i=0; i=AL_PermitLength) return VL_SearchLen; + + VPC_Origin++; VPC_Permit=APC_Permit; j=0; + }/* + for(TypeLength i=0; i + static TypeLength GetLength_PermitChar(const TTyChars& AR_CCharsOrigin, const TTyChars& AR_CCharsSearch) + { + return ZtCMainChars::GetLength_PermitChar( + AR_CCharsOrigin.data(), AR_CCharsOrigin.size(), AR_CCharsSearch.data(), AR_CCharsSearch.size()); + }/* + template + static TypeLength GetLength_PermitChar(const TTyChars& AR_CCharsOrigin, const TTyChars& AR_CCharsSearch) */ + + + static TypeLength GetLength_PermitCharRange( + TypeCharC* APC_Origin, TypeLength AL_Length, TypeCharC* APC_Permit, TypeLength AL_PermitLength) + { + /*//////////////////////////////////////////////// + + AL_PermitLength 2 μ, 2 ڰ, + ϴ Ÿ. + + -- 2011-08-12 00:53:00 + + ////////////////////////////////////////////////*/ + + if(AL_Length<1 || AL_PermitLength<2) return 0; + + TypeCharC* VPC_Origin=APC_Origin; + TypeCharC* VPC_Permit=APC_Permit; + + TypeLength VL_SearchLen =0; + TypeLength VL_PermitLength=AL_PermitLength/2; + TypeLength j =0; + + for(TypeLength i=0;i=*VPC_Permit && *VPC_Origin<=*(VPC_Permit+1)) + { + ++VL_SearchLen; break; + }/* + if(*VPC_Origin>=*VPC_Permit && *VPC_Origin<=*(VPC_Permit+1))*/ + + VPC_Permit+=2; + }/* + for(; j=VL_PermitLength) return VL_SearchLen; + + VPC_Origin++; VPC_Permit=APC_Permit; j=0; + }/* + for(TypeLength i=0; i + static TypeLength GetLength_PermitCharRange(const TTyChars& AR_CCharsOrigin, const TTyChars& AR_CCharsSearch) + { + return ZtCMainChars::GetLength_PermitCharRange( + AR_CCharsOrigin.data(), AR_CCharsOrigin.size(), AR_CCharsSearch.data(), AR_CCharsSearch.size()); + }/* + template + static TypeLength GetLength_PermitCharRange(const TTyChars& AR_CCharsOrigin, const TTyChars& AR_CCharsSearch) */ + + template + static TypeLength GetLength_PermitCharRange2( + TypeCharC* APC_Origin, TypeLength AL_Length, const TStringArray& ARA_SearchArray) + { + // ARA_SearchArray ڿ Ҹ ã´. + + TypeLength VL_ArrSize =ARA_SearchArray.size(); + TypeLength VL_SearchNow=0; + TypeLength VL_SearchSum=0; + + if(AL_Length<1 || VL_ArrSize<1) return 0; + + + IterEasyIDc CI_IterEasyID(ARA_SearchArray.GetHeadIterEasyID()); + + for(TypeLength i=0; i + static TypeLength GetLength_PermitCharRange2( + TypeCharC* APC_Origin, TypeLength AL_Length, const TStringArray& ARA_SearchArray) */ + + template + static TypeLength GetLength_PermitCharRange2( + const TTyChars& AR_CCharsOrigin, const TStringArray& ARA_SearchArray) + { + return ZtCMainChars::GetLength_PermitCharRange2( + AR_CCharsOrigin.data(), AR_CCharsOrigin.size(), ARA_SearchArray ); + }/* + template + static TypeLength GetLength_PermitCharRange2( + const TTyChars& AR_CCharsOrigin, const TStringArray& ARA_SearchArray) */ + + + template + static TypeLength GetLength_PermitChar2( + TypeCharC* APC_Origin, TypeLength AL_Length, const TStringArray& ARA_SearchArray) + { + // ARA_SearchArray ڿ Ҹ ã´. + + TypeLength VL_ArrSize =ARA_SearchArray.size(); + TypeLength VL_SearchNow=0; + TypeLength VL_SearchSum=0; + + if(AL_Length<1 || VL_ArrSize<1) return 0; + + + IterEasyIDc CI_IterEasyID(ARA_SearchArray.GetHeadIterEasyID()); + + for(TypeLength i=0; i + static TypeLength GetLength_PermitChar2( + TypeCharC* APC_Origin, TypeLength AL_Length, const TStringArray& ARA_SearchArray)*/ + + template + static TypeLength GetLength_PermitChar2( + const TTyChars& AR_CCharsOrigin, const TStringArray& ARA_SearchArray) + { + return ZtCMainChars::GetLength_PermitChar2( + AR_CCharsOrigin.data(), AR_CCharsOrigin.size(), ARA_SearchArray); + }/* + template + static TypeLength GetLength_PermitChar2( + const TTyChars& AR_CCharsOrigin, const TStringArray& ARA_SearchArray) */ + + + /* Ư ڿ Ư ڿ , ش ̸ 1 ȯѴ. + ںʹ ' ڿ' ֱ ̴. */ + + template + static TypeLength GetLength_NoPermit( + TypeCharC* APC_Origin, TypeLength AL_Length, const TStringArray& ARA_SearchArray) + { + TypeLength VL_ArrSize=ARA_SearchArray.size(); + TypeLength VL_NowSize=0; + + if(AL_Length<1 || VL_ArrSize<1) return 0; + + + IterEasyIDc CI_IterEasyID(ARA_SearchArray.GetHeadIterEasyID()); + + for(TypeLength i=0; iARA_SearchArray.ItD(CI_IterEasyID).size() ? + ARA_SearchArray.ItD(CI_IterEasyID).size() : AL_Length ); + + const bool CB_IsOK=ZtCMainChars::DoStart( + APC_Origin, ARA_SearchArray.ItD(CI_IterEasyID).data(), + AL_Length , ARA_SearchArray.ItD(CI_IterEasyID).size() + /*//////////*/ ); + + if(CB_IsOK) return 0; ARA_SearchArray.MoveNextIter(RR(CI_IterEasyID)); + }/* + for(TypeLength i=0; i + static TypeLength GetLength_NoPermit( + TypeCharC* APC_Origin, TypeLength AL_Length, const TStringArray& ARA_SearchArray) */ + + template + static TypeLength GetLength_NoPermit(const TTyChars& AR_CCharsOrigin, const TStringArray& ARA_SearchArray) + { + return ZtCMainChars::GetLength_NoPermit(AR_CCharsOrigin.data(), AR_CCharsOrigin.size(), ARA_SearchArray); + }/* + template + static TypeLength GetLength_NoPermit(const TTyChars& AR_CCharsOrigin, const TStringArray& ARA_SearchArray) */ + + + template + static TypeLength GetLength_NoPermitRange( + TypeCharC* APC_Origin, TypeLength AL_Length, const TStringArray& ARA_SearchArray) + { + TypeLength VL_ArrSize=ARA_SearchArray.size()/2; + TypeLength VL_NowSize=0; + TypeLength i =0; + int VI_Compare=0; + + if(AL_Length<1 || VL_ArrSize<1) return 0; + + + IterEasyIDc CI_IterEasyID(ARA_SearchArray.GetHeadIterEasyID()); + + for(; i0) + { + VL_NowSize= ARA_SearchArray.ItD(CI_IterEasyID).size()>AL_Length ? + AL_Length : ARA_SearchArray.ItD(CI_IterEasyID).size() ; + + VI_Compare=ZtCMainChars::Minus( + APC_Origin, ARA_SearchArray.ItD(CI_IterEasyID).data(), + VL_NowSize, ARA_SearchArray.ItD(CI_IterEasyID).size() ); + }/* + if(ARA_SearchArray.ItD(CI_IterEasyID).size()>0)*/ + + ARA_SearchArray.MoveNextIter(RR(CI_IterEasyID)); + + if(VI_Compare>=0 && ARA_SearchArray.ItD(CI_IterEasyID).size()>0) + { + VL_NowSize = ( + ARA_SearchArray.ItD(CI_IterEasyID).size()>AL_Length ? AL_Length : ARA_SearchArray.ItD(CI_IterEasyID).size() ) ; + + if(ZtCMainChars::Minus( + APC_Origin, ARA_SearchArray.ItD(CI_IterEasyID).data(), VL_NowSize, ARA_SearchArray.ItD(CI_IterEasyID).size())<=0) + { + return 0; + }/* + if(ZtCMainChars::Minus( + APC_Origin, ARA_SearchArray.ItD(CI_IterEasyID).data(), VL_NowSize, ARA_SearchArray.ItD(CI_IterEasyID).size())<=0) */ + }/* + if(VI_Compare>=0 && ARA_SearchArray.ItD(CI_IterEasyID).size()>0)*/ + + ARA_SearchArray.MoveNextIter(RR(CI_IterEasyID)); + }/* + for(; i + static TypeLength GetLength_NoPermitRange( + TypeCharC* APC_Origin, TypeLength AL_Length, const TStringArray& ARA_SearchArray) */ + + template + static TypeLength GetLength_NoPermitRange( + const TTyChars& AR_CChars, const TStringArray& ARA_SearchArray) + { + return ZtCMainChars::GetLength_NoPermitRange( + AR_CChars.data(), AR_CChars.size(), ARA_SearchArray ); + }/* + template + static TypeLength GetLength_NoPermitRange( + const TTyChars& AR_CChars, const TStringArray& ARA_SearchArray) */ + + + static TypeLength GetLength_NoPermitChar + ( + TypeCharC* APC_Origin , TypeLength AL_Length, + TypeCharC* APC_NoPermit, TypeLength AL_NoPermitLength + ) + //////////////////////////////////////// + { + if(AL_Length<1 || AL_NoPermitLength<1) return 0; + + TypeCharC* VPC_Origin =APC_Origin ; + TypeCharC* VPC_NoPermit=APC_NoPermit; + + TypeLength VL_SearchLen=0; + TypeLength j =0; + + for(TypeLength i=0; i + static TypeLength GetLength_NoPermitChar( + const TTyChars& AR_CCharsOrigin, const TTyChars& AR_CCharsSearch) + { + return ZtCMainChars::GetLength_NoPermitChar( + AR_CCharsOrigin.data(), AR_CCharsOrigin.size(), AR_CCharsSearch.data(), AR_CCharsSearch.size()); + }/* + template + static TypeLength GetLength_PermitChar( + const TTyChars& AR_CCharsOrigin, const TTyChars& AR_CCharsSearch) */ + + + template + static TypeLength GetLength_NoPermitChar2( + TypeCharC* APC_Origin, TypeLength AL_Length, const TStringArray& ARA_SearchArray) + { + // ARA_SearchArray ڿ Ҹ ã´. + + TypeLength VL_ArrSize =ARA_SearchArray.size(); + TypeLength VL_SearchNow=0; + TypeLength VL_SearchSum=0; + + if(AL_Length<1 || VL_ArrSize<1) return 0; + + + IterEasyIDc CI_IterEasyID(ARA_SearchArray.GetHeadIterEasyID()); + + for(TypeLength i=0; i + static TypeLength GetLength_NoPermitChar2( + TypeCharC* APC_Origin, TypeLength AL_Length, const TStringArray& ARA_SearchArray) */ + + template + static TypeLength GetLength_NoPermitChar2( + const TTyChars& AR_CCharsOrigin, const TStringArray& ARA_SearchArray) + { + return ZtCMainChars::GetLength_NoPermitChar2( + AR_CCharsOrigin.data(), AR_CCharsOrigin.size(), ARA_SearchArray); + }/* + template + static TypeLength GetLength_NoPermitChar2( + const TTyChars& AR_CCharsOrigin, const TStringArray& ARA_SearchArray) */ + + + static TypeLength GetLength_NoPermitCharRange( + TypeCharC* APC_Origin, TypeLength AL_Length, TypeCharC* APC_Permit, TypeLength AL_PermitLength) + { + /*//////////////////////////////////////////////// + + AL_PermitLength 2 μ, 2 ڰ, + ʴ Ÿ. + + -- 2011-08-12 00:53:00 + + ////////////////////////////////////////////////*/ + + if(AL_Length<1 || AL_PermitLength<2) return 0; + + TypeCharC* VPC_Origin=APC_Origin; + TypeCharC* VPC_Permit=APC_Permit; + + TypeLength VL_SearchLen =0; + TypeLength VL_PermitLength=AL_PermitLength/2; + TypeLength j =0; + + for(TypeLength i=0; i=*VPC_Permit && *VPC_Origin<=*(VPC_Permit+1)) + { + ++VL_SearchLen; break; + }/* + if(*VPC_Origin>=*VPC_Permit && *VPC_Origin<=*(VPC_Permit+1))*/ + + VPC_Permit+=2; + }/* + for(; j + static TypeLength GetLength_NoPermitCharRange(const TTyChars& AR_CCharsOrigin, const TTyChars& AR_CCharsSearch) + { + return ZtCMainChars::GetLength_NoPermitCharRange( + AR_CCharsOrigin.data(), AR_CCharsOrigin.size(), AR_CCharsSearch.data(), AR_CCharsSearch.size()); + }/* + template + static TypeLength GetLength_NoPermitCharRange(const TTyChars& AR_CCharsOrigin, const TTyChars& AR_CCharsSearch) */ + + template + static TypeLength GetLength_NoPermitCharRange2( + TypeCharC* APC_Origin, TypeLength AL_Length, const TStringArray& ARA_SearchArray) + { + // ARA_SearchArray ڿ Ҹ ã´. + + TypeLength VL_ArrSize =ARA_SearchArray.size(); + TypeLength VL_SearchNow=0; + TypeLength VL_SearchSum=0; + + if(AL_Length<1 || VL_ArrSize<1) return 0; + + + IterEasyIDc CI_IterEasyID(ARA_SearchArray.GetHeadIterEasyID()); + + for(TypeLength i=0; i + static TypeLength GetLength_NoPermitCharRange2( + TypeCharC* APC_Origin, TypeLength AL_Length, const TStringArray& ARA_SearchArray)*/ + + template + static TypeLength GetLength_NoPermitCharRange2( + const TTyChars& AR_CCharsOrigin, const TStringArray& ARA_SearchArray) + { + return ZtCMainChars::GetLength_NoPermitCharRange2( + AR_CCharsOrigin.data(), AR_CCharsOrigin.size(), ARA_SearchArray); + }/* + template + static TypeLength GetLength_NoPermitCharRange2( + const TTyChars& AR_CCharsOrigin, const TStringArray& ARA_SearchArray) */ + + + template static TypeLength GetLength_Repeat_Find + ( + int AI_RepeatMin , + int AI_RepeatMax , + TypeCharC* APC_Origin , + TypeLength AL_Length , + const TStringArray& ARA_SearchArray , + ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over + ) + /*###################################################################*/ + { + int VI_RepeatCnt=0; + TypeLength VL_LengthAll=0; + TypeLength VL_LengthNow=0; + + if(AI_RepeatMax<1) // ȿ 'ִ ݺ Ƚ' , Ѵ ݺ + { + do ////// + { + VL_LengthAll += VL_LengthNow = ZtCMainChars::GetLength_Find2 + ( + APC_Origin+VL_LengthAll, AL_Length-VL_LengthAll, ARA_SearchArray + ); + //////////////////////////////////////////////////////////// + + if(VL_LengthNow<1) + { + if(VI_RepeatCnt>=AI_RepeatMin) + return VL_LengthAll; + else + return 0; + }/* + if(VL_LengthNow<1)*/ + + ++VI_RepeatCnt; + } + while(true); + } + else // AI_RepeatMax>=1 + { + do //// + { + VL_LengthAll += VL_LengthNow = ZtCMainChars::GetLength_Find2 + ( + APC_Origin+VL_LengthAll, AL_Length-VL_LengthAll, ARA_SearchArray + ); + //////////////////////////////////////////////////////////// + + // VI_RepeatCnt AI_RepeatMax) return 0; // 'ִ ݺ Ƚ' 0 ȯ. + } + else // AE_ESearchMax==ZNsEnum::ZESearchMax_Stop + { + if(++VI_RepeatCnt>=AI_RepeatMax) return VL_LengthAll; // 'ִ ݺ Ƚ' ̸ . + }/* + else // AE_ESearchMax==ZNsEnum::ZESearchMax_Stop*/ + } + while(true); + }/* + else // AI_RepeatMax>=1 */ + + return VL_LengthAll; + }/* + template static TypeLength GetLength_Repeat_Find + ( + int AI_RepeatMin , + int AI_RepeatMax , + TypeCharC* APC_Origin , + TypeLength AL_Length , + const TStringArray& ARA_SearchArray , + ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over + ) + #####################################################################*/ + + template + static TypeLength GetLength_Repeat_Find( + int AI_RepeatMin, int AI_RepeatMax, const TTyChars& AR_CChars, const TStringArray& ARA_SearchArray, ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over) + { + return ZtCMainChars::GetLength_Repeat_Find( + AI_RepeatMin, AI_RepeatMax, AR_CChars.data(), AR_CChars.size(), ARA_SearchArray, AE_ESearchMax); + }/* + template + static TypeLength GetLength_Repeat_Find( + int AI_RepeatMin, int AI_RepeatMax, const TTyChars& AR_CChars, const TStringArray& ARA_SearchArray, ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over) */ + + + template + static TypeLength GetLength_Repeat_FindChar( /////////////////////////////// + int AI_RepeatMin , + int AI_RepeatMax , + TypeCharC* APC_Origin , + TypeLength AL_Length , + const TStringArray& ARA_SearchArray , + ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over + /*/////////*/ ) + { + int VI_RepeatCnt=0; + TypeLength VL_LengthAll=0; + TypeLength VL_LengthNow=0; + + if(AI_RepeatMax<1) // ȿ 'ִ ݺ Ƚ' , Ѵ ݺ + { + do ////// + { + VL_LengthAll += VL_LengthNow = ZtCMainChars::GetLength_FindChar2 + ( + APC_Origin+VL_LengthAll, AL_Length-VL_LengthAll, ARA_SearchArray + ); + //////////////////////////////////////////////////////////////// + + if(VL_LengthNow<1) + { + if(VI_RepeatCnt>=AI_RepeatMin) + return VL_LengthAll; + else + return 0; + }/* + if(VL_LengthNow<1)*/ + + ++VI_RepeatCnt; + } + while(true); + } + else // AI_RepeatMax>=1 + { + do ////// + { + VL_LengthAll += VL_LengthNow = ZtCMainChars::GetLength_FindChar2 + ( + APC_Origin+VL_LengthAll, AL_Length -VL_LengthAll, ARA_SearchArray + ); + //////////////////////////////////////////////////////////////// + + if(VL_LengthNow<1) + { + // VI_RepeatCnt<=AI_RepeatMax ´. + + if(VI_RepeatCnt AI_RepeatMax) return 0; + } + else // AE_ESearchMax==ZNsEnum::ZESearchMax_Stop + { + if(++VI_RepeatCnt>=AI_RepeatMax) return VL_LengthAll; + }/* + else // AE_ESearchMax==ZNsEnum::ZESearchMax_Stop*/ + } + while(true); + }/* + else // AI_RepeatMax>=1*/ + + return VL_LengthAll; + }/* + template + static TypeLength GetLength_Repeat_FindChar( /////////////////////////////// + int AI_RepeatMin , + int AI_RepeatMax , + TypeCharC* APC_Origin , + TypeLength AL_Length , + const TStringArray& ARA_SearchArray , + ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over + /?/////////// ) */ + + template + static TypeLength GetLength_Repeat_FindChar( + int AI_RepeatMin, int AI_RepeatMax, const TTyChars& AR_CChars, const TStringArray& ARA_SearchArray, ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over) + { + return ZtCMainChars::GetLength_Repeat_FindChar( + AI_RepeatMin, AI_RepeatMax, AR_CChars.data(), AR_CChars.size(), ARA_SearchArray, AE_ESearchMax); + }/* + template + static TypeLength GetLength_Repeat_FindChar( + int AI_RepeatMin, int AI_RepeatMax, const TTyChars& AR_CChars, const TStringArray& ARA_SearchArray, ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over) */ + + + template static TypeLength GetLength_Repeat_FindEscape + ( + int AI_RepeatMin, int AI_RepeatMax, + TypeCharC* APC_Origin , TypeLength AL_Length , + const TStringArray& ARA_SearchArray , + ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over + ) + /*#########################################################################*/ + { + /* ARA_SearchArray ù° Ҹ escape ڿ . + ARA_SearchArray 迭 2 ̻̾ Ѵ. + + ARA_SearchArray ڿ ã ϹǷ + ã ڿ ؾ Ѵ. */ + + int VI_RepeatCnt=0; + TypeLength VL_LengthAll=0; + TypeLength VL_LengthNow=0; + + if(AI_RepeatMax<1) // ȿ 'ִ ݺ Ƚ' , Ѵ ݺ + { + do ////// + { + VL_LengthAll += VL_LengthNow = + + ZtCMainChars::GetLength_FindEscape2( /////////// + APC_Origin+VL_LengthAll , + AL_Length -VL_LengthAll , + ARA_SearchArray + /*/////////*/ ); /////////////////////////////// + + if(VL_LengthNow<1) + { + if(VI_RepeatCnt>=AI_RepeatMin) + return VL_LengthAll; + else + return 0; + }/* + if(VL_LengthNow<1)*/ + + ++VI_RepeatCnt; + } + while(true); + } + else // AI_RepeatMax>=1 + { + do ////// + { + VL_LengthAll += VL_LengthNow = + + ZtCMainChars::GetLength_FindEscape2( /////////// + APC_Origin+VL_LengthAll , + AL_Length -VL_LengthAll , + ARA_SearchArray + /*//////////*/ ); ////////////////////////////// + + // VI_RepeatCnt AI_RepeatMax) return 0; + } + else // AE_ESearchMax==ZNsEnum::ZESearchMax_Stop + { + if(++VI_RepeatCnt>=AI_RepeatMax) return VL_LengthAll; + }/* + else // AE_ESearchMax==ZNsEnum::ZESearchMax_Stop*/ + } + while(true); + }/* + else // AI_RepeatMax>=1*/ + + return VL_LengthAll; + }/* + template static TypeLength GetLength_Repeat_FindEscape + ( + int AI_RepeatMin, int AI_RepeatMax, + TypeCharC* APC_Origin , TypeLength AL_Length , + const TStringArray& ARA_SearchArray , + ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over + ) + ###########################################################################*/ + + template + static TypeLength GetLength_Repeat_FindEscape( + int AI_RepeatMin, int AI_RepeatMax, const TTyChars& AR_CChars, const TStringArray& ARA_SearchArray, ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over) + { + return ZtCMainChars::GetLength_Repeat_FindEscape( + AI_RepeatMin, AI_RepeatMax, AR_CChars.data(), AR_CChars.size(), ARA_SearchArray, AE_ESearchMax); + }/* + template + static TypeLength GetLength_Repeat_FindEscape( + int AI_RepeatMin, int AI_RepeatMax, const TTyChars& AR_CChars, const TStringArray& ARA_SearchArray, ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over) */ + + + template static TypeLength GetLength_Repeat_FindSerial + ( + int AI_RepeatMin , int AI_RepeatMax , + TypeCharC* APC_Origin , TypeLength AL_Length, + const TStringArray& ARA_SearchArray , + ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over + ) + ///////////////////////////////////////////////////////////////////////////// + { + int VI_RepeatCnt=0; + TypeLength VL_LengthAll=0; + TypeLength VL_LengthNow=0; + + if(AI_RepeatMax<1) // ȿ 'ִ ݺ Ƚ' , Ѵ ݺ + { + do ////// + { + VL_LengthAll += VL_LengthNow = + + ZtCMainChars::GetLength_FindSerial( //////////// + APC_Origin+VL_LengthAll , + AL_Length -VL_LengthAll , + ARA_SearchArray + /*/////////*/ ); /////////////////////////////// + + if(VL_LengthNow<1) + { + if(VI_RepeatCnt>=AI_RepeatMin) + return VL_LengthAll; + else + return 0; + }/* + if(VL_LengthNow<1)*/ + + ++VI_RepeatCnt; + } + while(true); + } + else // AI_RepeatMax>=1 + { + do ////// + { + VL_LengthAll += VL_LengthNow = + + ZtCMainChars::GetLength_FindSerial( //////////// + APC_Origin+VL_LengthAll , + AL_Length -VL_LengthAll , + ARA_SearchArray + /*//////////*/ ); ////////////////////////////// + + // VI_RepeatCnt AI_RepeatMax) return 0; + } + else // AE_ESearchMax==ZNsEnum::ZESearchMax_Stop + { + if(++VI_RepeatCnt>=AI_RepeatMax) return VL_LengthAll; + }/* + else // AE_ESearchMax==ZNsEnum::ZESearchMax_Stop*/ + } + while(true); + }/* + else // AI_RepeatMax>=1*/ + + return VL_LengthAll; + }/* + template static TypeLength GetLength_Repeat_FindSerial + ( + int AI_RepeatMin , int AI_RepeatMax , + TypeCharC* APC_Origin , TypeLength AL_Length, + const TStringArray& ARA_SearchArray , + ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over + ) + ///////////////////////////////////////////////////////////////////////////*/ + + template + static TypeLength GetLength_Repeat_FindSerial( + int AI_RepeatMin, int AI_RepeatMax, const TTyChars& AR_CChars, const TStringArray& ARA_SearchArray, ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over) + { + return ZtCMainChars::GetLength_Repeat_FindSerial(AI_RepeatMin, AI_RepeatMax, AR_CChars.data(), AR_CChars.size(), ARA_SearchArray, AE_ESearchMax); + }/* + template + static TypeLength GetLength_Repeat_FindSerial( + int AI_RepeatMin, int AI_RepeatMax, const TTyChars& AR_CChars, const TStringArray& ARA_SearchArray, ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over) */ + + + template static TypeLength GetLength_Repeat_FindSerialChar + ( + int AI_RepeatMin, int AI_RepeatMax, + TypeCharC* APC_Origin , TypeLength AL_Length , + const TStringArray& ARA_SearchArray , + ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over + ) + /*#############################################################################*/ + { + int VI_RepeatCnt=0; + TypeLength VL_LengthAll=0; + TypeLength VL_LengthNow=0; + + if(AI_RepeatMax<1) // ȿ 'ִ ݺ Ƚ' , Ѵ ݺ + { + do ////// + { + VL_LengthAll += VL_LengthNow = ZtCMainChars::GetLength_FindSerialChar2 + ( + APC_Origin+VL_LengthAll, AL_Length-VL_LengthAll, ARA_SearchArray + ); + ////////////////////////////////////////////////////////////////////// + + if(VL_LengthNow<1) + { + if(VI_RepeatCnt>=AI_RepeatMin) + return VL_LengthAll; + else + return 0; + }/* + if(VL_LengthNow<1)*/ + + ++VI_RepeatCnt; + } + while(true); + } + else // AI_RepeatMax>=1 + { + do ////// + { + VL_LengthAll += VL_LengthNow = ZtCMainChars::GetLength_FindSerialChar2 + ( + APC_Origin+VL_LengthAll, AL_Length -VL_LengthAll, ARA_SearchArray + ); + ////////////////////////////////////////////////////////////////////// + + if(VL_LengthNow<1) + { + // VI_RepeatCnt<=AI_RepeatMax ´. + + if(VI_RepeatCnt AI_RepeatMax) return 0; + } + else // AE_ESearchMax==ZNsEnum::ZESearchMax_Stop + { + if(++VI_RepeatCnt>=AI_RepeatMax) return VL_LengthAll; + }/* + else // AE_ESearchMax==ZNsEnum::ZESearchMax_Stop*/ + } + while(true); + }/* + else // AI_RepeatMax>=1*/ + + return VL_LengthAll; + }/* + template static TypeLength GetLength_Repeat_FindSerialChar + ( + int AI_RepeatMin, int AI_RepeatMax, + TypeCharC* APC_Origin , TypeLength AL_Length , + const TStringArray& ARA_SearchArray , + ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over + ) + ###############################################################################*/ + + template + static TypeLength GetLength_Repeat_FindSerialChar( + int AI_RepeatMin, int AI_RepeatMax, const TTyChars& AR_CChars, const TStringArray& ARA_SearchArray, ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over) + { + return ZtCMainChars::GetLength_Repeat_FindSerialChar( + AI_RepeatMin, AI_RepeatMax, AR_CChars.data(), AR_CChars.size(), ARA_SearchArray, AE_ESearchMax); + }/* + template + static TypeLength GetLength_Repeat_FindSerialChar( + int AI_RepeatMin, int AI_RepeatMax, const TTyChars& AR_CChars, const TStringArray& ARA_SearchArray, ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over) */ + + + template static TypeLength GetLength_Repeat_StartFind + ( + int AI_RepeatMin, int AI_RepeatMax, + TypeCharC* APC_Origin , TypeLength AL_Length , + const TStringArray& ARA_SearchArray , + ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over + ) + /*########################################################################*/ + { + int VI_RepeatCnt=0; + TypeLength VL_LengthAll=0; + TypeLength VL_LengthNow=0; + + if(AI_RepeatMax<1) // ȿ 'ִ ݺ Ƚ' , Ѵ ݺ + { + do ////// + { + VL_LengthAll += VL_LengthNow = + + ZtCMainChars::GetLength_StartFind( //////////// + APC_Origin+VL_LengthAll , + AL_Length -VL_LengthAll , + ARA_SearchArray + /*/////////*/ ); ////////////////////////////// + + if(VL_LengthNow<1) + { + if(VI_RepeatCnt>=AI_RepeatMin) + return VL_LengthAll; + else + return 0; + }/* + if(VL_LengthNow<1)*/ + + ++VI_RepeatCnt; + } + while(true); + } + else // AI_RepeatMax>=1 + { + do ////// + { + VL_LengthAll += VL_LengthNow = + + ZtCMainChars::GetLength_StartFind( //////////// + APC_Origin+VL_LengthAll , + AL_Length -VL_LengthAll , + ARA_SearchArray + /*//////////*/ ); ///////////////////////////// + + // VI_RepeatCnt AI_RepeatMax) return 0; + } + else // AE_ESearchMax==ZNsEnum::ZESearchMax_Stop + { + if(++VI_RepeatCnt>=AI_RepeatMax) return VL_LengthAll; + }/* + else // AE_ESearchMax==ZNsEnum::ZESearchMax_Stop*/ + } + while(true); + }/* + else // AI_RepeatMax>=1*/ + + return VL_LengthAll; + }/* + template static TypeLength GetLength_Repeat_StartFind + ( + int AI_RepeatMin, int AI_RepeatMax, + TypeCharC* APC_Origin , TypeLength AL_Length , + const TStringArray& ARA_SearchArray , + ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over + ) + ##########################################################################*/ + + template + static TypeLength GetLength_Repeat_StartFind( + int AI_RepeatMin, int AI_RepeatMax, const TTyChars& AR_CChars, const TStringArray& ARA_SearchArray, ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over) + { + return ZtCMainChars::GetLength_Repeat_StartFind( + AI_RepeatMin, AI_RepeatMax, AR_CChars.data(), AR_CChars.size(), ARA_SearchArray, AE_ESearchMax); + }/* + template + static TypeLength GetLength_Repeat_StartFind( + int AI_RepeatMin, int AI_RepeatMax, const TTyChars& AR_CChars, const TStringArray& ARA_SearchArray, ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over) */ + + + template static TypeLength GetLength_Repeat_StartFindChar + ( + int AI_RepeatMin, int AI_RepeatMax, + TypeCharC* APC_Origin , TypeLength AL_Length , + const TStringArray& ARA_SearchArray , + ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over + ) + /*#############################################################################*/ + { + int VI_RepeatCnt=0; + TypeLength VL_LengthAll=0; + TypeLength VL_LengthNow=0; + + if(AI_RepeatMax<1) // ȿ 'ִ ݺ Ƚ' , Ѵ ݺ + { + do ////// + { + VL_LengthAll += VL_LengthNow = ZtCMainChars::GetLength_StartFindChar2 + ( + APC_Origin+VL_LengthAll, AL_Length-VL_LengthAll, ARA_SearchArray + ); + ///////////////////////////////////////////////////////////////////// + + if(VL_LengthNow<1) + { + if(VI_RepeatCnt>=AI_RepeatMin) + return VL_LengthAll; + else + return 0; + }/* + if(VL_LengthNow<1)*/ + + ++VI_RepeatCnt; + } + while(true); + } + else // AI_RepeatMax>=1 + { + do ////// + { + VL_LengthAll += VL_LengthNow = ZtCMainChars::GetLength_StartFindChar2 + ( + APC_Origin+VL_LengthAll, AL_Length -VL_LengthAll, ARA_SearchArray + ); + ///////////////////////////////////////////////////////////////////// + + if(VL_LengthNow<1) + { + // VI_RepeatCnt<=AI_RepeatMax ´. + + if(VI_RepeatCnt AI_RepeatMax) return 0; + } + else // AE_ESearchMax==ZNsEnum::ZESearchMax_Stop + { + if(++VI_RepeatCnt>=AI_RepeatMax) return VL_LengthAll; + }/* + else // AE_ESearchMax==ZNsEnum::ZESearchMax_Stop*/ + } + while(true); + }/* + else // AI_RepeatMax>=1*/ + + return VL_LengthAll; + }/* + template static TypeLength GetLength_Repeat_StartFindChar + ( + int AI_RepeatMin, int AI_RepeatMax, + TypeCharC* APC_Origin , TypeLength AL_Length , + const TStringArray& ARA_SearchArray , + ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over + ) + ###############################################################################*/ + + template + static TypeLength GetLength_Repeat_StartFindChar( + int AI_RepeatMin, int AI_RepeatMax, const TTyChars& AR_CChars, const TStringArray& ARA_SearchArray, ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over) + { + return ZtCMainChars::GetLength_Repeat_StartFindChar( + AI_RepeatMin, AI_RepeatMax, AR_CChars.data(), AR_CChars.size(), ARA_SearchArray, AE_ESearchMax); + }/* + template + static TypeLength GetLength_Repeat_StartFindChar( + int AI_RepeatMin, int AI_RepeatMax, const TTyChars& AR_CChars, const TStringArray& ARA_SearchArray, ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over) */ + + + template static TypeLength GetLength_Repeat_Permit + ( + int AI_RepeatMin, int AI_RepeatMax, + TypeCharC* APC_Origin , TypeLength AL_Length , + const TStringArray& ARA_SearchArray , + ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over + ) + /*#####################################################################*/ + { + int VI_RepeatCnt=0; + TypeLength VL_LengthAll=0; + TypeLength VL_LengthNow=0; + + if(AI_RepeatMax<1) // ȿ 'ִ ݺ Ƚ' , Ѵ ݺ + { + do ////// + { + VL_LengthAll += VL_LengthNow = ZtCMainChars::GetLength_Permit + ( + APC_Origin+VL_LengthAll, AL_Length-VL_LengthAll, ARA_SearchArray + ); + ///////////////////////////////////////////////////////////// + + if(VL_LengthNow<1) + { + if(VI_RepeatCnt>=AI_RepeatMin) + return VL_LengthAll; + else + return 0; + }/* + if(VL_LengthNow<1)*/ + + ++VI_RepeatCnt; + } + while(true); + } + else // AI_RepeatMax>=1 + { + do ////// + { + VL_LengthAll += VL_LengthNow = ZtCMainChars::GetLength_Permit + ( + APC_Origin+VL_LengthAll, AL_Length-VL_LengthAll, ARA_SearchArray + ); + ///////////////////////////////////////////////////////////// + + if(VL_LengthNow<1) + { + // VI_RepeatCnt<=AI_RepeatMax ´. + + if(VI_RepeatCnt AI_RepeatMax) return 0; + } + else // AE_ESearchMax==ZNsEnum::ZESearchMax_Stop + { + if(++VI_RepeatCnt>=AI_RepeatMax) return VL_LengthAll; + }/* + else // AE_ESearchMax==ZNsEnum::ZESearchMax_Stop*/ + } + while(true); + }/* + else // AI_RepeatMax>=1*/ + + return VL_LengthAll; + }/* + template static TypeLength GetLength_Repeat_Permit + ( + int AI_RepeatMin, int AI_RepeatMax, + TypeCharC* APC_Origin , TypeLength AL_Length , + const TStringArray& ARA_SearchArray , + ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over + ) + ///////////////////////////////////////////////////////////////////////*/ + + template + static TypeLength GetLength_Repeat_Permit( + int AI_RepeatMin, int AI_RepeatMax, const TTyChars& AR_CChars, const TStringArray& ARA_SearchArray, ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over) + { + return ZtCMainChars::GetLength_Repeat_Permit( + AI_RepeatMin, AI_RepeatMax, AR_CChars.data(), AR_CChars.size(), ARA_SearchArray, AE_ESearchMax); + }/* + template + static TypeLength GetLength_Repeat_Permit( + int AI_RepeatMin, int AI_RepeatMax, const TTyChars& AR_CChars, const TStringArray& ARA_SearchArray, ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over) */ + + + template static TypeLength GetLength_Repeat_PermitRange + ( + int AI_RepeatMin, int AI_RepeatMax, + TypeCharC* APC_Origin , TypeLength AL_Length , + const TStringArray& ARA_SearchArray , + ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over + ) + ////////////////////////////////////////////////////////////////////////////// + { + int VI_RepeatCnt=0; + TypeLength VL_LengthAll=0; + TypeLength VL_LengthNow=0; + + if(AI_RepeatMax<1) // ȿ ִ ݺ Ƚ , Ѵ ݺ + { + do ////// + { + VL_LengthAll += VL_LengthNow = ZtCMainChars::GetLength_PermitRange + ( + APC_Origin+VL_LengthAll, AL_Length-VL_LengthAll, ARA_SearchArray + ); + ////////////////////////////////////////////////////////////////// + + if(VL_LengthNow<1) + { + if(VI_RepeatCnt>=AI_RepeatMin) + return VL_LengthAll; + else + return 0; + }/* + if(VL_LengthNow<1)*/ + + ++VI_RepeatCnt; + } + while(true); + } + else // AI_RepeatMax>=1 + { + do ////// + { + VL_LengthAll += VL_LengthNow = ZtCMainChars::GetLength_PermitRange + ( + APC_Origin+VL_LengthAll, AL_Length-VL_LengthAll, ARA_SearchArray + ); + ////////////////////////////////////////////////////////////////// + + if(VL_LengthNow<1) + { + // VI_RepeatCnt<=AI_RepeatMax ´. + + if(VI_RepeatCnt AI_RepeatMax) return 0; + } + else // AE_ESearchMax==ZNsEnum::ZESearchMax_Stop + { + if(++VI_RepeatCnt>=AI_RepeatMax) return VL_LengthAll; + }/* + else // AE_ESearchMax==ZNsEnum::ZESearchMax_Stop*/ + } + while(true); + }/* + else // AI_RepeatMax>=1*/ + + return VL_LengthAll; + }/* + template static TypeLength GetLength_Repeat_PermitRange + ( + int AI_RepeatMin, int AI_RepeatMax, + TypeCharC* APC_Origin , TypeLength AL_Length , + const TStringArray& ARA_SearchArray , + ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over + ) + ////////////////////////////////////////////////////////////////////////////*/ + + template + static TypeLength GetLength_Repeat_PermitRange( + int AI_RepeatMin, int AI_RepeatMax, const TTyChars& AR_CChars, const TStringArray& ARA_SearchArray, ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over) + { + return ZtCMainChars::GetLength_Repeat_PermitRange( + AI_RepeatMin, AI_RepeatMax, AR_CChars.data(), AR_CChars.size(), ARA_SearchArray, AE_ESearchMax); + }/* + template + static TypeLength GetLength_Repeat_PermitRange( + int AI_RepeatMin, int AI_RepeatMax, const TTyChars& AR_CChars, const TStringArray& ARA_SearchArray, ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over) */ + + + template static TypeLength GetLength_Repeat_PermitChar + ( + int AI_RepeatMin, int AI_RepeatMax, + TypeCharC* APC_Origin , TypeLength AL_Length , + const TStringArray& ARA_SearchArray , + ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over + ) + /*#########################################################################*/ + { + int VI_RepeatCnt=0; + TypeLength VL_LengthAll=0; + TypeLength VL_LengthNow=0; + + if(AI_RepeatMax<1) // ȿ 'ִ ݺ Ƚ' , Ѵ ݺ + { + do ////// + { + VL_LengthAll += VL_LengthNow = ZtCMainChars::GetLength_PermitChar2 + ( + APC_Origin+VL_LengthAll, AL_Length-VL_LengthAll, ARA_SearchArray + ); + ////////////////////////////////////////////////////////////////// + + if(VL_LengthNow<1) + { + if(VI_RepeatCnt>=AI_RepeatMin) + return VL_LengthAll; + else + return 0; + }/* + if(VL_LengthNow<1)*/ + + ++VI_RepeatCnt; + } + while(true); + } + else // AI_RepeatMax>=1 + { + do ////// + { + VL_LengthAll += VL_LengthNow = ZtCMainChars::GetLength_PermitChar2 + ( + APC_Origin+VL_LengthAll, AL_Length-VL_LengthAll, ARA_SearchArray + ); + ////////////////////////////////////////////////////////////////// + + if(VL_LengthNow<1) + { + // VI_RepeatCnt<=AI_RepeatMax ´. + + if(VI_RepeatCnt AI_RepeatMax) return 0; + } + else // AE_ESearchMax==ZNsEnum::ZESearchMax_Stop + { + if(++VI_RepeatCnt>=AI_RepeatMax) return VL_LengthAll; + }/* + else // AE_ESearchMax==ZNsEnum::ZESearchMax_Stop*/ + } + while(true); + }/* + else // AI_RepeatMax>=1*/ + + return VL_LengthAll; + }/* + template static TypeLength GetLength_Repeat_PermitChar + ( + int AI_RepeatMin, int AI_RepeatMax, + TypeCharC* APC_Origin , TypeLength AL_Length , + const TStringArray& ARA_SearchArray , + ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over + ) + ###########################################################################*/ + + template + static TypeLength GetLength_Repeat_PermitChar( + int AI_RepeatMin, int AI_RepeatMax, const TTyChars& AR_CChars, const TStringArray& ARA_SearchArray, ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over) + { + return ZtCMainChars::GetLength_Repeat_PermitChar( + AI_RepeatMin, AI_RepeatMax, AR_CChars.data(), AR_CChars.size(), ARA_SearchArray, AE_ESearchMax); + }/* + template + static TypeLength GetLength_Repeat_PermitChar( + int AI_RepeatMin, int AI_RepeatMax, const TTyChars& AR_CChars, const TStringArray& ARA_SearchArray, ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over) */ + + + template static TypeLength GetLength_Repeat_PermitCharRange + ( + int AI_RepeatMin, int AI_RepeatMax, + TypeCharC* APC_Origin , TypeLength AL_Length , + const TStringArray& ARA_SearchArray , + ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over + ) + /*##############################################################################*/ + { + int VI_RepeatCnt=0; + TypeLength VL_LengthAll=0; + TypeLength VL_LengthNow=0; + + if(AI_RepeatMax<1) // ȿ 'ִ ݺ Ƚ' , Ѵ ݺ + { + do ////// + { + VL_LengthAll += VL_LengthNow = ZtCMainChars::GetLength_PermitCharRange2 + ( + APC_Origin+VL_LengthAll, AL_Length-VL_LengthAll, ARA_SearchArray + ); + /////////////////////////////////////////////////////////////////////// + + if(VL_LengthNow<1) + { + if(VI_RepeatCnt>=AI_RepeatMin) + return VL_LengthAll; + else + return 0; + }/* + if(VL_LengthNow<1)*/ + + ++VI_RepeatCnt; + } + while(true); + } + else // AI_RepeatMax>=1 + { + do ////// + { + VL_LengthAll += VL_LengthNow = ZtCMainChars::GetLength_PermitCharRange2 + ( + APC_Origin+VL_LengthAll, AL_Length-VL_LengthAll, ARA_SearchArray + ); + /////////////////////////////////////////////////////////////////////// + + if(VL_LengthNow<1) + { + // VI_RepeatCnt<=AI_RepeatMax ´. + + if(VI_RepeatCnt AI_RepeatMax) return 0; + } + else // AE_ESearchMax==ZNsEnum::ZESearchMax_Stop + { + if(++VI_RepeatCnt>=AI_RepeatMax) return VL_LengthAll; + }/* + else // AE_ESearchMax==ZNsEnum::ZESearchMax_Stop*/ + } + while(true); + }/* + else // AI_RepeatMax>=1*/ + + return VL_LengthAll; + }/* + template static TypeLength GetLength_Repeat_PermitCharRange + ( + int AI_RepeatMin, int AI_RepeatMax, + TypeCharC* APC_Origin , TypeLength AL_Length , + const TStringArray& ARA_SearchArray , + ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over + ) + ################################################################################*/ + + template + static TypeLength GetLength_Repeat_PermitCharRange( + int AI_RepeatMin, int AI_RepeatMax, const TTyChars& AR_CChars, const TStringArray& ARA_SearchArray, ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over) + { + return ZtCMainChars::GetLength_Repeat_PermitCharRange( + AI_RepeatMin, AI_RepeatMax, AR_CChars.data(), AR_CChars.size(), ARA_SearchArray, AE_ESearchMax); + }/* + template + static TypeLength GetLength_Repeat_PermitCharRange( + int AI_RepeatMin, int AI_RepeatMax, const TTyChars& AR_CChars, const TStringArray& ARA_SearchArray, ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over) */ + + + template static TypeLength GetLength_Repeat_NoPermit + ( + int AI_RepeatMin, int AI_RepeatMax, + TypeCharC* APC_Origin , TypeLength AL_Length , + const TStringArray& ARA_SearchArray , + ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over + ) + /////////////////////////////////////////////////////////////////////////// + { + int VI_RepeatCnt=0; + TypeLength VL_LengthAll=0; + TypeLength VL_LengthNow=0; + + if(AI_RepeatMax<1) // ȿ ִ ݺ Ƚ , Ѵ ݺ + { + do ////// + { + VL_LengthAll += VL_LengthNow = ZtCMainChars::GetLength_NoPermit + ( + APC_Origin+VL_LengthAll, AL_Length-VL_LengthAll, ARA_SearchArray + ); + /////////////////////////////////////////////////////////////// + + if(VL_LengthNow<1) + { + if(VI_RepeatCnt>=AI_RepeatMin) + return VL_LengthAll; + else + return 0; + }/* + if(VL_LengthNow<1)*/ + + ++VI_RepeatCnt; + } + while(true); + } + else // AI_RepeatMax>=1 + { + do ////// + { + VL_LengthAll += VL_LengthNow = ZtCMainChars::GetLength_NoPermit + ( + APC_Origin+VL_LengthAll, AL_Length-VL_LengthAll, ARA_SearchArray + ); + /////////////////////////////////////////////////////////////// + + if(VL_LengthNow<1) + { + // VI_RepeatCnt<=AI_RepeatMax ´. + + if(VI_RepeatCnt AI_RepeatMax) return 0; + } + else // AE_ESearchMax==ZNsEnum::ZESearchMax_Stop + { + if(++VI_RepeatCnt>=AI_RepeatMax) return VL_LengthAll; + }/* + else // AE_ESearchMax==ZNsEnum::ZESearchMax_Stop*/ + } + while(true); + }/* + else // AI_RepeatMax>=1*/ + + return VL_LengthAll; + }/* + template static TypeLength GetLength_Repeat_NoPermit + ( + int AI_RepeatMin , int AI_RepeatMax , + TypeCharC* APC_Origin , TypeLength AL_Length, + const TStringArray& ARA_SearchArray , + ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over + ) + /////////////////////////////////////////////////////////////////////////*/ + + template + static TypeLength GetLength_Repeat_NoPermit( + int AI_RepeatMin, int AI_RepeatMax, const TTyChars& AR_CChars, const TStringArray& ARA_SearchArray, ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over) + { + return ZtCMainChars::GetLength_Repeat_NoPermit( + AI_RepeatMin, AI_RepeatMax, AR_CChars.data(), AR_CChars.size(), ARA_SearchArray, AE_ESearchMax); + }/* + template + static TypeLength GetLength_Repeat_NoPermit( + int AI_RepeatMin, int AI_RepeatMax, const TTyChars& AR_CChars, const TStringArray& ARA_SearchArray, ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over) */ + + + template static TypeLength GetLength_Repeat_NoPermitRange + ( + int AI_RepeatMin, int AI_RepeatMax, + TypeCharC* APC_Origin , TypeLength AL_Length , + const TStringArray& ARA_SearchArray , + ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over + ) + //////////////////////////////////////////////////////////////////////////////// + { + int VI_RepeatCnt=0; + TypeLength VL_LengthAll=0; + TypeLength VL_LengthNow=0; + + if(AI_RepeatMax<1) // ȿ ִ ݺ Ƚ , Ѵ ݺ + { + do ////// + { + VL_LengthAll += VL_LengthNow = ZtCMainChars::GetLength_NoPermitRange + ( + APC_Origin+VL_LengthAll, AL_Length-VL_LengthAll, ARA_SearchArray + ); + //////////////////////////////////////////////////////////////////// + + if(VL_LengthNow<1) + { + if(VI_RepeatCnt>=AI_RepeatMin) + return VL_LengthAll; + else + return 0; + }/* + if(VL_LengthNow<1)*/ + + ++VI_RepeatCnt; + } + while(true); + } + else // AI_RepeatMax>=1 + { + do ////// + { + VL_LengthAll += VL_LengthNow = ZtCMainChars::GetLength_NoPermitRange + ( + APC_Origin+VL_LengthAll, AL_Length-VL_LengthAll, ARA_SearchArray + ); + //////////////////////////////////////////////////////////////////// + + if(VL_LengthNow<1) + { + // VI_RepeatCnt<=AI_RepeatMax ´. + + if(VI_RepeatCnt AI_RepeatMax) return 0; + } + else // AE_ESearchMax==ZNsEnum::ZESearchMax_Stop + { + if(++VI_RepeatCnt>=AI_RepeatMax) return VL_LengthAll; + }/* + else // AE_ESearchMax==ZNsEnum::ZESearchMax_Stop*/ + } + while(true); + }/* + else // AI_RepeatMax>=1*/ + + return VL_LengthAll; + }/* + template static TypeLength GetLength_Repeat_NoPermitRange + ( + int AI_RepeatMin, int AI_RepeatMax, + TypeCharC* APC_Origin , TypeLength AL_Length , + const TStringArray& ARA_SearchArray , + ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over + ) + //////////////////////////////////////////////////////////////////////////////*/ + + template + static TypeLength GetLength_Repeat_NoPermitRange( + int AI_RepeatMin, int AI_RepeatMax, const TTyChars& AR_CChars, const TStringArray& ARA_SearchArray, ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over) + { + return ZtCMainChars::GetLength_Repeat_NoPermitRange( + AI_RepeatMin, AI_RepeatMax, AR_CChars.data(), AR_CChars.size(), ARA_SearchArray, AE_ESearchMax); + }/* + template + static TypeLength GetLength_Repeat_NoPermitRange( + int AI_RepeatMin, int AI_RepeatMax, const TTyChars& AR_CChars, const TStringArray& ARA_SearchArray, ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over) */ + + + template static TypeLength GetLength_Repeat_NoPermitChar + ( + int AI_RepeatMin, int AI_RepeatMax, + TypeCharC* APC_Origin , TypeLength AL_Length , + const TStringArray& ARA_SearchArray , + ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over + ) + /*###########################################################################*/ + { + int VI_RepeatCnt=0; + TypeLength VL_LengthAll=0; + TypeLength VL_LengthNow=0; + + if(AI_RepeatMax<1) // ȿ ִ ݺȽ , Ѵ ݺ + { + do ////// + { + VL_LengthAll += VL_LengthNow = ZtCMainChars::GetLength_NoPermitChar2 + ( + APC_Origin+VL_LengthAll, AL_Length-VL_LengthAll, ARA_SearchArray + ); + //////////////////////////////////////////////////////////////////// + + if(VL_LengthNow<1) + { + if(VI_RepeatCnt>=AI_RepeatMin) + return VL_LengthAll; + else + return 0; + }/* + if(VL_LengthNow<1)*/ + + ++VI_RepeatCnt; + } + while(true); + } + else // AI_RepeatMax>=1 + { + do ////// + { + VL_LengthAll += VL_LengthNow = ZtCMainChars::GetLength_NoPermitChar2 + ( + APC_Origin+VL_LengthAll, AL_Length-VL_LengthAll, ARA_SearchArray + ); + //////////////////////////////////////////////////////////////////// + + if(VL_LengthNow<1) + { + // VI_RepeatCnt<=AI_RepeatMax ´. + + if(VI_RepeatCnt AI_RepeatMax) return 0; + } + else // AE_ESearchMax==ZNsEnum::ZESearchMax_Stop + { + if(++VI_RepeatCnt>=AI_RepeatMax) return VL_LengthAll; + }/* + else // AE_ESearchMax==ZNsEnum::ZESearchMax_Stop*/ + } + while(true); + }/* + else // AI_RepeatMax>=1*/ + + return VL_LengthAll; + }/* + template static TypeLength GetLength_Repeat_NoPermitChar + ( + int AI_RepeatMin, int AI_RepeatMax, + TypeCharC* APC_Origin , TypeLength AL_Length , + const TStringArray& ARA_SearchArray , + ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over + ) + #############################################################################*/ + + template + static TypeLength GetLength_Repeat_NoPermitChar( + int AI_RepeatMin, int AI_RepeatMax, const TTyChars& AR_CChars, const TStringArray& ARA_SearchArray, ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over) + { + return ZtCMainChars::GetLength_Repeat_NoPermitChar( + AI_RepeatMin, AI_RepeatMax, AR_CChars.data(), AR_CChars.size(), ARA_SearchArray, AE_ESearchMax); + }/* + template + static TypeLength GetLength_Repeat_NoPermitChar( + int AI_RepeatMin, int AI_RepeatMax, const TTyChars& AR_CChars, const TStringArray& ARA_SearchArray, ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over) */ + + + template static TypeLength GetLength_Repeat_NoPermitCharRange + ( + int AI_RepeatMin, int AI_RepeatMax, + TypeCharC* APC_Origin , TypeLength AL_Length , + const TStringArray& ARA_SearchArray , + ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over + ) + /*################################################################################*/ + { + int VI_RepeatCnt=0; + TypeLength VL_LengthAll=0; + TypeLength VL_LengthNow=0; + + if(AI_RepeatMax<1) // ȿ ִ ݺ Ƚ , Ѵ ݺ + { + do ////// + { + VL_LengthAll += VL_LengthNow = ZtCMainChars::GetLength_NoPermitCharRange2 + ( + APC_Origin+VL_LengthAll, AL_Length-VL_LengthAll, ARA_SearchArray + ); + ///////////////////////////////////////////////////////////////////////// + + if(VL_LengthNow<1) + { + if(VI_RepeatCnt>=AI_RepeatMin) + return VL_LengthAll; + else + return 0; + }/* + if(VL_LengthNow<1)*/ + + ++VI_RepeatCnt; + } + while(true); + } + else // AI_RepeatMax>=1 + { + do ////// + { + VL_LengthAll += VL_LengthNow = ZtCMainChars::GetLength_NoPermitCharRange2 + ( + APC_Origin+VL_LengthAll, AL_Length-VL_LengthAll, ARA_SearchArray + ); + ///////////////////////////////////////////////////////////////////////// + + if(VL_LengthNow<1) + { + // VI_RepeatCnt<=AI_RepeatMax ´. + + if(VI_RepeatCnt AI_RepeatMax) return 0; + } + else // AE_ESearchMax==ZNsEnum::ZESearchMax_Stop + { + if(++VI_RepeatCnt>=AI_RepeatMax) return VL_LengthAll; + }/* + else // AE_ESearchMax==ZNsEnum::ZESearchMax_Stop*/ + } + while(true); + }/* + else // AI_RepeatMax>=1*/ + + return VL_LengthAll; + }/* + template static TypeLength GetLength_Repeat_NoPermitCharRange + ( + int AI_RepeatMin, int AI_RepeatMax, + TypeCharC* APC_Origin , TypeLength AL_Length , + const TStringArray& ARA_SearchArray , + ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over + ) + ##################################################################################*/ + + template + static TypeLength GetLength_Repeat_NoPermitCharRange( + int AI_RepeatMin, int AI_RepeatMax, const TTyChars& AR_CChars, const TStringArray& ARA_SearchArray, ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over) + { + return ZtCMainChars::GetLength_Repeat_NoPermitCharRange( + AI_RepeatMin, AI_RepeatMax, AR_CChars.data(), AR_CChars.size(), ARA_SearchArray, AE_ESearchMax); + }/* + template + static TypeLength GetLength_Repeat_NoPermitCharRange( + int AI_RepeatMin, int AI_RepeatMax, const TTyChars& AR_CChars, const TStringArray& ARA_SearchArray, ZNsEnum::ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over) */ + + public: + };/* + template< typename TTypeChars=ZNsType::ZtCTypeChars + > + class ZtCMainChars //////////////////////////////////////*/ + + + + namespace ZNsInterface + { + + template class ZtISearchCCharsEmpty + { + public: + typedef typename TCChars::TypeChar TypeChar ; + typedef typename TCChars::TypeLength TypeLength; + public: + typedef ZtISearchCCharsEmpty ZCNowObj ; + typedef ZtISearchCCharsEmpty ZCNextObj; + typedef ZtISearchCCharsEmpty ZCNodeObj; + public: + enum{EBoolNextObj=0}; + public: + int GetLength (const TypeChar*, TypeLength) const{return 0;} + int GetRepeatCntMin () const{return 0;} + int GetRepeatCntMax () const{return 0;} + int GetSearchCharMin() const{return 0;} + int GetSearchCharMax() const{return 0;} + int GetSearchSumMin () const{return 0;} + int GetSearchSumMax () const{return 0;} + + ZNsEnum::ZERegFlag GetERegFlag () const{return ZNsEnum::ZERegFlag_Nothing;} + ZNsEnum::ZESearchMax GetESearchMax() const{return ZNsEnum::ZESearchMax_Over ;} + + ZtISearchCCharsEmpty& GetNowObj (){return *this;} + ZtISearchCCharsEmpty& GetNextObj(){return *this;} + ZtISearchCCharsEmpty& GetSubObj (){return *this;} + + const ZtISearchCCharsEmpty& GetNowObj ()const{return *this;} + const ZtISearchCCharsEmpty& GetNextObj()const{return *this;} + const ZtISearchCCharsEmpty& GetSubObj ()const{return *this;} + public: + };/* + template class ZtISearchCCharsEmpty*/ + + }/* + namespace ZNsInterface*/ + + + #define _ISEARCH_CCHARS_EMPTY_ ZNsIFace::ZtISearchCCharsEmpty + + template< typename TCharsArr , + typename TNextObj =_ISEARCH_CCHARS_EMPTY_, // ZNsIFace::ZtISearchCCharsEmpty, ZtCSearchCChars<>, etc + bool TBoolNextObj=false + > + class ZtCSearchCChars : public TNextObj + { + public : + enum{EBoolNextObj=(int)TBoolNextObj} ; + public : + typedef ZtCSearchCChars ZCSearchCChars; + typedef ZtCSearchCChars ZCNowObj ; // cf) std::NsTmplChain::CTmplChain_T<> + typedef TNextObj ZCNextObj ; + public : + typedef TCharsArr ZCCharsArr ; + typedef ZNsEnum::ZERegFlag ZERegFlag ; + typedef ZNsEnum::ZESearchMax ZESearchMax ; + public : + typedef typename TCharsArr::TypeData ZCChars ; + typedef typename ZCChars ::ZCTypeChars ZCTypeChars; + typedef typename ZCChars ::TypeChar TypeChar ; + typedef typename ZCChars ::TypeCharC TypeCharC ; + typedef typename ZCChars ::TypeLength TypeLength ; + typedef ZtCMainChars ZCMainChars; + protected: + + int mi_RepeatCntMin ; + int mi_RepeatCntMax ; + + int mi_SearchCharMin; // enum ZERegErr ּ . + int mi_SearchCharMax; + + int mi_SearchSumMin ; // enum ZERegErr ּ . + int mi_SearchSumMax ; + + ZERegFlag me_ERegFlag ; + ZESearchMax me_ESearchMax; + ZCCharsArr mo_CCharsArr ; + + /*protected:*/ + protected: + + /*/////////////////////////////////////////////////////////////////////////////// + + Ʒ 2 ZtCSearchCChars<> ̳ʿ ǹ̰ ִ. + + int mi_SearchSumMin; + int mi_SearchSumMax; + + ZtCSearchCChars<> ̳ Ҹ ȸϸ鼭, ã ̸ ϰ + Ǵµ, ̶ ϴ ϴ ̴. + + -- 2011-10-02 18:52:00 + + ///////////////////////////////////////////////////////////////////////////////*/ + + /*protected:*/ + public : + + ZtCSearchCChars() + { + Init(); + }/* + ZtCSearchCChars()*/ + + ZtCSearchCChars(int AI_RepeatCntMin , int AI_RepeatCntMax , + int AI_SearchCharMin, int AI_SearchCharMax, + int AI_SearchSumMin , int AI_SearchSumMax , + ZERegFlag AE_ERegFlag, ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over + /*//////////*/ ) + { + Init(AI_RepeatCntMin, AI_RepeatCntMax, AI_SearchCharMin, AI_SearchCharMax, AI_SearchSumMin, AI_SearchSumMax, AE_ERegFlag, AE_ESearchMax); + }/* + ZtCSearchCChars(int AI_RepeatCntMin , int AI_RepeatCntMax , + int AI_SearchCharMin, int AI_SearchCharMax, + int AI_SearchSumMin , int AI_SearchSumMax , + ZERegFlag AE_ERegFlag, ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over + ////////////// ) */ + + + void Init() + { + mi_RepeatCntMin =0; + mi_RepeatCntMax =0; + mi_SearchCharMin=0; + mi_SearchCharMax=0; + mi_SearchSumMin =0; + mi_SearchSumMax =0; + me_ERegFlag =ZNsEnum::ZERegFlag_Nothing; + me_ESearchMax =ZNsEnum::ZESearchMax_Over ; + }/* + void Init()*/ + + void Init ( int AI_RepeatCntMin , int AI_RepeatCntMax , + int AI_SearchCharMin, int AI_SearchCharMax, + int AI_SearchSumMin , int AI_SearchSumMax , + ZERegFlag AE_ERegFlag, ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over + /*///////*/ ) + { + mi_RepeatCntMin =AI_RepeatCntMin ; + mi_RepeatCntMax =AI_RepeatCntMax ; + mi_SearchCharMin=AI_SearchCharMin; + mi_SearchCharMax=AI_SearchCharMax; + mi_SearchSumMin =AI_SearchSumMin ; + mi_SearchSumMax =AI_SearchSumMax ; + me_ERegFlag =AE_ERegFlag ; + me_ESearchMax =AE_ESearchMax ; + }/* + void Init ( int AI_RepeatCntMin , int AI_RepeatCntMax , + int AI_SearchCharMin, int AI_SearchCharMax, + int AI_SearchSumMin , int AI_SearchSumMax , + ZERegFlag AE_ERegFlag, ZESearchMax AE_ESearchMax=ZNsEnum::ZESearchMax_Over + /////////// ) */ + + + ZtCSearchCChars& GetNowObj() {return *this;} + const ZtCSearchCChars& GetNowObj() const{return *this;} + + ZCNextObj& GetNextObj() {return static_cast< ZCNextObj&>(*this);} + const ZCNextObj& GetNextObj() const{return static_cast(*this);} + + ZCCharsArr& GetCCharsArr() {return mo_CCharsArr;} + const ZCCharsArr& GetCCharsArr() const{return mo_CCharsArr;} + + int GetRepeatCntMin () const{return mi_RepeatCntMin ;} + int GetRepeatCntMax () const{return mi_RepeatCntMax ;} + int GetSearchCharMin() const{return mi_SearchCharMin;} + int GetSearchCharMax() const{return mi_SearchCharMax;} + int GetSearchSumMin () const{return mi_SearchSumMin ;} + int GetSearchSumMax () const{return mi_SearchSumMax ;} + + ZERegFlag GetERegFlag () const{return me_ERegFlag ;} + ZESearchMax GetESearchMax() const{return me_ESearchMax;} + + + TypeLength GetLength(TypeCharC* APC_Origin, TypeLength AL_Length) const + { + switch(me_ERegFlag) + { + case ZNsEnum::ZERegFlag_Permit : return ZCMainChars::GetLength_Repeat_Permit (mi_RepeatCntMin, mi_RepeatCntMax, APC_Origin, AL_Length, mo_CCharsArr, me_ESearchMax); + case ZNsEnum::ZERegFlag_PermitRange : return ZCMainChars::GetLength_Repeat_PermitRange (mi_RepeatCntMin, mi_RepeatCntMax, APC_Origin, AL_Length, mo_CCharsArr, me_ESearchMax); + case ZNsEnum::ZERegFlag_PermitChar : return ZCMainChars::GetLength_Repeat_PermitChar (mi_RepeatCntMin, mi_RepeatCntMax, APC_Origin, AL_Length, mo_CCharsArr, me_ESearchMax); + case ZNsEnum::ZERegFlag_PermitCharRange : return ZCMainChars::GetLength_Repeat_PermitCharRange (mi_RepeatCntMin, mi_RepeatCntMax, APC_Origin, AL_Length, mo_CCharsArr, me_ESearchMax); + case ZNsEnum::ZERegFlag_NoPermit : return ZCMainChars::GetLength_Repeat_NoPermit (mi_RepeatCntMin, mi_RepeatCntMax, APC_Origin, AL_Length, mo_CCharsArr, me_ESearchMax); + case ZNsEnum::ZERegFlag_NoPermitRange : return ZCMainChars::GetLength_Repeat_NoPermitRange (mi_RepeatCntMin, mi_RepeatCntMax, APC_Origin, AL_Length, mo_CCharsArr, me_ESearchMax); + case ZNsEnum::ZERegFlag_NoPermitChar : return ZCMainChars::GetLength_Repeat_NoPermitChar (mi_RepeatCntMin, mi_RepeatCntMax, APC_Origin, AL_Length, mo_CCharsArr, me_ESearchMax); + case ZNsEnum::ZERegFlag_NoPermitCharRange : return ZCMainChars::GetLength_Repeat_NoPermitCharRange(mi_RepeatCntMin, mi_RepeatCntMax, APC_Origin, AL_Length, mo_CCharsArr, me_ESearchMax); + case ZNsEnum::ZERegFlag_Find : return ZCMainChars::GetLength_Repeat_Find (mi_RepeatCntMin, mi_RepeatCntMax, APC_Origin, AL_Length, mo_CCharsArr, me_ESearchMax); + case ZNsEnum::ZERegFlag_FindChar : return ZCMainChars::GetLength_Repeat_FindChar (mi_RepeatCntMin, mi_RepeatCntMax, APC_Origin, AL_Length, mo_CCharsArr, me_ESearchMax); + case ZNsEnum::ZERegFlag_FindSerial : return ZCMainChars::GetLength_Repeat_FindSerial (mi_RepeatCntMin, mi_RepeatCntMax, APC_Origin, AL_Length, mo_CCharsArr, me_ESearchMax); + case ZNsEnum::ZERegFlag_FindSerialChar : return ZCMainChars::GetLength_Repeat_FindSerialChar (mi_RepeatCntMin, mi_RepeatCntMax, APC_Origin, AL_Length, mo_CCharsArr, me_ESearchMax); + case ZNsEnum::ZERegFlag_FindEscape : return ZCMainChars::GetLength_Repeat_FindEscape (mi_RepeatCntMin, mi_RepeatCntMax, APC_Origin, AL_Length, mo_CCharsArr, me_ESearchMax); + case ZNsEnum::ZERegFlag_StartFind : return ZCMainChars::GetLength_Repeat_StartFind (mi_RepeatCntMin, mi_RepeatCntMax, APC_Origin, AL_Length, mo_CCharsArr, me_ESearchMax); + case ZNsEnum::ZERegFlag_StartFindChar : return ZCMainChars::GetLength_Repeat_StartFindChar (mi_RepeatCntMin, mi_RepeatCntMax, APC_Origin, AL_Length, mo_CCharsArr, me_ESearchMax); + }/* + switch(me_ERegFlag)*/ + + return 0; + }/* + TypeLength GetLength(TypeCharC* APC_Origin, TypeLength AL_Length) const*/ + + template TypeLength GetLength(const TCChars& AR_CChars) const + { + return GetLength(AR_CChars.data(), AR_CChars.size()); + }/* + template TypeLength GetLength(const TCChars& AR_CChars) const */ + + TypeLength GetLengthEx + ( + ZNsEnum::ZERegErr& ARRE_ZERegErr, + TypeCharC* APC_Origin , TypeLength AL_Length + ) const + /*##################*/ + { + TypeLength VL_Length = + GetLength(APC_Origin, AL_Length); + + ARRE_ZERegErr=ZNsEnum::ZERegErr_None; + + const bool CB_IsTrue = ( + VL_Length 0 && VL_Length>mi_SearchCharMax) + ); + + if(CB_IsTrue) + ARRE_ZERegErr=ZNsEnum::ZERegErr_CharCount; + + return VL_Length; + }/* + TypeLength GetLengthEx + ( + ZNsEnum::ZERegErr& ARRE_ZERegErr, + TypeCharC* APC_Origin , TypeLength AL_Length + ) const + ////////////////////*/ + + template TypeLength + GetLengthEx(ZNsEnum::ZERegErr& ARRE_ZERegErr, const TCChars& AR_CChars) const + { + return GetLengthEx(RR(ARRE_ZERegErr), AR_CChars.data(), AR_CChars.size()); + }/* + template TypeLength + GetLengthEx(ZNsEnum::ZERegErr& ARRE_ZERegErr, const TCChars& AR_CChars) const */ + + + template + static TypeLength GetLengthByCSearchCCharsArr + ( + const TSearchCCharsArr& AR_CSearchCCharsArr , + ZNsEnum::ZERegErr& ARRE_ZERegErr , + TypeCharC* APC_Origin , + TypeLength AL_Length + ) + /*#################################################*/ + { + typedef typename TSearchCCharsArr::iterator iterator; + typedef typename TSearchCCharsArr::TypeData TypeData; + + const iterator VO_iterator(AR_CSearchCCharsArr.begin()); + + TypeLength VL_SearchSum=0; + TypeLength VL_SearchNow=0; + int VI_ArrSize =AR_CSearchCCharsArr.size(); + + if(VI_ArrSize<1) return 0; + + for(int i=0; i0 && VL_SearchNow>VR_CSearchCChars.GetSearchCharMax())) + { + ARRE_ZERegErr=ZNsEnum::ZERegErr_CharCount; return 0; + } + if(VL_SearchSum0 && VL_SearchSum>VR_CSearchCChars.GetSearchSumMax ())) + { + ARRE_ZERegErr=ZNsEnum::ZERegErr_CharSum ; return 0; + }/* + if(VL_SearchSum0 && VL_SearchSum>VR_CSearchCChars.GetSearchSumMax ()))*/ + + /*/////////////////////////////////////////////////////// + + if(AL_Length<=VL_SearchSum) return VL_SearchSum; + + ڵ带 ּ ´. ǿ , + ã ڿ ̰ 0 ִ ̴. + + -- 2011-08-05 16:30:00 + + ///////////////////////////////////////////////////////*/ + + AR_CSearchCCharsArr.MoveNextIter(VO_iterator); + }/* + for(int i=0; i + static TypeLength GetLengthByCSearchCCharsArr + ( + const TSearchCCharsArr& AR_CSearchCCharsArr , + ZNsEnum::ZERegErr& ARRE_ZERegErr , + TypeCharC* APC_Origin , + TypeLength AL_Length + ) + ///////////////////////////////////////////////////*/ + + template + static TypeLength GetLengthByCSearchCCharsArr + ( + const TSearchCCharsArr& AR_CSearchCCharsArr , + ZNsEnum::ZERegErr& ARRE_ZERegErr , + const TCChars& AR_CChars + ) + /*#################################################*/ + { + return GetLengthByCSearchCCharsArr( + AR_CSearchCCharsArr, RR(ARRE_ZERegErr), AR_CChars.data(), AR_CChars.size() ); + }/* + template + static TypeLength GetLengthByCSearchCCharsArr + ( + const TSearchCCharsArr& AR_CSearchCCharsArr , + ZNsEnum::ZERegErr& ARRE_ZERegErr , + const TCChars& AR_CChars + ) + ///////////////////////////////////////////////////*/ + + public: + };/* + template< typename TCharsArr , + typename TNextObj =_ISEARCH_CCHARS_EMPTY_, // ZNsIFace::ZtISearchCCharsEmpty, ZtCSearchCChars<>, etc + bool TBoolNextObj=false + > + class ZtCSearchCChars /////////////////////////////////*/ + + + template< typename TCharsArr , + typename TNextObj =_ISEARCH_CCHARS_EMPTY_, // ZNsIFace::ZtISearchCCharsEmpty, ZtCSearchCChars<>, etc + typename TSubObj =_ISEARCH_CCHARS_EMPTY_, // ZNsIFace::ZtISearchCCharsEmpty, ZtCSearchCChars<>, etc + bool TBoolNextObj=false + > + class ZtCSearchCCharsEx : public ZtCSearchCChars + { + public : + enum{EBoolNextObj=(int)TBoolNextObj}; + public : + typedef ZtCSearchCChars ZCSearchCChars; + public : + typedef ZCSearchCChars ZCNowObj ; + typedef TNextObj ZCNextObj; + typedef TSubObj CSubObj ; + private: + CSubObj mo_CSubObj; + public : + /***/ CSubObj& GetCSubObj() {return mo_CSubObj;} + const CSubObj& GetCSubObj()const{return mo_CSubObj;} + public : + };/* + template< typename TCharsArr , + typename TNextObj =_ISEARCH_CCHARS_EMPTY_, // ZNsIFace::ZtISearchCCharsEmpty, ZtCSearchCChars<>, etc + typename TSubObj =_ISEARCH_CCHARS_EMPTY_, // ZNsIFace::ZtISearchCCharsEmpty, ZtCSearchCChars<>, etc + bool TBoolNextObj=false + > + class ZtCSearchCCharsEx */ + + + #undef _ISEARCH_CCHARS_EMPTY_ // ZNsIFace::ZtISearchCCharsEmpty + + + namespace ZNsType + { + + template< ZTypLength TIntCode , // 'A' L'' ü ڰ ´. + typename TTypeChar=char, + typename TCharCInt=char // TTypeChar ǥ ִ ڷ̴. + > + class ZtCTypeCharChain + { + public: + typedef TTypeChar TypeChar; + typedef TCharCInt TypeCInt; + public: + typedef const TTypeChar TypeCharC; + public: + enum{ZETypeCharTmplChain=ZNsEnum::ZETypeCharTmplChain_Char}; + public: + static TypeCInt GetCInt(){return (TypeCInt)TIntCode;} + static TypeChar GetChar(){return (TypeChar)TIntCode;} + public: + static bool DoHave(TypeChar AC_Char){return AC_Char==(TypeChar)TIntCode;} + public: + };/* + template< ZTypLength TIntCode , // 'A' L'' ü ڰ ´. + typename TTypeChar=char, + typename TCharCInt =char // TTypeChar ǥ ִ ڷ̴. + > + class ZtCTypeCharChain */ + + + // ZtCTypeChar2Chain<> 2 Ÿ. + + template< ZTypLength TIntCode1 , // 'A' L'' ü ڰ ´. + ZTypLength TIntCode2 , // 'A' L'' ü ڰ ´. + typename TTypeChar=char, + typename TCharCInt=char // TTypeChar ǥ ִ ڷ̴. + > + class ZtCTypeChar2Chain + { + public: + typedef TTypeChar TypeChar; + typedef TCharCInt TypeCInt; + public: + typedef const TTypeChar TypeCharC; + public: + enum{ZETypeCharTmplChain=ZNsEnum::ZETypeCharTmplChain_Char2}; + public: + static TypeCInt GetCInt1(){return (TypeCInt)TIntCode1;} + static TypeCInt GetCInt2(){return (TypeCInt)TIntCode2;} + static TypeChar GetChar1(){return (TypeChar)TIntCode1;} + static TypeChar GetChar2(){return (TypeChar)TIntCode2;} + public: + static bool DoHave(TypeChar AC_Char) + { + return AC_Char>=(TypeChar)TIntCode1 && AC_Char<=(TypeChar)TIntCode2; + }/* + static bool DoHave(TypeChar AC_Char)*/ + public: + };/* + template< ZTypLength TIntCode1 , // 'A' L'' ü ڰ ´. + ZTypLength TIntCode2 , // 'A' L'' ü ڰ ´. + typename TTypeChar=char, + typename TCharCInt=char // TTypeChar ǥ ִ ڷ̴. + > + class ZtCTypeChar2Chain */ + + + template< typename TTypeChar=char, + typename TCharCInt=char // TTypeChar ǥ ִ ڷ̴. + > + class ZtCTypeCharChainEach + { + public: + + typedef ZtCTypeCharChain CTypeCharTmplChainOfA; + typedef ZtCTypeCharChain CTypeCharTmplChainOfB; + typedef ZtCTypeCharChain CTypeCharTmplChainOfC; + typedef ZtCTypeCharChain CTypeCharTmplChainOfD; + typedef ZtCTypeCharChain CTypeCharTmplChainOfE; + typedef ZtCTypeCharChain CTypeCharTmplChainOfF; + typedef ZtCTypeCharChain CTypeCharTmplChainOfG; + typedef ZtCTypeCharChain CTypeCharTmplChainOfH; + typedef ZtCTypeCharChain CTypeCharTmplChainOfI; + typedef ZtCTypeCharChain CTypeCharTmplChainOfJ; + typedef ZtCTypeCharChain CTypeCharTmplChainOfK; + typedef ZtCTypeCharChain CTypeCharTmplChainOfL; + typedef ZtCTypeCharChain CTypeCharTmplChainOfM; + typedef ZtCTypeCharChain CTypeCharTmplChainOfN; + typedef ZtCTypeCharChain CTypeCharTmplChainOfO; + typedef ZtCTypeCharChain CTypeCharTmplChainOfP; + typedef ZtCTypeCharChain CTypeCharTmplChainOfQ; + typedef ZtCTypeCharChain CTypeCharTmplChainOfR; + typedef ZtCTypeCharChain CTypeCharTmplChainOfS; + typedef ZtCTypeCharChain CTypeCharTmplChainOfT; + typedef ZtCTypeCharChain CTypeCharTmplChainOfU; + typedef ZtCTypeCharChain CTypeCharTmplChainOfV; + typedef ZtCTypeCharChain CTypeCharTmplChainOfW; + typedef ZtCTypeCharChain CTypeCharTmplChainOfX; + typedef ZtCTypeCharChain CTypeCharTmplChainOfY; + typedef ZtCTypeCharChain CTypeCharTmplChainOfZ; + + typedef ZtCTypeCharChain CTypeCharTmplChainOfa; + typedef ZtCTypeCharChain CTypeCharTmplChainOfb; + typedef ZtCTypeCharChain CTypeCharTmplChainOfc; + typedef ZtCTypeCharChain CTypeCharTmplChainOfd; + typedef ZtCTypeCharChain CTypeCharTmplChainOfe; + typedef ZtCTypeCharChain CTypeCharTmplChainOff; + typedef ZtCTypeCharChain CTypeCharTmplChainOfg; + typedef ZtCTypeCharChain CTypeCharTmplChainOfh; + typedef ZtCTypeCharChain CTypeCharTmplChainOfi; + typedef ZtCTypeCharChain CTypeCharTmplChainOfj; + typedef ZtCTypeCharChain CTypeCharTmplChainOfk; + typedef ZtCTypeCharChain CTypeCharTmplChainOfl; + typedef ZtCTypeCharChain CTypeCharTmplChainOfm; + typedef ZtCTypeCharChain CTypeCharTmplChainOfn; + typedef ZtCTypeCharChain CTypeCharTmplChainOfo; + typedef ZtCTypeCharChain CTypeCharTmplChainOfp; + typedef ZtCTypeCharChain CTypeCharTmplChainOfq; + typedef ZtCTypeCharChain CTypeCharTmplChainOfr; + typedef ZtCTypeCharChain CTypeCharTmplChainOfs; + typedef ZtCTypeCharChain CTypeCharTmplChainOft; + typedef ZtCTypeCharChain CTypeCharTmplChainOfu; + typedef ZtCTypeCharChain CTypeCharTmplChainOfv; + typedef ZtCTypeCharChain CTypeCharTmplChainOfw; + typedef ZtCTypeCharChain CTypeCharTmplChainOfx; + typedef ZtCTypeCharChain CTypeCharTmplChainOfy; + typedef ZtCTypeCharChain CTypeCharTmplChainOfz; + + typedef ZtCTypeCharChain CTypeCharTmplChainOf0; + typedef ZtCTypeCharChain CTypeCharTmplChainOf1; + typedef ZtCTypeCharChain CTypeCharTmplChainOf2; + typedef ZtCTypeCharChain CTypeCharTmplChainOf3; + typedef ZtCTypeCharChain CTypeCharTmplChainOf4; + typedef ZtCTypeCharChain CTypeCharTmplChainOf5; + typedef ZtCTypeCharChain CTypeCharTmplChainOf6; + typedef ZtCTypeCharChain CTypeCharTmplChainOf7; + typedef ZtCTypeCharChain CTypeCharTmplChainOf8; + typedef ZtCTypeCharChain CTypeCharTmplChainOf9; + + typedef ZtCTypeCharChain CTypeCharTmplChainOfSpace ; // space bar + typedef ZtCTypeCharChain CTypeCharTmplChainOfTab ; // horizontal tab + typedef ZtCTypeCharChain CTypeCharTmplChainOfLF ; // line feed() + typedef ZtCTypeCharChain CTypeCharTmplChainOfCR ; // carriage return() + typedef ZtCTypeCharChain CTypeCharTmplChainOfGraAcc ; // grave accent + typedef ZtCTypeCharChain CTypeCharTmplChainOfTilde ; // tilde, swung dash + typedef ZtCTypeCharChain CTypeCharTmplChainOfExcMark ; // exclamation mark + typedef ZtCTypeCharChain CTypeCharTmplChainOfAt ; // at sign + typedef ZtCTypeCharChain CTypeCharTmplChainOfHash ; // number sign/pound/hash + typedef ZtCTypeCharChain CTypeCharTmplChainOfDollar ; // dollar sign + typedef ZtCTypeCharChain CTypeCharTmplChainOfPercent ; + typedef ZtCTypeCharChain CTypeCharTmplChainOfCaret ; // caret + typedef ZtCTypeCharChain CTypeCharTmplChainOfAmper ; // ampersand + typedef ZtCTypeCharChain CTypeCharTmplChainOfAster ; // asterisk + typedef ZtCTypeCharChain CTypeCharTmplChainOfRoundB ; // round brackets, open brackets, brackets (UK), or parentheses + typedef ZtCTypeCharChain CTypeCharTmplChainOfRoundB2 ; + typedef ZtCTypeCharChain CTypeCharTmplChainOfSquareB ; // square brackets, closed brackets, or brackets (US) + typedef ZtCTypeCharChain CTypeCharTmplChainOfSquareB2 ; + typedef ZtCTypeCharChain' ),TTypeChar,TCharCInt> CTypeCharTmplChainOfMoreThan ; // inequality signs, brakets + typedef ZtCTypeCharChain CTypeCharTmplChainOfLessThan ; // inequality signs, brakets + typedef ZtCTypeCharChain CTypeCharTmplChainOfBrace ; // curly brackets, definite brackets, swirly brackets, curly braces, birdie brackets, Scottish brackets, squirrelly brackets, braces, gullwings, fancy brackets, or squiggly brackets + typedef ZtCTypeCharChain CTypeCharTmplChainOfBrace2 ; + typedef ZtCTypeCharChain CTypeCharTmplChainOfHyphen ; // hyphen + typedef ZtCTypeCharChain CTypeCharTmplChainOfUnderSco ; // underscore, understrike, low line, low dash + typedef ZtCTypeCharChain CTypeCharTmplChainOfPlus ; // plus sign + typedef ZtCTypeCharChain CTypeCharTmplChainOfEquals ; // equality sign, equals sign + typedef ZtCTypeCharChain CTypeCharTmplChainOfVertical ; // vertical bar + typedef ZtCTypeCharChain CTypeCharTmplChainOfBackslash; // backslash, reverse solidus + typedef ZtCTypeCharChain CTypeCharTmplChainOfSemiColon; + typedef ZtCTypeCharChain CTypeCharTmplChainOfColon ; + typedef ZtCTypeCharChain CTypeCharTmplChainOfApostrop ; // apostrophe + typedef ZtCTypeCharChain CTypeCharTmplChainOfQuotation; // quotation mark + typedef ZtCTypeCharChain CTypeCharTmplChainOfComma ; // comma + typedef ZtCTypeCharChain CTypeCharTmplChainOfPeriod ; // period + typedef ZtCTypeCharChain CTypeCharTmplChainOfQuestion ; // question mark + typedef ZtCTypeCharChain CTypeCharTmplChainOfSlash ; // slash, solidus + + typedef ZtCTypeChar2Chain CTypeChar2TmplChainOfaz; + typedef ZtCTypeChar2Chain CTypeChar2TmplChainOfAZ; + typedef ZtCTypeChar2Chain CTypeChar2TmplChainOf09; + + public: + };/* + template< typename TTypeChar=char, + typename TCharCInt=char // TTypeChar ǥ ִ ڷ̴. + > + class ZtCTypeCharChainEach */ + + }/* + namespace ZNsType*/ + + + /*/////////////////////////////////////////////////////////// + + typename TTypeCharChain + + ZNsType::ZtCTypeCharChain<> + ZNsType::ZtCTypeChar2Chain<> + ZNsType::ZtCTypeCharChainEach<>::CTypeCharTmplChainOf~ + ZNsType::ZtCTypeCharChainEach<>::CTypeChar2TmplChainOf~ + + ִ. + + -- 2011-10-09 05:27:00 + + ///////////////////////////////////////////////////////////*/ + + template< typename TTypeCharChain, + typename TNextCharChain, + typename TNextCharChain2 + > + class ZtCCharChain ///////////////// + { + public: + typedef TTypeCharChain TypeCharChain ; + typedef TNextCharChain ZCNextObj ; + typedef TNextCharChain2 ZCNextObj2; + typedef typename TypeCharChain::TTypeChar TypeChar ; + typedef typename TypeCharChain::TCharCInt TypeCInt ; + public: + typedef const TypeChar TypeCharC; + public: + enum{ENextObjNo =ZCNextObj ::ENextObjNo +1}; + enum{ENextObjNo2 =ZCNextObj2::ENextObjNo2+1}; + enum{EObjChainCnt =ZCNextObj ::EObjChainCnt+ZCNextObj2::EObjChainCnt+2}; + enum{EBoolNextObj =1}; + enum{EBoolNextObj2=1}; + public: + static bool DoHave(TypeChar AC_Char){return TypeCharChain::DoHave(AC_Char);} + public: + };/* + template< typename TTypeCharChain, + typename TNextCharChain, + typename TNextCharChain2 + > + class ZtCCharChain ///////////////*/ + + template< typename TTypeCharChain, /////////////////////////////// + typename TNextCharChain + > + class ZtCCharChain + { + public: + typedef TTypeCharChain TypeCharChain ; + typedef TNextCharChain ZCNextObj ; + typedef TNextCharChain ZCNextObj2; // interface ȣȯ ؼ . + typedef typename TypeCharChain::TTypeChar TypeChar ; + typedef typename TypeCharChain::TCharCInt TypeCInt ; + public: + typedef const TypeChar TypeCharC; + public: + enum{ENextObjNo =ZCNextObj::ENextObjNo+1}; + enum{ENextObjNo2 =0}; + enum{EBoolNextObj =1}; + enum{EBoolNextObj2=0}; + enum{EObjChainCnt =ZCNextObj::EObjChainCnt+1}; + public: + static bool DoHave(TypeChar AC_Char){return TypeCharChain::DoHave(AC_Char);} + public: + };/* + template< typename TTypeCharChain, ////////////////////////////////// + typename TNextCharChain + > + class ZtCCharChain */ + + template< typename TTypeCharChain, //////////////////////////////// + typename TNextCharChain2 + > + class ZtCCharChain + { + public: + typedef TTypeCharChain TypeCharChain ; + typedef TNextCharChain2 ZCNextObj ; // interface ȣȯ ؼ . + typedef TNextCharChain2 ZCNextObj2; + typedef typename TypeCharChain::TTypeChar TypeChar ; + typedef typename TypeCharChain::TCharCInt TypeCInt ; + public: + typedef const TypeChar TypeCharC; + public: + enum{ENextObjNo =0}; + enum{ENextObjNo2 =ZCNextObj2::ENextObjNo2+1}; + enum{EBoolNextObj =0}; + enum{EBoolNextObj2=1}; + enum{EObjChainCnt =ZCNextObj2::EObjChainCnt+1}; + public: + static bool DoHave(TypeChar AC_Char){return TypeCharChain::DoHave(AC_Char);} + public: + };/* + template< typename TTypeCharChain, /////////////////////////////////// + typename TNextCharChain2 + > + class ZtCCharChain */ + + template class ZtCCharChain + < TTypeCharChain, ZNsMain::ZCEmpty, ZNsMain::ZCEmpty > + { + public: + typedef ZtCCharChain< ////////////////////////////// + TTypeCharChain , + ZNsMain::ZCEmpty, + ZNsMain::ZCEmpty + /*/////////*/ > CCharChain; //////////////////////// + public: + typedef TTypeCharChain TypeCharChain ; + typedef CCharChain ZCNextObj ; // interface ȣȯ ؼ . + typedef CCharChain ZCNextObj2; // interface ȣȯ ؼ . + typedef typename TypeCharChain::TTypeChar TypeChar ; + typedef typename TypeCharChain::TCharCInt TypeCInt ; + public: + typedef const TypeChar TypeCharC; + public: + enum{ENextObjNo =0}; + enum{ENextObjNo2 =0}; + enum{EBoolNextObj =0}; + enum{EBoolNextObj2=0}; + enum{EObjChainCnt =1}; + public: + static bool DoHave(TypeChar AC_Char){return TypeCharChain::DoHave(AC_Char);} + public: + };/* + template class ZtCCharChain + < TTypeCharChain, ZNsMain::ZCEmpty, ZNsMain::ZCEmpty > */ + + + template< typename TTypeChars=ZNsType::ZtCTypeChars + > + class ZtCSearchCursor ///////////////////////////////////// + { + public : + typedef TTypeChars ZCTypeChars; + typedef ZtCMainChars ZCMainChars; + typedef typename ZCTypeChars::ZCChars ZCChars ; + typedef typename ZCTypeChars::TypeChar TypeChar ; + typedef typename ZCTypeChars::TypeCharC TypeCharC ; + typedef typename ZCTypeChars::TypeLength TypeLength ; + private: + TypeChar* mpc_OriginChar; + TypeLength ml_OriginLen ; + TypeLength ml_SearchPos ; + TypeLength ml_SearchLen ; + public : + + ZtCSearchCursor() + { + Init(); + }/* + ZtCSearchCursor()*/ + + void Init() + { + mpc_OriginChar=0; + ml_OriginLen =0; + ml_SearchPos =0; + ml_SearchLen =0; + }/* + void Init()*/ + + void InitSearch() + { + ml_SearchPos =0; + ml_SearchLen =0; + }/* + void InitSearch()*/ + + void InitOrigin(TypeChar* APC_Origin, TypeLength AL_Length) + { + mpc_OriginChar=APC_Origin; + ml_OriginLen =AL_Length ; + }/* + void InitOrigin(TypeChar* APC_Origin, TypeLength AL_Length)*/ + + void InitOrigin(ZCChars& AR_CCharsOrigin) + { + mpc_OriginChar=AR_CCharsOrigin.data(); + ml_OriginLen =AR_CCharsOrigin.size(); + }/* + void InitOrigin(ZCChars& AR_CCharsOrigin)*/ + + void InitOrigin(const ZCChars& AR_CCharsOrigin) + { + mpc_OriginChar=const_cast(AR_CCharsOrigin.data()); + ml_OriginLen = AR_CCharsOrigin.size() ; + }/* + void InitOrigin(const ZCChars& AR_CCharsOrigin)*/ + + TypeChar* GetOriginData() + { + return mpc_OriginChar; + }/* + TypeChar* GetOriginData()*/ + + TypeCharC* GetOriginData() const + { + return mpc_OriginChar; + }/* + TypeCharC* GetOriginData() const*/ + + + TypeLength GetOriginLen() const{return ml_OriginLen ;} + TypeLength GetRemainLen() const{return ml_OriginLen-ml_SearchPos;} + + + void AddSearchPos() + { + ml_SearchPos+=ml_SearchLen; + }/* + void AddSearchPos()*/ + + void AddSearchPos(TypeLength AL_AddSearchPos) + { + ml_SearchPos += AL_AddSearchPos ; + }/* + void AddSearchPos(TypeLength AL_AddSearchPos)*/ + + void AddInitSearchPos() + { + ml_SearchPos+=ml_SearchLen; ml_SearchLen=0; + }/* + void AddInitSearchPos()*/ + + + TypeLength GetSearchLen() const{return ml_SearchLen;} + TypeLength GetSearchPos() const{return ml_SearchPos;} + + void SetSearchLen(TypeLength AL_SearchLen) + { + if(AL_SearchLen>=0) ml_SearchLen=AL_SearchLen; + }/* + void SetSearchLen(TypeLength AL_SearchLen)*/ + + void SetSearchPos(TypeLength AL_SearchPos) + { + if(AL_SearchPos>=0) ml_SearchPos=AL_SearchPos; + }/* + void SetSearchPos(TypeLength AL_SearchPos)*/ + + void SetSearchPos() + { + ml_SearchPos=ml_SearchLen; + }/* + void SetSearchPos()*/ + + + bool DoStart(TypeCharC* APC_Search, TypeLength AL_Length) + { + return ZCMainChars::DoStart( + mpc_OriginChar+ml_SearchPos, APC_Search, ml_OriginLen-ml_SearchPos, AL_Length); + }/* + bool DoStart(TypeCharC* APC_Search, TypeLength AL_Length)*/ + + template bool DoStart(const TCChars& AR_CChars) + { + return DoStart(AR_CChars.data(), AR_CChars.size()); + }/* + template bool DoStart(const TCChars& AR_CChars) */ + + TypeLength FindPos(TypeCharC* APC_Search,TypeLength AL_Length) + { + return ZCMainChars::FindPos( + mpc_OriginChar, APC_Search, ml_OriginLen, AL_Length, ml_SearchPos); + }/* + TypeLength FindPos(TypeCharC* APC_Search,TypeLength AL_Length)*/ + + template TypeLength FindPos(const TCChars& AR_CChars) + { + return FindPos(AR_CChars.data(), AR_CChars.size()); + }/* + template TypeLength FindPos(const TCChars& AR_CChars) */ + + TypeLength AddSearchByFind(TypeCharC* APC_Search, TypeLength AL_Length) + { + // APC_Search ã, ̸ Ѵ. + + TypeLength VL_FindPos = FindPos(APC_Search, AL_Length); + + if(VL_FindPos<0) return -1; + + return ml_SearchLen = VL_FindPos-ml_SearchPos; + }/* + TypeLength AddSearchByFind(TypeCharC* APC_Search, TypeLength AL_Length)*/ + + template bool AddSearchByFind(const TCChars& AR_CChars) + { + return AddSearchByFind(AR_CChars.data(), AR_CChars.size()); + }/* + template bool AddSearchByFind(const TCChars& AR_CChars) */ + + template + TypeLength AddSearchByCSearchCChars(const TSearchCChars& AR_CSearchCChars) + { + return ml_SearchLen += AR_CSearchCChars.GetLength + ( mpc_OriginChar+ml_SearchPos, ml_OriginLen-ml_SearchPos ); + }/* + template + TypeLength AddSearchByCSearchCChars(const TSearchCChars& AR_CSearchCChars) */ + + template + TypeLength AddSearchByTmplChain + ( + TChainStack& AR_CStackOfTmplChain, + const TTmplChain& AR_CTmplChain , + ZNsEnum::ZERegErr& ARRE_ZERegErr + ) + { + // TChainStack ZNsInterface::ZtCStackOfTmplChain<> interface ´. + + ml_SearchLen += GetLengthByTmplChain( + RR(AR_CStackOfTmplChain), AR_CTmplChain, RR(ARRE_ZERegErr)); + + return (ARRE_ZERegErr==ZNsEnum::ZERegErr_None) ? ml_SearchLen : 0 ; + }/* + template + TypeLength AddSearchByTmplChain + ( + TChainStack& AR_CStackOfTmplChain, + const TTmplChain& AR_CTmplChain , + ZNsEnum::ZERegErr& ARRE_ZERegErr + ) + /////////////////////////////////////////////////*/ + + template TypeLength + AddSearchByTmplChain(TTmplChain& AR_CTmplChain, ZNsEnum::ZERegErr& ARRE_ZERegErr) + { + ZNsInterface::ZtCStackOfTmplChain VO_CStackOfTmplChain; + + return AddSearchByTmplChain(VO_CStackOfTmplChain, AR_CTmplChain, RR(ARRE_ZERegErr)); + }/* + template TypeLength + AddSearchByTmplChain(TTmplChain& AR_CTmplChain, ZNsEnum::ZERegErr& ARRE_ZERegErr) */ + + + template + TypeLength AddSearchByTmplTreeChain + ( + TChainStack& AR_CStackOfTmplChain, + const TTmplTreeChain& AR_CTmplChain , + ZNsEnum::ZERegErr& ARRE_ZERegErr + ) + { + // TChainStack ZNsInterface::ZtCStackOfTmplChain<> interface ´. + + ml_SearchLen += GetLengthByTmplTreeChain( + RR(AR_CStackOfTmplChain), AR_CTmplChain, RR(ARRE_ZERegErr)); + + return (ARRE_ZERegErr==ZNsEnum::ZERegErr_None) ? ml_SearchLen : 0 ; + }/* + template + TypeLength AddSearchByTmplTreeChain + ( + TChainStack& AR_CStackOfTmplChain, + const TTmplTreeChain& AR_CTmplChain , + ZNsEnum::ZERegErr& ARRE_ZERegErr + ) + /////////////////////////////////////////////////////*/ + + template TypeLength AddSearchByTmplTreeChain + ( const TTmplTreeChain& AR_CTmplChain, ZNsEnum::ZERegErr& ARRE_ZERegErr ) + { + ZNsInterface:: + ZtCStackOfTmplChain VO_CStackOfTmplChain ; + + return AddSearchByTmplTreeChain( + VO_CStackOfTmplChain, AR_CTmplChain, RR(ARRE_ZERegErr) ); + }/* + template TypeLength AddSearchByTmplTreeChain + ( const TTmplTreeChain& AR_CTmplChain, ZNsEnum::ZERegErr& ARRE_ZERegErr ) */ + + + template + TypeLength GetLengthByTmplChain + ( + TChainStack& AR_CStackOfTmplChain, + const TTmplChain& AR_CTmplChain , + ZNsEnum::ZERegErr& ARRE_ZERegErr + ) + /*###############################################*/ + { + /*//////////////////////////////////////////////////////////////////////////// + + TTmplChain ڷδ ZtCSearchCChars<> ϴ. + + -- 2011-09-29 22:47:00 + + AR_CStackOfTmplChain Ƿ ؼ *this ʾƵ ȴ. + + -- 2013-06-26 01:56:00 + + ////////////////////////////////////////////////////////////////////////////*/ + + typedef typename TTmplChain::ZCNowObj ZCNowObj; + + const ZCNowObj& VR_CNowObj=AR_CTmplChain.GetNowObj(); + + TypeLength VL_LengthNow =VR_CNowObj.GetLength + ( + mpc_OriginChar+ml_SearchPos+AR_CStackOfTmplChain.GetSearchSum(), + ml_OriginLen -ml_SearchPos-AR_CStackOfTmplChain.GetSearchSum() + ); + ///////////////////////////////////////////// + + if(VL_LengthNow 0 && VL_LengthNow>VR_CNowObj.GetSearchCharMax())) + { + ARRE_ZERegErr=ZNsEnum::ZERegErr_CharCount; return 0; + } + if(AR_CStackOfTmplChain.GetSearchSum()0 && VL_LengthNow>VR_CNowObj.GetSearchSumMax ())) + { + ARRE_ZERegErr=ZNsEnum::ZERegErr_CharSum ; return 0; + }/* + if(AR_CStackOfTmplChain.GetSearchSum()0 && VL_LengthNow>VR_CNowObj.GetSearchSumMax ()))*/ + + AR_CStackOfTmplChain.AddSearchSum(VL_LengthNow); + + if(TTmplChain::EBoolNextObj<1) + return AR_CStackOfTmplChain.GetSearchSum() ; + + return VL_LengthNow + GetLengthByTmplChain( + AR_CStackOfTmplChain, AR_CTmplChain.GetNextObj(), RR(ARRE_ZERegErr)); + }/* + template + TypeLength GetLengthByTmplChain + ( + TChainStack& AR_CStackOfTmplChain, + const TTmplChain& AR_CTmplChain , + ZNsEnum::ZERegErr& ARRE_ZERegErr + ) + /////////////////////////////////////////////////*/ + + template TypeLength + GetLengthByTmplChain(TTmplChain& AR_CTmplChain, ZNsEnum::ZERegErr& ARRE_ZERegErr) + { + ZNsInterface::ZtCStackOfTmplChain VO_CStackOfTmplChain; + + return GetLengthByTmplChain(VO_CStackOfTmplChain, AR_CTmplChain, RR(ARRE_ZERegErr)); + }/* + template TypeLength + GetLengthByTmplChain(TTmplChain& AR_CTmplChain, ZNsEnum::ZERegErr& ARRE_ZERegErr) */ + + + template + TypeLength GetLengthByTmplTreeChain + ( + TChainStack& AR_CStackOfTmplChain, + const TTmplTreeChain& AR_CTmplTreeChain , + ZNsEnum::ZERegErr& ARRE_ZERegErr + ) + /////////////////////////////////////////////////////// + { + // ׽Ʈ ʿ. 2013-06-26 17:20:00 + + typedef typename TTmplTreeChain::ZCNowObj ZCNowObj; + + const ZCNowObj& VR_CNowObj=AR_CTmplTreeChain.GetNowObj(); + + if(VR_CNowObj.GetERegFlag()==ZNsEnum::ZERegFlag_BlockStart) + { + TChainStack VO_CChainStack; + ZNsEnum::ZERegErr VE_ZERegErr =ZNsEnum::ZERegErr_None; + TypeLength VL_LengthNow=0; + TypeLength VL_LengthSum=0; + TypeLength VL_SearchCnt=0; + + /*////////////////////////////////////////////////////////////////////////////////// + + *this ǵ帮 ʴ ٸ , AR_CStackOfTmplChain ̿ܿ + ZtCCharChain<> object ؼ ϸ Ǵµ, ? + + -- 2013-06-26 01:08:00 + + //////////////////////////////////////////////////////////////////////////////////*/ + + while(true) + { + // 'ȸ Block' Ͽ ã Ƚ VR_CNowObj.GetRepeatCntMax() + // ʴ while ݺѴ. + + VL_LengthNow=GetLengthByTmplTreeChain( /////// + RR(VO_CChainStack) , + AR_CTmplTreeChain.GetSubObj(), + RR(VE_ZERegErr) + /*/////////*/ ); ///////////////////////////// + + if(VE_ZERegErr!=ZNsEnum::ZERegErr_None) + { + AR_CStackOfTmplChain.AddSearchSum(-VL_LengthSum); break; + }/* + if(VE_ZERegErr!=ZNsEnum::ZERegErr_None)*/ + + ++VL_SearchCnt; VL_LengthSum+=VL_LengthNow; + + if(VR_CNowObj.GetESearchMax()==ZNsEnum::ZESearchMax_Stop) + { + if(VL_SearchCnt==VR_CNowObj.GetRepeatCntMax()) + { + AR_CStackOfTmplChain.AddSearchSum(-VL_LengthSum); break; + }/* + if(VL_SearchCnt==VR_CNowObj.GetRepeatCntMax())*/ + } + if(VR_CNowObj.GetRepeatCntMax()>0) + { + if(VL_SearchCnt>VR_CNowObj.GetRepeatCntMax()) + { + AR_CStackOfTmplChain.AddSearchSum(-VL_LengthSum); VL_LengthSum=0; break; + }/* + if(VL_SearchCnt>VR_CNowObj.GetRepeatCntMax())*/ + }/* + if(VR_CNowObj.GetRepeatCntMax()>0)*/ + + AR_CStackOfTmplChain.AddSearchSum(VL_LengthNow); + + if(ml_OriginLen<=ml_SearchPos+AR_CStackOfTmplChain.GetSearchSum()) + { + AR_CStackOfTmplChain.AddSearchSum(-VL_LengthSum); break; + }/* + if(ml_OriginLen<=ml_SearchPos+AR_CStackOfTmplChain.GetSearchSum())*/ + }/* + while(true)*/ + + + if(VL_SearchCnt0 && VL_LengthSum>VR_CNowObj.GetSearchCharMax() ) ; + + if(CB_IsCharCntErr) + { + ARRE_ZERegErr=ZNsEnum::ZERegErr_CharCount; return 0; + }/* + if(CB_IsCharCntErr)*/ + + + AR_CStackOfTmplChain.AddSearchSum(VL_LengthSum); + + const bool CB_IsCharSumErr= AR_CStackOfTmplChain.GetSearchSum()0 && AR_CStackOfTmplChain.GetSearchSum()>VR_CNowObj.GetSearchSumMax() ); + + if(CB_IsCharSumErr) + { + ARRE_ZERegErr=ZNsEnum::ZERegErr_CharSum; + + AR_CStackOfTmplChain. + AddSearchSum( -VL_LengthSum ); + + return 0; + }/* + if(CB_IsCharSumErr)*/ + + + if(TTmplTreeChain::EBoolNextObj<1) return VL_LengthSum; + + return VL_LengthSum + GetLengthByTmplTreeChain( + AR_CStackOfTmplChain, AR_CTmplTreeChain.GetNextObj(), RR(ARRE_ZERegErr)); + }/* + if (VR_CNowObj.GetERegFlag()==ZNsEnum::ZERegFlag_BlockStart)*/ + else if(VR_CNowObj.GetERegFlag()==ZNsEnum::ZERegFlag_BlockClose) + { + return 0; + }/* + else if(VR_CNowObj.GetERegFlag()==ZNsEnum::ZERegFlag_BlockClose)*/ + + + TypeLength VL_LengthNow = VR_CNowObj.GetLength + ( + mpc_OriginChar+ml_SearchPos+AR_CStackOfTmplChain.GetSearchSum(), + ml_OriginLen -ml_SearchPos-AR_CStackOfTmplChain.GetSearchSum() + ); + ////////////////////////////////////////////// + + if(VL_LengthNow 0 && VL_LengthNow>VR_CNowObj.GetSearchCharMax())) + { + ARRE_ZERegErr=ZNsEnum::ZERegErr_CharCount; return 0; + } + if(AR_CStackOfTmplChain.GetSearchSum()0 && VL_LengthNow>VR_CNowObj.GetSearchSumMax ())) + { + ARRE_ZERegErr=ZNsEnum::ZERegErr_CharSum ; return 0; + }/* + if(AR_CStackOfTmplChain.GetSearchSum()0 && VL_LengthNow>VR_CNowObj.GetSearchSumMax ()))*/ + + + AR_CStackOfTmplChain.AddSearchSum(VL_LengthNow); + + if(TTmplTreeChain::EBoolNextObj<1) return VL_LengthNow; + + return VL_LengthNow + GetLengthByTmplTreeChain( + AR_CStackOfTmplChain, AR_CTmplTreeChain.GetNextObj(), RR(ARRE_ZERegErr)); + }/* + template + TypeLength GetLengthByTmplTreeChain + ( + TChainStack& AR_CStackOfTmplChain, + const TTmplTreeChain& AR_CTmplTreeChain , + ZNsEnum::ZERegErr& ARRE_ZERegErr + ) + /////////////////////////////////////////////////////*/ + + template TypeLength GetLengthByTmplTreeChain + ( TTmplTreeChain& AR_CTmplChain, ZNsEnum::ZERegErr& ARRE_ZERegErr ) + { + ZNsInterface:: + ZtCStackOfTmplChain VO_CStackOfTmplChain; + + return GetLengthByTmplTreeChain( + VO_CStackOfTmplChain, AR_CTmplChain, RR(ARRE_ZERegErr)); + }/* + template TypeLength GetLengthByTmplTreeChain + ( TTmplTreeChain& AR_CTmplChain, ZNsEnum::ZERegErr& ARRE_ZERegErr ) */ + + public: + };/* + template< typename TTypeChars=ZNsType::ZtCTypeChars + > + class ZtCSearchCursor ///////////////////////////////////*/ + + + typedef ZNsType::ZtCTypeChars ZCTypeChars; + typedef ZtCMainChars ZCMainChars; + + }/* + namespace ZNsChars*/ + + + typedef ZNsChars ::ZCTypeChars ZCTypeChars; + typedef ZNsChars ::ZCMainChars ZCMainChars; + typedef ZCMainChars::ZCChars ZCChars ; + +}/* +namespace ZNsMain */ + + +#endif // __ZCPPMAIIN__ZTCMAINCHARS_H__ + + +/*///////////////////////////////////////////////////////////////////////////////////////// + + namespace ZNsChars ڿ Լ µ, MainChars.H ִ Լ + Ȯ强ְ Ͽ. ׷ ϱ⿡ ټ ϴ. ׸ ZtCMainChars.H Ŀ + MainChars.H ü ̴. + + -- 2011-07-10 03:48:00 + + ׷ Ʒ namespace std ߰ؼ, ϱ ߴ. + + typedef ZNsChars::ZCTypeChars ZCTypeChars; + typedef ZNsChars::ZCMainChars ZCMainChars; + + -- 2011-08-15 18:16:00 + + ZtCMainChars<>::DoStart() Լ ҹڸ θ, ZtCMainChars<> ø + ڿ bool Ϸ Ͽ, utf8 쿡 ġ Ƽ, + ⺻ ҹ ϴ Ѵ. ҹ ϰ , + ǥ object . + + -- 2011-07-12 07:14:00 + + 'char int Ȯ忡 ڵ' + + Ʒ Լ + + int ZtCMainChars<>::Minus(TypeCharC*, TypeCharC*, TypeLength, TypeLength) + + return + + return VC_Minus; // VC_Minus *(VP_Left-1)-*(VP_Right-1) + + + + return int(*(VP_Left-1))-int(*(VP_Right-1)); + + ƴ. Ϸ , char int Ȯϸ (+) ִ ̴. + ˾ҳĸ, LG CNS Ʈ . ׶ ELDK 4.0 tool chain + Ϸ ߴµ, NsUtility::CLoadSimUrlConfig_T<> о , + ν ϰ ־. CLoadSimUrlConfig_T<> ns1.cppschool.com + ns2.cppschool.com ׽Ʈ Ŭ̴. ׷ ̷ ߻ ̴. + Hemose ޽ ̷ ־µ, Ǯ + ſ ϰ ־. CObjAVL.H AddKey() Լ ϴ κп cout + ϱ, ׻ '>' ƴѰ. ׷ ZtCMainChars<>::Minus() Լ ĵ + ϴ ϱ ׻ ! ̷, ؾ Ѵ. ׷ + ׻ . ϱ, ش Ϸ, char int Ȯ忡 + ڵ带 ó ġ Ǿ. + + -- 2011-12-29 17:35:00 + +/////////////////////////////////////////////////////////////////////////////////////////*/ diff --git a/ZCppMain/ZtCObjAVL.H b/ZCppMain/ZtCObjAVL.H new file mode 100644 index 0000000..214d6ec --- /dev/null +++ b/ZCppMain/ZtCObjAVL.H @@ -0,0 +1,2483 @@ + + +#ifndef __ZNSMAIN_ZTOBJAVL_H__ +#define __ZNSMAIN_ZTOBJAVL_H__ + + +#include "ZCppMain/ZMainAVL.H" + + +namespace ZNsMain +{ + + /*///////////////////////////////////////////////////////////////////////////////////////// + + ■ 이 AVL tree 는 각 노드가 트리 구조를 이루며, 동시에 이중 원형 연결리스트를 이루고 있다. + 자료를 기본적으로 오름차순 정렬한다. + + ■ Type 자료형에는 <,>,== 연산이 가능해야 한다. + + ■ 어떤 클래스에 비교연산자를 정의할 때 bool operator>(const CStringHash& rhs) const 와 같 + 이 하면 인수에도 const, 멤버함수에도 const 를 잊지 말 것. + + ■ 접미어 Key 가 붙어있는 멤버 함수는 Type 보다는 크기가 작은 어떤 자료형이다. 삽입, 삭제 + 시에 메모리를 절약하기 위해서 사용한다. Type 자료형과 Key 자료형 사이에는 <,>,==,= 의 연 + 산이 가능해야 한다. + + ■ multi set 으로 활용하는 코드는 MainAVL.H 파일의 주석에 예시하였다. typename TNodeBase 를 + std::NsInterface::CAVL_Multi_NodeBase_T<> 으로 지정하고 있다. + + /////////////////////////////////////////////////////////////////////////////////////////*/ + + + template< typename Type , + typename TTypArg =const Type& , + typename TTypBase =ZNsMain::ZNsIFace::ZtCAVL_BASE , + typename TNodeBase =ZNsMain::ZNsIFace::ZtCAVL_NodeBase , + typename TAlloc =ZNsMain::ZCAllocator , + typename TSize =ZNsMain::ZTypLong , + typename TCompare =ZNsMain::ZNsFunc::ZtCCompare, + typename TMoveObj =ZNsMain::ZNsFunc::ZtCMoveObj + > + class ZtCObjAVL : public TTypBase /////////////////////////////////////////////////////// + { + public: + typedef Type TypeData ; + typedef TTypArg TypeArg ; + typedef TTypBase TypeBase ; + typedef TNodeBase TypeNodeBase; + typedef TAlloc TypeAlloc ; + typedef TSize TypeSize ; + typedef TCompare TypeCompare ; + typedef TMoveObj TypeMoveObj ; + public: + + class ZCNode : public TNodeBase, public TAlloc /* ZCNode object 는 이중 원형 연결리스트로 관리된다. */ + { + public : + friend class ZtCObjAVL; + protected: + + ZCNode* mp_PrevNode; /* 이전 노드 */ + ZCNode* mp_NextNode; /* 다음 노드 */ + ZCNode* mp_LeftNode; /* 왼쪽 노드 */ + ZCNode* mp_RighNode; /* 오른쪽 노드 */ + ZCNode* mp_HighNode; /* 상위 노드 */ + + Type mo_Type ; + int mi_Balance ; + + /* 오른쪽 노드에 삽입될 때마다 mi_Balance 는 1 씩 증가하고 + * 왼쪽 노드에 삽입될 때마다 mi_Balance 는 1 씩 감소한다. + * 이 값이 +2 나 -2 가 될 때 노드의 회전을 수행하여 평형을 맞춘다. + * 결과적으로 -1<=mi_Balance && mi_Balance<=1 이 되게 한다. + */ + + inline void InsertBefore(ZCNode* AP_Node) + { + ZCNode* VP_PrevNode=this->mp_PrevNode; + + JoinNode(VP_PrevNode, AP_Node); + JoinNode(AP_Node , this ); + }/* + inline void InsertBefore(ZCNode* AP_Node)*/ + + inline void InsertAfter(ZCNode* AP_Node) + { + ZCNode* VP_NextNode=this->mp_NextNode; + + JoinNode(this , AP_Node ); + JoinNode(AP_Node, VP_NextNode); + }/* + inline void InsertAfter(ZCNode* AP_Node)*/ + + inline static void JoinNode(ZCNode* AP_Before, ZCNode* AP_After) + { + AP_Before->mp_NextNode=AP_After ; + AP_After ->mp_PrevNode=AP_Before; + }/* + inline static void JoinNode(ZCNode* AP_Before, ZCNode* AP_After)*/ + + inline static void MakeRing(ZCNode* AP_Head, ZCNode* AP_Tail) + { + AP_Head->mp_PrevNode=AP_Tail; + AP_Tail->mp_NextNode=AP_Head; + }/* + inline static void MakeRing(ZCNode* AP_Head, ZCNode* AP_Tail)*/ + + ZCNode() + { + mp_NextNode = + mp_PrevNode = + mp_LeftNode = + mp_RighNode = + mp_HighNode = 0; + mi_Balance = 0; + }/* + ZCNode()*/ + + ZCNode(const ZCNode& rhs) + { + mp_NextNode = + mp_PrevNode = + mp_LeftNode = + mp_RighNode = + mp_HighNode = 0; + mi_Balance = 0; + }/* + ZCNode(const ZCNode& rhs)*/ + + ZCNode& operator=(const ZCNode& rhs) + { + // AVL 상태를 해칠 수 있기 때문에 아무 짓도 하지 않는다. + + return *this; + }/* + ZCNode& operator=(const ZCNode& rhs)*/ + + /*private:*/ + public : + + ~ZCNode() + { + mp_NextNode = + mp_PrevNode = + mp_LeftNode = + mp_RighNode = + mp_HighNode = 0; + mi_Balance = 0; + }/* + ~ZCNode()*/ + + ZCNode* GetNextPrevPtr(TypeSize AL_FarNum) // AL_FarNum 은 0 이거나 음수일 수 있다. + { + ZCNode* VP_TmpNode=this; + + if(AL_FarNum>=0) + { + while(--AL_FarNum>=0) + VP_TmpNode=VP_TmpNode->mp_NextNode; + /*end while*/ + } + else /* AL_FarNum<0 인 경우. */ + { + while(++AL_FarNum<=0) + VP_TmpNode=VP_TmpNode->mp_PrevNode; + /*end while*/ + } + //else /* AL_FarNum<0 인 경우. */ + + return VP_TmpNode; + }/* + ZCNode* GetNextPrevPtr(TypeSize AL_FarNum)*/ + + const ZCNode* GetNextPrevPtr(TypeSize AL_FarNum) const + { + ZCNode* VP_TmpNode=const_cast(this); + + /* 이 함수는 뒤에 const keyword 가 붙어 있는데 이것 때문에 this pointer 는 상수 + 포인터로 간주된다. 윗줄에서 이 this 포인터를 비상수 포인터로 먼저 형변환하였다. + + ZCNode* VP_TmpNode=const_castthis; + + 라 하면 g++ 2.96 에서는 에러 ###############################################*/ + + if(AL_FarNum>=0) + { + while(--AL_FarNum>=0) + { VP_TmpNode=VP_TmpNode->mp_NextNode; } + } + else // AL_FarNum<0 + { + while(++AL_FarNum<=0) + { VP_TmpNode=VP_TmpNode->mp_PrevNode; } + } + //else // AL_FarNum<0 + + return VP_TmpNode; + }/* + const ZCNode* GetNextPrevPtr(TypeSize AL_FarNum) const*/ + + ZCNode* GetPrevPtr (){return mp_PrevNode;} + ZCNode* GetNextPtr (){return mp_NextNode;} + ZCNode* GetLeftPtr (){return mp_LeftNode;} + ZCNode* GetRightPtr(){return mp_RighNode;} + ZCNode* GetHighPtr (){return mp_HighNode;} + + const ZCNode* GetPrevPtr () const{return mp_PrevNode;} + const ZCNode* GetNextPtr () const{return mp_NextNode;} + const ZCNode* GetLeftPtr () const{return mp_LeftNode;} + const ZCNode* GetRightPtr() const{return mp_RighNode;} + const ZCNode* GetHighPtr () const{return mp_HighNode;} + + int GetDepthBalance() const + { + return mi_Balance; + }/* + int GetDepthBalance() const*/ + + bool IsFullNode() const + { + /* 양쪽 노드가 차 있어야 true */ + + return (mp_LeftNode!=0 && mp_RighNode!=0); + }/* + bool IsFullNode() const*/ + + TTypArg GetData() const + { + return mo_Type; + }/* + TTypArg GetData() const*/ + + bool operator==(TTypArg AR_Type) const{return mo_Type==AR_Type;} + bool operator> (TTypArg AR_Type) const{return mo_Type> AR_Type;} + bool operator< (TTypArg AR_Type) const{return mo_Type< AR_Type;} + + template static void IterInOrder (ZCNode* AP_Node, TFunctor AO_Functor) + { + if(AP_Node!=0) + { + ZCNode::template IterInOrder(AP_Node->mp_LeftNode, AO_Functor); + { + ZNsMain::ZtCTypeData::GetObjRef(AO_Functor)(AP_Node->mo_Type); + } + ZCNode::template IterInOrder(AP_Node->mp_RighNode, AO_Functor); + }/* + if(AP_Node!=0)*/ + }/* + template static void IterInOrder (ZCNode* AP_Node, TFunctor AO_Functor) */ + + template static void IterPreOrder(ZCNode* AP_Node, TFunctor AO_Functor) + { + if(AP_Node!=0) + { + ZNsMain::ZtCTypeData::GetObjRef(AO_Functor)(AP_Node->mo_Type); + + ZCNode::template IterPreOrder(AP_Node->mp_LeftNode, AO_Functor); + ZCNode::template IterPreOrder(AP_Node->mp_RighNode, AO_Functor); + }/* + if(AP_Node!=0)*/ + }/* + template static void IterPreOrder(ZCNode* AP_Node,TFunctor AO_Functor) */ + + template static void IterPostOrder(ZCNode* AP_Node, TFunctor AO_Functor) + { + if(AP_Node!=0) + { + ZCNode::template IterPostOrder(AP_Node->mp_LeftNode, AO_Functor); + ZCNode::template IterPostOrder(AP_Node->mp_RighNode, AO_Functor); + + ZNsMain::ZtCTypeData::GetObjRef(AO_Functor)(AP_Node->mo_Type); + }/* + if(AP_Node!=0)*/ + }/* + template static void IterPostOrder(ZCNode* AP_Node, TFunctor AO_Functor) */ + + + template static void IterInOrder + (ZCNode* AP_Node, TFunctor AO_Functor, THelpObj AR_HelpObj) + /*####################################################################*/ + { + if(AP_Node!=0) + { + ZCNode::template IterInOrder + (AP_Node->mp_LeftNode, AO_Functor, AR_HelpObj); + { + ZNsMain::ZtCTypeData:: + GetObjRef(AO_Functor)(AP_Node->mo_Type, AR_HelpObj); + } + ZCNode::template IterInOrder + (AP_Node->mp_RighNode, AO_Functor, AR_HelpObj); + }/* + if(AP_Node!=0)*/ + }/* + template static void IterInOrder + (ZCNode* AP_Node, TFunctor AO_Functor, THelpObj AR_HelpObj) + ######################################################################*/ + + template static void IterPreOrder + (ZCNode* AP_Node, TFunctor AO_Functor, THelpObj AR_HelpObj) + /*####################################################################*/ + { + if(AP_Node!=0) + { + ZNsMain::ZtCTypeData:: + GetObjRef(AO_Functor)(AP_Node->mo_Type, AR_HelpObj); + + ZCNode::template IterPreOrder + (AP_Node->mp_LeftNode, AO_Functor, AR_HelpObj); + ZCNode::template IterPreOrder + (AP_Node->mp_RighNode, AO_Functor, AR_HelpObj); + }/* + if(AP_Node!=0)*/ + }/* + template static void IterPreOrder + (ZCNode* AP_Node, TFunctor AO_Functor, THelpObj AR_HelpObj) + ######################################################################*/ + + template static void IterPostOrder + (ZCNode* AP_Node, TFunctor AO_Functor, THelpObj AR_HelpObj) + /*####################################################################*/ + { + if(AP_Node!=0) + { + ZCNode::template IterPostOrder + ( AP_Node->mp_LeftNode, AO_Functor, AR_HelpObj ); + ZCNode::template IterPostOrder + ( AP_Node->mp_RighNode, AO_Functor, AR_HelpObj ); + + ZNsMain::ZtCTypeData:: + GetObjRef(AO_Functor)(AP_Node->mo_Type, AR_HelpObj); + }/* + if(AP_Node!=0)*/ + }/* + template static void IterPostOrder + (ZCNode* AP_Node, TFunctor AO_Functor, THelpObj AR_HelpObj) + ######################################################################*/ + + public: + };/* + class ZCNode*/ + + + ////////////////////////////////////////////// + + /************** end class ZCNode ************/ + + ////////////////////////////////////////////// + + + /*public :*/ + protected: + ZCNode* mp_RootNode ; + ZCNode* mp_HeadNode ; + TypeSize ml_NodeSize ; + protected: + + ZCNode* CutEmptyNode(ZCNode* AP_CutNode) + { + #ifdef _DEBUG + + if(AP_CutNode->IsFullNode()==true) + { + // 양쪽 연결 노드 중 어느 한 쪽은 비어 있어야 한다. + + std::fstream fileout("DEBUG.txt",std::ios::in | std::ios::out | std::ios::app); + fileout<IsFullNode()==true)*/ + + #endif //_DEBUG + + /* + * 7 + * * * + * * * + * 4 8 + * * * * + * * * * + * 2 6 9 + * * + * * + * 1 + */ + + /* 위 예에서 7 을 삭제한다고 생각해 보자 + * 그러자면 일단 6 의 트리 연결을 끊는 사전작업을 해두고 + * 6 를 7 의 자리로 옮겨야 한다. + * CutEmptyNode() 함수는 노드 6 과 같이 + * 최소한 어느 한쪽의 연결노드가 비어 있는 노드를 자를 때 쓴다. + * 이중 연결 리스트 상태를 그대로 두고 트리 노드 상태만 자른다. + */ + + /*/////////////////////////////////////////////////////////////////////////// + + ■ ZCNode* VP_ApexNode 는 디폴트로 VP_HighNode 이거나 회전이 이루어진 다음에 + 다시 꼭지점으로 오게 되는 노드다. 위의 예에서 7 이 삭제되면 6 이 올라와 + 야 되는데 그러자면 1, 2, 4 에 노드에 회전이 발생해서 2 가 1, 2, 4 의 꼭 + 지점으로 오게 되는데 이때의 2 가 해당한다. 이 노드의 평형계수가 0 이 되면 + 상위노드로 순회하면서 평형계수를 바꾸어 주어야 한다. 왜 그런지는 종이에 + 그려서 확인해보자. + + ///////////////////////////////////////////////////////////////////////////*/ + + ZCNode* VP_HighNode=AP_CutNode->mp_HighNode ; + ZCNode* VP_ApexNode=VP_HighNode ; + + if(AP_CutNode->mp_LeftNode==0) + { + if(AP_CutNode->mp_RighNode==0) + { + // 양쪽 노드가 다 비어있는 경우 + + /* VP_HighNode==0 즉 AP_CutNode==mp_RootNode(이때 ml_NodeSize==1) 인 경우는 + 이중 원형 연결상태를 조정할 때 따질 것이므로 여기서는 다루지 않는다. */ + + if(AP_CutNode==VP_HighNode->mp_LeftNode) + { + // VP_HighNode->mi_Balance 이 1 증가 + + VP_HighNode->mp_LeftNode=0; + + if(VP_HighNode->mi_Balance==1) + { + /* + * 4 (VP_HighNode) + * * * + * * * + *(AP_CutNode) 3 5 + * * + * * + * 6 + */ + + VP_ApexNode=Balance(VP_HighNode, VP_HighNode->mp_RighNode->mi_Balance); + } + else + { + ++VP_HighNode->mi_Balance ; + }/* + else*/ + + /* 지금 VP_ApexNode==VP_HighNode 이다. 따라서 VP_HighNode 는 더 상위노드로 옮겨야 합리적이다. */ + + VP_HighNode=VP_ApexNode->mp_HighNode; + } + else // AP_CutNode==VP_HighNode->mp_RighNode + { + // VP_HighNode->mi_Balance 이 1 감소 + + VP_HighNode->mp_RighNode=0; + + if(VP_HighNode->mi_Balance==-1) + { + /* + * 4 (VP_HighNode) + * * * + * * * + * 3 5 (AP_CutNode) + * * + * * + * 2 + */ + + VP_ApexNode=Balance(VP_HighNode, VP_HighNode->mp_LeftNode->mi_Balance); + } + else // VP_HighNode->mi_Balance!=-1 + { + --VP_HighNode->mi_Balance; + }/* + else // VP_HighNode->mi_Balance!=-1*/ + + /* 지금 VP_ApexNode==VP_HighNode 이다. 따라서 VP_HighNode 는 더 상위노드로 옮겨야 합리적이다. */ + + VP_HighNode=VP_ApexNode->mp_HighNode; + }/* + else // AP_CutNode==VP_HighNode->mp_RighNode*/ + + // 지금까지 양쪽 노드가 비어 있는 경우를 다루었다. + } + else // AP_CutNode->mp_LeftNode==0 && AP_CutNode->mp_RighNode!=0 + { + // 오른쪽 연결 노드만 있는 경우 + + if(VP_HighNode==0) // AP_CutNode==mp_RootNode + { + mp_RootNode=AP_CutNode->mp_RighNode; + mp_RootNode->mp_RighNode=0; + mp_RootNode->mp_HighNode=0; + mp_RootNode->mi_Balance =0; + + return AP_CutNode; + } + else if(AP_CutNode==VP_HighNode->mp_LeftNode) + { + // VP_HighNode->mi_Balance 이 1 증가 + + /* 7 (VP_HighNode) + * * * + * * * + * 5 (AP_CutNode) + * * + * * + * 6 + */ + + VP_HighNode->mp_LeftNode=AP_CutNode->mp_RighNode; + AP_CutNode->mp_RighNode->mp_HighNode=VP_HighNode; + + if(VP_HighNode->mi_Balance==1) + { + VP_ApexNode=Balance(VP_HighNode, VP_HighNode->mp_RighNode->mi_Balance); + VP_HighNode=VP_ApexNode->mp_HighNode; + } + else // VP_HighNode->mi_Balance==1 + { + ++VP_HighNode->mi_Balance ; + VP_ApexNode=VP_HighNode ; + VP_HighNode=VP_ApexNode->mp_HighNode; + }/* + else // VP_HighNode->mi_Balance==1*/ + } + else + { + // AP_CutNode->mp_LeftNode==0 && + // AP_CutNode->mp_RighNode!=0 && + // AP_CutNode==VP_HighNode->mp_RighNode + // VP_HighNode->mi_Balance 이 1 감소 + + /* 4 (VP_HighNode) + * * * + * * * + * 5 (AP_CutNode) + * * + * * + * 6 + */ + + VP_HighNode->mp_RighNode=AP_CutNode->mp_RighNode; + AP_CutNode->mp_RighNode->mp_HighNode=VP_HighNode; + + if(VP_HighNode->mi_Balance==-1) + { + VP_ApexNode=Balance(VP_HighNode, VP_HighNode->mp_LeftNode->mi_Balance); + VP_HighNode=VP_ApexNode->mp_HighNode; + } + else // VP_HighNode->mi_Balance==-1 + { + --VP_HighNode->mi_Balance ; + VP_ApexNode=VP_HighNode ; + VP_HighNode=VP_ApexNode->mp_HighNode; + }/* + else // VP_HighNode->mi_Balance==-1*/ + }/* + else*/ + }/* + else*/ + } + else if(AP_CutNode->mp_RighNode==0) + { + // AP_CutNode->mp_LeftNode!=0 왼쪽 연결노드만 차있는 경우 + + if(VP_HighNode==0) // AP_CutNode==mp_RootNode + { + mp_RootNode=AP_CutNode->mp_LeftNode; + mp_RootNode->mp_LeftNode=0; + mp_RootNode->mp_HighNode=0; + mp_RootNode->mi_Balance =0; + + return AP_CutNode; + } + else if(AP_CutNode==VP_HighNode->mp_LeftNode) + { + // VP_HighNode->mi_Balance 이 1 증가 + + /* 7 (VP_HighNode) + * * * + * * * + * 5 (AP_CutNode) + * * + * * + * 4 + */ + + VP_HighNode->mp_LeftNode=AP_CutNode->mp_LeftNode; + AP_CutNode->mp_LeftNode->mp_HighNode=VP_HighNode; + + if(VP_HighNode->mi_Balance==1) + { + VP_ApexNode=Balance(VP_HighNode, VP_HighNode->mp_RighNode->mi_Balance); + VP_HighNode=VP_ApexNode->mp_HighNode; + } + else // VP_HighNode->mi_Balance!=1 + { + ++VP_HighNode->mi_Balance ; + VP_ApexNode=VP_HighNode ; + VP_HighNode=VP_ApexNode->mp_HighNode; + }/* + else // VP_HighNode->mi_Balance!=1*/ + } + else + { + // AP_CutNode->mp_RighNode==0 && + // AP_CutNode->mp_LeftNode!=0 && + // AP_CutNode==VP_HighNode->mp_RighNode + // VP_HighNode->mi_Balance 이 1 감소 + + /* 4 (VP_HighNode) + * * * + * * * + * 6 (AP_CutNode) + * * + * * + * 5 + */ + + VP_HighNode->mp_RighNode=AP_CutNode->mp_LeftNode; + AP_CutNode->mp_LeftNode->mp_HighNode=VP_HighNode; + + if(VP_HighNode->mi_Balance==-1) + { + VP_ApexNode=Balance(VP_HighNode, VP_HighNode->mp_LeftNode->mi_Balance); + VP_HighNode=VP_ApexNode->mp_HighNode; + } + else // VP_HighNode->mi_Balance==-1 + { + --VP_HighNode->mi_Balance; + VP_ApexNode=VP_HighNode; + VP_HighNode=VP_ApexNode->mp_HighNode; + }/* + else // VP_HighNode->mi_Balance==-1*/ + }/* + else*/ + }/* + else*/ + + /* VP_ApexNode->mi_Balance==0 인 경우 상위노드로 순회하면서 + 평형계수를 조정하거나 평형을 맞춘다. + VP_ApexNode->mi_Balance!=0 이면 순회를 멈춘다. */ + + while(VP_HighNode!=0 && VP_ApexNode->mi_Balance==0) + { + if(VP_ApexNode==VP_HighNode->mp_LeftNode) + { + if(VP_HighNode->mi_Balance==1) + { + VP_ApexNode=Balance(VP_HighNode, VP_HighNode->mp_RighNode->mi_Balance); + } + else // VP_HighNode->mi_Balance==1 + { + VP_ApexNode=VP_HighNode; + ++VP_HighNode->mi_Balance; + }/* + else // VP_HighNode->mi_Balance==1*/ + } + else // VP_ApexNode==VP_HighNode->mp_RighNode + { + if(VP_HighNode->mi_Balance==-1) + { + VP_ApexNode=Balance(VP_HighNode, VP_HighNode->mp_LeftNode->mi_Balance); + } + else // VP_HighNode->mi_Balance==-1 + { + VP_ApexNode=VP_HighNode; + --VP_HighNode->mi_Balance; + }/* + else // VP_HighNode->mi_Balance==-1*/ + }/* + else // VP_ApexNode==VP_HighNode->mp_RighNode*/ + + VP_HighNode=VP_ApexNode->mp_HighNode; + }/* + while(VP_HighNode!=0 && VP_ApexNode->mi_Balance==0)*/ + + return AP_CutNode; + }/* + ZCNode* CutEmptyNode(ZCNode* AP_CutNode)*/ + + ZCNode* CutNode(ZCNode* AP_CutNode) + { + #ifdef _DEBUG + + if(FindNode(AP_CutNode)==0) + { + std::fstream fileout("DEBUG.txt",std::ios::in | std::ios::out | std::ios::app); + fileout<mi_Balance == 1 이면 + AP_CutNode 의 오른쪽 노드에서 가장 왼쪽 노드가 AP_CutNode 위치로 올라오는 것으로 한다. + AP_CutNode->mi_Balance == -1 이나 0 이면 + AP_CutNode 의 왼쪽 노드에서 가장 오른쪽 노드가 AP_CutNode 위치로 올라오는 것으로 한다. */ + + if(AP_CutNode==mp_HeadNode && ml_NodeSize==1) + { + mp_HeadNode=0; + mp_RootNode=0; + ml_NodeSize=0; + + return AP_CutNode; + } + if(AP_CutNode->mp_LeftNode==0 || AP_CutNode->mp_RighNode==0) + { + CutEmptyNode(AP_CutNode); + } + else + //(AP_CutNode->mp_LeftNode!=0 && AP_CutNode->mp_RighNode!=0) + { + /*///////////////////////////////////////////////////////////////// + + ■ CutEmptyNode(AP_CutNode) 멤버 함수는 AP_CutNode 의 트리연결 상태만 + 끊는다. + + ■ AP_CutNode->mp_PrevNode 이거나 AP_CutNode->mp_NextNode 인 노드는 + 왼쪽 노드, 오른쪽 노드 어느 한쪽이 반드시 비어있다. + + ■ 언뜻 생각하기에 + + AP_CutNode->mp_PrevNode==AP_CutNode->mp_LeftNode + AP_CutNode->mp_NextNode==AP_CutNode->mp_RighNode + + 라고 생각하기 쉬운데 아래 그림을 보면 그렇지 않다는 것을 알 수 있다. + AP_CutNode 를 5 라고 생각해보자. AP_CutNode->mp_NextNode 는 6 인데 + AP_CutNode->mp_RighNode 는 7 이다. + + 5 + * * + * * + 3 7 + * * * * + * * * * + * * * * + 2 4 6 8 + * + * + 1 + + /////////////////////////////////////////////////////////////////*/ + + ZCNode* VP_TempCut; + + if(AP_CutNode->mi_Balance<=0) + { + VP_TempCut=CutEmptyNode(AP_CutNode->mp_PrevNode); + } + else + { + VP_TempCut=CutEmptyNode(AP_CutNode->mp_NextNode); + } + if(AP_CutNode==mp_RootNode) + { + mp_RootNode=VP_TempCut; + }/* + if(AP_CutNode==mp_RootNode)*/ + + // VP_TempCut 와 AP_CutNode 의 위치를 바꾼다. + + VP_TempCut->mp_HighNode=AP_CutNode->mp_HighNode; + VP_TempCut->mp_RighNode=AP_CutNode->mp_RighNode; + VP_TempCut->mp_LeftNode=AP_CutNode->mp_LeftNode; + VP_TempCut->mi_Balance =AP_CutNode->mi_Balance ; + + if(AP_CutNode->mp_HighNode!=0) + { + if(AP_CutNode->mp_HighNode->mp_LeftNode==AP_CutNode) + AP_CutNode->mp_HighNode->mp_LeftNode=VP_TempCut; + else + AP_CutNode->mp_HighNode->mp_RighNode=VP_TempCut; + //else + } + if(AP_CutNode->mp_LeftNode!=0) + { + AP_CutNode->mp_LeftNode->mp_HighNode=VP_TempCut; + } + if(AP_CutNode->mp_RighNode!=0) + { + AP_CutNode->mp_RighNode->mp_HighNode=VP_TempCut; + }/* + if(AP_CutNode->mp_RighNode!=0)*/ + }/* + else // AP_CutNode->mp_LeftNode!=0 && AP_CutNode->mp_RighNode!=0*/ + + // 이중 원형 상태를 끊는다. + + if(AP_CutNode==mp_HeadNode) + { + // ml_NodeSize==1 인 경우는 위에서 이미 조사했다. + + ZCNode* VP_EndNode=mp_HeadNode->GetPrevPtr(); + mp_HeadNode =mp_HeadNode->GetNextPtr(); + ZCNode::MakeRing(mp_HeadNode, VP_EndNode) ; + } + else + { + ZCNode::JoinNode(AP_CutNode->GetPrevPtr(), AP_CutNode->GetNextPtr()); + }/* + else*/ + + --ml_NodeSize; return AP_CutNode; + }/* + ZCNode* CutNode(ZCNode* AP_CutNode)*/ + + /*private:*/ + public : + + ZtCObjAVL() + { + Init(); + + mp_RootNode =0 ; + mp_HeadNode =0 ; + ml_NodeSize =0 ; + }/* + ZtCObjAVL()*/ + + ZtCObjAVL(const ZtCObjAVL& rhs) + { + Init(); + + mp_RootNode =0 ; + mp_HeadNode =0 ; + ml_NodeSize =0 ; + + if(rhs.mp_HeadNode==0) return ; + + ZCNode* VP_Temp=rhs.mp_HeadNode ; + ZCNode* VP_Tail=rhs.mp_HeadNode->mp_PrevNode; + + do /**/ + { + AddData(VP_Temp->mo_Type); + + if(VP_Temp==VP_Tail) return; + + VP_Temp=VP_Temp->mp_NextNode; + } + while(true); + }/* + ZtCObjAVL(const ZtCObjAVL& rhs)*/ + + ZtCObjAVL& operator=(const ZtCObjAVL& rhs) + { + if(this==&rhs) {return ;} + + DeleteAll(); if(rhs.mp_HeadNode==0){ return; } + + ZCNode* VP_Temp=rhs.mp_HeadNode; + ZCNode* VP_Tail=rhs.mp_HeadNode->mp_PrevNode; + + do /**/ + { + AddData(VP_Temp->mo_Type); + + if(VP_Temp==VP_Tail) return *this; + + VP_Temp=VP_Temp->mp_NextNode; + } + while(true); + + return *this; + }/* + ZtCObjAVL& operator=(const ZtCObjAVL& rhs)*/ + + ~ZtCObjAVL() + { + DeleteAll(); + }/* + ~ZtCObjAVL()*/ + + void Init() + { + // add initial codes here + }/* + void Init()*/ + + + bool operator()(TTypArg AR_Type) + { + return AddData(AR_Type); + }/* + bool operator()(TTypArg AR_Type)*/ + + inline ZCNode* GetRootNodePtr() + { + return mp_RootNode; + }/* + inline ZCNode* GetRootNodePtr()*/ + + inline const ZCNode* GetRootNodePtr() const + { + return mp_RootNode; + }/* + inline const ZCNode* GetRootNodePtr() const*/ + + inline ZCNode* GetHeadNodePtr() + { + return mp_HeadNode; + }/* + inline ZCNode* GetHeadNodePtr()*/ + + inline const ZCNode* GetHeadNodePtr() const + { + return mp_HeadNode; + }/* + inline inline const ZCNode* GetHeadNodePtr() const*/ + + inline ZCNode* GetTailNodePtr() + { + return mp_HeadNode==0 ? 0 : mp_HeadNode->mp_PrevNode ; + }/* + inline ZCNode* GetTailNodePtr()*/ + + inline const ZCNode* GetTailNodePtr() const + { + return mp_HeadNode==0 ? 0 : mp_HeadNode->mp_PrevNode ; + }/* + inline const ZCNode* GetTailNodePtr() const*/ + + ZCNode* GetNodePtr(TypeSize AL_Index) + { + #ifdef _DEBUG + + if(AL_Index<1 || AL_Index>ml_NodeSize) + { + std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); + fileout<ml_NodeSize)*/ + + #endif // _DEBUG + + TypeSize VI_LeftDistance =AL_Index-1 ; + TypeSize VI_RightDistance=ml_NodeSize-AL_Index+1; + TypeSize VI_ShortDistance=(VI_LeftDistance<=VI_RightDistance ? VI_LeftDistance : -VI_RightDistance); + + return (static_cast(mp_HeadNode->GetNextPrevPtr(VI_ShortDistance))); + }/* + ZCNode* GetNodePtr(TypeSize AL_Index)*/ + + const ZCNode* GetNodePtr(TypeSize AL_Index) const // or 'ZCNode const * const GetNodePtr(TypeSize AL_Index) const' + { + #ifdef _DEBUG + + if(AL_Index<1 || AL_Index>ml_NodeSize) + { + std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); + fileout<ml_NodeSize)*/ + + #endif //_DEBUG + + TypeSize VI_LeftDistance =AL_Index-1 ; + TypeSize VI_RightDistance=ml_NodeSize-AL_Index+1; + TypeSize VI_ShortDistance=(VI_LeftDistance<=VI_RightDistance ? VI_LeftDistance : -VI_RightDistance); + + return mp_HeadNode->GetNextPrevPtr(VI_ShortDistance); + }/* + const ZCNode* GetNodePtr(TypeSize AL_Index) const*/ + + ZtCObjAVL& Minus(const ZtCObjAVL& rhs) + { + if(this==&rhs || mp_HeadNode==0 || rhs.mp_HeadNode==0) + { return *this; } + + ZCNode* VP_Temp=rhs.mp_HeadNode ; + ZCNode* VP_Tail=rhs.mp_HeadNode->mp_PrevNode; + + do /**/ + { + DeleteData(VP_Temp->mo_Type); + + if(VP_Temp==VP_Tail) return *this; + + VP_Temp=VP_Temp->mp_NextNode; + } + while(true); + + return *this; + }/* + ZtCObjAVL& Minus(const ZtCObjAVL& rhs)*/ + + + void DeleteNode(ZCNode* AP_DelNode) + { + #ifdef _DEBUG + + if(FindNode(AP_DelNode)==0) + { + std::fstream fileout("DEBUG.txt", std::ios::in | std::ios::out | std::ios::app); + fileout<mp_NextNode; + delete VP_NodeCut; + VP_NodeCut=VP_NodeNext; + }/* + __for0(TypeSize, i, ml_NodeSize)*/ + + ml_NodeSize =0; + mp_HeadNode =0; + mp_RootNode =0; + }/* + if(mp_HeadNode!=0)*/ + }/* + void DeleteAll()*/ + + void clear() + { + this->DeleteAll(); + }/* + void clear()*/ + + + template void IterNode(TFunctor AO_Functor) const + { + if(mp_HeadNode==0) return ; + + const ZCNode* VP_Temp=mp_HeadNode ; + const ZCNode* VP_Tail=mp_HeadNode->mp_PrevNode; + + do /*#####*/ + { + /* 아래 줄에서 VP_Temp->mo_Type 을 받는 인수는 + 복사로 받거나 const Type& 으로 받아야 한다. */ + + ZNsMain::ZtCTypeData:: + GetObjRef(AO_Functor)(VP_Temp->mo_Type); + + if(VP_Temp==VP_Tail) return; VP_Temp=VP_Temp->mp_NextNode; + } + while(true); + }/* + template void IterNode(TFunctor AO_Functor) const */ + + template + void IterNode(TFunctor AO_Functor, TypeHelp AO_HelpType) const + { + if(mp_HeadNode==0) return ; + + const ZCNode* VP_Temp=mp_HeadNode ; + const ZCNode* VP_Tail=mp_HeadNode->mp_PrevNode; + + do /*#####*/ + { + /* 아래 줄에서 VP_Temp->mo_Type 을 받는 인수는 + 복사로 받거나 const Type& 으로 받아야 한다. */ + + ZNsMain::ZtCTypeData:: + GetObjRef(AO_Functor)(VP_Temp->mo_Type, AO_HelpType) ; + + if(VP_Temp==VP_Tail) return; VP_Temp=VP_Temp->mp_NextNode; + } + while(true); + }/* + template + void IterNode(TFunctor AO_Functor, TypeHelp AO_HelpType) const */ + + template + void IterNodeRef(TFunctor AO_Functor, TypeHelp& AR_HelpType) const + { + if(mp_HeadNode==0) return ; + + const ZCNode* VP_Temp=mp_HeadNode ; + const ZCNode* VP_Tail=mp_HeadNode->mp_PrevNode; + + do /*#####*/ + { + ZNsMain::ZtCTypeData:: + GetObjRef(AO_Functor)(VP_Temp->mo_Type, AR_HelpType) ; + + if(VP_Temp==VP_Tail) return; VP_Temp=VP_Temp->mp_NextNode; + } + while(true); + }/* + template + void IterNodeRef(TFunctor AO_Functor, TypeHelp& AR_HelpType) const */ + + template void IterInOrder (TFunctor AO_Functor) const{ + ZCNode::template IterInOrder (mp_RootNode, AO_Functor);} + template void IterPreOrder (TFunctor AO_Functor) const{ + ZCNode::template IterPreOrder (mp_RootNode, AO_Functor);} + template void IterPostOrder(TFunctor AO_Functor) const{ + ZCNode::template IterPostOrder(mp_RootNode, AO_Functor);} + + template void IterInOrder (TFunctor AO_Functor, THelpObj AR_HelpObj) const{ + ZCNode::template IterInOrder (mp_RootNode, AO_Functor, AR_HelpObj);} + template void IterPreOrder (TFunctor AO_Functor, THelpObj AR_HelpObj) const{ + ZCNode::template IterPreOrder (mp_RootNode, AO_Functor, AR_HelpObj);} + template void IterPostOrder(TFunctor AO_Functor, THelpObj AR_HelpObj) const{ + ZCNode::template IterPostOrder(mp_RootNode, AO_Functor, AR_HelpObj);} + + + TypeSize GetSize() const{return ml_NodeSize;} + TypeSize size () const{return ml_NodeSize;} + + bool IsEmpty() const + { + return mp_HeadNode==0; + }/* + bool IsEmpty() const*/ + + bool AddData(TTypArg AR_Type) + { + if(mp_RootNode==0) + { + mp_RootNode=new ZCNode ; + mp_HeadNode=mp_RootNode ; + ZCNode::MakeRing(mp_HeadNode, mp_HeadNode); + mp_RootNode->mo_Type=AR_Type; + + ++ml_NodeSize; return true; + } + else // mp_RootNode!=0 + { + return AddData(*mp_RootNode, AR_Type)!=ZNsMain::ZNsEnum::ZEAVL_INSERT_NONE ; + }/* + else // mp_RootNode!=0*/ + }/* + bool AddData(TTypArg AR_Type)*/ + + + template ZCNode* AddKey(TKey AR_Key) + { + if(mp_RootNode==0) + { + mp_RootNode=new ZCNode ; + mp_HeadNode=mp_RootNode; + + ZCNode::MakeRing(mp_HeadNode, mp_HeadNode); + + mp_RootNode->mo_Type=AR_Key; ++ml_NodeSize; + + return mp_RootNode; /*///////////////////*/ + } + else // mp_RootNode==0 + { + ZCNode* VP_CNode=0; // 삽입된 링크를 대입받는다. + + AddKey(*mp_RootNode, AR_Key, RR(VP_CNode)); + + return VP_CNode; /*////////////////////////////*/ + }/* + else // mp_RootNode==0*/ + }/* + template ZCNode* AddKey(TKey AR_Key) */ + + ZCNode* UpdateData(TTypArg AR_Type, TTypArg AR_NewType) + { + /* AR_Type 값을 가지고 있는 노드를 찾아내어 AR_NewType 로 업데이트한다. + AR_Type 값을 가지고 있는 노드를 찾아내어 잘라낸 다음, AR_NewType 로 + 업데이트하고 다시 삽입한다. */ + + ZCNode* VP_FindNode=FindData(AR_Type); + + if(VP_FindNode==0) return 0; ///////// + + + (void)CutNode(VP_FindNode); + + VP_FindNode->mo_Type=AR_NewType; + + // 같은 값을 가진 노드가 있어서 삽입에 실패했다면, 잘라낸 노드를 지워버린다. + + const ZNsMain::ZNsEnum::ZEAVL_INSERT + CE_EAVL_INSERT = AddNode(*mp_RootNode, *VP_FindNode); + + if(CE_EAVL_INSERT==ZNsMain::ZNsEnum::ZEAVL_INSERT_NONE) + { + delete VP_FindNode; return 0; + }/* + if(CE_EAVL_INSERT==ZNsMain::ZNsEnum::ZEAVL_INSERT_NONE)*/ + + return VP_FindNode; + }/* + ZCNode* UpdateData(TTypArg AR_Type, TTypArg AR_NewType)*/ + + + template ZCNode* UpdateKey(TKey AR_Key, TKey AR_NewKey) + { + /* AR_Key 값을 가지고 있는 노드를 찾아내어 AR_NewKey 로 업데이트한다. + AR_Key 값을 가지고 있는 노드를 찾아내어 잘라낸 다음, AR_NewKey 로 + 업데이트하고 다시 삽입한다. */ + + ZCNode* VP_FindNode=FindKey(AR_Key); + + if(VP_FindNode==0) return 0; //////////// + + + (void)CutNode(VP_FindNode); + + VP_FindNode->mo_Type=AR_NewKey; + + // 같은 키 값을 가진 노드가 있어서 삽입에 실패했다면, 잘라낸 노드를 지워버린다. + + const ZNsMain::ZNsEnum::ZEAVL_INSERT + CE_EAVL_INSERT = AddNode(*mp_RootNode, *VP_FindNode) ; + + if(CE_EAVL_INSERT==ZNsMain::ZNsEnum::ZEAVL_INSERT_NONE) + { + delete VP_FindNode; return 0; + }/* + if(CE_EAVL_INSERT==ZNsMain::ZNsEnum::ZEAVL_INSERT_NONE)*/ + + return VP_FindNode; + }/* + template ZCNode* UpdateKey(TKey AR_Key, TKey AR_NewKey) */ + + + TypeSize FindNode /*#######################*/ + ( + const ZCNode* AP_SearchNode , + TypeSize AL_FirstFindIndex =1, + bool AB_DoFindFromFront=true + ) const + /*#########################################*/ + { + /* 맨 앞 링크부터 이중 원형 상태를 따라서 순회하면서 찾는다. + 이 경우 AVL 트리 상태로 순회하면서 찾는 것이 좋으나 DEBUG + 용 함수로 사용하고 그냥 내버려 둔다. */ + + const bool CB_IsBad = + ( mp_HeadNode ==0 || + AL_FirstFindIndex< 1 || + AL_FirstFindIndex> ml_NodeSize + ); + if(CB_IsBad) { return 0; } + + TypeSize VL_FindIndex= AL_FirstFindIndex ; + ZCNode* VP_TempNode = const_cast + ( GetNodePtr(AL_FirstFindIndex) ) ; + + if(AB_DoFindFromFront==true) + { + do /**/ + { + if(VP_TempNode ==AP_SearchNode) return VL_FindIndex; + if(VL_FindIndex==ml_NodeSize ) return 0 ; + + VP_TempNode=VP_TempNode->mp_NextNode; ++VL_FindIndex; + } + while(true); + } + else // AB_DoFindFromFront!=true + { + do /**/ + { + if(VP_TempNode ==AP_SearchNode) return VL_FindIndex; + if(VL_FindIndex==1 ) return 0 ; + + VP_TempNode=VP_TempNode->mp_PrevNode; --VL_FindIndex; + } + while(true); + }/* + else // AB_DoFindFromFront!=true*/ + }/* + TypeSize FindNode ########################### + ( + const ZCNode* AP_SearchNode , + TypeSize AL_FirstFindIndex =1, + bool AB_DoFindFromFront=true + ) const + #########################################*/ + + + ZCNode* FindData(TTypArg AR_Type) const + { + /* mp_RootNode 부터 하위 노드로 순회하면서 + mo_Type 를 가지는 노드를 찾는다. */ + + return FindData(AR_Type, mp_RootNode); + }/* + ZCNode* FindData(TTypArg AR_Type) const*/ + + + ZCNode* FindData(TTypArg AR_Type, ZCNode* AP_StartNode) const + { + /* AP_StartNode 부터 하위 노드로 순회하면서 + mo_Type 를 가지는 노드를 찾는다. */ + + #ifdef _DEBUG + + if(AP_StartNode!=0 && FindNode(AP_StartNode)==0) + { + std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); + fileout<mo_Type==AR_Type) + { + return AP_StartNode; + } + else if(AP_StartNode->mo_Type>AR_Type) + { + AP_StartNode=AP_StartNode->mp_LeftNode; + } + else + { + AP_StartNode=AP_StartNode->mp_RighNode; + }/* + else*/ + }/* + while(AP_StartNode!=0)*/ + + return 0; + }/* + ZCNode* FindData(TTypArg AR_Type, ZCNode* AP_StartNode) const*/ + + + bool DeleteData(TTypArg AR_Type) + { + ZCNode* VP_FindNode=FindData(AR_Type); + + if(VP_FindNode) + { + DeleteNode(VP_FindNode); return true; + }/* + if(VP_FindNode)*/ + + return false; + }/* + bool DeleteData(TTypArg AR_Type)*/ + + template bool DeleteKey(TKey AR_Key) + { + /*//////////////////////////////////////////////// + + ■ cf) bool DeleteData(TTypArg AR_Type) + + AR_Key 가 AR_Type 보다 작은 크기의 object 라면 + 아래 FindKey() 함수에서 성능향상이 있는 것이다. + + ////////////////////////////////////////////////*/ + + ZCNode* VP_FindNode=FindKey(AR_Key); + + if(VP_FindNode) + { + DeleteNode(VP_FindNode); return true; + }/* + if(VP_FindNode)*/ + + return false; + }/* + template bool DeleteKey(TKey AR_Key) */ + + + template const ZCNode* + FindKey(TKey AR_Key, ZCNode* AP_StartNode) const + { + /*////////////////////////////////////////////////////////////////////////////// + + ■ AP_StartNode 부터 하위 노드로 순회하면서 AR_Key 를 가지는 노드를 찾는다. + FindData(TTypArg AR_Type,ZCNode* AP_StartNode) 같은 함수는 찾으려는 object 가 + AR_Type 이 크기가 큰 object 일 수 있는데, 이를 피하기 위해 그 보다 작은 크기 + 의 자료형 TKey 로부터 해당 데이타를 찾는다. 물론 mo_Type 과 TKey 에 대한 비 + 교 연산이 정의되어 있어야 한다. + + //////////////////////////////////////////////////////////////////////////////*/ + + #ifdef _DEBUG + + if(AP_StartNode!=0 && FindNode(AP_StartNode)==0) + { + std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); + fileout< const ZCNode* ZtCObjAVL::FindKey(TKey AR_Key,ZCNode* AP_StartNode) const'"<mo_Type==AR_Key) return AP_StartNode; + + if(AP_StartNode->mo_Type>AR_Key) + AP_StartNode=AP_StartNode->mp_LeftNode; + else + AP_StartNode=AP_StartNode->mp_RighNode; + //else + }/* + while(AP_StartNode!=0)*/ + + return 0; + }/* + template const ZCNode* + FindKey(TKey AR_Key, ZCNode* AP_StartNode) const */ + + + template ZCNode* + FindKey(TKey AR_Key, ZCNode* AP_StartNode) + { + /*////////////////////////////////////////////////////////////////////////////// + + ■ AP_StartNode 부터 하위 노드로 순회하면서 AR_Key 를 가지는 노드를 찾는다. + FindData(TTypArg AR_Type,ZCNode* AP_StartNode) 같은 함수는 찾으려는 object 가 + AR_Type 이 크기가 큰 object 일 수 있는데, 이를 피하기 위해 그 보다 작은 크기 + 의 자료형 TKey 로부터 해당 데이타를 찾는다. 물론 mo_Type 과 TKey 에 대한 비 + 교 연산이 정의되어 있어야 한다. + + //////////////////////////////////////////////////////////////////////////////*/ + + #ifdef _DEBUG + + if(AP_StartNode!=0 && FindNode(AP_StartNode)==0) + { + std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); + fileout< ZCNode* ZtCObjAVL::FindKey(TKey AR_Key,ZCNode* AP_StartNode)'"<mo_Type==AR_Key) return AP_StartNode; + + if(AP_StartNode->mo_Type>AR_Key) + AP_StartNode=AP_StartNode->mp_LeftNode; + else + AP_StartNode=AP_StartNode->mp_RighNode; + //else + }/* + while(AP_StartNode!=0)*/ + + return 0; + }/* + template ZCNode* + FindKey(TKey AR_Key, ZCNode* AP_StartNode) */ + + template const ZCNode* FindKey(TKey AR_Key) const + { + return FindKey(AR_Key, mp_RootNode); + }/* + template const ZCNode* FindKey(TKey AR_Key) const */ + + template ZCNode* FindKey(TKey AR_Key) + { + return FindKey(AR_Key,mp_RootNode); + }/* + template ZCNode* FindKey(TKey AR_Key) */ + + + const ZCNode* find(TTypArg AR_Type) const // for stl + { + return FindData(AR_Type,mp_RootNode); + }/* + const ZCNode* find(TTypArg AR_Type) const*/ + + const ZCNode* end() const // for stl + { + return 0; + }/* + const ZCNode* end() const*/ + + bool erase(TTypArg AR_Type) + { + return DeleteData(AR_Type); + }/* + bool erase(TTypArg AR_Type)*/ + + + #ifdef _DEBUG + + void DEBUG_WriteNodeStatus() + { + std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); + fileout<0 ? + TypeCompare::Exec(AR_Node.GetData(), AR_Type) : + ZECompareResult_Equal + ); + ////////////////////////// + + const bool CB_IsEqual = + ( + TypeCompare::ZEUseCompareObj>0 ? + VI_CompareResultCode==ZECompareResult_Equal : + AR_Node.GetData() ==AR_Type + ); + /*///////////////////*/ + #endif + + #if(_CODE_OLD_) + if(AR_Node.GetData()==AR_Type) + #else + if(CB_IsEqual) + #endif + { + /*/////////////////////////////////////////////////////////////////// + + ■ 기초 클래스 TTypBase 에서 OnEqual 멤버를 정의할 때, ZCNode 자료형을 + 모른다. 따라서 템플릿 멤버로 정의해야 한다. + + template void TTypBase + ::OnEqual(TTypArg AR_Data,TNode* AP_Node) + { + } + + ///////////////////////////////////////////////////////////////////*/ + + this->TTypBase::OnEqual(AR_Type, &AR_Node); return ZNsMain::ZNsEnum::ZEAVL_INSERT_NONE; + }/* + if(CB_IsEqual)*/ + + + const bool CB_IsLess = + ( + TypeCompare::ZEUseCompareObj>0 ? + VI_CompareResultCodemp_HighNode=&AR_Node; + + if(++AR_Node.mi_Balance==0) + return ZNsMain::ZNsEnum::ZEAVL_INSERT_OK; + else return ZNsMain::ZNsEnum::ZEAVL_INSERT_RIGHT; + } + else // AR_Node.mp_RighNode!=0 + { + int VI_AddState = AddData(*AR_Node.mp_RighNode, AR_Type); + + if(VI_AddState==ZNsMain::ZNsEnum::ZEAVL_INSERT_NONE) + { + return ZNsMain::ZNsEnum::ZEAVL_INSERT_NONE; + } + if(VI_AddState!=ZNsMain::ZNsEnum::ZEAVL_INSERT_OK) + { + if(AR_Node.mi_Balance==1) + { + Balance(&AR_Node, VI_AddState); return ZNsMain::ZNsEnum::ZEAVL_INSERT_OK; + } + else if(++AR_Node.mi_Balance==0) { return ZNsMain::ZNsEnum::ZEAVL_INSERT_OK ; } + else { return ZNsMain::ZNsEnum::ZEAVL_INSERT_RIGHT; } + }/* + if(VI_AddState!=ZNsMain::ZNsEnum::ZEAVL_INSERT_OK)*/ + + return ZNsMain::ZNsEnum::ZEAVL_INSERT_OK; + }/* + else // AR_Node.mp_RighNode!=0*/ + }/* + if(CB_IsLess)*/ + + + // AR_Node.mo_Type>AR_Type) + + if(AR_Node.mp_LeftNode==0) + { + ZCNode* VP_Temp=JoinBefore(&AR_Node, AR_Type); + + AR_Node.mp_LeftNode =VP_Temp ; + VP_Temp->mp_HighNode=&AR_Node; + + if(--AR_Node.mi_Balance==0) + return ZNsMain::ZNsEnum::ZEAVL_INSERT_OK ; + else return ZNsMain::ZNsEnum::ZEAVL_INSERT_LEFT; + } + else // AR_Node.mp_RighNode!=0 + { + int VI_AddState = AddData(*AR_Node.mp_LeftNode, AR_Type); + + if(VI_AddState==ZNsMain::ZNsEnum::ZEAVL_INSERT_NONE) + { + return ZNsMain::ZNsEnum::ZEAVL_INSERT_NONE; + } + if(VI_AddState!=ZNsMain::ZNsEnum::ZEAVL_INSERT_OK) + { + if(AR_Node.mi_Balance==-1) + { + Balance(&AR_Node,VI_AddState); return ZNsMain::ZNsEnum::ZEAVL_INSERT_OK; + } + else if(--AR_Node.mi_Balance==0) { return ZNsMain::ZNsEnum::ZEAVL_INSERT_OK ; } + else { return ZNsMain::ZNsEnum::ZEAVL_INSERT_LEFT; } + }/* + if(VI_AddState!=ZNsMain::ZNsEnum::ZEAVL_INSERT_OK)*/ + + return ZNsMain::ZNsEnum::ZEAVL_INSERT_OK; + }/* + else // AR_Node.mp_RighNode!=0*/ + }/* + int AddData(ZCNode& AR_Node, TTypArg AR_Type)*/ + + + template + int AddKey(ZCNode& AR_Node, TKey AR_Key, ZCNode*& APR_CNode) + { + using ZNsMain::ZNsEnum::ZECompareResult_Equal; + + #if(_CODE_NEW_) + int VI_CompareResultCode = + ( + TypeCompare::ZEUseCompareObj>0 ? + TypeCompare::Exec(AR_Node.GetData(), AR_Key) : + ZECompareResult_Equal + ); + ////////////////////////// + + const bool CB_IsEqual = + ( + TypeCompare::ZEUseCompareObj>0 ? + VI_CompareResultCode==ZECompareResult_Equal : + AR_Node.GetData() ==AR_Key + ); + /////////////////////// + #endif + + #if(_CODE_OLD_) + if(AR_Node.GetData()==AR_Key) + #else + if(CB_IsEqual) + #endif + { + this->TTypBase::OnEqualKey(AR_Key, &AR_Node); + + return ZNsMain::ZNsEnum::ZEAVL_INSERT_NONE; + }/* + if(CB_IsEqual)*/ + + + const bool CB_IsLess = + ( + TypeCompare::ZEUseCompareObj>0 ? + VI_CompareResultCodemp_HighNode=&AR_Node; + + if(++AR_Node.mi_Balance==0) + return ZNsMain::ZNsEnum::ZEAVL_INSERT_OK; + else + return ZNsMain::ZNsEnum::ZEAVL_INSERT_RIGHT; + //else + } + else /* AR_Node.mp_RighNode!=0 */ + { + int VI_AddState = AddKey + (*AR_Node.mp_RighNode, AR_Key, APR_CNode); + + if(VI_AddState==ZNsMain::ZNsEnum::ZEAVL_INSERT_NONE) + { + return ZNsMain::ZNsEnum::ZEAVL_INSERT_NONE; + } + if(VI_AddState!=ZNsMain::ZNsEnum::ZEAVL_INSERT_OK) + { + if(AR_Node.mi_Balance==1) + { + Balance(&AR_Node, VI_AddState); + + return ZNsMain::ZNsEnum::ZEAVL_INSERT_OK; + } + else if(++AR_Node.mi_Balance==0) + { + return ZNsMain::ZNsEnum::ZEAVL_INSERT_OK; + } + else + { + return ZNsMain::ZNsEnum::ZEAVL_INSERT_RIGHT; + }/* + else*/ + }/* + if(VI_AddState!=ZNsMain::ZNsEnum::ZEAVL_INSERT_OK)*/ + + return ZNsMain::ZNsEnum::ZEAVL_INSERT_OK; + }/* + else // AR_Node.mp_RighNode!=0 */ + }/* + if(CB_IsLess)*/ + + + // AR_Node.mo_Type>AR_Type + + if(AR_Node.mp_LeftNode==0) + { + APR_CNode=JoinBeforeKey(&AR_Node, AR_Key); + + AR_Node. mp_LeftNode=APR_CNode; + APR_CNode->mp_HighNode=&AR_Node ; + + if(--AR_Node.mi_Balance==0) + return ZNsMain::ZNsEnum::ZEAVL_INSERT_OK; + else + return ZNsMain::ZNsEnum::ZEAVL_INSERT_LEFT; + //else + } + else /* AR_Node.mp_RighNode!=0 */ + { + int VI_AddState = AddKey + (*AR_Node.mp_LeftNode, AR_Key, APR_CNode); + + if(VI_AddState==ZNsMain::ZNsEnum::ZEAVL_INSERT_NONE) + { + return ZNsMain::ZNsEnum::ZEAVL_INSERT_NONE; + } + if(VI_AddState!=ZNsMain::ZNsEnum::ZEAVL_INSERT_OK) + { + if(AR_Node.mi_Balance==-1) + { + Balance(&AR_Node, VI_AddState); return ZNsMain::ZNsEnum::ZEAVL_INSERT_OK; + } + else if(--AR_Node.mi_Balance==0) + { + return ZNsMain::ZNsEnum::ZEAVL_INSERT_OK; + } + else + { + return ZNsMain::ZNsEnum::ZEAVL_INSERT_LEFT; + }/* + else*/ + }/* + if(VI_AddState!=ZNsMain::ZNsEnum::ZEAVL_INSERT_OK)*/ + + return ZNsMain::ZNsEnum::ZEAVL_INSERT_OK; + }/* + else // AR_Node.mp_RighNode!=0 */ + }/* + template + int AddKey(ZCNode& AR_Node, TKey AR_Key, ZCNode*& APR_CNode) */ + + + int AddNode(ZCNode& AR_Node, ZCNode& AR_AddNode) + { + using ZNsMain::ZNsEnum::ZECompareResult_Equal ; + + #if(_CODE_NEW_) + int VI_CompareResultCode = + ( + TypeCompare::ZEUseCompareObj>0 ? + TypeCompare::Exec + (AR_Node.GetData(), AR_AddNode.GetData()) : + ZECompareResult_Equal + ); + ////////////////////////// + + const bool CB_IsEqual = + ( + TypeCompare::ZEUseCompareObj>0 ? + VI_CompareResultCode==ZECompareResult_Equal : + AR_Node.GetData() ==AR_AddNode.GetData() + ) ; + /////////////////////// + #endif + + #if(_CODE_OLD_) + if(AR_Node.GetData()==AR_AddNode.GetData()) + #else + if(CB_IsEqual) + #endif + { + this->TTypBase::OnEqual(AR_AddNode.GetData(), &AR_Node); + + return ZNsMain::ZNsEnum::ZEAVL_INSERT_NONE; + }/* + if(CB_IsEqual)*/ + + + const bool CB_IsLess = + ( + TypeCompare::ZEUseCompareObj>0 ? + VI_CompareResultCodeAR_Type) + + if(AR_Node.mp_LeftNode==0) + { + (void)JoinBefore(&AR_Node, &AR_AddNode); + + AR_Node. mp_LeftNode=&AR_AddNode; + AR_AddNode.mp_HighNode=&AR_Node ; + + if(--AR_Node.mi_Balance==0) + return ZNsMain::ZNsEnum::ZEAVL_INSERT_OK; + else + return ZNsMain::ZNsEnum::ZEAVL_INSERT_LEFT; + //else + } + else /* AR_Node.mp_RighNode!=0 */ + { + int VI_AddState = AddNode(*AR_Node.mp_LeftNode, AR_AddNode); + + if(VI_AddState==ZNsMain::ZNsEnum::ZEAVL_INSERT_NONE) + { + return ZNsMain::ZNsEnum::ZEAVL_INSERT_NONE; + } + if(VI_AddState!=ZNsMain::ZNsEnum::ZEAVL_INSERT_OK) + { + if(AR_Node.mi_Balance==-1) + { + Balance(&AR_Node,VI_AddState); return ZNsMain::ZNsEnum::ZEAVL_INSERT_OK; + } + else if(--AR_Node.mi_Balance==0) + { + return ZNsMain::ZNsEnum::ZEAVL_INSERT_OK; + } + else + { + return ZNsMain::ZNsEnum::ZEAVL_INSERT_LEFT; + }/* + else*/ + }/* + if(VI_AddState!=ZNsMain::ZNsEnum::ZEAVL_INSERT_OK)*/ + + return ZNsMain::ZNsEnum::ZEAVL_INSERT_OK; + }/* + else // AR_Node.mp_RighNode!=0 */ + }/* + int AddNode(ZCNode& AR_Node, ZCNode& AR_AddNode)*/ + + + inline ZCNode* JoinBefore(ZCNode* AP_StdNode, ZCNode* AP_Insert) + { + /* AP_StdNode 앞에 AP_Insert 를 삽입 */ + + #ifdef _DEBUG + + /* AP_StdNode 는 현재의 리스트에 속해 있어야 하며 */ + /* AP_Insert 는 현재의 리스트에 속해 있지 않아야 한다. */ + + if(FindNode(AP_StdNode)==0 || FindNode(AP_Insert)!=0) + { + std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); + fileout<InsertBefore(AP_Insert), ++ml_NodeSize); + + return (AP_StdNode==mp_HeadNode) ? mp_HeadNode=AP_Insert : AP_Insert ; + }/* + inline ZCNode* JoinBefore(ZCNode* AP_StdNode, ZCNode* AP_Insert)*/ + + inline ZCNode* JoinBefore(ZCNode* AP_StdNode, TTypArg AR_Type) + { + ZCNode* VP_NewNode=new ZCNode; + + #if(_CODE_NEW_) + if(TypeMoveObj::ZEUseMoveObj>0) + TypeMoveObj::Exec(VP_NewNode->mo_Type, AR_Type); + else + #endif + VP_NewNode->mo_Type=AR_Type; + + return JoinBefore(AP_StdNode, VP_NewNode); + }/* + inline ZCNode* JoinBefore(ZCNode* AP_StdNode, TTypArg AR_Type)*/ + + template + inline ZCNode* JoinBeforeKey(ZCNode* AP_StdNode, TKey AR_Key) + { + ZCNode* VP_NewNode=new ZCNode; + + #if(_CODE_NEW_) + if(TypeMoveObj::ZEUseMoveObj>0) + TypeMoveObj::Exec(VP_NewNode->mo_Type, AR_Key); + else + #endif + VP_NewNode->mo_Type=AR_Key; + + return JoinBefore(AP_StdNode, VP_NewNode); + }/* + template + inline ZCNode* JoinBeforeKey(ZCNode* AP_StdNode, TTypArg AR_Key) */ + + inline ZCNode* JoinAfter(ZCNode* AP_StdNode, ZCNode* AP_Insert) + { + /* AP_StdNode 뒤에 AP_Insert 를 삽입 */ + + #ifdef _DEBUG + + /* AP_StdNode 는 현재의 리스트에 속해 있어야 하며 */ + /* AP_Insert 는 현재의 리스트에 속해 있지 않아야 한다. */ + + if(FindNode(AP_StdNode)==0 || FindNode(AP_Insert)!=0) + { + std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); + fileout<InsertAfter(AP_Insert), ++ml_NodeSize); return AP_Insert; + }/* + inline ZCNode* JoinAfter(ZCNode* AP_StdNode, ZCNode* AP_Insert)*/ + + inline ZCNode* JoinAfter(ZCNode* AP_StdNode, TTypArg AR_Type) + { + ZCNode* VP_NewNode=new ZCNode; + + #if(_CODE_NEW_) + if(TypeMoveObj::ZEUseMoveObj>0) + TypeMoveObj::Exec(VP_NewNode->mo_Type, AR_Type); + else + #endif + VP_NewNode->mo_Type=AR_Type; + + return JoinAfter(AP_StdNode, VP_NewNode); + }/* + inline ZCNode* JoinAfter(ZCNode* AP_StdNode, TTypArg AR_Type)*/ + + template + inline ZCNode* JoinAfterKey(ZCNode* AP_StdNode, TKey AR_Key) + { + ZCNode* VP_NewNode=new ZCNode; + + #if(_CODE_NEW_) + if(TypeMoveObj::ZEUseMoveObj>0) + TypeMoveObj::Exec(VP_NewNode->mo_Type, AR_Key); + else + #endif + VP_NewNode->mo_Type=AR_Key; + + return JoinAfter(AP_StdNode, VP_NewNode); + }/* + template + inline ZCNode* JoinAfterKey(ZCNode* AP_StdNode, TTypArg AR_Key) */ + + #ifdef _DEBUG + + static void DEBUG_EachNode(ZCNode& AR_Node, std::fstream& fileout) + { + fileout<<"Node Ptr = "<<&AR_Node<mp_LeftNode, fileout, pf_DEBUG_EachNode); + DEBUG_PreOrder(AP_Node->mp_RighNode, fileout, pf_DEBUG_EachNode); + }/* + if(AP_Node!=0)*/ + }/* + static void DEBUG_PreOrder( ZCNode* AP_Node, + std::fstream& fileout, + void pf_DEBUG_EachNode(ZCNode&, std::fstream&) + ///////////////////////// ) */ + + #endif //_DEBUG + + ZCNode* Balance(ZCNode* AP_Node, int AI_AddState) + { + /*////////////////////////////////////////////// + + ■ 평형을 맞추는 멤버 함수다. + + AI_AddState 은 아래 두 값 중의 하나다. + + ZNsMain::ZNsEnum::ZEAVL_INSERT_LEFT -1 + ZNsMain::ZNsEnum::ZEAVL_INSERT_RIGHT +1 + + AP_Node 은 회전하는 노드 중에서 가장 높은 노드. + + 평형을 이루는 꼭지점에 해당하는 노드를 반환한다. + 이 정보는 노드를 삭제한 다음에 + 평형을 다시 이루어야 할 때 필요하다. + + //////////////////////////////////////////////*/ + + ZCNode* VP_HighNode=AP_Node->mp_HighNode; + ZCNode* VP_DownNode=0; + ZCNode* VP_DownDown=0; + + // AI_AddState 은 VP_DownNode 의 평형계수와 같다. + + if(AP_Node->mi_Balance==1) + { + if(AI_AddState>=0) // AI_AddState==ZNsMain::ZNsEnum::ZEAVL_INSERT_RIGHT || AI_AddState==0 + { + /* AI_AddState==ZNsMain::ZNsEnum::ZEAVL_INSERT_RIGHT + * + * 1 (AP_Node) + * * + * * + * 2 (VP_DownNode) + * * + * * + * 3 (VP_DownDown) + */ + + /* AI_AddState==0 이때는 AP_Node->mp_LeftNode 가 삭제되는 때이다. + * + * 1 (AP_Node) + * * + * * + * 3 (VP_DownNode) + * * * + * * * + * 2 4 (VP_DownDown) + */ + + VP_DownNode=AP_Node->mp_RighNode ; + VP_DownDown=VP_DownNode->mp_RighNode; + AP_Node ->mi_Balance = (AI_AddState==ZNsMain::ZNsEnum::ZEAVL_INSERT_RIGHT ? 0 : 1 ); + --VP_DownNode->mi_Balance ; + AP_Node ->mp_RighNode=VP_DownNode->mp_LeftNode; + AP_Node ->mp_HighNode=VP_DownNode; + VP_DownNode->mp_LeftNode=AP_Node ; + + if(AP_Node->mp_RighNode!=0) + AP_Node->mp_RighNode->mp_HighNode=AP_Node; + /*endif*/ + + VP_DownNode->mp_HighNode=VP_HighNode; + + if(VP_HighNode==0) /* AP_Node==mp_RootNode */ + { + mp_RootNode=VP_DownNode; + } + else if(VP_HighNode->mp_RighNode==AP_Node) + { + VP_HighNode->mp_RighNode=VP_DownNode; + } + else + { + VP_HighNode->mp_LeftNode=VP_DownNode; + }/* + else*/ + + return VP_DownNode; + } + else // if(AI_AddState<0) + { + /* '>' 형태 + * + * 1 (AP_Node) + * * * + * * * + * 0 3 (VP_DownNode) + * * * + * * * + * 2 (VP_DownDown) + * * + * * + * 1.5 + */ + + VP_DownNode=AP_Node->mp_RighNode ; + VP_DownDown=VP_DownNode->mp_LeftNode; + AP_Node ->mi_Balance =(VP_DownDown->mi_Balance<=0 ? 0 : -1); + VP_DownNode->mi_Balance =(VP_DownDown->mi_Balance>=0 ? 0 : 1); + VP_DownDown->mi_Balance =0 ; + AP_Node ->mp_RighNode=VP_DownDown->mp_LeftNode; + VP_DownNode->mp_LeftNode=VP_DownDown->mp_RighNode; + VP_DownDown->mp_LeftNode=AP_Node ; + VP_DownDown->mp_RighNode=VP_DownNode; + AP_Node ->mp_HighNode=VP_DownDown; + VP_DownNode->mp_HighNode=VP_DownDown; + VP_DownDown->mp_HighNode=VP_HighNode; + + if(AP_Node->mp_RighNode!=0) + AP_Node->mp_RighNode->mp_HighNode=AP_Node; + if(VP_DownNode->mp_LeftNode!=0) + VP_DownNode->mp_LeftNode->mp_HighNode=VP_DownNode; + + if(VP_HighNode==0) /* AP_Node==mp_RootNode */ + { + mp_RootNode=VP_DownDown; + } + else if(VP_HighNode->mp_RighNode==AP_Node) + { + VP_HighNode->mp_RighNode=VP_DownDown; + } + else + { + VP_HighNode->mp_LeftNode=VP_DownDown; + }/* + else*/ + + return VP_DownDown; + }/* + else // if(AI_AddState<0)*/ + } + else // AP_Node->mi_Balance==-1 + { + // 위 주석에서도 설명했지만 AI_AddState 은 VP_DownNode 의 평형계수와 같다. + + if(AI_AddState==ZNsMain::ZNsEnum::ZEAVL_INSERT_RIGHT) // ZNsMain::ZNsEnum::ZEAVL_INSERT_RIGHT==1 + { + /* '<' 형태 + * + * 3 (AP_Node) + * * * + * * * + *(VP_DownNode) 1 4 + * * * * + * * * * + * (VP_DownDown) 2 5 + * * * * + * * * * + * -1 1.5 2.5 + * * + * * + * 2.6 + * + */ + + VP_DownNode=AP_Node->mp_LeftNode ; + VP_DownDown=VP_DownNode->mp_RighNode; + AP_Node ->mi_Balance =(VP_DownDown->mi_Balance>=0 ? 0 : 1); + VP_DownNode->mi_Balance =(VP_DownDown->mi_Balance<=0 ? 0 : -1); + VP_DownDown->mi_Balance =0 ; + AP_Node ->mp_LeftNode=VP_DownDown->mp_RighNode; + VP_DownNode->mp_RighNode=VP_DownDown->mp_LeftNode; + VP_DownDown->mp_RighNode=AP_Node ; + VP_DownDown->mp_LeftNode=VP_DownNode; + VP_DownNode->mp_HighNode=VP_DownDown; + AP_Node ->mp_HighNode=VP_DownDown; + VP_DownDown->mp_HighNode=VP_HighNode; + + if(AP_Node->mp_LeftNode!=0) + AP_Node->mp_LeftNode->mp_HighNode=AP_Node; + if(VP_DownNode->mp_RighNode!=0) + VP_DownNode->mp_RighNode->mp_HighNode=VP_DownNode; + + if(VP_HighNode==0) /* AP_Node==mp_RootNode */ + { + mp_RootNode=VP_DownDown; + } + else if(VP_HighNode->mp_RighNode==AP_Node) + { + VP_HighNode->mp_RighNode=VP_DownDown; + } + else + { + VP_HighNode->mp_LeftNode=VP_DownDown; + }/* + else*/ + + return VP_DownDown; + } + else // AI_AddState==ZNsMain::ZNsEnum::ZEAVL_INSERT_LEFT || AI_AddState==0 + { + /* AI_AddState==ZNsMain::ZNsEnum::ZEAVL_INSERT_LEFT + * + * 3 (AP_Node) + * * + * * + * 2 (VP_DownNode) + * * + * * + * 1 (VP_DownDown) + */ + + /* AI_AddState==0 이때는 AP_Node->mp_RighNode 가 삭제되는 경우이다. + * + * 4 (AP_Node) + * * + * * + * 2 (VP_DownNode) + * * * + * * * + *(VP_DownDown)1 3 + */ + + VP_DownNode=AP_Node->mp_LeftNode ; + VP_DownDown=VP_DownNode->mp_LeftNode; + AP_Node ->mi_Balance = ( AI_AddState==ZNsMain::ZNsEnum::ZEAVL_INSERT_LEFT ? 0 : -1 ) ; + ++VP_DownNode->mi_Balance ; + AP_Node ->mp_LeftNode=VP_DownNode->mp_RighNode; + VP_DownNode->mp_RighNode=AP_Node ; + AP_Node ->mp_HighNode=VP_DownNode; + + if(AP_Node->mp_LeftNode!=0) + { AP_Node->mp_LeftNode->mp_HighNode=AP_Node; } + + VP_DownNode->mp_HighNode=VP_HighNode; + + if(VP_HighNode==0) /* AP_Node==mp_RootNode */ + { + mp_RootNode=VP_DownNode; + } + else if(VP_HighNode->mp_RighNode==AP_Node) + { + VP_HighNode->mp_RighNode=VP_DownNode; + } + else + { + VP_HighNode->mp_LeftNode=VP_DownNode; + }/* + else*/ + + return VP_DownNode; + }/* + else // AI_AddState==ZNsMain::ZNsEnum::ZEAVL_INSERT_LEFT || AI_AddState==0*/ + }/* + else // AP_Node->mi_Balance==-1*/ + }/* + ZCNode* Balance(ZCNode* AP_Node,int AI_AddState)*/ + + private: + };/* + template< typename Type , + typename TTypArg =const Type& , + typename TTypBase =ZNsMain::ZNsIFace::ZtCAVL_BASE , + typename TNodeBase =ZNsMain::ZNsIFace::ZtCAVL_NodeBase , + typename TAlloc =ZNsMain::ZCAllocator , + typename TSize =ZNsMain::ZTypLong , + typename TCompare =ZNsMain::ZNsFunc::ZtCCompare, + typename TMoveObj =ZNsMain::ZNsFunc::ZtCMoveObj + > + class ZtCObjAVL /////////////////////////////////////////////////////////////////////*/ + +}/* +namespace ZNsMain */ + + +/*######################################################################################### + +■ ZtCObjAVL 예제 -- 2025-08-11 20:43 + + #include + #include "ZCppMain/ZtCObjAVL.H" + + using namespace std ; + using namespace ZNsMain; + + void ShowDataInNode(int AI_Data) + { + cout<<"* Node Data : "< VO_CObjAVL; + + VO_CObjAVL.AddData(10); + VO_CObjAVL.AddData(20); + VO_CObjAVL.AddData(30); + VO_CObjAVL.AddData(40); + VO_CObjAVL.AddData(9 ); + + cout<<"# In Order" <, + typename TTypBase =ZNsMain::ZNsIFace::ZtCAVL_BASE , + typename TNodeBase =ZNsMain::ZNsIFace::ZtCAVL_NodeBase , + typename TAlloc =ZNsMain::ZCAllocator , + typename TSize =long , + typename TMoveObj =ZNsMain::ZNsFunc::ZtCMoveObj + > + class ZtCParamObjAVL_Compare ////////////////////////////////////////////////////////// + { + public: typedef ZNsMain::ZtCObjAVL< + Type, TTypArg, TTypBase, TNodeBase, TAlloc, TSize, TCompare, TMoveObj> TypeData; + };/* + template< typename Type , + typename TTypArg =const Type& , + typename TCompare =ZNsMain::ZNsFunc ::ZtCCompare, + typename TTypBase =ZNsMain::ZNsIFace::ZtCAVL_BASE , + typename TNodeBase =ZNsMain::ZNsIFace::ZtCAVL_NodeBase , + typename TAlloc =ZNsMain::ZCAllocator , + typename TSize =long , + typename TMoveObj =ZNsMain::ZNsFunc::ZtCMoveObj + > + class ZtCParamObjAVL_Compare ////////////////////////////////////////////////////////*/ + + }/* + namespace ZNsTmplParam*/ + +}/* +namespace ZNsMain*/ + + +#endif //__ZNSMAIN_ZTOBJAVL_H__ + + +/*////////////////////////////////////////////////////////////////////////// + +■ Red Black Tree : http://www.ezdoum.com/stories.php?story=02/06/26/9759347 + + ※ 빨강-검정 나무의 성질 (c 로 배우는 알고리즘 - 이재규 지음) + + 1. 각 외부 노드로 가는 경로의 검정 노드의 수는 같다. + 2. 새로 삽입되는 노드는 빨강 노드이다. + 3. 경로상에 연이어 두 개의 빨강 노드가 나타날 수 없다.(회전 필요) + 4. 부모의 두 자식 노드가 모두 빨강 노드이면 부모는 빨강 노드로 하고 + 자식은 검정 노드로 바꿀 수 있다. (색상변환) + 5. 루트 노드는 빨강 노드일 수 없다. 검정색으로 바뀜 + 6. 빨강 노드는 자식이 없든가 있으면 두 개의 검정 노드여야 한다. + 7. 검정 노드는 자식이 없던가 있으면 + 하나의 빨강 노드나 두 개의 빨강 노드나 두개의 검정 노드를 가진다. + 단 하나의 검정 노드를 자식으로 가질 수 없다. + + 걀걀걀... + +//////////////////////////////////////////////////////////////////////////*/ diff --git a/ZCppMain/ZtCObjList.H b/ZCppMain/ZtCObjList.H index ba98ba6..35127b2 100644 --- a/ZCppMain/ZtCObjList.H +++ b/ZCppMain/ZtCObjList.H @@ -1,10 +1,10 @@ + + +#ifndef __ZCPPMAIIN__ZTCOBJLIST_H__ +#define __ZCPPMAIIN__ZTCOBJLIST_H__ -#ifndef __NSCPP_COBJLIST_H__ -#define __NSCPP_COBJLIST_H__ - - -#include "ZtCSortObjList.H" +#include "ZCppMain/ZtCSortObjList.H" namespace ZNsMain @@ -12,35 +12,40 @@ namespace ZNsMain /*///////////////////////////////////////////////////////////////// - ■ std::CDoubleList template 이나 std::ZtCObjList template 와는 달리 - 단순하게 구현되어 있는 연결리스트 class ZtCObjList 를 만든다. - - ■ typename TypCInit 는 별다른 역할을 하지 않고 있다. 다른 리스트 + ■ typename TTypCInit 는 별다른 역할을 하지 않고 있다. 다른 리스트 클래스와 템플릿 인수를 비슷하게 맞추기 위해, 그리고 차후의 설계 를 위해 일단 이대로 두자. + ■ typename ZCInit 가 필요한지 모르겠다. 일단 주석으로 막는다. + + -- 2025-08-11 14:47 + + ZtCTreeData.H 에서 ZtCObjList<> 에서 TTypCInit 자리에 형을 지정 + 하고 있다. 쓰긴 쓰니까 주석을 해제하자. -- 2025-08-14 13:43 + /////////////////////////////////////////////////////////////////*/ template class ZtCSortObjList; - template< typename Type , - typename TypCArg =const Type&, - typename TypCAlloc=ZCAllocator, - typename TypCInit =ZCInit , - typename TypSize =ZTypLong + template< typename TType , + typename TTypCArg =const TType&, + typename TTypCAlloc=ZCAllocator , + typename TTypCInit =ZCInit , + typename TTypSize =ZTypLong > - class ZtCObjList + class ZtCObjList //////////////////////////// { public: template friend class ZtCSortObjList; public: - typedef Type TypeData ; - typedef TypCArg TypeArg ; - typedef TypCAlloc TypeAlloc; - typedef TypCInit TypeInit ; - typedef TypSize TypeSize ; + typedef TType Type ; + typedef TType TypeData ; + typedef TTypCArg TypeArg ; + typedef TTypCAlloc TypeAlloc; + //typedef TTypCInit TypeInit ; + typedef TTypSize TypeSize ; public: class ZCIterator; class ZCLink ; @@ -50,15 +55,15 @@ namespace ZNsMain typedef const ZCIterator const_iterator; public: - class ZCLink : public TypCAlloc + class ZCLink : public TypeAlloc { public : template friend class ZtCSortObjList; /*##########################*/ friend class ZtCObjList ; private: - Type mo_Type ; - ZCLink* mp_NextLink; - ZCLink* mp_PrevLink; + TypeData mo_Type ; + ZCLink* mp_NextLink; + ZCLink* mp_PrevLink; private: static void JoinLink(ZCLink* AP_PrevLink, ZCLink* AP_NextLink) @@ -83,34 +88,34 @@ namespace ZNsMain mp_NextLink=0; mp_PrevLink=0; }/* - ZCLink(TypCArg AR_Type)*/ + ZCLink()*/ - ZCLink(TypCArg AR_Type):mo_Type(AR_Type) + ZCLink(TypeArg AR_Type):mo_Type(AR_Type) { mp_NextLink=0; mp_PrevLink=0; }/* - ZCLink(TypCArg AR_Type)*/ + ZCLink(TypeArg AR_Type)*/ ZCLink(const ZCLink& rhs):mo_Type(rhs.mo_Type) { mp_NextLink=0; mp_PrevLink=0; }/* - ZCLink(TypCArg AR_Type)*/ + ZCLink(const ZCLink& rhs)*/ - operator Type& (){return mo_Type;} - operator Type (){return mo_Type;} - Type& GetData (){return mo_Type;} - Type& operator*(){return mo_Type;} + operator Type& (){return mo_Type;} + operator Type (){return mo_Type;} + Type& GetData (){return mo_Type;} + Type& operator*(){return mo_Type;} - operator const Type& () const{return mo_Type;} - const Type& GetData () const{return mo_Type;} - const Type& operator*() const{return mo_Type;} + operator const Type& () const{return mo_Type;} + const Type& GetData () const{return mo_Type;} + const Type& operator*() const{return mo_Type;} - ZCLink* GetNextPrevPtr(TypSize AL_FarNum) // AL_FarNum 은 0 이거나 음수일 수 있다. + ZCLink* GetNextPrevPtr(TypeSize AL_FarNum) // AL_FarNum 은 0 이거나 음수일 수 있다. { ZCLink* VP_TmpLink=this; @@ -126,9 +131,9 @@ namespace ZNsMain return VP_TmpLink; }/* - ZCLink* GetNextPrevPtr(TypSize AL_FarNum)*/ + ZCLink* GetNextPrevPtr(TypeSize AL_FarNum)*/ - const ZCLink* GetNextPrevPtr(TypSize AL_FarNum) const // or ZCLink const * const GetNextPrevPtr(TypSize AL_FarNum) const + const ZCLink* GetNextPrevPtr(TypeSize AL_FarNum) const // or ZCLink const * const GetNextPrevPtr(TypeSize AL_FarNum) const { ZCLink* VP_TmpLink=const_cast(this); @@ -144,7 +149,7 @@ namespace ZNsMain return VP_TmpLink; }/* - const ZCLink* GetNextPrevPtr(TypSize AL_FarNum) const*/ + const ZCLink* GetNextPrevPtr(TypeSize AL_FarNum) const*/ ZCLink* GetNextPtr(){return mp_NextLink;} @@ -154,56 +159,54 @@ namespace ZNsMain const ZCLink* GetPrevPtr() const{return mp_PrevLink;} - ZCLink* GetNextPtr(TypSize AL_Distance) + ZCLink* GetNextPtr(TypeSize AL_Distance) { - TypSize VL_LoopIndex=0; - - ZCLink* VP_TmpLink=this; + TypeSize VL_LoopIndex=0 ; + ZCLink* VP_TmpLink =this; while(VL_LoopIndex++mp_NextLink; return VP_TmpLink; }/* - ZCLink* GetNextPtr(TypSize AL_Distance)*/ + ZCLink* GetNextPtr(TypeSize AL_Distance)*/ - ZCLink* GetPrevPtr(TypSize AL_Distance) + ZCLink* GetPrevPtr(TypeSize AL_Distance) { - TypSize VL_LoopIndex=0 ; - ZCLink* VP_TmpLink =this; + TypeSize VL_LoopIndex=0 ; + ZCLink* VP_TmpLink =this; while(VL_LoopIndex++mp_PrevtLink; return VP_TmpLink; }/* - ZCLink* GetPrevPtr(TypSize AL_Distance)*/ + ZCLink* GetPrevPtr(TypeSize AL_Distance)*/ - const ZCLink* GetNextPtr(TypSize AL_Distance) const + const ZCLink* GetNextPtr(TypeSize AL_Distance) const { - TypSize VL_LoopIndex=0; - - ZCLink* VP_TmpLink=const_cast(this); + TypeSize VL_LoopIndex=0 ; + ZCLink* VP_TmpLink =const_cast(this); while(VL_LoopIndex++mp_NextLink; return VP_TmpLink; }/* - const ZCLink* GetNextPtr(TypSize AL_Distance) const*/ + const ZCLink* GetNextPtr(TypeSize AL_Distance) const*/ - const ZCLink* GetPrevPtr(TypSize AL_Distance) const + const ZCLink* GetPrevPtr(TypeSize AL_Distance) const { - TypSize VL_LoopIndex=0; - ZCLink* VP_TmpLink =const_cast(this); + TypeSize VL_LoopIndex=0 ; + ZCLink* VP_TmpLink = const_cast(this) ; while(VL_LoopIndex++mp_PrevtLink; return VP_TmpLink; }/* - const ZCLink* GetPrevPtr(TypSize AL_Distance) const*/ + const ZCLink* GetPrevPtr(TypeSize AL_Distance) const*/ public: @@ -213,41 +216,41 @@ namespace ZNsMain /*public :*/ protected: - ZCLink* mp_HeadLink; - TypSize ml_Size ; + ZCLink* mp_HeadLink; + TypeSize ml_Size ; protected: virtual void OnDelete( - ZCLink* AP_CutHead, TypSize AI_CutHeadPos, - ZCLink* AP_CutTail, TypSize AI_CutTailPos + ZCLink* AP_CutHead, TypeSize AI_CutHeadPos, + ZCLink* AP_CutTail, TypeSize AI_CutTailPos /*//////////*/ ) { // 상속클래스에서 추가된 멤버 데이타가 링크의 삭제시 변해야 하는 값이라면 // 이 함수를 overload 하여 값을 조종한다. }/* virtual void OnDelete( - ZCLink* AP_CutHead,TypSize AI_CutHeadPos, - ZCLink* AP_CutTail,TypSize AI_CutTailPos + ZCLink* AP_CutHead, TypeSize AI_CutHeadPos, + ZCLink* AP_CutTail, TypeSize AI_CutTailPos ////////////// ) */ virtual void OnInsert( - TypSize AI_InsertPos , // 삽입되는 위치 - TypSize AI_InsertSize, // 삽입되는 링크의 갯수 - ZCLink* AP_HeadInsert // 삽입되는 첫번째 링크의 포인터 + TypeSize AI_InsertPos , // 삽입되는 위치 + TypeSize AI_InsertSize, // 삽입되는 링크의 갯수 + ZCLink* AP_HeadInsert // 삽입되는 첫번째 링크의 포인터 /*//////////*/ ) { // 상속클래스에서 추가된 멤버 데이타가 링크의 삽입시 변해야 하는 값이라면 // 이 함수를 overload 하여 값을 조종한다. }/* virtual void OnInsert( - TypSize AI_InsertPos , - TypSize AI_InsertSize, - ZCLink* AP_HeadInsert + TypeSize AI_InsertPos , + TypeSize AI_InsertSize, + ZCLink* AP_HeadInsert ////////////// ) */ - void JoinAfter(ZCLink* AP_LinkInsert, ZCLink* AP_LinkStd, TypSize AL_PosStd) + void JoinAfter(ZCLink* AP_LinkInsert, ZCLink* AP_LinkStd, TypeSize AL_PosStd) { // AP_LinkInsert 를 AL_PosStd 번째 링크인 AP_LinkStd 뒤에 삽입한다. // AL_PosStd==0 이면 맨 앞에 삽입한다. @@ -285,10 +288,10 @@ namespace ZNsMain }/* else*/ }/* - void JoinAfter(ZCLink* AP_LinkInsert, ZCLink* AP_LinkStd, TypSize AL_PosStd)*/ + void JoinAfter(ZCLink* AP_LinkInsert, ZCLink* AP_LinkStd, TypeSize AL_PosStd)*/ - public : void JoinAfter(ZtCObjList& AO_CObjList, ZCLink* AP_LinkStd, TypSize AL_PosStd) + public : void JoinAfter(ZtCObjList& AO_CObjList, ZCLink* AP_LinkStd, TypeSize AL_PosStd) { #ifdef _DEBUG @@ -298,7 +301,7 @@ namespace ZNsMain fileout<mp_NextLink, + ZCLink::MakeCircle( mp_HeadLink=mp_HeadLink->mp_NextLink, AP_CutLink->mp_PrevLink - /*////////////*/ ); + /*/////////////*/ ); }/* else*/ } @@ -370,10 +373,10 @@ namespace ZNsMain return (--ml_Size, AP_CutLink); }/* - ZCLink* CutLink(ZCLink* AP_CutLink)*/ + protected: ZCLink* CutLink(ZCLink* AP_CutLink)*/ - ZCLink* CutLink(ZCLink* AP_CutLink, TypSize AL_CutPos) + ZCLink* CutLink(ZCLink* AP_CutLink, TypeSize AL_CutPos) { OnDelete(AP_CutLink, AL_CutPos, AP_CutLink, AL_CutPos); @@ -383,9 +386,9 @@ namespace ZNsMain mp_HeadLink=0; else { - ZCLink::MakeCircle( mp_HeadLink=mp_HeadLink->mp_NextLink, + ZCLink::MakeCircle( mp_HeadLink=mp_HeadLink->mp_NextLink, AP_CutLink->mp_PrevLink - /*////////////*/ ); + /*/////////////*/ ); }/* else*/ } @@ -395,13 +398,16 @@ namespace ZNsMain return (--ml_Size, AP_CutLink); }/* - ZCLink* CutLink(ZCLink* AP_CutLink, TypSize AL_CutPos)*/ + ZCLink* CutLink(ZCLink* AP_CutLink, TypeSize AL_CutPos)*/ - ZtCObjList& CutLink( - ZCLink* AP_CutHead, TypSize AL_CutHeadPos, - ZCLink* AP_CutTail, TypSize AL_CutTailPos, ZtCObjList& ARR_StoreList - /*//////////////*/ ) + ZtCObjList& CutLink /*########################################################*/ + ( + ZCLink* AP_CutHead, TypeSize AL_CutHeadPos, + ZCLink* AP_CutTail, TypeSize AL_CutTailPos, + ZtCObjList& ARR_StoreList + ) + /*#############################################################################*/ { // AP_CutHead 는 삭제하려는 링크의 범위의 앞의 링크, AL_CutHeadPos 는 그 위치 // AP_CutTail 은 삭제하려는 링크의 범위의 뒤의 링크, AL_CutTailPos 는 그 위치 @@ -414,8 +420,8 @@ namespace ZNsMain { std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); fileout<AL_CutTailPos"<GetNextPrevPtr(AL_FarNum) 링크까지를 복사한다. // AL_FarNum 은 0 이거나 음수일 수 있다. @@ -499,8 +510,8 @@ namespace ZNsMain { std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); fileout<(AP_CopyLink), - AL_FarNum , - VP_HeadLink, - VP_TailLink - /*//////////*/ ); ////////////////////////////// + GetManyLinkCopy ///////////////////////////// + ( + const_cast(AP_CopyLink), + AL_FarNum , + VP_HeadLink , + VP_TailLink + ); + ///////////////////////////////////////////// ZCLink::MakeCircle(VP_HeadLink, VP_TailLink); @@ -528,10 +542,13 @@ namespace ZNsMain return ARR_StoreList; }/* - ZtCObjList& CopyLink( const ZCLink* AP_CopyLink, - TypSize AL_FarNum , - ZtCObjList& ARR_StoreList - ///////////////// ) const */ + ZtCObjList& CopyLink ########################################################### + ( + const ZCLink* AP_CopyLink , + TypeSize AL_FarNum , + ZtCObjList& ARR_StoreList + ) const + ###############################################################################*/ ZtCObjList& CopyThis(ZtCObjList& ARR_StoreList) const @@ -541,7 +558,7 @@ namespace ZNsMain ZtCObjList& CopyThis(ZtCObjList& ARR_StoreList) const*/ - ZtCObjList& MakeDefault(TypSize AL_DefaultSize, ZtCObjList& ARR_StoreList) const + ZtCObjList& MakeDefault(TypeSize AL_DefaultSize, ZtCObjList& ARR_StoreList) const { // must AL_DefaultSize > 0 @@ -556,14 +573,11 @@ namespace ZNsMain return ARR_StoreList; }/* - ZtCObjList& MakeDefault(TypSize AL_DefaultSize, ZtCObjList& ARR_StoreList) const*/ + ZtCObjList& MakeDefault(TypeSize AL_DefaultSize, ZtCObjList& ARR_StoreList) const*/ void GetManyLink( - TypSize AL_LinkSize , - ZCLink*& APR_HeadLink, - ZCLink*& APR_TailLink - /*///////////*/ ) const + TypeSize AL_LinkSize , ZCLink*& APR_HeadLink, ZCLink*& APR_TailLink) const { #ifdef _DEBUG ZNsMain::ZCCheckAlloc::ZCAllowAlloc VO_CAllowAllocObj; @@ -571,27 +585,26 @@ namespace ZNsMain APR_HeadLink=new ZCLink; ZCLink* VP_TempLink=APR_HeadLink; - for(TypSize i=2; i<=AL_LinkSize; ++i) + for(TypeSize i=2; i<=AL_LinkSize; ++i) { ZCLink::JoinLink(VP_TempLink, new ZCLink); VP_TempLink=VP_TempLink->mp_NextLink; }/* - for(TypSize i=2; i<=AL_LinkSize; ++i)*/ + for(TypeSize i=2; i<=AL_LinkSize; ++i)*/ APR_TailLink=VP_TempLink; }/* void GetManyLink( - TypSize AL_LinkSize , - ZCLink*& APR_HeadLink, - ZCLink*& APR_TailLink - /////////////// ) const */ + TypeSize AL_LinkSize , ZCLink*& APR_HeadLink, ZCLink*& APR_TailLink) const */ - void GetManyLinkCopy( - ZCLink* AP_CopyLink , TypSize AL_FarNum , - ZCLink*& APR_HeadLink, ZCLink*& APR_TailLink - /*///////////////*/ ) const + void GetManyLinkCopy /*#######################################################*/ + ( + ZCLink* AP_CopyLink , TypeSize AL_FarNum , + ZCLink*& APR_HeadLink, ZCLink*& APR_TailLink + ) const + /*#############################################################################*/ { // AL_FarNum 의 절대값 + 1 개의 링크가 생성된다. @@ -606,7 +619,7 @@ namespace ZNsMain ZCLink* VP_TempLink=APR_HeadLink; - for(TypSize i=1; i<=AL_FarNum; ++i) + for(TypeSize i=1; i<=AL_FarNum; ++i) { AP_CopyLink=AP_CopyLink->mp_NextLink; @@ -615,18 +628,18 @@ namespace ZNsMain VP_TempLink=VP_TempLink->mp_NextLink; }/* - for(TypSize i=1; i<=AL_FarNum; ++i)*/ + for(TypeSize i=1; i<=AL_FarNum; ++i)*/ APR_TailLink=VP_TempLink; } else //AL_FarNum<=0 { APR_TailLink= - new ZCLink(AP_CopyLink->GetData()); + new ZCLink( AP_CopyLink->GetData() ); ZCLink* VP_TempLink=APR_TailLink; - for(TypSize i=AL_FarNum; i<0; ++i) + for(TypeSize i=AL_FarNum; i<0; ++i) { AP_CopyLink=AP_CopyLink->mp_PrevLink; @@ -635,16 +648,18 @@ namespace ZNsMain VP_TempLink=VP_TempLink->mp_PrevLink; }/* - for(TypSize i=AL_FarNum; i<0; ++i)*/ + for(TypeSize i=AL_FarNum; i<0; ++i)*/ APR_HeadLink=VP_TempLink; }/* else //AL_FarNum<=0*/ }/* - void GetManyLinkCopy( - ZCLink* AP_CopyLink , TypSize AL_FarNum , - ZCLink*& APR_HeadLink, ZCLink*& APR_TailLink - ////////////////// ) const */ + void GetManyLinkCopy ########################################################### + ( + ZCLink* AP_CopyLink , TypeSize AL_FarNum , + ZCLink*& APR_HeadLink, ZCLink*& APR_TailLink + ) const + ###############################################################################*/ /*protected:*/ @@ -685,23 +700,26 @@ namespace ZNsMain ZCLink* pRhsLink=rhs.mp_HeadLink; ZCLink* pLhsLink= mp_HeadLink; - __for1(TypSize, i, ml_Size) + __for1(TypeSize, i, ml_Size) { pLhsLink->GetData()=pRhsLink->GetData(); pLhsLink=pLhsLink->mp_NextLink; pRhsLink=pRhsLink->mp_NextLink; }/* - __for1(TypSize, i, ml_Size)*/ + __for1(TypeSize, i, ml_Size)*/ } else { ZtCObjList VO_StoreList; - CutLink( GetLinkPtr(rhs.ml_Size+1),rhs.ml_Size+1, - GetLinkPtr( ml_Size ), ml_Size , - RR(VO_StoreList) - /****/ ).DeleteAll(); ////////////////////////////// + CutLink /////////////////////////////////////// + ( + GetLinkPtr(rhs.ml_Size+1),rhs.ml_Size+1, + GetLinkPtr( ml_Size ), ml_Size , + RR(VO_StoreList) + ). DeleteAll(); + //////////////////////////////////////////////// }/* else*/ @@ -717,8 +735,8 @@ namespace ZNsMain bool IsEmpty() const*/ - TypSize GetSize() const{return ml_Size;} - TypSize size () const{return ml_Size;} + TypeSize GetSize() const{return ml_Size;} + TypeSize size () const{return ml_Size;} ZCLink* GetHeadLinkPtr(){return mp_HeadLink;} ZCLink* GetTailLinkPtr() @@ -736,24 +754,7 @@ namespace ZNsMain const ZCLink* GetTailLinkPtr() const*/ - IterEasy GetHeadIterEasy (){return GetHeadLinkPtr();} - IterEasy GetTailIterEasy (){return GetTailLinkPtr();} - IterEasyID GetHeadIterEasyID(){return (IterEasyID)GetHeadLinkPtr();} - IterEasyID GetTailIterEasyID(){return (IterEasyID)GetTailLinkPtr();} - - IterEasy GetHeadIterEasy () const{return GetHeadLinkPtr();} - IterEasy GetTailIterEasy () const{return GetTailLinkPtr();} - IterEasyID GetHeadIterEasyID() const{return (IterEasyID)GetHeadLinkPtr();} - IterEasyID GetTailIterEasyID() const{return (IterEasyID)GetTailLinkPtr();} - - IterEasyID ItHead() {return GetHeadIterEasyID();} - IterEasyID ItTail() {return GetTailIterEasyID();} - - IterEasyID ItHead() const{return GetHeadIterEasyID();} - IterEasyID ItTail() const{return GetTailIterEasyID();} - - - Type& operator[](TypSize AL_Index) + Type& operator[](TypeSize AL_Index) { // [] 에 들어가는 AL_Index 은 1 부터 시작하는 첨자이다. @@ -763,7 +764,7 @@ namespace ZNsMain { std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); fileout<GetData(); }/* - Type& operator[](TypSize AL_Index)*/ + Type& operator[](TypeSize AL_Index)*/ - const Type& operator[](TypSize AL_Index) const + const Type& operator[](TypeSize AL_Index) const { #ifdef _DEBUG @@ -784,7 +785,7 @@ namespace ZNsMain { std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); fileout<GetData(); }/* - Type& operator[](TypSize AL_Index) const*/ + Type& operator[](TypeSize AL_Index) const*/ - TypSize Find(TypCArg AR_SearchType, TypSize AL_FirstFindIndex=1, bool AB_DoFindFromFront=true) const + TypeSize Find /*###############################################################*/ + ( + TypeArg AR_SearchType , + TypeSize AL_FirstFindIndex =1 , + bool AB_DoFindFromFront=true + ) const + /*#############################################################################*/ { // AB_DoFindFromFront==true 이면 AL_FirstFindIndex 번째 링크부터 // 다음 링크로 순회하면서 GetData() == AR_SearchType 이 되는 // 최초의 위치를 반환한다. - const bool CB_IsTrue = ( - mp_HeadLink == 0 || - AL_FirstFindIndex < 1 || - AL_FirstFindIndex > ml_Size - /*//////////////////*/ ) ; + const bool CB_IsTrue = ////////////////// + ( + mp_HeadLink == 0 || + AL_FirstFindIndex < 1 || + AL_FirstFindIndex > ml_Size + ) ; + if(CB_IsTrue) return 0; //////////////// - if(CB_IsTrue) return 0; - - TypSize VL_FindIndex=AL_FirstFindIndex; const - ZCLink* VP_TempLink =GetLinkPtr(AL_FirstFindIndex); + TypeSize VL_FindIndex=AL_FirstFindIndex; const + ZCLink* VP_TempLink =GetLinkPtr(AL_FirstFindIndex); if(AB_DoFindFromFront==true) { @@ -841,16 +848,30 @@ namespace ZNsMain return 0; }/* - TypSize Find(TypCArg AR_SearchType, TypSize AL_FirstFindIndex=1, bool AB_DoFindFromFront=true) const*/ + TypeSize Find ################################################################### + ( + TypeArg AR_SearchType , + TypeSize AL_FirstFindIndex =1 , + bool AB_DoFindFromFront=true + ) const + ###############################################################################*/ - TypSize Find(const ZCLink* AP_SearchLink, TypSize AL_FirstFindIndex=1, bool AB_DoFindFromFront=true) const + + TypeSize Find /*##############################################################*/ + ( + const ZCLink* AP_SearchLink , + TypeSize AL_FirstFindIndex =1, + bool AB_DoFindFromFront=true + ) const + /*#############################################################################*/ { if(mp_HeadLink==0 || AL_FirstFindIndex<1 || AL_FirstFindIndex>ml_Size) return 0; - //endif + ////////////////////////////////////////////////////////////////////// - TypSize VL_FindIndex=AL_FirstFindIndex; - ZCLink* VP_TempLink =const_cast(GetLinkPtr(AL_FirstFindIndex)); + TypeSize VL_FindIndex= AL_FirstFindIndex; + ZCLink* VP_TempLink = const_cast + ( GetLinkPtr(AL_FirstFindIndex) ); if(AB_DoFindFromFront==true) { @@ -878,26 +899,34 @@ namespace ZNsMain return 0; }/* - TypSize Find(ZCLink* AP_SearchLink, TypSize AL_FirstFindIndex=1, bool AB_DoFindFromFront=true) const*/ + TypeSize Find ################################################################## + ( + ZCLink* AP_SearchLink , + TypeSize AL_FirstFindIndex =1 , + bool AB_DoFindFromFront=true + ) const + /*#############################################################################*/ /*//////////////////////////////////////////////////////////////////////////////////////// - ■ FindData(TypeCArg, ~) 함수가 없다면, TypeCArg 이 const Type& 으로 정의되어 있는 경우, + ■ FindData(TypeArg, ~) 함수가 없다면, TypeArg 이 const Type& 으로 정의되어 있는 경우, const Type& 에 대해서만 찾기를 수행할 수 있고, Type& 에 대해서는 찾기를 수행할 수 없다. -- 2010-05-29 21:31:00 ////////////////////////////////////////////////////////////////////////////////////////*/ - TypSize FindData(TypCArg AR_SearchType, TypSize AL_FirstFindIndex=1, bool AB_DoFindFromFront=true) const + TypeSize FindData( + TypeArg AR_SearchType, TypeSize AL_FirstFindIndex=1, bool AB_DoFindFromFront=true) const { return Find(AR_SearchType, AL_FirstFindIndex, AB_DoFindFromFront); }/* - TypSize FindData(TypCArg AR_SearchType, TypSize AL_FirstFindIndex=1, bool AB_DoFindFromFront=true) const*/ + TypeSize FindData( + TypeArg AR_SearchType, TypeSize AL_FirstFindIndex=1, bool AB_DoFindFromFront=true) const*/ - ZCLink* GetLinkPtr(TypSize AL_Index) + ZCLink* GetLinkPtr(TypeSize AL_Index) { #ifdef _DEBUG @@ -905,7 +934,7 @@ namespace ZNsMain { std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); fileout<GetNextPrevPtr(VI_ShortDistance); }/* - ZCLink* GetLinkPtr(TypSize AL_Index)*/ + ZCLink* GetLinkPtr(TypeSize AL_Index)*/ - const ZCLink* GetLinkPtr(TypSize AL_Index) const // or 'ZCLink const * const GetLinkPtr(TypSize AL_Index) const' + const ZCLink* GetLinkPtr(TypeSize AL_Index) const // or 'ZCLink const * const GetLinkPtr(TypeSize AL_Index) const' { #ifdef _DEBUG @@ -931,7 +960,7 @@ namespace ZNsMain { std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); fileout<GetNextPrevPtr(VI_ShortDistance); }/* - const ZCLink* GetLinkPtr(TypSize AL_Index) const*/ + const ZCLink* GetLinkPtr(TypeSize AL_Index) const*/ ZtCObjList& DeleteAll() @@ -1005,7 +1034,7 @@ namespace ZNsMain }/* ZtCObjList& DeleteLink(ZCLink* AP_DeleteLink)*/ - ZtCObjList& DeleteLink(ZCLink* AP_DeleteLink, TypSize AL_DeletePos) + ZtCObjList& DeleteLink(ZCLink* AP_DeleteLink, TypeSize AL_DeletePos) { #ifdef _DEBUG @@ -1013,7 +1042,7 @@ namespace ZNsMain { std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); fileout<CutLink(AP_DeleteLink, AL_DeletePos); return *this; }/* - ZtCObjList& DeleteLink(ZCLink* AP_DeleteLink, TypSize AL_DeletePos)*/ + ZtCObjList& DeleteLink(ZCLink* AP_DeleteLink, TypeSize AL_DeletePos)*/ ZtCObjList& Delete(ZCLink* AP_DeleteLink) @@ -1034,19 +1063,19 @@ namespace ZNsMain }/* ZtCObjList& Delete(ZCLink* AP_DeleteLink)*/ - ZtCObjList& Delete(ZCLink* AP_DeleteLink, TypSize AL_DeletePos) + ZtCObjList& Delete(ZCLink* AP_DeleteLink, TypeSize AL_DeletePos) { return DeleteLink(AP_DeleteLink, AL_DeletePos); }/* - ZtCObjList& Delete(ZCLink* AP_DeleteLink, TypSize AL_DeletePos)*/ + ZtCObjList& Delete(ZCLink* AP_DeleteLink, TypeSize AL_DeletePos)*/ - ZtCObjList& DeleteLink(TypSize AL_DeletePos) + ZtCObjList& DeleteLink(TypeSize AL_DeletePos) { if(AL_DeletePos<1 || this->ml_Size>AL_DeletePos) return *this; Delete(this->GetLinkPtr(AL_DeletePos), AL_DeletePos); return *this; }/* - ZtCObjList& DeleteLink(TypSize AL_DeletePos)*/ + ZtCObjList& DeleteLink(TypeSize AL_DeletePos)*/ ZtCObjList& DeleteHead() @@ -1058,19 +1087,19 @@ namespace ZNsMain }/* ZtCObjList& DeleteHead()*/ - ZtCObjList& DeleteHead(TypSize AI_DeleteCnt) + ZtCObjList& DeleteHead(TypeSize AI_DeleteCnt) { - __for1(TypSize, i, AI_DeleteCnt) + __for1(TypeSize, i, AI_DeleteCnt) { if(ml_Size<1) return *this; delete this->CutLink(mp_HeadLink); }/* - __for1(TypSize, i, AI_DeleteCnt)*/ + __for1(TypeSize, i, AI_DeleteCnt)*/ return *this; }/* - ZtCObjList& DeleteHead(TypSize AI_DeleteCnt)*/ + ZtCObjList& DeleteHead(TypeSize AI_DeleteCnt)*/ ZtCObjList& DeleteTail() { @@ -1082,7 +1111,7 @@ namespace ZNsMain ZtCObjList& DeleteTail()*/ - ZCLink* AddDefault(TypSize AL_DefaultSize, TypSize AL_AddPos) + ZCLink* AddDefault(TypeSize AL_DefaultSize, TypeSize AL_AddPos) { if(AL_DefaultSize<1 || AL_AddPos<1 || AL_AddPos>ml_Size+1) return 0; @@ -1099,14 +1128,14 @@ namespace ZNsMain return VP_HeadLink; }/* - ZCLink* AddDefault(TypSize AL_DefaultSize, TypSize AL_AddPos)*/ + ZCLink* AddDefault(TypeSize AL_DefaultSize, TypeSize AL_AddPos)*/ - ZtCObjList& AddHead(TypCArg AR_Type) + ZtCObjList& AddHead(TypeArg AR_Type) { JoinAfter(new ZCLink(AR_Type), 0, 0); return *this; }/* - ZtCObjList& AddHead(TypCArg AR_Type)*/ + ZtCObjList& AddHead(TypeArg AR_Type)*/ ZtCObjList& AddHead(const ZtCObjList& rhs) { @@ -1119,21 +1148,11 @@ namespace ZNsMain ZtCObjList& AddHead(const ZtCObjList& rhs)*/ - ZCLink* AddHeadDefault() - { - /* 아래 코드 중 return 문이 return *this 라고 되어 있었다. 10 여년간 이를 - 모른 것이다. 자그마치 10 여년간! -- 2015-02-21- 21:36:00 - */ - ZCLink* VP_NewLink=new ZCLink; JoinAfter(VP_NewLink, 0, 0); return VP_NewLink; - }/* - ZCLink& AddHeadDefault()*/ - - - ZtCObjList& AddTail(TypCArg AR_Type) + ZtCObjList& AddTail(TypeArg AR_Type) { JoinAfter(new ZCLink(AR_Type), GetTailLinkPtr(), ml_Size); return *this; }/* - ZtCObjList& AddTail(TypCArg AR_Type)*/ + ZtCObjList& AddTail(TypeArg AR_Type)*/ ZtCObjList& AddTail(const ZtCObjList& rhs) { @@ -1142,20 +1161,27 @@ namespace ZNsMain ZtCObjList& AddTail(const ZtCObjList& rhs)*/ + /*/////////////////////////////////////////////////////////////////// + + ■ ZCLink* AddHeadDefault() 함수의 코드 중 return 문이 return *this + 라고 되어 있었다. 10 여년간 이를 모른 것이다. 자그마치 10 여년간! + -- 2015-02-21- 21:36:00 + + ///////////////////////////////////////////////////////////////////*/ + + ZCLink* AddHeadDefault() + { ZCLink* VP_NewLink = new ZCLink ; + JoinAfter(VP_NewLink, 0 /*/////////*/ , 0 ); return VP_NewLink; } ZCLink* AddTailDefault() - { - ZCLink* VP_NewLink=new ZCLink; + { ZCLink* VP_NewLink = new ZCLink ; + JoinAfter(VP_NewLink, GetTailLinkPtr(), ml_Size); return VP_NewLink; } - JoinAfter( - VP_NewLink, GetTailLinkPtr(), ml_Size); - - return VP_NewLink; - }/* - ZCLink* AddTailDefault()*/ + ZCLink* AddHeadDef(){ return AddHeadDefault(); } + ZCLink* AddTailDef(){ return AddTailDefault(); } - ZtCObjList& pop_back (TypCArg AR_Type){return AddHead(AR_Type);} - ZtCObjList& push_back(TypCArg AR_Type){return AddTail(AR_Type);} + ZtCObjList& pop_back (TypeArg AR_Type){return AddHead(AR_Type);} + ZtCObjList& push_back(TypeArg AR_Type){return AddTail(AR_Type);} ZtCObjList& JoinHead(ZtCObjList& rhs) @@ -1190,13 +1216,13 @@ namespace ZNsMain ZtCObjList& JoinTail(ZtCObjList& rhs, ZCLink* AP_CLink)*/ - ZtCObjList& JoinAfter( - ZtCObjList& rhs , - ZCLink* AP_LinkOfRhs , - TypSize AL_AddPosOfRhs , - ZCLink* AP_LinkStd , - TypSize AL_PosStd - /*////////////////*/ ) + ZtCObjList& JoinAfter /*######################################################*/ + ( + ZtCObjList& rhs , + ZCLink* AP_LinkOfRhs, TypeSize AL_AddPosOfRhs , + ZCLink* AP_LinkStd , TypeSize AL_PosStd + ) + /*#############################################################################*/ { // rhs 의 AP_LinkOfRhs 링크를 잘라서 AP_LinkStd 앞에 붙인다. @@ -1209,9 +1235,9 @@ namespace ZNsMain fileout<<"Error In 'ZtCObjList& JoinAfter(ZtCObjList& rhs,"<AL_CutTailPos"<GetData(); }/* - Type& GetData(TypSize AI_Index)*/ + Type& GetData(TypeSize AI_Index)*/ - const Type& GetData(TypSize AI_Index) const + const Type& GetData(TypeSize AI_Index) const { #ifdef _DEBUG @@ -1353,7 +1386,7 @@ namespace ZNsMain { std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); fileout<GetData(); }/* - const Type& GetData(TypSize AI_Index) const*/ + const Type& GetData(TypeSize AI_Index) const*/ Type& GetHeadData() @@ -1460,32 +1493,19 @@ namespace ZNsMain const Type& back () const{return GetTailData();} - ZtCObjList& Rotate(TypSize AL_RotateNum) + ZtCObjList& Rotate(TypeSize AL_RotateNum) { - if(ml_Size>0) - mp_HeadLink=mp_HeadLink->GetNextPrevPtr(AL_RotateNum); + if(ml_Size>0) mp_HeadLink = + mp_HeadLink->GetNextPrevPtr(AL_RotateNum); return *this; }/* - ZtCObjList& Rotate(TypSize AL_RotateNum)*/ - - ZtCObjList& Rotate() - { - if(ml_Size>0) - mp_HeadLink=mp_HeadLink->mp_NextLink; - - return *this; - }/* - ZtCObjList& Rotate()*/ + ZtCObjList& Rotate(TypeSize AL_RotateNum)*/ + ZtCObjList& Rotate () + { if(ml_Size>0) mp_HeadLink = mp_HeadLink->mp_NextLink ; return *this; } ZtCObjList& RotateBack() - { - if(ml_Size>0) - mp_HeadLink=mp_HeadLink->mp_PrevLink; - - return *this; - }/* - ZtCObjList& RotateBack()*/ + { if(ml_Size>0) mp_HeadLink = mp_HeadLink->mp_PrevLink ; return *this; } template void IterElement(TFunctor AO_Functor) @@ -1509,9 +1529,9 @@ namespace ZNsMain void IterElement(TFunctor AO_Functor, TTypeHelp AO_TypeHelp) { /*///////////////////////////////////////////////////////////////////////////// - + ■ TTypeHelp 가 class 일 경우, 크기가 커서 참조로 넘어가야 한다면, - + IterElement(myFunctor_obj, myClass_Obj); 의 형태로 호출할 게 아니라, ZtCObjectPtr<> 을 사용하여, @@ -1537,9 +1557,9 @@ namespace ZNsMain __for0(int, i, ml_Size) { ZtCTypeData::GetObjRef(AO_Functor) - ( - VP_LoopLink->mo_Type, ZCCheckRef::PassData(AO_TypeHelp) - ); + ( + VP_LoopLink->mo_Type, ZCCheckRef::PassData(AO_TypeHelp) + ); //////////////////////////////////////////// /* 위 코드로 인해서, AO_Functor 이 함수일 때 뿐이 아니라, operator() @@ -1556,9 +1576,13 @@ namespace ZNsMain void IterElement(TFunctor AO_Functor, TTypeHelp AO_TypeHelp) */ - template - void IterElement(TFunctor AO_Functor, - TTypeHelp1 AO_TypeHelp1, TTypeHelp2 AO_TypeHelp2) + template + /*###########*/ + void IterElement + ( + TFunctor AO_Functor, TTypeHelp1 AO_TypeHelp1, TTypeHelp2 AO_TypeHelp2 + ) + /*#############################################################################*/ { /*///////////////////////////////////////////////////////////////////////////// @@ -1590,11 +1614,11 @@ namespace ZNsMain __for0(int, i, ml_Size) { ZtCTypeData::GetObjRef(AO_Functor) - ( - VP_LoopLink->mo_Type - , ZCCheckRef1::PassData(AO_TypeHelp1) - , ZCCheckRef2::PassData(AO_TypeHelp2) - ); + ( + VP_LoopLink->mo_Type + , ZCCheckRef1::PassData(AO_TypeHelp1) + , ZCCheckRef2::PassData(AO_TypeHelp2) + ); //////////////////////////////////////////// /* 위 코드로 인해서, AO_Functor 이 함수일 때 뿐이 아니라, operator() @@ -1604,9 +1628,13 @@ namespace ZNsMain }/* __for0(int, i, ml_Size)*/ }/* - template - void IterElement(TFunctor AO_Functor, - TTypeHelp1 AO_TypeHelp1, TTypeHelp2 AO_TypeHelp2)*/ + template + ############### + void IterElement + ( + TFunctor AO_Functor, TTypeHelp1 AO_TypeHelp1, TTypeHelp2 AO_TypeHelp2 + ) + ###############################################################################*/ template @@ -1618,8 +1646,8 @@ namespace ZNsMain __for0(int, i, ml_Size) { - ZtCTypeData:: - GetObjRef(AO_Functor)(VP_LoopLink->mo_Type, AR_TypeHelp); + ZtCTypeData::GetObjRef + (AO_Functor)(VP_LoopLink->mo_Type, AR_TypeHelp); VP_LoopLink = VP_LoopLink->mp_NextLink ; }/* @@ -1629,9 +1657,13 @@ namespace ZNsMain void IterElemRef(TFunctor AO_Functor, TTypeHelp& AR_TypeHelp) */ - template - void IterElemRef(TFunctor AO_Functor, - TTypeHelp1& AR_TypeHelp1, TTypeHelp2& AR_TypeHelp2) + template + /*###########*/ + void IterElemRef + ( + TFunctor AO_Functor, TTypeHelp1& AR_TypeHelp1, TTypeHelp2& AR_TypeHelp2 + ) + /*#############################################################################*/ { /* TTypeHelp1 과 2 을 참조로 받고 있음에 주의한다. -- 2021-03-04 04:00:00 */ @@ -1646,9 +1678,13 @@ namespace ZNsMain }/* __for0(int, i, ml_Size)*/ }/* - template - void IterElemRef(TFunctor AO_Functor, - TTypeHelp1& AR_TypeHelp1, TTypeHelp2& AR_TypeHelp2) */ + template + ############### + void IterElemRef + ( + TFunctor AO_Functor, TTypeHelp1& AR_TypeHelp1, TTypeHelp2& AR_TypeHelp2 + ) + /*#############################################################################*/ /*/////////////////////////////////////////////////////////////////////////// @@ -1656,18 +1692,18 @@ namespace ZNsMain ■ IterElement() 예제. #include - #include "ZtCObjList.H" + #include "ZCppMain/ZtCObjList.H" using namespace std; int main() { - ZNsMain:: ZtCObjList myArray; + ZNsMain:: ZtCObjList myObjList; - myArray.AddTail(10); - myArray.AddTail(20); - myArray.AddTail(30); - myArray.AddTail(40); + myObjList.AddTail(10); + myObjList.AddTail(20); + myObjList.AddTail(30); + myObjList.AddTail(40); struct StFunctor { @@ -1685,8 +1721,8 @@ namespace ZNsMain StFunctor2 VO_StFunctor2; - myArray.IterElement(StFunctor::ShowElement); - myArray.IterElement(&VO_StFunctor2); // linux g++ 4.4.7 에서 컴파일 에러다. + myObjList.IterElement(StFunctor::ShowElement); + myObjList.IterElement(&VO_StFunctor2); // linux g++ 4.4.7 에서 컴파일 에러다. // struct StFunctor2 정의를 main() 함수 바깥으로 빼면 컴파일된다. return 0; } @@ -1699,16 +1735,16 @@ namespace ZNsMain class ZCIterator { protected: - mutable ZCLink* mp_Link; - mutable TypSize ml_Pos ; + mutable ZCLink* mp_Link; + mutable TypeSize ml_Pos ; public : - ZCIterator(ZCLink* AP_CLink=0, TypSize AL_Pos=0) + ZCIterator(ZCLink* AP_CLink=0, TypeSize AL_Pos=0) { mp_Link=AP_CLink; ml_Pos =AL_Pos ; }/* - ZCIterator(ZCLink* AP_CLink=0, TypSize AL_Pos=0)*/ + ZCIterator(ZCLink* AP_CLink=0, TypeSize AL_Pos=0)*/ ZCLink* GetLink() { @@ -1722,11 +1758,11 @@ namespace ZNsMain }/* const ZCLink* GetLink() const*/ - TypSize GetPos() const + TypeSize GetPos() const { return ml_Pos; }/* - TypSize GetPos() const*/ + TypeSize GetPos() const*/ Type& operator *() { @@ -1889,6 +1925,17 @@ namespace ZNsMain void erase(ZCIterator& AR_CIterator1, ZCIterator& AR_CIterator2)*/ + IterEasy GetHeadIterEasy (){return GetHeadLinkPtr();} + IterEasy GetTailIterEasy (){return GetTailLinkPtr();} + IterEasyID GetHeadIterEasyID(){return (IterEasyID)GetHeadLinkPtr();} + IterEasyID GetTailIterEasyID(){return (IterEasyID)GetTailLinkPtr();} + + IterEasy GetHeadIterEasy () const{return GetHeadLinkPtr();} + IterEasy GetTailIterEasy () const{return GetTailLinkPtr();} + IterEasyID GetHeadIterEasyID() const{return (IterEasyID)GetHeadLinkPtr();} + IterEasyID GetTailIterEasyID() const{return (IterEasyID)GetTailLinkPtr();} + + /*/////////////////////////////////////////////////////////////////////////// ■ 순차적으로 각 원소를 순회할 수 있는 자료 구조, 즉 리스트나 배열 클래스는 @@ -2058,16 +2105,44 @@ namespace ZNsMain const Type& GetDataInIter(IterEasyIDc ARRI_IterEasyID, TypeSize AI_FarNum) const*/ - // 아래 ItD() 함수는 GetDataInIter() 를 짧게 줄인 것이다. + // cf typedef ZCLink* IterEasy; - Type& ItD(ZCLink* AP_CLink ){return GetDataInIter(AP_CLink );} + IterEasy ItHEasy(){return mp_HeadLink ;} + IterEasy ItTEasy(){return mp_HeadLink->mp_PrevLink ;} + IterEasyID ItHID (){return (IterEasyID) mp_HeadLink ;} + IterEasyID ItTID (){return (IterEasyID)(mp_HeadLink->mp_PrevLink);} + + const IterEasy ItHEasy() const{return mp_HeadLink ;} + const IterEasy ItTEasy() const{return mp_HeadLink->mp_PrevLink ;} + const IterEasyID ItHID () const{return (IterEasyID) mp_HeadLink ;} + const IterEasyID ItTID () const{return (IterEasyID)(mp_HeadLink->mp_PrevLink);} + + void ItNext(IterEasy& ARR_IterEasy ) const{ARR_IterEasy=ARR_IterEasy->mp_NextLink;} + void ItNext(iterator& ARR_CIterator) const{++ARR_CIterator;} + void ItNext(IterEasyID& AI_IterEasyID) const + { ItNext((IterEasy&)AI_IterEasyID); } + void ItNext(const IterEasy& ARR_IterEasy ) const{ARR_IterEasy=ARR_IterEasy->mp_NextLink;} + void ItNext(const iterator& ARR_CIterator) const{++ARR_CIterator;} + void ItNext(const IterEasyID& AI_IterEasyID) + const{ ItNext((const IterEasy&)AI_IterEasyID); } + + void ItPrev(IterEasy& ARR_IterEasy ) const{ARR_IterEasy=ARR_IterEasy->mp_PrevLink;} + void ItPrev(iterator& ARR_CIterator) const{--ARR_CIterator;} + void ItPrev(IterEasyID& AI_IterEasyID) const + { ItPrev((IterEasy&)AI_IterEasyID); } + void ItPrev(const IterEasy& ARR_IterEasy ) const{ARR_IterEasy=ARR_IterEasy->mp_PrevLink;} + void ItPrev(const iterator& ARR_CIterator) const{--ARR_CIterator;} + void ItPrev(const IterEasyID& AI_IterEasyID) + const{ ItPrev((const Type*&)AI_IterEasyID); } + + Type& ItD(IterEasy AP_CLink ){return GetDataInIter(AP_CLink );} Type& ItD(iterator& ARR_CIterator ){return GetDataInIter(ARR_CIterator );} Type& ItD(IterEasyID ARRI_IterEasyID ){return GetDataInIter(ARRI_IterEasyID );} Type& ItD(ZCLink* AP_CLink , TypeSize AI_FarNum){return GetDataInIter(AP_CLink , AI_FarNum);} Type& ItD(iterator& ARR_CIterator , TypeSize AI_FarNum){return GetDataInIter(ARR_CIterator , AI_FarNum);} Type& ItD(IterEasyID ARRI_IterEasyID, TypeSize AI_FarNum){return GetDataInIter(ARRI_IterEasyID, AI_FarNum);} - const Type& ItD(const ZCLink* AP_CLink ) const{return GetDataInIter(AP_CLink );} + const Type& ItD(const IterEasy AP_CLink ) const{return GetDataInIter(AP_CLink );} const Type& ItD(const iterator& ARR_CIterator ) const{return GetDataInIter(ARR_CIterator );} const Type& ItD(IterEasyIDc ARRI_IterEasyID ) const{return GetDataInIter(ARRI_IterEasyID );} const Type& ItD(const ZCLink* AP_CLink , TypeSize AI_FarNum) const{return GetDataInIter(AP_CLink );} @@ -2076,13 +2151,133 @@ namespace ZNsMain public: };/* - template< typename Type , - typename TypCArg =const Type&, - typename TypCAlloc=ZCAllocator, - typename TypCInit =ZCInit , - typename TypSize =long + template< typename TType , + typename TTypCArg =const TType&, + typename TTypCAlloc=ZCAllocator , + typename TTypCInit =ZCInit , + typename TTypSize =ZTypLong > - class ZtCObjList ////////////////////////*/ + class ZtCObjList //////////////////////////*/ + + + /*///////////////////////////////////////////////////////////////////////////// + + ■ 주로 IterElement() 을 사용하는 ZtCObjList<> 예제 --2025-08-10 11:41 + + #include + + #include "ZCppMain/ZtCArray.H" + #include "ZCppMain/ZtCObjList.H" + + + using namespace std ; + using namespace ZNsMain; + + + int main() + { + typedef ZtCArray CArray ; + typedef ZtCObjList CObjList ; + typedef CArray ::IterEasy IterEasyA; + typedef CObjList::IterEasy IterEasyL; + + + CArray VO_CArray; CObjList VO_CObjList; + + VO_CArray.AddTail(10); + VO_CArray.AddTail(20); + VO_CArray.AddTail(30); + VO_CArray.AddTail(40); + + VO_CObjList.AddTail(10); + VO_CObjList.AddTail(20); + VO_CObjList.AddTail(30); + VO_CObjList.AddTail(40); + + IterEasyA VH_IterA = VO_CArray .ItHEasy(); + IterEasyL VH_IterL = VO_CObjList.ItHEasy(); + + + class CHelpObj + { + public: + + CHelpObj() + { + } + + CHelpObj(const CHelpObj& rhs) + { + cout<<"* CHelpObj(const CHelpObj& rhs)"< 의 멤버 함수로 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::WriteFile(const TTypCh*, const typename TTypeString::ZCTypeChars::TypeChar*, typename TTypeString::ZCTypeChars::TypeLength, bool, int) [with TTypCh = char, TAlloc = std::ZtCAllocClass, TAllocSize = std::ZtCAllocMemSize, TTypeString = std::ZNsType::ZtCTypeStringBase, std::ZtCAllocMemSize, long int>] + Donut.H:23318: note: candidate 2: bool std::ZtCStringBase::WriteFile(const TTypCh*, bool, int) const [with TTypCh = char, TAlloc = std::ZtCAllocClass, TAllocSize = std::ZtCAllocMemSize, TTypeString = std::ZNsType::ZtCTypeStringBase, std::ZtCAllocMemSize, 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::WriteFile(const TTypCh*, const typename TTypeString::ZCTypeChars::TypeChar*, typename TTypeString::ZCTypeChars::TypeLength, bool, int) [with TTypCh = char, TAlloc = std::ZtCAllocClass, TAllocSize = std::ZtCAllocMemSize, TTypeString = std::ZNsType::ZtCTypeStringBase, std::ZtCAllocMemSize, long int>] + Donut.H:23318: note: candidate 2: bool std::ZtCStringBase::WriteFile(const TTypCh*, bool, int) const [with TTypCh = char, TAlloc = std::ZtCAllocClass, TAllocSize = std::ZtCAllocMemSize, TTypeString = std::ZNsType::ZtCTypeStringBase, std::ZtCAllocMemSize, 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) 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& SetCharSet(TypeChar* APC_ArgBuf, TypeLength AL_ArgAllLen) + { + // AL_ArgAllLen 는 맨 끝에 널 문자를 위한 1 개의 공간을 뺀 길이다. + + mpc_Buff =APC_ArgBuf ; + ml_Length=0 ; + ml_AllLen=AL_ArgAllLen; + + return *this; + }/* + ZtCCharPtr& SetCharSet(TypeChar* APC_ArgBuf, TypeLength AL_ArgAllLen)*/ + + ZtCCharPtr& 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& Add(TypeChar* APC_ArgChar, TypeLength AL_ArgLength)*/ + + ZtCCharPtr& Add(TypeChar* APC_ArgChar) + { + return Add(APC_ArgChar, ZNsMain::ZftGetLengthType(APC_ArgChar)); + }/* + ZtCCharPtr& 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 CCharPtr ; + typedef ZtCCharPtr CCharPtrA; + typedef ZtCCharPtr CCharPtrW; + + + template< typename TTypCh , /*######*/ + typename TAlloc , + typename TAllocSize , + typename TTypeString + > + class ZtCStringBase; /*###################*/ + + + namespace ZNsType + { + + template< typename TTypCh , + typename TAlloc =ZNsMain::ZtCAllocClass , + typename TAllocSize=ZNsMain::ZtCAllocMemSize, + typename TLength =ZNsMain::ZTypLength + > + class ZtCTypeStringBase ///////////////////////////////////////// + { + public: + typedef TLength TypeLong ; + typedef TLength TypeLength; + typedef TTypCh TypeChar ; + public: + typedef ZNsMain::ZNsChars::ZNsType:: + ZtCTypeChars ZCTypeChars; + typedef ZNsMain::ZNsChars:: + ZtCMainChars ZCMainChars; + public: + typedef typename ZCTypeChars::ZCChars ZCChars ; + public: + + + template class ZtCHelpBase + { + public: + typedef ZNsMain::ZtCObjList< ////////////////// + TDeriveString , + const TDeriveString&, + TAlloc + /*/////////*/ > ZCStringList; ///////////////// + public: + };/* + templateclass 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 , + typename TAllocSize=ZNsMain::ZtCAllocMemSize, + typename TLength =ZNsMain::ZTypLength + > + class ZtCTypeStringBase ///////////////////////////////////////*/ + + }/* + namespace ZNsType*/ + + + template class ZtCHString; + + + /*///////////////////////////////////////////////////////////////// + + ■ stl 의 string 클래스는 문자열 처리가 PHP 에 비해 다소 불편하므로 + 별도의 문자열 클래스 템플릿 class ZtCStringBase<> 을 설계한다. + + ■ 파일입출력 및 몇몇 멤버함수에 관련해서 + class ZtCStringBase 클래스를 별도로 설계할 필요가 있다. + + /////////////////////////////////////////////////////////////////*/ + + + template< typename TTypCh, + typename TAlloc =ZNsMain::ZtCAllocClass , + typename TAllocSize =ZNsMain::ZtCAllocMemSize, + 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; + public: + + enum EWriteFile // WriteFile() 에서 사용한다. + { + EWriteFile_Append , // 데이타를 파일에 덧붙인다. + EWriteFile_OverWrite // 기존 파일의 내용을 지우고 데이타를 파일에 쓴다. + };/* + enum EWriteFile*/ + + public: + + + template 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; jGetData(); + + 위 코드처럼 하면 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 void MakeInfoList + ( + TypeCharC* APC_Search , + TypeLength AL_SearchLen, + TypeLength AL_StartPos , + TSearchInfoList& ARR_InfoList + ) + //////////////////////////////////////////////////*/ + + + template 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; j0) + { + 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_PrevPosmp_Char=VP_Origin+VL_PrevPos ; + VP_CSearchInfo->ml_Pos =VL_PrevPos ; + VP_CSearchInfo->ml_Len =ml_UseLen-VL_PrevPos ; + }/* + if(VL_PrevPos 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; i0) 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=0 && AL_Index=0 && AL_IndexAL_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(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(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(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(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 ZCStringBase& AddObject(TObject& AR_CObject) + { + return (*this)((TypeCharC*)&AR_CObject, sizeof(AR_CObject)); + }/* + template 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(APC_Search) , + ZftGetLengthType(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_ReplaceLenAL_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 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; iAL_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 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(APC_Search ), + ZftGetLengthType(APC_Replace), + AL_StartPos + ); + //////////////////////////////////////////////////////////// + }/* + ZCStringBase& Replace(TypeCharC* APC_Search, TypeCharC* APC_Replace, TypeLength AL_StartPos=0)*/ + + template ZCStringBase& + ReplaceType(TypeCharC* APC_Search, TypeCharC* APC_Replace, TypeLength AL_StartPos=0) + { + using ZNsMain::ZftGetLengthType ; + + return ReplaceType + ( + APC_Search , + APC_Replace , + ZftGetLengthType(APC_Search) , + ZftGetLengthType(APC_Replace) , + AL_StartPos + ); + /////////////////////////////////// + }/* + template 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 ZCStringBase& ReplaceType( + const ZCStringBase& AR_CStrSearch , + const ZCStringBase& AR_CStrReplace, + TypeLength AL_StartPos=0 + /*/////////*/ ) //////////////////////////////////////////// + { + return ReplaceType( /////// + AR_CStrSearch. data(), + AR_CStrReplace.data(), + AR_CStrSearch. size(), + AR_CStrReplace.size(), + AL_StartPos + /*/////////*/ ); /////////////////////////// + }/* + template 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 + { + 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(APC_Origin ), + ZftGetLengthType(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 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_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=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 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(APC_Search1), + ZftGetLengthType(APC_Search2), + ZftGetLengthType(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=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(APC_Search1), + ZftGetLengthType(APC_Search2), + ZftGetLengthType(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 /*#########################################*/ + 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 ############################################# + 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(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<=AL_OriginLen) + { + return ARR_SaveList; + }/* + if(VL_CopyStartPos>=AL_OriginLen)*/ + + if(VL_PrevListSize + 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 TSaveList& SplitToListType( /*#####*/ + TSaveList& ARR_SaveList , + TypeCharC* APC_SearchChar , + TypeLength AL_SearchLen , + bool AB_DoEndWhenNoMatch=true, + bool AB_DoAppendEmpty =false + /*#########*/ ) const /*########################################*/ + { + return SplitToListType( /*######*/ + ARR_SaveList , + mpc_Data , + APC_SearchChar , + ml_UseLen , + AL_SearchLen , + AB_DoEndWhenNoMatch , + AB_DoAppendEmpty + /*########*/ ); /*#########################*/ + }/* + template TSaveList& SplitToListType( ######### + TSaveList& ARR_SaveList , + TypeCharC* APC_SearchChar , + TypeLength AL_SearchLen , + bool AB_DoEndWhenNoMatch=true, + bool AB_DoAppendEmpty =false + ############ ) const ##########################################*/ + + + /* cf) + + ZNsMain::ZtCStringBase myc; + myc="Z,'A,,'B,C,'D,,,''E'ET,"; + myc.SplitToListWrap(l1, ",", "'", "'", (TypeLength)1,(TypeLength)1,(TypeLength)1); + */ + template 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 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 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(APC_SearchChar), + ZftGetLengthType(APC_WrapStart) , + ZftGetLengthType(APC_WrapClose) , + AB_DoEndWhenNoMatch, + AB_DoAppendEachLink + /*//////////*/ ); /////////////////////////////////////////////////////// + }/* + template 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 + + template 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(APC_OriginChar) ; + TypeChar* VP_CopyCloseChar=VP_CopyStartChar; + + for(TypeLength i=0; iVL_CopyStartPos) + { + ((CString&)ARR_SaveList).append + ( VP_CopyStartChar, i-VL_CopyStartPos ) ; + }/* + if(i>VL_CopyStartPos)*/ + + VL_CopyStartPos =i+1; + VP_CopyStartChar=VP_CopyCloseChar ; + }/* + if(j static TStringList& SplitByCondOr + ( + TStringList& ARR_SaveList , + TypeCharC* APC_OriginChar, + TypeCharC* APC_SearchChar, + TypeLength AL_OriginLen , + TypeLength AL_SearchLen + ) + //////////////////////////////////////////////////////////////*/ + + + template TStringList& SplitByCondOr( /////// + TStringList& ARR_SaveList , + TypeCharC* APC_SearchChar, + TypeLength AL_SearchLen + /*//////////*/ ) const /////////////////////////////////////////// + { + return SplitByCondOr( + RR(ARR_SaveList), mpc_Data, APC_SearchChar, ml_UseLen, AL_SearchLen); + }/* + TStringList& SplitByCondOr( ////////////////////////////////////// + TStringList& ARR_SaveList , + TypeCharC* APC_SearchChar, + TypeLength AL_SearchLen + ////////////// ) const /////////////////////////////////////////*/ + + + template TStringList& SplitByCondOr( /////// + TStringList& ARR_SaveList, + TypeCharC* APC_SearchChar + /*/////////*/ ) const //////////////////////////////////////////// + { + return SplitByCondOr( //////////////////////////////////// + RR(ARR_SaveList), + mpc_Data , + APC_SearchChar , + ml_UseLen , + ZNsMain::ZftGetLengthType + (APC_SearchChar) + /*/////////*/ ); + }/* + template 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(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(AR_FindList.ItD(VI_Iter_OR_List).data()); + VPC_CloseChar =VPC_StartChar; + VL_ClosePos =VL_StartPos ; + + if(VL_SearchLen=AL_SearchMinLen) // 실제로는 k==VL_SearchLen + { + for(k=AL_SearchMinLen; 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_CopyPosVL_LoopSize + { + ++VL_StartPos ; + ++VPC_StartChar; + }/* + else //j>VL_LoopSize*/ + }/* + while(VL_StartPos /*#############*/ + 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(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 + (AR_FindList.ItD(VO_Iter_OR_List).data()) ; + VPC_CloseChar =VPC_StartChar; + VL_ClosePos =VL_StartPos ; + + if(VL_SearchLen<1 || VL_SearchLen=AL_SearchMinLen) // 실제로는 k==AL_SearchMinLen + { + for(k=AL_SearchMinLen; 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_CopyPosVL_LoopSize + { + ++VL_StartPos ; + ++VPC_StartChar; + }/* + else // j>VL_LoopSize*/ + + VO_Iter_OR_List=AR_FindList.GetHeadIterEasyID() ; + }/* + while(VL_StartPos ################# + static TSaveList& SplitByCondOrExType + ( + TSaveList& ARR_SaveList , + TFindList& AR_FindList , + TypeCharC* APC_OriginChar, + TypeLength AL_OriginLen , + TypeLength AL_SearchMinLen=1 + ) + /*##############################################################*/ + + + template + TSaveList& SplitByCondOrExType( ////////////////////////////// + TSaveList& ARR_SaveList , + TFindList& AR_FindList , + TypeLength AL_SearchMinLen=1 + /*/////////////*/ ) const + { + return SplitByCondOrExType( + ARR_SaveList, AR_FindList, mpc_Data, ml_UseLen, AL_SearchMinLen); + }/* + template + 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(APC_Search1Char), + ZftGetLengthType(APC_Search2Char), + AB_DoIncludeSearch + /*/////////*/ ); //////////////////////////////////////////////////////// + }/* + ZCStringList& ExtractBetweenToList( /////////////////////////////// + ZCStringList& ARR_SaveList , + TypeCharC* APC_Search1Char, + TypeCharC* APC_Search2Char, + bool AB_DoIncludeSearch=false + //////////// ) const //////////////////////////////////////////*/ + + + template + 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 + 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 + TypeList& ExtractBetweenToListType( ////////////////////////// + TypeList& ARR_SaveList , + TypeCharC* APC_Search1Char , + TypeCharC* APC_Search2Char , + TypeLength AL_Search1Len , + TypeLength AL_Search2Len , + bool AB_DoIncludeSearch=false + /*/////////*/ ) const + { + return ExtractBetweenToListType( ////// + ARR_SaveList , + mpc_Data , + APC_Search1Char , + APC_Search2Char , + ml_UseLen , + AL_Search1Len , + AL_Search2Len , + AB_DoIncludeSearch + /*/////////*/ ); //////////////////////////////// + }/* + template + TypeList& ExtractBetweenToListType( ////////////////////////// + TypeList& ARR_SaveList , + TypeCharC* APC_Search1Char , + TypeCharC* APC_Search2Char , + TypeLength AL_Search1Len , + TypeLength AL_Search2Len , + bool AB_DoIncludeSearch=false + /*/////////*/ ) const //////////////////////////////////////////*/ + + template + TypeList& ExtractBetweenToListType( ////////////////////////// + TypeList& ARR_SaveList , + TypeCharC* APC_Search1Char, + TypeCharC* APC_Search2Char, + bool AB_DoIncludeSearch=false + /*/////////*/ ) const + { + using ZNsMain::ZftGetLengthType ; + + return ExtractBetweenToListType( ////////////////////////////// + ARR_SaveList , + mpc_Data , + APC_Search1Char , + APC_Search2Char , + ml_UseLen , + ZftGetLengthType(APC_Search1Char), + ZftGetLengthType(APC_Search2Char), + AB_DoIncludeSearch + /*/////////*/ ); //////////////////////////////////////////////////////// + }/* + template + TypeList& ExtractBetweenToListType( ////////////////////////// + TypeList& ARR_SaveList , + TypeCharC* APC_Search1Char, + TypeCharC* APC_Search2Char, + bool AB_DoIncludeSearch=false + ///////////// ) const //////////////////////////////////////////*/ + + template + static TStringList& MakeNullAllLink(TStringList& ARR_SaveList) + { + /* 리스트 자료구조는 프로그램상에서 구현한 정적 버퍼에서 링크를 만들어서 가져오고 + 링크가 삭제될 때도 이 정적버퍼로 보내게 되는데 이 링크를 다시 가져올 때 원치 + 않는 자료가 이미 있을 수 있으므로 각 링크를 Null 로 초기화한다. */ + + TypeLength VL_MaxLoop =ARR_SaveList.GetSize(); + IterEasyID VI_IterEasy=ARR_SaveList.GetHeadIterEasyID(); + + for(TypeLength i=0; i + static TStringList& MakeNullAllLink(TStringList& ARR_SaveList) */ + + template + static TStringList& MakeNullAllDelete(TStringList& ARR_SaveList) + { + MakeNullAllLink(RR(ARR_SaveList)); ARR_SaveList.DeleteAll(); return ARR_SaveList; + }/* + template + 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=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=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=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(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_Offset0) + { + 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_Offset0) + { + 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=AL_SearchLen) + { + // 해당하는 문자열을 찾았다면... + + if(++VL_NowSearchCnt>=AL_SearchCnt) + { return VL_AllReadSize+i+1; } + + VL_SearchIndex=0; + }/* + if(++VL_SearchIndex>=AL_SearchLen)*/ + }/* + for(i=0; i0)*/ + + 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=AL_SearchLen) + { + // 해당하는 문자열을 찾았다면... + + if(++VL_NowSearchCnt>=AL_SearchCnt) + { return VL_AllReadSize+i+1; } + + VL_SearchIndex=0; + }/* + if(++VL_SearchIndex>=AL_SearchLen)*/ + }/* + for(i=0; i0)*/ + + 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=AL_SearchLen) + { + // 해당하는 문자열을 찾았다면... + + if(++VL_NowSearchCnt>=AL_SearchCnt) + { return VL_AllReadSize+i+1; } + + VL_SearchIndex=0; + }/* + if(++VL_SearchIndex>=AL_SearchLen)*/ + }/* + for(i=0;i 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)(APC_Origin), + ZftGetLengthType(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 + (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(APC_Search), + ZftGetLengthType(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=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 + (APC_Search) + ) ; + ///////////////////// + }/* + TypeLength FindPosFromEnd(TypeCharC* APC_Search) const*/ + + + template 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 static TypeLength FindPosType( ########## + TypeCharC* APC_Origin , + TList& AR_SearchList, + TypeLength AL_OriginLen , + TypeLength& ARRL_MatchLen, + TypeLength AL_StartPos=0 + ########### ) ################################################*/ + + + template static TypeLength FindPosType( /*######*/ + TypeCharC* APC_Origin , + TList& AR_SearchList, + TypeLength& ARRL_MatchLen + /*#########*/ ) /*##############################################*/ + { + return FindPosType + ( + APC_Origin, AR_SearchList, + ZNsMain::ZftGetLengthType + (APC_Origin), + ARRL_MatchLen + ); + ////////////////// + }/* + template static TypeLength FindPosType( ########## + TypeCharC* APC_Origin , + TList& AR_SearchList, + TypeLength& ARRL_MatchLen + ############ ) ################################################*/ + + + template static TypeLength + FindPosType(TypeCharC* APC_Origin, TList& AR_SearchList) + { + using ZNsMain::ZftGetLengthType ; + + TypeLength VL_MatchLen=0; return FindPosType( /*##########################*/ + APC_Origin , + AR_SearchList , + ZftGetLengthType(APC_Origin), + RR(VL_MatchLen) + /*########*/ ); /*########################################################*/ + }/* + template 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(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(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'9') + { + return false; + }/* + else if(VC_CharTemp<'0' || VC_CharTemp>'9')*/ + }/* + for(TypeLength i=0; i(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(APC_Origin) , + ZftGetLengthType(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(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 + (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 + (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_StartPos0) + { + TypeLength VL_Index=0; + + for(TypeLength i=AL_StartPos; i0)*/ + + 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(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-1) + { return APC_Data; } + ////////////////////////////////////////////////// + + + VPC_StartChar=APC_Data+(VL_CurrentPos=AI_LengthDec-1) ; + + while(VL_PeriodPos=AI_LengthDec-1) + { return *this; } + ////////////////////////////////////////////////// + + + VPC_StartChar = mpc_Data+(VL_CurrentPos=AI_LengthDec-1) ; + + while(VL_PeriodPos='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(APC_Left), + ZftGetLengthType(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 + (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(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 + (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 + (".") + ); + //////////////////////////////////////////////////// + + 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 + (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 + (".") + ); + //////////////////////////////////////////////// + + 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 + (".") + ); + //////////////////////////////////////////////////// + + 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(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(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 + (".") + ); + //////////////////////////////////////////////// + + 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 + (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 + 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; i0) + {(*this)("1");} + else{(*this)("0");} + + VUI_Value>>=1; /*##########*/ + }/* + for(int i=1; i + ZCStringBase& AddBitByUInt(TyUInt AUC_Value)*/ + + + // 아래 멤버함수는 class CFileLarge 에서 펑크터로 사용할 때 필요하다. + + + template + void OnKnowFileSize(ZTypLLong ALL_FileSize, TFileHandle AH_FileHandle) + { + ReAllocKeep(ml_UseLen+ALL_FileSize); // 파일 크기를 대입받는다. + }/* + template + 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 + (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 , + typename TAllocSize =ZNsMain::ZtCAllocMemSize, + typename TTypeString=ZNsMain::ZNsType::ZtCTypeStringBase + < + TTypCh , + TAlloc , + TAllocSize + > + > + class ZtCStringBase /////////////////////////////////////////*/ + + + + template< typename TTypCh, + typename TAlloc =ZNsMain::ZtCAllocClass , + typename TAllocSize =ZNsMain::ZtCAllocMemSize, + typename TTypeString=ZNsMain::ZNsType::ZtCTypeStringBase + < + TTypCh , + TAlloc , + TAllocSize + > + > + class ZtCStringEx : + public ZtCStringBase + { + public : + typedef TTypCh TypeChar ; + typedef TTypCh TypeData ; + typedef ZtCStringBase + TypeBase ; + typedef ZtCStringBase + 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 + (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 + (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(*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(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 , + typename TAllocSize =ZNsMain::ZtCAllocMemSize, + typename TTypeString=ZNsMain::ZNsType::ZtCTypeStringBase + < + TTypCh, TAlloc, TAllocSize + > + > + class ZtCStringEx //////////////////////////////////////////////*/ + + + template + + std::ostream& operator << + ( + std::ostream& AR_COStream, const ZtCStringBase + & AR_CStringBase + ) + { + /*///////////////////////////////////////////////////////////////////////////////////// + + ■ ZtCStringBase~ 앞에 const 를 붙이지 않으면, 비 const ZtCStringBase<> object 에 대하 + 여, 이 중첩 함수는 호출되지 않는다. 따라서 const 는 아주 중요한 역할을 한다. + + /////////////////////////////////////////////////////////////////////////////////////*/ + + if(AR_CStringBase.size()>0) AR_COStream< + std::ostream& operator << + ( + std::ostream& AR_COStream, const ZtCStringBase + & AR_CStringBase + ) */ + + + namespace NsFunc + { + + template + void __FastMoveObj( + ZNsMain::ZtCStringBase& AR_CString1, + ZNsMain::ZtCStringBase& AR_CString2 + /*//////////*/ ) + { + #ifdef _DEBUG_FAST_MOVE_OBJ_ + cout<<" ▶▶ __FastMoveObj(CString&, CString&) Start!"< + void __FastMoveObj( + ZNsMain::ZtCStringBase& AR_CString1, + ZNsMain::ZtCStringBase& AR_CString2 + ////////////// ) */ + + + template + void __FastMoveObj( + ZNsMain::ZtCStringBase& AR_CString1, + const ZNsMain::ZtCStringBase& AR_CString2 + /*//////////*/ ) + { + typedef ZNsMain::ZtCStringBase CStringType; + + #ifdef _DEBUG_FAST_MOVE_OBJ_ + cout<<" ▶▶ __FastMoveObj(CString&, const CString&) Start!"<(AR_CString2)); + + #ifdef _DEBUG_FAST_MOVE_OBJ_ + cout<<" ▶▶ __FastMoveObj(CString&, const CString&) Close!"< + void __FastMoveObj( + ZNsMain::ZtCStringBase& AR_CString1, + const ZNsMain::ZtCStringBase& AR_CString2 + ////////////// ) */ + + }/* + namespace NsFunc*/ + +}/* +namespace ZNsMain */ + + +/*/////////////////////////////////////////////////////////////////////////////////// + +■ 문자열 메모리를 복사할 때, for 문을 쓰지 말고, memcpy() 를 썼으면 더 좋을 뻔 했다. + + -- 2012-02-29 10:45:00 + +///////////////////////////////////////////////////////////////////////////////////*/ + + +#endif //__ZCPPMAIIN__ZTCSTRINGEX_H__ diff --git a/ZCppMain/ZtCTreeData.H b/ZCppMain/ZtCTreeData.H new file mode 100644 index 0000000..8dc82bf --- /dev/null +++ b/ZCppMain/ZtCTreeData.H @@ -0,0 +1,993 @@ + + +#ifndef __ZCPPMAIN__ZCTREEDATA_H__ +#define __ZCPPMAIN__ZCTREEDATA_H__ + + +#include "ZCppMain/ZtCObjList.H" + + +namespace ZNsMain +{ + + namespace ZNsView + { + + template< typename TypeData, typename TypeSize=int + > + class ZtCViewTreeData //////////////////////////// + { + private: + + void ShowDepth(TypeSize AI_Depth) + { + __for1(TypeSize, i, AI_Depth) cout<<" "; + }/* + void ShowDepth(TypeSize AI_Depth)*/ + + public : + + ZNsMain::ZNsEnum::ZERun OnDataStart(TypeSize AI_Depth) + { + ShowDepth(AI_Depth); cout<<" OnDataStart:"< + class ZtCViewTreeData //////////////////////////*/ + + }/* + namespace ZNsView*/ + + + namespace ZNsType + { + + /*///////////////////////////////////////////////////////////////////////////////////// + + class ZtCTypeTreeData ø ǿ ٸ ø(list ̳ ø) + ϰ . ̰ ZtCTreeData<> Ȱϴ κ Ʒó + + typedef typename TTypeTreeData::template ZtCTypeClass::TypeData ZCNode1List; + typedef typename TTypeTreeData::template ZtCTypeClass::TypeData ZCNode2List; + + ټ δ. + + -- 2011-11-01 14:39:00 + + /////////////////////////////////////////////////////////////////////////////////////*/ + + template class ZtCTypeTreeData + { + public: + typedef TTypeSize TypeSize; + public: + + template< typename TType , + typename TTypeArg =const TType& , + typename TTypeAlloc=ZNsMain::ZCAllocator, + typename TTypeInit =ZNsMain::ZtCInit + > + class ZtCTypeClass ///////////////////////////////// + { + public: + typedef TTypeAlloc TypeAlloc; + typedef TTypeInit TypeInit ; + public: + typedef ZNsMain::ZtCObjList + + TypeList; ///////////////// + public: + };/* + template< typename TType , + typename TTypeArg =const TType& , + typename TTypeAlloc=ZNsMain::ZCAllocator, + typename TTypeInit =ZNsMain::ZtCInit + > + class ZtCTypeClass ///////////////////////////////*/ + + public: + };/* + template class ZtCTypeTreeData*/ + + }/* + namespace ZNsType*/ + + + template< typename TType , + typename TTypeInit =ZNsMain::ZtCInit, + typename TTypeTreeData=ZNsType::ZtCTypeTreeData + > + class ZtCTreeData /*###########################################*/ + { + public: + class ZCNode1; class ZCNode2; class ZCNodeInfo; + public: + typedef TType TypeData ; + typedef TTypeInit ZCTypeInit ; + typedef TTypeTreeData ZCTypeTreeData; + public: + typedef typename TTypeTreeData::TypeSize TypeSize ; + typedef typename TTypeTreeData::template + ZtCTypeClass::TypeList ZCNode1List ; + typedef typename TTypeTreeData::template + ZtCTypeClass::TypeList ZCNode2List ; + public: + typedef ZCNode1 ZCNode ; + typedef ZCNode1List ZCNodeList ; + public: + typedef typename ZCNodeList::ZCLink ZCNodeLink; + typedef typename ZCNodeList::iterator IterOfNode; + public: + + class ZCNode1 : public ZCTypeInit + { + public : + friend class ZCNodeInfo; + private: + ZCNode* mp_HighNode ; + TypeData mo_TypeData ; + ZCNode2List mo_CNodeList; + public : + + ZCNode1() + { + mp_HighNode=0; this->ZCTypeInit::OnInit(mo_TypeData); + }/* + ZCNode1()*/ + + ~ZCNode1() + { + mp_HighNode=0; this->ZCTypeInit::OnFini(mo_TypeData); + }/* + ~ZCNode1()*/ + + ZCNode* GetHighNodePtr () {return (ZCNode*)mp_HighNode;} + const ZCNode* GetHighNodePtr ()const{return (ZCNode*)mp_HighNode;} + + TypeData& GetData () {return mo_TypeData;} + const TypeData& GetData ()const{return mo_TypeData;} + const ZCNodeList& GetCNodeList()const{return (ZCNodeList&)mo_CNodeList;} + + TypeSize GetNodeCnt(){return mo_CNodeList.size();} + + void DeleteCNodeList(){mo_CNodeList.DeleteAll();} + void clear (){mo_CNodeList.DeleteAll();} + + ZCNode& AddSubNode() + { + ZCNode* VP_CNode=(ZCNode*)&(**mo_CNodeList.AddTailDef()); + + VP_CNode->mp_HighNode=(ZCNode*)this; return *VP_CNode ; + }/* + ZCNode& AddSubNode()*/ + + ZCNodeInfo GetHeadNodeIter() + { + return ZCNodeInfo((ZCNode*)this, ((ZCNodeList&)mo_CNodeList).GetHeadLinkPtr()); + }/* + ZCNodeInfo GetHeadNodeIter()*/ + + + /*////////////////////////////////////////////////////////////////////////////// + + TViewClass interface + + ZNsMain::ZNsEnum::ZERun OnDataBody(TypeData, TypeSize AI_Depth, TypeSize AI_Index=0) + + ZNsMain::ZNsEnum::ZERun OnSubNodeStart(int AI_Depth, int AI_NodeCnt) + ZNsMain::ZNsEnum::ZERun OnSubNodeClose(int AI_Depth, int AI_NodeCnt) + + -- 2011-10-31 21:53:00 + + //////////////////////////////////////////////////////////////////////////////*/ + + template ZNsMain::ZNsEnum::ZERun IterPreOrder + ( TViewClass& AR_CViewClass, TypeSize AI_StartDepth=0, TypeSize AI_NodeIndex=0 ) + /*##############################################################*/ + { + const bool CB_DoStop = /////////////////////////////// + ( + AR_CViewClass.OnDataBody + (mo_TypeData, AI_StartDepth, AI_NodeIndex) + == ZNsMain::ZNsEnum::ZERun_NO + ); + ////////////////////////////////////////////////////// + + if(CB_DoStop) return ZNsMain::ZNsEnum::ZERun_NO; + + TypeSize VL_NodeCnt= ((ZCNodeList&)mo_CNodeList).size () ; + IterOfNode VO_iter_Node(((ZCNodeList&)mo_CNodeList).begin()); + + if ( AR_CViewClass. ////////////////////////////////////// + OnSubNodeStart(AI_StartDepth, VL_NodeCnt)== + ZNsMain::ZNsEnum::ZERun_NO + ) + { return ZNsMain::ZNsEnum::ZERun_NO; } ////////////////////// + + + ++AI_StartDepth; + { + __for1(TypeSize, i, VL_NodeCnt) + { + const bool CB_DoStop = + ( + ((ZCNodeList&)mo_CNodeList).ItD(VO_iter_Node). + IterPreOrder + (AR_CViewClass, AI_StartDepth, i) + == ZNsMain::ZNsEnum::ZERun_NO + ); + ////////////////////// + + if(CB_DoStop) return ZNsMain::ZNsEnum::ZERun_NO; + + ((ZCNodeList&)mo_CNodeList).MoveNextIter(RR(VO_iter_Node)); + }/* + __for1(TypeSize, i, VL_NodeCnt)*/ + } + --AI_StartDepth; + + const ZNsMain::ZNsEnum::ZERun CE_ERun = + AR_CViewClass.OnSubNodeClose(AI_StartDepth, VL_NodeCnt); + + if(CE_ERun==ZNsMain::ZNsEnum::ZERun_NO) + return ZNsMain::ZNsEnum::ZERun_NO; ///////////////////// + + return ZNsMain::ZNsEnum::ZERun_OK; + }/* + template ZNsMain::ZNsEnum::ZERun IterPreOrder + (TViewClass& AR_CViewClass, TypeSize AI_StartDepth=0, TypeSize AI_NodeIndex=0) + /*##############################################################*/ + + template ZNsMain::ZNsEnum::ZERun IterPostOrder + ( TViewClass& AR_CViewClass, TypeSize AI_StartDepth=0, TypeSize AI_NodeIndex=0 ) + /*###############################################################*/ + { + TypeSize VL_NodeCnt = ((ZCNodeList&)mo_CNodeList).size () ; + IterOfNode VO_iter_Node(((ZCNodeList&)mo_CNodeList).begin()); + + if(AR_CViewClass.OnSubNodeStart + (AI_StartDepth, VL_NodeCnt)==ZNsMain::ZNsEnum::ZERun_NO) + { return ZNsMain::ZNsEnum::ZERun_NO; } + + + ++AI_StartDepth; /*####################*/ + { + __for1(TypeSize, i, VL_NodeCnt) + { + const bool CB_DoStop = + ( + ((ZCNodeList&)mo_CNodeList).ItD(VO_iter_Node). + IterPostOrder(AR_CViewClass, AI_StartDepth, i) + == ZNsMain::ZNsEnum::ZERun_NO + ); + ////////////////////// + + if(CB_DoStop) return ZNsMain::ZNsEnum::ZERun_NO; + + ((ZCNodeList&)mo_CNodeList).MoveNextIter(VO_iter_Node); + }/* + __for1(TypeSize, i, VL_NodeCnt)*/ + } + --AI_StartDepth; /*####################*/ + + if(AR_CViewClass.OnSubNodeClose + (AI_StartDepth, VL_NodeCnt)==ZNsMain::ZNsEnum::ZERun_NO) + { return ZNsMain::ZNsEnum::ZERun_NO; } + + + const bool CB_DoStop = ///////////////////////// + ( + AR_CViewClass.OnDataBody + ( mo_TypeData, AI_StartDepth, AI_NodeIndex ) + ==ZNsMain::ZNsEnum::ZERun_NO + ) ; + //////////////////////////////////////////////// + + if(CB_DoStop) + { return ZNsMain::ZNsEnum::ZERun_NO; } + + return ZNsMain::ZNsEnum::ZERun_OK; + }/* + template ZNsMain::ZNsEnum::ZERun IterPostOrder + (TViewClass& AR_CViewClass, TypeSize AI_StartDepth=0, TypeSize AI_NodeIndex=0) + /*###############################################################*/ + + public: + };/* + class ZCNode1*/ + + class ZCNode2 : public ZCTypeInit + { + public : + friend class ZCNodeInfo; + private: + ZCNode* mp_HighNode ; + TypeData mo_TypeData ; + ZCNode1List mo_CNodeList; + public : + + ZCNode2() + { + mp_HighNode=0; this->ZCTypeInit::OnInit(mo_TypeData); + }/* + ZCNode2()*/ + ~ZCNode2() + { + mp_HighNode=0; this->ZCTypeInit::OnFini(mo_TypeData); + }/* + ~ZCNode2()*/ + + ZCNode* GetHighNodePtr () {return (ZCNode*)mp_HighNode;} + const ZCNode* GetHighNodePtr ()const{return (ZCNode*)mp_HighNode;} + + TypeData& GetData () {return mo_TypeData ;} + const TypeData& GetData ()const{return mo_TypeData ;} + const ZCNodeList& GetCNodeList()const{return (ZCNodeList&)mo_CNodeList;} + + TypeSize GetNodeCnt(){return mo_CNodeList.size();} + + void DeleteCNodeList(){mo_CNodeList.DeleteAll();} + void clear (){mo_CNodeList.DeleteAll();} + + ZCNode& AddSubNode() + { + ZCNode* VP_CNode=(ZCNode*)&(**mo_CNodeList.AddTailDef()); + + VP_CNode->mp_HighNode=(ZCNode*)this; return *VP_CNode ; + }/* + ZCNode& AddSubNode()*/ + + ZCNodeInfo GetHeadNodeIter() + { + return ZCNodeInfo((ZCNode*)this, ((ZCNodeList&)mo_CNodeList).GetHeadLinkPtr()); + }/* + ZCNodeInfo GetHeadNodeIter()*/ + + /*////////////////////////////////////////////////////////////////////////////////////////////// + + ZCNode1 ZCNode2 ̹Ƿ, ZCNode2 IterPreOrder() IterPostOrder() + ʿ. ZCNode2 ZCNode1 ȯǾ ZCNode1 IterPreOrder() IterPostOrder() + ̱ ̴. + + -- 2011-11-01 10:40:00 + + //////////////////////////////////////////////////////////////////////////////////////////////*/ + + public: + };/* + class ZCNode2*/ + + class ZCNodeInfo + { + private: + ZCNode* mp_NowNodeWrap; + ZCNodeLink* mp_NowNodeLink; + public : + + ZCNodeInfo(ZCNode* AP_CNode=0, ZCNodeLink* AP_CNodeLink=0) + { + mp_NowNodeWrap=AP_CNode; mp_NowNodeLink=AP_CNodeLink; + }/* + ZCNodeInfo(ZCNode* AP_CNode=0, ZCNodeLink* AP_CNodeLink=0)*/ + + ZCNode* GetNowNodeWrap(){return mp_NowNodeWrap;} + ZCNodeLink* GetNowNodeLink(){return mp_NowNodeLink;} + + bool DeleteNode() + { + if(mp_NowNodeWrap==0 || mp_NowNodeLink==0) return false; + + ((ZCNodeList&)(mp_NowNodeWrap->mo_CNodeList)). + DeleteLink(mp_NowNodeLink); + mp_NowNodeLink=0; return true; /////////////// + }/* + bool DeleteNode()*/ + + ZCNodeInfo& operator ++ (int) + {mp_NowNodeWrap->mo_CNodeList.MoveNextIter(mp_NowNodeLink); return *this;} + + ZCNode& operator*() {return mp_NowNodeWrap->mo_CNodeList.ItD(mp_NowNodeLink);} + const ZCNode& operator*()const{return mp_NowNodeWrap->mo_CNodeList.ItD(mp_NowNodeLink);} + + public: + };/* + class ZCNodeInfo*/ + + + /*public :*/ + private: + ZCNode mo_RootNode; + public : + ZCNode& GetRootNode() {return mo_RootNode;} + const ZCNode& GetRootNode()const{return mo_RootNode;} + + void DeleteAll(){mo_RootNode.clear();} + void clear (){mo_RootNode.clear();} + + /*///////////////////////////////////////////////////////////////////////////////////////// + + clear() Լ mo_RootNode.clear() ȣϰ ִµ, mo_RootNode.mo_TypeData + ̳ , mo_TypeData ߰ ʱȭϴ ڵ尡 ʿ ִ. ̿ ؼ + CXmlInfo_T<>::clear() Ѵ. + + -- 2012-10-12 13:20:00 + + /////////////////////////////////////////////////////////////////////////////////////////*/ + + + template void IterPreOrder(TViewClass& AR_CViewClass) + { + mo_RootNode.IterPreOrder(AR_CViewClass, 0, 0); + }/* + template void IterPreOrder(TViewClass& AR_CViewClass) */ + + template void IterPostOrder(TViewClass& AR_CViewClass) + { + mo_RootNode.IterPostOrder(AR_CViewClass, 0, 0); + }/* + template void IterPostOrder(TViewClass& AR_CViewClass) */ + + public: + };/* + template< typename TType , + typename TTypeInit =ZNsMain::ZtCInit, + typename TTypeTreeData=ZNsType::ZtCTypeTreeData + > + class ZtCTreeData #############################################*/ + + + + /*/////////////////////////////////////////////////////////////// + + class ZtCTreeData -- 2015-08-14 14:00 + + #include + #include "ZCppMain/ZtCTreeData.H" + + using namespace std ; + using namespace ZNsMain; + + typedef ZtCStringBase CStringBase ; + typedef ZtCTreeData CStrTreeData ; + typedef CStrTreeData::ZCNode CNodeCStr ; + typedef ZNsMain::ZNsView:: + ZtCViewTreeData CViewTreeData; + + int main() + { + CStringBase VO_CStringBase ; + CStrTreeData VO_CStrTreeData ; + CViewTreeData VO_CViewTreeData; + + CNodeCStr& VO_CNodeCStr1 = VO_CStrTreeData.GetRootNode().AddSubNode(); + CNodeCStr& VO_CNodeCStr2 = VO_CStrTreeData.GetRootNode().AddSubNode(); + CNodeCStr& VO_CNodeCStr3 = VO_CStrTreeData.GetRootNode().AddSubNode(); + + CNodeCStr& VO_CNodeCStr11 = VO_CNodeCStr1 .AddSubNode(); + CNodeCStr& VO_CNodeCStr12 = VO_CNodeCStr1 .AddSubNode(); + + CNodeCStr& VO_CNodeCStr121= VO_CNodeCStr12.AddSubNode(); + CNodeCStr& VO_CNodeCStr122= VO_CNodeCStr12.AddSubNode(); + + CNodeCStr& VO_CNodeCStr21 = VO_CNodeCStr2 .AddSubNode(); + CNodeCStr& VO_CNodeCStr22 = VO_CNodeCStr2 .AddSubNode(); + + VO_CStrTreeData.GetRootNode().GetData()="## Root Node ##"; + + VO_CNodeCStr1 . GetData()="Node1" ; + VO_CNodeCStr2 . GetData()="Node2" ; + VO_CNodeCStr3 . GetData()="Node3" ; + + VO_CNodeCStr11. GetData()="Node11" ; + VO_CNodeCStr12. GetData()="Node12" ; + + VO_CNodeCStr21. GetData()="Node21" ; + VO_CNodeCStr22. GetData()="Node22" ; + + VO_CNodeCStr121.GetData()="Node121"; + VO_CNodeCStr122.GetData()="Node122"; + + cout<<"# Pre Order"<::ZCNode1 mo_TypeData ִٸ, + class ZtCTreeDataEx<>::ZCNode1 mo_CDataList ִ. + + ///////////////////////////////////////////////////////////////*/ + + + template< typename TType, + typename TTypeTreeData=ZNsType::ZtCTypeTreeData + > + class ZtCTreeDataEx /*#########################################*/ + { + public: + typedef TType TypeData ; + typedef TTypeTreeData ZCTypeTreeData; + public: + class ZCNode1; class ZCNode2; class ZCNodeInfo ; + public: + typedef typename TTypeTreeData::TypeSize TypeSize; + public: + typedef typename TTypeTreeData:: + template ZtCTypeClass::TypeList ZCDataList ; + typedef typename TTypeTreeData:: + template ZtCTypeClass::TypeList ZCNode1List; + typedef typename TTypeTreeData:: + template ZtCTypeClass::TypeList ZCNode2List; + public: + typedef ZCNode1 ZCNode ; + typedef ZCNode1List ZCNodeList; + typedef typename ZCNodeList::ZCLink ZCNodeLink; + typedef typename ZCDataList::ZCLink ZCDataLink; + public: + typedef typename ZCDataList::iterator IterOfData; + typedef typename ZCNodeList::iterator IterOfNode; + public: + + class ZCNode1 + { + public : + friend class ZCNodeInfo; + private: + ZCNode* mp_HighNode ; + ZCDataList mo_CDataList; + ZCNode2List mo_CNodeList; + public : + + ZCNode1() + { + mp_HighNode=0; + }/* + ZCNode1()*/ + + ZCNode* GetHighNodePtr() {return (ZCNode*)mp_HighNode;} + const ZCNode* GetHighNodePtr()const{return (ZCNode*)mp_HighNode;} + + ZCDataList& GetZCDataList() {return mo_CDataList;} + const ZCDataList& GetZCDataList()const{return mo_CDataList;} + const ZCNodeList& GetCNodeList()const{return (ZCNodeList&)mo_CNodeList;} + + TypeSize GetDataCnt(){return mo_CDataList.size();} + TypeSize GetNodeCnt(){return mo_CNodeList.size();} + + void DeleteCDataList(){mo_CDataList.DeleteAll();} + void DeleteCNodeList(){mo_CNodeList.DeleteAll();} + void DeleteAll (){mo_CDataList.DeleteAll(); mo_CNodeList.DeleteAll();} + void clear (){DeleteAll();} + + ZCNode& AddSubNode() + { + ZCNode* VP_CNode=(ZCNode*)&(**mo_CNodeList.AddTailDef()); + + VP_CNode->mp_HighNode=(ZCNode*)this; return *VP_CNode ; + }/* + ZCNode& AddSubNode()*/ + + ZCNodeInfo GetHeadNodeIter() + { + return ZCNodeInfo((ZCNode*)this, ((ZCNodeList&)mo_CNodeList).GetHeadLinkPtr()); + }/* + ZCNodeInfo GetHeadNodeIter()*/ + + + /*////////////////////////////////////////////////////////////////////////////// + + TViewClass interface + + ZNsMain::ZNsEnum::ZERun OnDataStart(int AI_Depth) + ZNsMain::ZNsEnum::ZERun OnDataBody(TypeData, TypeSize AI_Depth, TypeSize AI_Index) + ZNsMain::ZNsEnum::ZERun OnDataClose(int AI_Depth) + + ZNsMain::ZNsEnum::ZERun OnSubNodeStart(int AI_Depth, int AI_NodeCnt) + ZNsMain::ZNsEnum::ZERun OnSubNodeClose(int AI_Depth, int AI_NodeCnt) + + -- 2011-10-31 21:53:00 + + //////////////////////////////////////////////////////////////////////////////*/ + + template ZNsMain::ZNsEnum::ZERun IterPreOrder + ( + TViewClass& AR_CViewClass , + TypeSize AI_StartDepth=0, + TypeSize AI_NodeIndex =0 + ) + /*##############################################################*/ + { + TypeSize VL_DataCnt= mo_CDataList .size(); + TypeSize VL_NodeCnt=((ZCNodeList&)mo_CNodeList).size(); + + IterOfData VO_iter_Data( mo_CDataList.begin()); + IterOfNode VO_iter_Node(((ZCNodeList&)mo_CNodeList).begin()); + + if(AR_CViewClass.OnDataStart(AI_StartDepth)==ZNsMain::ZNsEnum::ZERun_NO) + { return ZNsMain::ZNsEnum::ZERun_NO; } + /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ + { + __for1(TypeSize, i, VL_DataCnt) + { + const bool CB_DoStop = + ( + AR_CViewClass.OnDataBody + ( + mo_CDataList.ItD(VO_iter_Data), AI_StartDepth, AI_NodeIndex + ) + == ZNsMain::ZNsEnum::ZERun_NO + ); + ////////////////////// + + if(CB_DoStop) return ZNsMain::ZNsEnum::ZERun_NO; + + mo_CDataList.MoveNextIter(VO_iter_Data); /////// + }/* + __for1(TypeSize, i, VL_DataCnt)*/ + } + if(AR_CViewClass.OnDataClose(AI_StartDepth)==ZNsMain::ZNsEnum::ZERun_NO) + { return ZNsMain::ZNsEnum::ZERun_NO; } + /*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ + + if(AR_CViewClass.OnSubNodeStart + (AI_StartDepth, VL_NodeCnt)==ZNsMain::ZNsEnum::ZERun_NO) + { return ZNsMain::ZNsEnum::ZERun_NO; } + + ++AI_StartDepth; /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ + { + __for1(TypeSize, i, VL_NodeCnt) + { + const bool CB_DoStop = /////////////////////////////// + ( + ((ZCNodeList&)mo_CNodeList).ItD(VO_iter_Node). + IterPreOrder + (AR_CViewClass, AI_StartDepth. i) + == ZNsMain::ZNsEnum::ZERun_NO + ); + ////////////////////////////////////////////////////// + + if(CB_DoStop) return ZNsMain::ZNsEnum::ZERun_NO; + + ((ZCNodeList&)mo_CNodeList).MoveNextIter(VO_iter_Node); + }/* + __for1(TypeSize, i, VL_NodeCnt)*/ + } + --AI_StartDepth; /*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ + + if(AR_CViewClass.OnSubNodeClose + (AI_StartDepth, VL_NodeCnt)==ZNsMain::ZNsEnum::ZERun_NO) + { return ZNsMain::ZNsEnum::ZERun_NO; } + + return ZNsMain::ZNsEnum::ZERun_OK; ///////////////////////// + }/* + template ZNsMain::ZNsEnum::ZERun IterPreOrder + ( + TViewClass& AR_CViewClass, TypeSize AI_StartDepth=0 + TypeSize AI_NodeIndex =0 + ) */ + /*###############################################################*/ + + template ZNsMain::ZNsEnum::ZERun IterPostOrder + ( + TViewClass& AR_CViewClass , + TypeSize AI_StartDepth=0, + TypeSize AI_NodeIndex =0 + ) + /*###############################################################*/ + { + TypeSize VL_DataCnt= mo_CDataList. size(); + TypeSize VL_NodeCnt=((ZCNodeList&)mo_CNodeList).size(); + + IterOfData VO_iter_Data( mo_CDataList. begin()); + IterOfNode VO_iter_Node(((ZCNodeList&)mo_CNodeList).begin()); + + if(AR_CViewClass.OnSubNodeStart + (AI_StartDepth, VL_NodeCnt)==ZNsMain::ZNsEnum::ZERun_NO) + { return ZNsMain::ZNsEnum::ZERun_NO; } + + ++AI_StartDepth; /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ + { + __for1(TypeSize, i, VL_NodeCnt) + { + const bool CB_DoStop = //////////////////////////////// + ( + ((ZCNodeList&)mo_CNodeList). + ItD(VO_iter_Node).IterPostOrder + (AR_CViewClass, AI_StartDepth, i) + == ZNsMain::ZNsEnum::ZERun_NO + ); + /////////////////////////////////////////////////////// + + if(CB_DoStop) return ZNsMain::ZNsEnum::ZERun_NO; + + ((ZCNodeList&)mo_CNodeList).MoveNextIter(VO_iter_Node); + }/* + __for1(TypeSize, i, VL_NodeCnt)*/ + } + --AI_StartDepth; /*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ + + if(AR_CViewClass.OnSubNodeClose + (AI_StartDepth, VL_NodeCnt)==ZNsMain::ZNsEnum::ZERun_NO) + { return ZNsMain::ZNsEnum::ZERun_NO; } + + if(AR_CViewClass.OnDataStart(AI_StartDepth)==ZNsMain::ZNsEnum::ZERun_NO) + { return ZNsMain::ZNsEnum::ZERun_NO; } + /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ + { + __for1(TypeSize, i, VL_DataCnt) + { + const bool CB_DoStop = //////////////////// + ( + AR_CViewClass.OnDataBody + ( + mo_CDataList.ItD(VO_iter_Data), AI_StartDepth, AI_NodeIndex + ) + == ZNsMain::ZNsEnum::ZERun_NO + ); + /////////////////////////////////////////// + + if(CB_DoStop) return ZNsMain::ZNsEnum::ZERun_NO; + + mo_CDataList.MoveNextIter(VO_iter_Data); /////////////// + }/* + __for1(TypeSize, i, VL_DataCnt)*/ + } + if(AR_CViewClass.OnDataClose(AI_StartDepth)==ZNsMain::ZNsEnum::ZERun_NO) + { return ZNsMain::ZNsEnum::ZERun_NO; } + /*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ + + return ZNsMain::ZNsEnum::ZERun_OK; + }/* + template ZNsMain::ZNsEnum::ZERun IterPostOrder + ( + TViewClass& AR_CViewClass , + TypeSize AI_StartDepth=0 , + TypeSize AI_NodeIndex =0 + ) + #################################################################*/ + + public: + };/* + class ZCNode1*/ + + class ZCNode2 + { + public : + friend class ZCNodeInfo; + private: + ZCNode* mp_HighNode ; + ZCDataList mo_CDataList; + ZCNode1List mo_CNodeList; + public : + + ZCNode2() + { + mp_HighNode=0; + }/* + ZCNode2()*/ + + ZCNode* GetHighNodePtr() {return (ZCNode*)mp_HighNode;} + const ZCNode* GetHighNodePtr()const{return (ZCNode*)mp_HighNode;} + + ZCDataList& GetZCDataList() {return mo_CDataList;} + const ZCDataList& GetZCDataList()const{return mo_CDataList;} + const ZCNodeList& GetCNodeList ()const{return (ZCNodeList&)mo_CNodeList;} + + TypeSize GetDataCnt(){return mo_CDataList.size();} + TypeSize GetNodeCnt(){return mo_CNodeList.size();} + + void DeleteCDataList(){mo_CDataList.DeleteAll();} + void DeleteCNodeList(){mo_CNodeList.DeleteAll();} + void DeleteAll (){mo_CDataList.DeleteAll(); mo_CNodeList.DeleteAll();} + void clear (){DeleteAll();} + + ZCNode& AddSubNode() + { + ZCNode* VP_CNode=(ZCNode*)& + ( **mo_CNodeList.AddTailDef() ); + + VP_CNode->mp_HighNode=(ZCNode*)this; return *VP_CNode; + }/* + ZCNode& AddSubNode()*/ + + ZCNodeInfo GetHeadNodeIter() + { + return ZCNodeInfo((ZCNode*)this, ((ZCNodeList&)mo_CNodeList).GetHeadLinkPtr()); + }/* + ZCNodeInfo GetHeadNodeIter()*/ + + /*////////////////////////////////////////////////////////////////////////////////////////////// + + ZCNode1 ZCNode2 ̹Ƿ, ZCNode2 IterPreOrder() IterPostOrder() + ʿ. ZCNode2 ZCNode1 ȯǾ ZCNode1 IterPreOrder() IterPostOrder() + ̱ ̴. + + -- 2011-11-01 10:40:00 + + //////////////////////////////////////////////////////////////////////////////////////////////*/ + + public: + };/* + class ZCNode2*/ + + class ZCNodeInfo + { + private: + ZCNode* mp_NowNodeWrap; + ZCNodeLink* mp_NowNodeLink; + public : + + ZCNodeInfo(ZCNode* AP_CNode=0,ZCNodeLink* AP_CNodeLink=0) + { + mp_NowNodeWrap=AP_CNode; mp_NowNodeLink=AP_CNodeLink; + }/* + ZCNodeInfo(ZCNode* AP_CNode=0,ZCNodeLink* AP_CNodeLink=0)*/ + + ZCNode* GetNowNodeWrap(){return mp_NowNodeWrap;} + ZCNodeLink* GetNowNodeLink(){return mp_NowNodeLink;} + + bool DeleteNode() + { + if(mp_NowNodeWrap==0 || mp_NowNodeLink==0) return false; + + ((ZCNodeList&)(mp_NowNodeWrap->mo_CNodeList)). + DeleteLink(mp_NowNodeLink); + mp_NowNodeLink=0; return true; ////////////// + }/* + bool DeleteNode()*/ + + ZCNodeInfo& operator++(int) + { + mp_NowNodeWrap->mo_CNodeList.MoveNextIter(mp_NowNodeLink); return *this; + }/* + ZCNodeInfo& operator++(int)*/ + + ZCNode& operator*() {return mp_NowNodeWrap->mo_CNodeList.ItD(mp_NowNodeLink);} + const ZCNode& operator*()const{return mp_NowNodeWrap->mo_CNodeList.ItD(mp_NowNodeLink);} + + public: + };/* + class ZCNodeInfo + + + public :*/ + private: + ZCNode mo_RootNode; + public: + ZCNode& GetRootNode() {return mo_RootNode;} + const ZCNode& GetRootNode()const{return mo_RootNode;} + + void DeleteAll(){mo_RootNode.clear();} + void clear (){mo_RootNode.clear();} + + template void IterPreOrder (TViewClass AO_CViewClass) + { mo_RootNode.IterPreOrder(AO_CViewClass, 0); } + template void IterPostOrder(TViewClass AO_CViewClass) + { mo_RootNode.IterPostOrder(AO_CViewClass, 0); } + + public: + };/* + template< typename TType, + typename TTypeTreeData=ZNsType::ZtCTypeTreeData + > + ZtCTreeDataEx #################################################*/ + +}/* +namespace ZNsMain*/ + + +/*////////////////////////////////////////////////////////////////////////////////////////// + + CTreeClass.H ü ̴. CTreeClass.H Ʈ ǥϴµ, + Ʒ + + class CMyNode; + { + public: + TypeData mo_TypeData; + ZNsMain::ZtCObjList mo_NodeList; // Ʈ. + }; + + , void* Ͽ. ׷ Ͽ, Ȱ + Ŭ ZCNode1, ZCNode2 ν, (!!) ͸ ϰ ִ. + + Ŭ ZCNode1 ZCNode2 ̳(Ʈ) ְ, + Ŭ ZCNode2 ZCNode1 ̳(Ʈ) ִ. + + ϰ, ̶ ƴ . + + 2011-10-29 , 7 ÿȭȸ 鼭, object + , ߿ object instance ϴ , Ų ذ + Ӹ ӿ ׷鼭, ̶ Ȯ . ׷ + , , ߴ Ų ƴϾ 巯. Ǹ ־ + , Ʈ , ȱ , ̸ ٸ 2 Ŭ Ʈ + ִٴ ó ̴. CTreeData.H ̴. + + ׷, ̾. + + ش µ, ڿ ΰ ִ , ٷ տ ŭ ٰ + . + + -- 2011-10-31 23:47:00 + + -- CTreeClass.H ŵǾ. -- 2013-05-01 17:22:00 + +//////////////////////////////////////////////////////////////////////////////////////////*/ + + +#endif // __ZCPPMAIN__ZCTREEDATA_H__