gates_of_skeldal/DDLReader/WStringProxy.h
2025-01-24 18:27:22 +01:00

232 lines
6.8 KiB
C++

// WStringProxy.h: interface for the WStringProxy class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_WSTRINGPROXY_H__863ADE82_7789_4E54_BE7D_B8F0740FD81B__INCLUDED_)
#define AFX_WSTRINGPROXY_H__863ADE82_7789_4E54_BE7D_B8F0740FD81B__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "WStringMemory.h"
#include "IWStringEffect.h"
#include <WCHAR.H>
#include <string.h>
#include <assert.h>
#include <malloc.h>
/*
List of proxy types
Memory_Proxy _operation=OpMemBlck
_blockData==0 and _blockData2==0
or
_blockData!=0 and _blockData2!=0
(_redirect - debug pointer)
(_blockData - 1)
Proxy_Const _operation=OpMemBlck
_redirect - pointer to string
_blockData2=0
Proxy_Shared _operation=OpMemBlck
_redirect - pointer to string
_blockData2=2;
Proxy_Immediate _operation=OpMemBlck
_blockData>0xFFFF
_blockData2>0xFFFF
both parameters are used by immediate memory manager
Proxy_Concat _operation=OpConcat
_baseString and _secondString is valid
Proxy_Link _operation=OpSubstr
_baseString is valid
_stringSize==_baseString->_stringSize
_offset==0;
NOTE: Can be used without rendering
Proxy_RightSub _operation=OpSubstr
_baseString is valid
_offset<=_baseString->_stringSize
_stringSize==_baseString->_stringSize-_offset
NOTE: Can be used without rendering
Proxy_SubString _operation=OpSubstr
_baseString is valid
_offset<=_baseString->_stringSize
_stringSize<=_baseString->_stringSize-_offset
Proxy_Effect _operation=OpEffect
_baseString is valid
_stringSize=_baseString->_stringSize
_effect defining effect code < 0xFFFF
Proxy_UserEffect _operation=OpEffect
_baseString is valid
_stringSize=_baseString->_stringSize
_effect>0xFFFF
_userEffect defining pointer to effect interface
*/
class WStringProxy
{
public:
enum Operation
{
OpConcat=0, //proxy contains two links to concat it
OpSubstr=1, //proxy contains link to another proxy and specified substring
OpMemBlck=-2, //proxy contains informations about following string
OpEffect=-1, //proxy describing some efect with string
};
enum Effect
{
EfLower, //effect lower case
EfUpper, //effect upper case
EfReverse, //effect reverse string
};
public:
unsigned long _refCount; //reference count
unsigned long _stringSize:30; //string size in characters (maximum size 1073741823 characters ~ 2147483646 bytes)
Operation _operation:2; //operation with string or proxy type
union
{
WStringProxy *_baseString; //pointer to next proxy referenced by this proxy
unsigned long _blockData; //user defined block data for OpMemBlock proxy type
const wchar_t *_redirect; //used for OpMemBlock, when _blockData2 is zero.
};
union
{
WStringProxy *_secondString; //pointer to second string for OpConcat
unsigned long _offset; //offset of substring for OpSubstr
Effect _effect; //effect selector for OpEffect
IWStringEffect *_userEffect; //user effect defined by IWStringEffect interface (valid when _effect is invalid)
unsigned long _blockData2; //user defined block data for OpMemBlock proxy type - exception: if this value is zero, member _redirect is valid
};
void RenderStringToBuffer(wchar_t *renderPtr);
void RenderStringToBufferSubstr(wchar_t *renderPtr, size_t offset, size_t size);
WStringProxy *TransitivniUzaver();
void RenderSimpleEffect(wchar_t *renderPtr);
public:
WStringProxy():_refCount(0),_operation(OpSubstr),_stringSize(0),_baseString(0),_secondString(0) {} //inicializes empty string proxy
WStringProxy(WStringProxy *other):
_refCount(0),
_stringSize(other->GetLength()),
_baseString(other),
_operation(OpSubstr),
_offset(0)
{_baseString->AddRef();}
WStringProxy(WStringProxy *other, unsigned long offset, unsigned long size):
_refCount(0),
_stringSize(size),
_baseString(other),
_operation(OpSubstr),
_offset(offset)
{_baseString->AddRef();}
WStringProxy(WStringProxy *a, WStringProxy *b):
_refCount(0),
_stringSize(a->GetLength()+b->GetLength()),
_baseString(a),
_operation(OpConcat),
_secondString(b)
{_baseString->AddRef();_secondString->AddRef();}
WStringProxy(WStringProxy *a, Effect effect):
_refCount(0),
_stringSize(a->GetLength()),
_baseString(a),
_operation(OpEffect),
_effect(effect)
{_baseString->AddRef();}
WStringProxy(WStringProxy *a, IWStringEffect *userEffect):
_refCount(0),
_stringSize(a->GetLength()+userEffect->GetEffectExtraSize(a->GetLength())),
_baseString(a),
_operation(OpEffect),
_userEffect(userEffect)
{_baseString->AddRef();}
WStringProxy(unsigned long size, unsigned long user1, unsigned long user2):
_refCount(0),
_stringSize(size),
_operation(OpMemBlck),
_blockData(user1),
_blockData2(user2)
{}
WStringProxy(const wchar_t *imText):
_refCount(0),
_stringSize(wcslen(imText)),
_redirect(imText),
_blockData2(0),
_operation(OpMemBlck)
{}
WStringProxy(const WStringProxy &other)
{
memcpy(this,&other,sizeof(*this));
if (_operation!=OpMemBlck) _baseString->AddRef();
if (_operation==OpConcat) _secondString->AddRef();
}
WStringProxy& operator=(const WStringProxy &other)
{
WStringProxy::~WStringProxy(); //call destructor to destruct current proxy
memcpy(this,&other,sizeof(*this)); //construct new proxy from template
if (_operation!=OpMemBlck) _baseString->AddRef();
if (_operation==OpConcat) _secondString->AddRef();
}
WStringProxy *RenderString();
~WStringProxy()
{
if (_operation!=OpMemBlck) _baseString->Release();
if (_operation==OpConcat) _secondString->Release();
}
unsigned long GetLength() {return _stringSize;}
void AddRef() {if (this) WStringMemory::AddRefProxy(this);}
void Release() {if (this) if (WStringMemory::ReleaseRefProxy(this)) WStringMemory::FreeProxy(this);}
const wchar_t *GetString()
{
if (_operation==OpMemBlck) return (const wchar_t *)(this+1);
WStringProxy *p=RenderString();
(*this)=*p;
return (const wchar_t *)(p+1);
}
const wchar_t *GetStringFromMemBlock()
{
assert(_operation==OpMemBlck);
if (_blockData2==0 && _redirect!=NULL) return _redirect;
else return (const wchar_t *)(this+1);
}
bool IsShared() {return _refCount>1;}
void RecalcLength()
{
const wchar_t *str=GetStringFromMemBlock();
_stringSize=wcslen(str);
}
};
#endif // !defined(AFX_WSTRINGPROXY_H__863ADE82_7789_4E54_BE7D_B8F0740FD81B__INCLUDED_)