Implemented cCompositeChat::ParseText(), incl. self-test.
This commit is contained in:
parent
b0dbe51210
commit
4a24e39ac1
@ -10,6 +10,96 @@
|
||||
|
||||
|
||||
|
||||
#if SELF_TEST
|
||||
|
||||
/** A simple self-test that verifies that the composite chat parser is working properly. */
|
||||
class SelfTest_CompositeChat
|
||||
{
|
||||
public:
|
||||
SelfTest_CompositeChat(void)
|
||||
{
|
||||
fprintf(stderr, "cCompositeChat self test...\n");
|
||||
TestParser1();
|
||||
TestParser2();
|
||||
TestParser3();
|
||||
TestParser4();
|
||||
TestParser5();
|
||||
fprintf(stderr, "cCompositeChat self test finished.\n");
|
||||
}
|
||||
|
||||
void TestParser1(void)
|
||||
{
|
||||
cCompositeChat Msg;
|
||||
Msg.ParseText("Testing @2color codes and http://links parser");
|
||||
const cCompositeChat::cParts & Parts = Msg.GetParts();
|
||||
assert(Parts.size() == 4);
|
||||
assert(Parts[0]->m_PartType == cCompositeChat::ptText);
|
||||
assert(Parts[1]->m_PartType == cCompositeChat::ptText);
|
||||
assert(Parts[2]->m_PartType == cCompositeChat::ptUrl);
|
||||
assert(Parts[3]->m_PartType == cCompositeChat::ptText);
|
||||
assert(Parts[0]->m_Style == "");
|
||||
assert(Parts[1]->m_Style == "@2");
|
||||
assert(Parts[2]->m_Style == "@2");
|
||||
assert(Parts[3]->m_Style == "@2");
|
||||
}
|
||||
|
||||
void TestParser2(void)
|
||||
{
|
||||
cCompositeChat Msg;
|
||||
Msg.ParseText("@3Advanced stuff: @5overriding color codes and http://links.with/@4color-in-them handling");
|
||||
const cCompositeChat::cParts & Parts = Msg.GetParts();
|
||||
assert(Parts.size() == 4);
|
||||
assert(Parts[0]->m_PartType == cCompositeChat::ptText);
|
||||
assert(Parts[1]->m_PartType == cCompositeChat::ptText);
|
||||
assert(Parts[2]->m_PartType == cCompositeChat::ptUrl);
|
||||
assert(Parts[3]->m_PartType == cCompositeChat::ptText);
|
||||
assert(Parts[0]->m_Style == "@3");
|
||||
assert(Parts[1]->m_Style == "@5");
|
||||
assert(Parts[2]->m_Style == "@5");
|
||||
assert(Parts[3]->m_Style == "@5");
|
||||
}
|
||||
|
||||
void TestParser3(void)
|
||||
{
|
||||
cCompositeChat Msg;
|
||||
Msg.ParseText("http://links.starting the text");
|
||||
const cCompositeChat::cParts & Parts = Msg.GetParts();
|
||||
assert(Parts.size() == 2);
|
||||
assert(Parts[0]->m_PartType == cCompositeChat::ptUrl);
|
||||
assert(Parts[1]->m_PartType == cCompositeChat::ptText);
|
||||
assert(Parts[0]->m_Style == "");
|
||||
assert(Parts[1]->m_Style == "");
|
||||
}
|
||||
|
||||
void TestParser4(void)
|
||||
{
|
||||
cCompositeChat Msg;
|
||||
Msg.ParseText("links finishing the text: http://some.server");
|
||||
const cCompositeChat::cParts & Parts = Msg.GetParts();
|
||||
assert(Parts.size() == 2);
|
||||
assert(Parts[0]->m_PartType == cCompositeChat::ptText);
|
||||
assert(Parts[1]->m_PartType == cCompositeChat::ptUrl);
|
||||
assert(Parts[0]->m_Style == "");
|
||||
assert(Parts[1]->m_Style == "");
|
||||
}
|
||||
|
||||
void TestParser5(void)
|
||||
{
|
||||
cCompositeChat Msg;
|
||||
Msg.ParseText("http://only.links");
|
||||
const cCompositeChat::cParts & Parts = Msg.GetParts();
|
||||
assert(Parts.size() == 1);
|
||||
assert(Parts[0]->m_PartType == cCompositeChat::ptUrl);
|
||||
assert(Parts[0]->m_Style == "");
|
||||
}
|
||||
|
||||
} gTest;
|
||||
#endif // SELF_TEST
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// cCompositeChat:
|
||||
|
||||
@ -101,7 +191,99 @@ void cCompositeChat::AddSuggestCommandPart(const AString & a_Text, const AString
|
||||
|
||||
void cCompositeChat::ParseText(const AString & a_ParseText)
|
||||
{
|
||||
// TODO
|
||||
size_t len = a_ParseText.length();
|
||||
size_t first = 0; // First character of the currently parsed block
|
||||
AString CurrentStyle;
|
||||
AString CurrentText;
|
||||
for (size_t i = 0; i < len; i++)
|
||||
{
|
||||
switch (a_ParseText[i])
|
||||
{
|
||||
case '@':
|
||||
{
|
||||
// Color code
|
||||
i++;
|
||||
if (i >= len)
|
||||
{
|
||||
// Not enough following text
|
||||
break;
|
||||
}
|
||||
if (a_ParseText[i] == '@')
|
||||
{
|
||||
// "@@" escape, just put a "@" into the current text and keep parsing as text
|
||||
if (i > first + 1)
|
||||
{
|
||||
CurrentText.append(a_ParseText.c_str() + first, i - first - 1);
|
||||
}
|
||||
first = i + 1;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// True color code. Create a part for the CurrentText and start parsing anew:
|
||||
if (i >= first)
|
||||
{
|
||||
CurrentText.append(a_ParseText.c_str() + first, i - first - 1);
|
||||
first = i + 1;
|
||||
}
|
||||
if (!CurrentText.empty())
|
||||
{
|
||||
m_Parts.push_back(new cTextPart(CurrentText, CurrentStyle));
|
||||
CurrentText.clear();
|
||||
}
|
||||
AddStyle(CurrentStyle, a_ParseText.substr(i - 1, 2));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ':':
|
||||
{
|
||||
const char * LinkPrefixes[] =
|
||||
{
|
||||
"http",
|
||||
"https"
|
||||
};
|
||||
for (size_t Prefix = 0; Prefix < ARRAYCOUNT(LinkPrefixes); Prefix++)
|
||||
{
|
||||
size_t PrefixLen = strlen(LinkPrefixes[Prefix]);
|
||||
if (
|
||||
(i >= first + PrefixLen) && // There is enough space in front of the colon for the prefix
|
||||
(strncmp(a_ParseText.c_str() + i - PrefixLen, LinkPrefixes[Prefix], PrefixLen) == 0) // the prefix matches
|
||||
)
|
||||
{
|
||||
// Add everything before this as a text part:
|
||||
if (i > first + PrefixLen)
|
||||
{
|
||||
CurrentText.append(a_ParseText.c_str() + first, i - first - PrefixLen);
|
||||
first = i - PrefixLen;
|
||||
}
|
||||
if (!CurrentText.empty())
|
||||
{
|
||||
AddTextPart(CurrentText, CurrentStyle);
|
||||
CurrentText.clear();
|
||||
}
|
||||
|
||||
// Go till the last non-whitespace char in the text:
|
||||
for (; i < len; i++)
|
||||
{
|
||||
if (isspace(a_ParseText[i]))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
AddUrlPart(a_ParseText.substr(first, i - first), a_ParseText.substr(first, i - first), CurrentStyle);
|
||||
first = i;
|
||||
break;
|
||||
}
|
||||
} // for Prefix - LinkPrefix[]
|
||||
break;
|
||||
} // case ':'
|
||||
} // switch (a_ParseText[i])
|
||||
} // for i - a_ParseText[]
|
||||
if (first < len)
|
||||
{
|
||||
AddTextPart(a_ParseText.substr(first, len - first), CurrentStyle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -117,6 +299,29 @@ void cCompositeChat::SetMessageType(eMessageType a_MessageType)
|
||||
|
||||
|
||||
|
||||
void cCompositeChat::AddStyle(AString & a_Style, const AString & a_AddStyle)
|
||||
{
|
||||
if (a_AddStyle.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (a_AddStyle[0] == '@')
|
||||
{
|
||||
size_t idx = a_Style.find('@');
|
||||
if ((idx != AString::npos) && (idx != a_Style.length()))
|
||||
{
|
||||
a_Style.erase(idx, 2);
|
||||
}
|
||||
a_Style.append(a_AddStyle);
|
||||
return;
|
||||
}
|
||||
a_Style.append(a_AddStyle);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// cCompositeChat::cBasePart:
|
||||
|
||||
|
@ -165,6 +165,11 @@ protected:
|
||||
|
||||
/** The message type, as indicated by prefixes. */
|
||||
eMessageType m_MessageType;
|
||||
|
||||
|
||||
/** Adds a_AddStyle to a_Style; overwrites the existing style if appropriate.
|
||||
If the style already contains something that a_AddStyle overrides, it is erased first. */
|
||||
void AddStyle(AString & a_Style, const AString & a_AddStyle);
|
||||
} ; // tolua_export
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user