OpenSource Published New version mybuff library here,
이것은 일전에 Intelligent-Memory-Buffer-Class-on-Non-MFCSDK-Platforms 라는 타이틀로 codeguru에 올렸던 mybufflib 의 확장된 최신 버전이다.
이전 버전은,
http://www.codeguru.com/cpp/misc/misc/memory/article.php/c14499/Intelligent-Memory-Buffer-Class-on-Non-MFCSDK-Platforms.htm
에 있음.
/*
* kxBuffLibrary : krkim's eXtended Intelligent & Sequencial Linear Buffer Library
* PURPOSE : Intelligent increasing buffer with a big buffer data,add to sequencial data,
* string,list like MFC String or PtrArray on Non-MFC platforms(general C/C++).
*
* Copyright(c) 2005-2010 Durumul.com ,Korea
* Author : K***(*******)
* yeamaec@hanafos.com (http://www.durumul.com,http://krkim.net)
*
* Version : 1.0.5
* This source is free to use as you like but leave this notice.
* If you make any changes(bugfix,updating),please mail the new version to me.
*
* This material is provided "as is", with absolutely no warranty expressed
* or implied. Any use is at your own risk.
*
* Permission to use or copy this software for any purpose is hereby granted
* without fee, provided the above notices are retained on all copies.
* Permission to modify the code and to distribute modified code is granted,
* provided the above notices are retained, and a notice that the code was
* modified is included with the above copyright notice.
*
*/
/*
This source code is extended last version of mybufflib i published at some years ago,
http://www.codeguru.com/cpp/misc/misc/memory/article.php/c14499/Intelligent-Memory-Buffer-Class-on-Non-MFCSDK-Platforms.htm
*/
/*
History:
1.0.5 - 2010.07.11 <krkim> bugfix kxString constructor.
1.0.3 - 2007.11.27 <krkim> add operators to IBuff.
1.0.2 - 2007.11 <krkim> Renew TCHAR and LPTSTR for UNICODE Compatible.
1.0.1 - 2006.12.07 <krkim> Add resize at kxList.
1.0.0 - not support decreasing buffer.
Initlal version 1.0 2005 12.15 KRKIM.
*/
#pragma once
#pragma warning (push)
#pragma warning(disable : 4996)
#ifndef KXBUFF__H
#define KXBUFF__H
#define KXBUFF_ASBIGSIZE ( 1 << 24) /* := 16mb */
#define KXBUFF_GETBLOCKNUM(x,b) ((x / b) + ((x % b) ? 1 : 0))
#define KXBUFF_GETBLOCKSIZE(x,b) (KXBUFF_GETBLOCKNUM(x,b) * b + 1) /* + oddinary one byte */
#define KXBUFF_PREFIX "Mb" /*map file prefix*/
#include <windef.h>
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
#include <strsafe.h>
#ifdef _KXBUFF_DISABLE_NO_VTABLE
#define KXBUFF_NO_VTABLE
#else
#define KXBUFF_NO_VTABLE __declspec(novtable)
#endif
#ifndef ASSERT
#define ASSERT( x ) ((void)0)
#define KFCASSERT( x ) ((void)0)
#endif
namespace kxBuffLib{
template < class _Ty = void>
class kxBuff
{
protected:
_Ty *m_buff;
int m_blksize; /*total allocated block size*/
int m_offset; /*current used size(offset)*/
HANDLE m_hFile, m_hFileMap;
TCHAR *m_mapfile;
int m_element_size;
int KXBUFF_BLOCKSIZE;
public:
void _init(){
m_element_size = sizeof(TCHAR);
m_blksize = m_offset = 0;
m_buff = NULL;
m_hFile = INVALID_HANDLE_VALUE;
m_hFileMap = 0;
m_mapfile = NULL;
KXBUFF_BLOCKSIZE = 32768;
}
kxBuff(){
_init();
}
inline kxBuff(LPCTSTR str){
_init();
addstr((LPTSTR)str);
}
inline kxBuff( const kxBuff & srcbuff){
_init();
_Ty *buff = (_Ty *)srcbuff.getdata();
add(buff,srcbuff.getsize());
}
~kxBuff(void){
reset();
}
BOOL isvalidoffset(int offset){
int size = getsize();
if(offset >= size || offset < 0) return false;
return true;
}
void reset(){
if(isbigmode()){
if(m_buff) UnmapViewOfFile(m_buff);
if (m_hFileMap) CloseHandle(m_hFileMap);
if (m_hFile != INVALID_HANDLE_VALUE) CloseHandle(m_hFile);
if(m_mapfile){
DeleteFile(m_mapfile);
free(m_mapfile);
}
m_mapfile = NULL;
m_hFile = INVALID_HANDLE_VALUE;
m_hFileMap = 0;
m_buff = 0;
m_offset = 0;
}
else{
if(m_buff)
free(m_buff);
m_offset = m_blksize = 0;
m_buff = 0;
}
}
_Ty* getdata(int offset = 0) const throw(){
return( reinterpret_cast< _Ty* >(m_buff + offset));
}
operator LPCTSTR() const throw(){ return (LPCTSTR)m_buff; }
operator LPTSTR() const throw(){ return (LPTSTR)m_buff; }
//operator LPSTR() const throw(){ return (LPSTR)m_buff; }
kxBuff& operator=(LPTSTR str){
reset(); addstr(str);
return (*this);
}
kxBuff& operator=(LPCTSTR str){
reset(); addstr((LPTSTR)str);
return (*this);
}
const kxBuff& operator=(const unsigned char * str){
reset(); addstr((LPTSTR)str);
return (*this);
}
kxBuff& operator=(const kxBuff& src){
LPVOID pSrc = src.getdata();
LPVOID pOld = getbuffer();
if( pSrc != pOld){
reset();
add(pSrc,src.getsize());
}
return(*this);
}
inline const kxBuff& operator += (const kxBuff& src){
LPVOID pSrc = src.getdata();
add(pSrc,src.getsize());
return(*this);
}
void resize(int size){
int oldoffset = m_offset;
if(size == 0){
reset();
return;
}
if(!isbigmode() && size < KXBUFF_ASBIGSIZE){
if(size > m_blksize){
int newalloc = KXBUFF_GETBLOCKSIZE(size,KXBUFF_BLOCKSIZE);
_Ty* newbuff = (_Ty*)realloc(m_buff,newalloc);
if(!newbuff){
newalloc = size;
newbuff = (_Ty*)malloc(newalloc);
memcpy(newbuff,m_buff,min(size,m_blksize));
free(m_buff);m_buff = NULL;
}
m_buff = newbuff;
memset((char*)m_buff + m_offset,0,newalloc - m_offset);
m_blksize = newalloc;
}
}
else if(size > m_blksize)
{
int wasbig = isbigmode();
LPVOID oldbuff = m_buff;
LPVOID mapping = 0;
if (wasbig && m_buff){
UnmapViewOfFile(m_buff);
m_buff = NULL;
}
if (m_hFileMap) CloseHandle(m_hFileMap);
m_hFileMap = 0;
int newalloc = KXBUFF_GETBLOCKSIZE(size,KXBUFF_BLOCKSIZE);
if(m_hFile == INVALID_HANDLE_VALUE)
{
TCHAR tmp[MAX_PATH];
GetTempPath(MAX_PATH,tmp);
if(m_mapfile)
free(m_mapfile);
m_mapfile = (TCHAR*)malloc(MAX_PATH+10);
GetTempFileName(tmp,(LPTSTR)KXBUFF_PREFIX,0,m_mapfile);
m_hFile = CreateFile(m_mapfile,GENERIC_READ|GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_TEMPORARY|FILE_FLAG_DELETE_ON_CLOSE,NULL);
}
if(m_hFile != INVALID_HANDLE_VALUE)
m_hFileMap = CreateFileMapping(m_hFile,NULL,PAGE_READWRITE,0,newalloc,NULL);
if(m_hFileMap)
mapping = MapViewOfFile(m_hFileMap,FILE_MAP_WRITE,0,0,newalloc);
if(mapping && !wasbig && oldbuff && m_offset > 0){ /*copy from tiny buff*/
memcpy(mapping,oldbuff,m_offset);
free(m_buff);/*destroy*/
m_buff = (_Ty*)mapping;
}
m_blksize = newalloc;
}
m_offset = size;
if(m_buff && oldoffset > m_offset)
memset((char*)m_buff + m_offset,0,oldoffset - m_offset);
}
int addstr(LPTSTR str){
int len = 0;
len = (str)? (int)_tcslen(str) : 0;
return add(str,len);
}
int add(const _Ty* data,int len){
if(data == NULL)
return 0;
int offset = m_offset;
int newsize = offset + len;
if(len == 0 && *data == 0){ // ""
if(m_buff)
*(m_buff + m_offset) = 0;
else{
resize(1);
*m_buff = 0;
m_offset = 0;
}
return 0;
}
else if(len <= 0)
return 0;
resize(newsize);
if(data)
memcpy((char*)m_buff + offset,data,len);
else
memset((char*)m_buff + offset,0x00,len);
return offset;/* return head position of inserting current data*/
}
int kxmemcmp(const void *b1, const void *b2, size_t n,int ignorecase = 0,int ignorenull = 1) const
{
const unsigned char *p1 = (const unsigned char*)b1;
const unsigned char *p2 = (const unsigned char*)b2;
if(ignorenull == 0 && (!b1||!b2)){
if(b1 && !b2) return -1;
if(!b1 && b2) return 1;
if(!b1 && !b2) return 0;
}
if(!n){
if(b1 && b2){
//if((char)*b1 == 0 && (char)*b2 == 0) return 0;
//if((char)*b1 && (char)*b2 == 0) return -1;
//if((char)*b1 == 0 && (char)*b2) return 1;
}
return 1;
}
for(size_t i = 0; i < n; i++){
if(ignorenull == 0){//string비교의 경우 둘중 하나가 null만나는 곳 까지만
if(p1[i] == 0x00 && p2[i] == 0x00)
return 0;
else if(p1[i] == 0x00)
return -1;
else if(p2[i] == 0x00)
return 1;
}
if(p1[i] != p2[i]){
if(ignorecase){
int c1 = toupper(p1[i]);
int c2 = toupper(p2[i]);
if(c1 != c2)
return p1[i]-p2[i];
}
return p1[i]-p2[i];
}
}
return 0;
}
/* ignorecase = TRUE : ignore CASE SENSITIVE */
int find(_Ty* str,int startpos,int len,int *lpelementindex,int ignorecase = 0,int ignorenull = 1){
int size = getsize();
int offset = startpos;
int findlen = len;
int elementindex = 0;
if(findlen <= 0)
findlen = (int)_tcslen((LPCSTR)str);
if(lpelementindex) *lpelementindex = -1;
_Ty* p;
while(offset < size){
p = getbuffer(offset);
int remainlen = size - offset;
if(remainlen < findlen)
return -1;
if(!kxmemcmp(str,p,findlen,ignorecase,ignorenull)){
if(lpelementindex) *lpelementindex = elementindex;
return offset;
}
offset += m_element_size;
elementindex ++;
}
return -1;
}
int getsize() const { return m_offset; }
int getblkcount() { return (m_blksize/KXBUFF_BLOCKSIZE); }
int getblksize() { return m_blksize; }
_Ty* getbuffer(int offset = 0) { return m_buff == NULL ? NULL : (_Ty*)((_Ty*)m_buff + offset); }
int isbigmode() { return ((m_hFile == INVALID_HANDLE_VALUE ) ? false : true);}
};
////////////////////////////////////////////////////////////////////////////////
// List Buff
template < class _Ty>
class kxList : public kxBuff<_Ty>/*like CPtrArray*/
{
public:
kxList(){
m_element_size = sizeof(_Ty);
KXBUFF_BLOCKSIZE = m_element_size * 2;
}
~kxList(){}
virtual int find(_Ty data,int *lpelementindex = 0,int comparesize = 0){/* return offset,lpindex is list index*/
int size = kxBuff::getsize();
int compsize = (comparesize > 0) ? comparesize :m_element_size;
return kxBuff::find(&data,0,compsize,lpelementindex);
}
virtual int add(_Ty data){
return kxBuff::add(&data,m_element_size);
}
//virtual int addlen(_Ty data,int len)
//{
// return m_list.add(&data,len);
//}
virtual int addlen(LPVOID data,int len){
return kxBuff::add(data,len);
}
_Ty * get(int offset){
if(!isvalidoffset(offset))
return NULL;
_Ty * p = (LPVOID)kxBuff::getbuffer(offset);
return p;
}
_Ty getat(int index,int *lpoffset = 0){
int size = getsize();
int offset = index * m_element_size;
if(lpoffset) *lpoffset = -1;
if(isvalidoffset(offset)){
LPVOID p = (LPVOID)kxBuff::getbuffer(offset);
if(lpoffset) *lpoffset = offset;
_Ty rv = *(_Ty *)p;
return rv;
}
return NULL;
}
virtual void insertat(int index,_Ty data){
int size = getsize();
int offset = (index + 1) * m_element_size;
if(!isvalidoffset(offset)){
resize(offset);
offset = index * m_element_size;
LPVOID p = (LPVOID)kxBuff::getbuffer(offset);
memcpy(p,&data,m_element_size);
}
else{
resize(size + m_element_size);
LPVOID p = (LPVOID)kxBuff::getbuffer((index + 1) * m_element_size);
LPVOID q = (LPVOID)kxBuff::getbuffer((index) * m_element_size);
memmove(p,q,size-m_element_size);
memset(q, 0, m_element_size);
memcpy(q,&data,m_element_size);
}
}
virtual void setat(int index,_Ty data){
int size = getsize();
int offset = index * m_element_size;
if(isvalidoffset(offset)){
LPVOID p = (LPVOID)kxBuff::getbuffer(offset);
memcpy(p,&data,m_element_size);
}
}
virtual void removeoffset(int offset){
int size = getsize();
LPVOID p = (LPVOID)kxBuff::getbuffer(offset);
if(offset + m_element_size <= size){
memcpy(p,(char *)p + m_element_size,size - (offset + m_element_size));
}
kxBuff::resize(size - m_element_size);
}
virtual void removeat(int index){
int offset = -1;
int size = getsize();
getat(index,&offset);/*no LPSTR checking for including NULL*/
if(isvalidoffset(offset)) /*found*/
removeoffset(offset);
}
virtual void removeall(){
kxBuff::reset();
}
virtual int getcount(){ /*number of index elements*/
return getsize() / m_element_size;
}
_Ty operator[](int nIndex)
{
return getat(nIndex);
}
};
//메모리 한 주소에 연속적으로 들어가는 linear string list
template < class _Ty>
class kxListString : public kxBuff<_Ty>
{
public:
kxListString()
{
KXBUFF_BLOCKSIZE = 512;
}
~kxListString(){}
virtual BOOL isvalidoffset(int offset){
if(!kxBuff::isvalidoffset(offset))
return false;
if(offset > 0){
CHAR *p = (CHAR *)kxBuff::getbuffer(offset - 1);
if(p != NULL) return false;
}
return true;
}
/* insensitive = TRUE : ignore CASE SENSITIVE */
virtual int find(LPTSTR str,int *lpelementindex,int ignorecase = 0){/* return offset,lpindex is list index*/
int size = kxBuff::getsize();
int offset = 0;
int elementindex = 0;
int findlen = (int)_tcslen(str);
TCHAR *p;
if(lpelementindex) *lpelementindex = -1;
while(offset < size){
p = (TCHAR *)kxBuff::getbuffer(offset);
if(!kxmemcmp(p,str,findlen,ignorecase,0)){
if(lpelementindex) *lpelementindex = elementindex;
return offset;
}
int len = (int)_tcslen(p);//null다음으로
offset += (len + 1);
elementindex ++;
}
return -1;
}
LPTSTR operator[](int index)
{
return getat(index);
}
virtual LPTSTR getat(int index,int *lpoffset = 0){
int size = kxBuff::getsize();
int offset = 0;
int ipos = 0;
TCHAR *p;
if(lpoffset) *lpoffset = -1;
while(offset < size){
p = (TCHAR *)kxBuff::getbuffer(offset);
if(index == ipos){
if(lpoffset) *lpoffset = offset;
return p;
}
int len = (int)_tcslen(p) + 1;
offset += len;
ipos ++;
}
return NULL;
}
virtual int addforce(LPTSTR str){ /*no find action,force add like list*/
int len = (str == NULL )? 1:((int)_tcslen(str) + 1);
return kxBuff::add(str,len);
}
virtual int add(LPTSTR str,int insensitive = 0){
int offset = find(str,NULL,insensitive);
if(offset >= 0 && insensitive > -1 )
return offset; /*insensitive = -1 to force add without compare */
int len = (str == NULL )? 1:((int)_tcslen(str) + 1);
return kxBuff::add(str,len);
}
virtual int addlen(_Ty* data,int len)
{
return kxBuff::add(data,len);
}
virtual void removeoffset(int offset)
{
int size = kxBuff::getsize();
TCHAR *p = (TCHAR *)kxBuff::getbuffer(offset);
int len = (int)_tcslen(p) + 1;
if(offset + len < size)
memcpy(p,p + len,size - (offset + len));
kxBuff::resize(size - len);
}
virtual void removeat(int index)
{
int offset = -1;
getat(index,&offset);/*no LPSTR checking for including NULL*/
if(isvalidoffset(offset)) /*found*/
removeoffset(offset);
}
virtual int getcount() /*number of index elements*/
{
int size = kxBuff::getsize();
int offset= 0;
int index = 0;
TCHAR *p;
while(offset < size){
p = (TCHAR *)kxBuff::getbuffer(offset);
int len = (int)_tcslen(p) + 1;
offset += len;
index ++;
}
return index;
}
virtual TCHAR *GetBuffer(int offset = 0){
return (TCHAR *)kxBuff::getbuffer(offset);
}
virtual void removeall(){kxBuff::reset();}
};
/*
mystr is clone class for action like MFC CString using non MFC Project fluent string management.
2006.03.18 KRKIM.
Usage mystr example
mystr text,text2;
text = "test text";
text2 = text;
LPCSTR sztext = text;
*/
class kxString : public kxBuff<CHAR>
{
public:
kxString(){
KXBUFF_BLOCKSIZE = sizeof(CHAR) * 2;/*bugfix*/
}
~kxString(){
}
inline kxString(LPCTSTR pszString){
KXBUFF_BLOCKSIZE = sizeof(CHAR) * 2;/*bugfix*/
Set(pszString);
}
inline kxString(const kxString & strSrc){
KXBUFF_BLOCKSIZE = sizeof(CHAR) * 2;/*bugfix*/
Set((LPCTSTR)strSrc.GetBuffer());
}
inline kxString(TCHAR ch, int nRepeat = 1)
{
if (nRepeat >= 1){
resize(nRepeat);
memset(GetBuffer(), ch, nRepeat);
}
}
public:
LPCTSTR cstr(){
return (LPCTSTR)GetBuffer();
}
LPTSTR str(){
return (LPTSTR)GetBuffer();
}
LPCTSTR Get(int pos = 0){
return (LPCTSTR)kxBuff::getbuffer(pos);
}
void Set(LPCTSTR pszString,int len = -1){
if(!pszString) return;
if(len == -1)
len = (int)_tcslen(pszString);
kxBuff::reset();
if(!pszString) return;
kxBuff::add(pszString,len);
}
void SetLength(int len){//버퍼를 주어진 길이로 맞춤,뒷부분자를때유용
kxBuff::resize(len);
addstr("");
}
void Append(LPCTSTR pszString){
kxBuff::addstr((LPTSTR)pszString);
}
void Delete(){
kxBuff::reset();
}
void Format(LPCTSTR pszFormat,...){
va_list arglist;
va_start(arglist,pszFormat);
FormatV((LPCSTR)pszFormat, arglist );
va_end(arglist);
}
void FormatV(LPCSTR pszFormat, va_list args){
int nLength = 4096;//_vscprintf( pszFormat, args );
//nLength = _vscprintf( pszFormat, args );
LPTSTR pszBuffer = (LPTSTR)malloc(nLength + 1);
if(!pszBuffer) return;
*(pszBuffer+nLength) = 0x00;
//int l = STRSAFE_MAX_CCH * sizeof(TCHAR);
//vsprintf((LPSTR)pszBuffer, pszFormat, args );
vsnprintf((LPSTR)pszBuffer,nLength, pszFormat, args);
kxBuff::reset();
kxBuff::add(pszBuffer,nLength);
free(pszBuffer);
}
TCHAR operator[](int offset) const
{
return (TCHAR)*(m_buff + offset);
}
operator LPCTSTR() const throw(){
return (LPCTSTR)GetBuffer();
}
//operator LPSTR() const throw(){
// return (LPSTR)kxBuff::LPTSTR();
//}
operator LPTSTR() const throw(){
return (LPTSTR)GetBuffer();
}
//LPTSTR operator&() throw()
//{
// return (LPTSTR)GetBuffer();
//}
// Assignment operators
kxString& operator=(LPTSTR pszString){
Set((LPCTSTR)pszString);
return (*this);
}
kxString& operator=(LPCTSTR pszString){
Set(pszString);
return (*this);
}
const kxString& operator=(const unsigned char * pszString){
Set((LPCTSTR)pszString);
return (*this);
}
LPTSTR GetBuffer(int pos = 0) const throw(){
return (reinterpret_cast<LPTSTR>(kxBuff::getdata(pos)));
}
kxString& operator=(const kxString& strSrc){
LPCTSTR pSrc = (LPCTSTR)strSrc.GetBuffer();
LPCTSTR pOld = GetBuffer();
if(pSrc != pOld)
Set(pSrc);
return (*this);
}
friend bool operator==(const kxString& str1, LPCTSTR psz2) throw(){
return (str1.Compare((LPTSTR)psz2) == 0);
}
friend bool operator==( const kxString& str1, const kxString& str2) throw(){
return (str1.Compare((LPTSTR)str2.GetBuffer()) == 0 );
}
friend bool operator!=(const kxString& str1, const kxString& str2) throw(){
return (str1.Compare((LPTSTR)str2.GetBuffer()) != 0 );
}
friend bool operator!=(const kxString& str1, LPCTSTR psz2) throw(){
return (str1.Compare((LPTSTR) psz2 ) != 0);
}
friend bool operator!=(const kxString& str1, LPTSTR psz2) throw(){
return (str1.Compare((LPTSTR) psz2 ) != 0);
}
BOOL operator==( const kxString& str1)
{
return (Compare((LPTSTR)str1.GetBuffer()) == 0);
}
BOOL operator==( LPCTSTR psz1)
{
return (Compare((LPTSTR)psz1) == 0);
}
BOOL operator!=(const kxString& str1)
{
return (Compare((LPTSTR)str1.GetBuffer()) != 0 );
}
BOOL operator!=( LPCTSTR psz1)
{
return (Compare((LPTSTR) psz1) != 0);
}
inline const kxString& operator += (const kxString& strSrc){
LPCTSTR pSrc = strSrc.GetBuffer();
Append(pSrc);
return (*this);
}
friend kxString operator+(const kxString& pszSrc1, const kxString& pszSrc2){
kxString strResult = pszSrc1;
strResult.Append(pszSrc2);
return strResult;
}
friend kxString operator+(LPCTSTR pszSrc1, const kxString& pszSrc2){
kxString strResult = pszSrc1;
strResult.Append(pszSrc2);
return strResult;
}
friend kxString operator+(const kxString& pszSrc1, LPCTSTR pszSrc2){
kxString strResult = pszSrc1;
strResult.Append(pszSrc2);
return strResult;
}
kxString& operator+=(LPTSTR pszSrc)
{
Append(pszSrc);
return (*this);
}
kxString& operator+=(LPCTSTR pszSrc)
{
Append(pszSrc);
return (*this);
}
const kxString& operator+=(TCHAR ch)
{
ASSERT( ch != _T( '\0' ));
int nLen = GetLength();
resize( nLen + 1);
*GetBuffer(nLen) = ch;
return *this;
}
inline int Compare(LPTSTR pszString,int ignorecase = 0) const
{
LPCTSTR psz = GetBuffer();
if(psz == NULL && pszString == NULL) return 0;
if(psz == NULL && pszString) return 1;
if(psz && pszString == NULL) return -1;
if(*psz && *pszString == NULL) return -1;
if(*psz == NULL && *pszString) return 1;
if(*psz == NULL && *pszString == NULL) return 0;
//return _tcscmp(pOld,(LPCTSTR)pszString);
int complen = (int)_tcslen(pszString);
int mylen = (int)_tcslen(psz);
if(mylen != complen)
return complen - mylen;
return kxBuff::kxmemcmp((LPCVOID)psz,(LPCVOID)pszString,complen,0,1);
}
inline int CompareNoCase(LPTSTR pszString) const
{
return Compare(pszString,1);
}
LPTSTR GetString(){ return GetBuffer(); }
int GetLength() const{ return kxBuff::getsize();}
BOOL IsEmpty() const{ return(GetLength() < 1 || !*GetBuffer());}
BOOL OemToAnsi(){
int nLength = GetLength();
LPTSTR pszBuffer = GetBuffer();
BOOL fSuccess=::OemToCharBuff(pszBuffer, pszBuffer, nLength);
return fSuccess;
}
BOOL AnsiToOem(){
int nLength = GetLength();
LPTSTR pszBuffer = GetBuffer();
BOOL fSuccess=::CharToOemBuffA(pszBuffer, pszBuffer, nLength);
return fSuccess;
}
int FindString(LPCTSTR szFind,BOOL ignorecase = 0){
//if(!m_buff) return -1;
//if(szFind == NULL) return -1;
//LPTSTR find = _tcsstr(m_buff,szFind);
//if(!find) return -1;
//return (int)(find - m_buff);
int compsize = (int)_tcslen(szFind);
return kxBuff::find((CHAR*)szFind,0,compsize,0,ignorecase,0);
}
int FindChar(TCHAR ch,BOOL bReverse = FALSE){
LPTSTR buff = GetBuffer();
if(!buff) return -1;
LPCTSTR find;
find = (bReverse) ? _tcsrchr(buff,ch) : _tcschr(buff,ch);
if(!find) return -1;
return (int)(find - buff);
}
// Replace all occurrences of character 'chOld' with character 'chNew'
int Replace(CHAR chOld,CHAR chNew){
int nCount = 0;
LPTSTR psz = GetBuffer();
while(psz && *psz){
if(*psz == chOld){
*psz = chNew;
nCount++;
}
psz++;
}
return (nCount);
}
inline BOOL IsSpace(TCHAR ch)
{
switch (ch)
{
case _T(' '):
case _T('\t'):
case _T('\r'):
case _T('\n'):
return TRUE;
}
return FALSE;
}
kxString &TrimLeft(){
LPTSTR pszLeft = GetBuffer();
while(pszLeft && IsSpace(*pszLeft))
pszLeft = CharNext(pszLeft);
LPTSTR pszBuffer = GetString();
if(pszLeft != pszBuffer){
int iFirst = int(pszLeft - pszBuffer);
int nDataLength = GetLength()-iFirst;
Set(pszLeft,nDataLength);
}
return (*this);
}
kxString &TrimRight(){
// find beginning of trailing spaces by starting
// at beginning (DBCS aware)
LPTSTR psz = GetString();
LPTSTR pszLast = NULL;
while(*psz != 0){
if(IsSpace(*psz)){
if(pszLast == NULL)
pszLast = psz;
}
else
pszLast = NULL;
psz = CharNext(psz);
}
if(pszLast != NULL){
// truncate at trailing space start
int iLast = int(pszLast-GetString());
SetLength(iLast);
}
return (*this);
}
kxString &Trim(){
return(TrimRight().TrimLeft());
}
void LoadString(HINSTANCE hInst,int nID)
{
resize(256);
::LoadString(hInst, nID,GetBuffer(), 256);
}
kxString Mid(int nFirst, int nCount)
{
kxString lpMid;
if (nFirst <0) nFirst=0;
if(nCount ==0) nCount=GetLength();
if (nCount > (GetLength()-nFirst) ) nCount =GetLength()-nFirst;
lpMid.SetLength( nCount );
_tcsncpy( lpMid.GetBuffer(), GetBuffer(nFirst), nCount );
return lpMid;
}
kxString Mid(int nFirst)
{
return Mid(nFirst);
}
kxString Left(int nCount)
{
ASSERT( nCount <= GetLength());
kxString cdest;
cdest.SetLength(nCount);
_tcsncpy( cdest.GetBuffer(), GetBuffer(), nCount );
return cdest;
}
kxString Right(int nCount)
{
ASSERT( nCount <= GetLength());
kxString cdest;
cdest.SetLength(nCount);
_tcsncpy( cdest.GetBuffer(), GetBuffer(GetLength()-nCount), nCount );
return cdest;
}
void MakeUpper()
{
_tcsupr(GetBuffer());
}
void MakeLower()
{
_tcslwr(GetBuffer());
}
//TODO:: ReverseFind,ReplaceText
};
}
using namespace kxBuffLib;
#endif
#pragma warning (pop)
Update Info::
2011.01.26
bugfix in resize() ,1바이트짜리 데이타 추가시 버퍼오버런 발생 오류 수정
if(size > m_blksize) ==> if(size >= m_blksize)
NEW VERSION
'kxLibrary' 카테고리의 다른 글
KxLibrary로 DLL 만들기 (0) | 2010.11.19 |
---|---|
OnInitDialog() 시 컨트롤 SetFocus 포커스가 안될때 예제 (0) | 2010.11.19 |
KFC1.0 - Windows SDK Platform C++ Development ToolKit 풀소스 공개 (0) | 2010.11.10 |
새로 작성중인 KFC로 만든 예제 프로그램 (0) | 2010.08.31 |
KFC 라이브러리 클래스 다이아그램 공개 (0) | 2010.08.26 |