Files
ladislav-zezula-FileTest/TFlagString.h
Ladislav Zezula ecbcbeb7d6 Progress
2023-12-06 22:33:49 +01:00

160 lines
4.9 KiB
C++

/*****************************************************************************/
/* TFlagString.h Copyright (c) Ladislav Zezula 2021 */
/*---------------------------------------------------------------------------*/
/* Convertor of flags to string lists */
/*---------------------------------------------------------------------------*/
/* Date Ver Who Comment */
/* -------- ---- --- ------- */
/* 22.04.21 1.00 Lad Created */
/*****************************************************************************/
#ifndef __TFLAGSTRING_H__
#define __TFLAGSTRING_H__
//-----------------------------------------------------------------------------
// Helper functions
inline const char * GetBitSeparator()
{
return " | ";
}
inline const char * GetBitSeparatorNewLine()
{
return " |\r\n";
}
inline const char * GetNewLineSeparator()
{
return "\r\n";
}
//-----------------------------------------------------------------------------
// Structure describing the flag information - name, value, mask
#define FLAGINFO_ALLSET 0xFFFFFFFF
#define FLAGINFO_BITV(value) { #value, value, value }
#define FLAGINFO_NUMV(value) { #value, value, FLAGINFO_ALLSET }
#define FLAGINFO_MASK(mask,value) { #value, value, mask }
#define FLAGINFO_SEPARATOR() { (LPCSTR)1, 0, 0 }
#define FLAGINFO_END() { (LPCSTR)0, 0, 0 }
struct TFlagInfo
{
bool IsValuePresent(ULONG64 dwBitMask)
{
return (IsSeparator() == false) && ((dwBitMask & dwMask) == (dwValue & dwMask));
}
bool IsSeparator()
{
return (szFlagText == (LPCSTR)1);
}
bool IsTerminator()
{
return (szFlagText == NULL);
}
const char * szFlagText;
unsigned int dwValue;
unsigned int dwMask;
};
//-----------------------------------------------------------------------------
// Extended version of TFlagInfo for dialogs
struct TDlgFlagInfo : public TFlagInfo
{
TDlgFlagInfo(const char * text, unsigned int value, unsigned int mask, unsigned int btn)
{
szFlagText = text;
dwValue = value;
dwMask = mask;
dwButtonType = btn;
}
unsigned int dwButtonType;
};
//-----------------------------------------------------------------------------
// The TFlagString class
class TFlagString : public TFastString<TCHAR>
{
public:
TFlagString(TFlagInfo * pFlags, ULONG64 dwBitMask, const char * szNextSep = NULL) : TFastString<TCHAR>()
{
// Reset the number of flags that were converted to text
dwFlagsConverted = 0;
// Only if we have some flags given
if(pFlags != NULL)
{
// Configure separators
const char * szNextSeparator = (szNextSep != NULL) ? szNextSep : GetBitSeparator();
const char * szSeparator = "";
// Parse all flags and add them to the buffer
for(size_t i = 0; !pFlags->IsTerminator(); i++, pFlags++)
{
if(pFlags->IsValuePresent(dwBitMask))
{
ULONG64 dwMask64 = pFlags->dwMask;
AppendSeparatorAndText(szSeparator, pFlags->szFlagText);
szSeparator = szNextSeparator;
dwBitMask = dwBitMask & ~dwMask64;
dwFlagsConverted++;
}
}
// Is there a nonzero value left?
if(dwBitMask != 0)
{
char szLeftOver[0x20];
StringCchPrintfA(szLeftOver, _countof(szLeftOver), "0x%08x", dwBitMask);
AppendSeparatorAndText(szSeparator, szLeftOver);
}
}
// Nothing appended?
if(IsEmpty())
{
AppendString(_T("0"));
}
}
ULONG GetConvertedFlagsCount()
{
return dwFlagsConverted;
}
protected:
void AppendSeparatorAndText(const char * szSeparator, const char * szFlagText)
{
size_t nLength1 = strlen(szSeparator);
size_t nLength2 = strlen(szFlagText);
// Append separator, if needed
if(EnsureSpace(Length() + nLength1 + nLength2))
{
#ifdef _UNICODE
MultiByteToWideChar(CP_ACP, 0, szSeparator, -1, m_pBufferPtr, (int)nLength1);
MultiByteToWideChar(CP_ACP, 0, szFlagText, -1, m_pBufferPtr+nLength1, (int)nLength2);
#else
memcpy(m_pBufferPtr, szSeparator, nLength1);
memcpy(m_pBufferPtr+nLength1, szFlagText, nLength2);
#endif
m_pBufferPtr += (nLength1 + nLength2);
}
}
ULONG dwFlagsConverted; // Number of flags that was converted to string
};
#endif // __TFLAGSTRING_H__