in src/main/cpp/properties.cpp [30:365]
void parse(LogString& in, Properties& properties)
{
LogString key, element;
LexemType lexemType = BEGIN;
logchar c;
bool finished = false;
if (!get(in, c))
{
return;
}
while (!finished)
{
switch (lexemType)
{
case BEGIN:
switch (c)
{
case 0x20: // ' '
case 0x09: // '\t'
case 0x0A: // '\n'
case 0x0D: // '\r'
if (!get(in, c))
{
finished = true;
}
break;
case 0x23: // '#'
case 0x21: // '!'
lexemType = COMMENT;
if (!get(in, c))
{
finished = true;
}
break;
default:
lexemType = KEY;
break;
}
break;
case KEY:
switch (c)
{
case 0x5C: // '\\'
lexemType = KEY_ESCAPE;
if (!get(in, c))
{
finished = true;
}
break;
case 0x09: // '\t'
case 0x20: // ' '
case 0x3A: // ':'
case 0x3D: // '='
lexemType = DELIMITER;
if (!get(in, c))
{
finished = true;
}
break;
case 0x0A:
case 0x0D:
// key associated with an empty string element
properties.setProperty(key, LogString());
key.erase(key.begin(), key.end());
lexemType = BEGIN;
if (!get(in, c))
{
finished = true;
}
break;
default:
key.append(1, c);
if (!get(in, c))
{
finished = true;
}
break;
}
break;
case KEY_ESCAPE:
switch (c)
{
case 0x74: // 't'
key.append(1, 0x09);
lexemType = KEY;
break;
case 0x6E: // 'n'
key.append(1, 0x0A);
lexemType = KEY;
break;
case 0x72: // 'r'
key.append(1, 0x0D);
lexemType = KEY;
break;
case 0x0A: // '\n'
lexemType = KEY_CONTINUE;
break;
case 0x0D: // '\r'
lexemType = KEY_CONTINUE2;
break;
default:
key.append(1, c);
lexemType = KEY;
}
if (!get(in, c))
{
finished = true;
}
break;
case KEY_CONTINUE:
switch (c)
{
case 0x20: // ' '
case 0x09: // '\t'
if (!get(in, c))
{
finished = true;
}
break;
default:
lexemType = KEY;
break;
}
break;
case KEY_CONTINUE2:
switch (c)
{
case 0x0A: // '\n'
if (!get(in, c))
{
finished = true;
}
lexemType = KEY_CONTINUE;
break;
default:
lexemType = KEY_CONTINUE;
break;
}
break;
case DELIMITER:
switch (c)
{
case 0x09: // '\t'
case 0x20: // ' '
case 0x3A: // ':'
case 0x3D: // '='
if (!get(in, c))
{
finished = true;
}
break;
default:
lexemType = ELEMENT;
break;
}
break;
case ELEMENT:
switch (c)
{
case 0x5C: // '\\'
lexemType = ELEMENT_ESCAPE;
if (!get(in, c))
{
finished = true;
}
break;
case 0x0A: // '\n'
case 0x0D: // '\r'
// key associated with an empty string element
properties.setProperty(key, element);
key.erase(key.begin(), key.end());
element.erase(element.begin(), element.end());
lexemType = BEGIN;
if (!get(in, c))
{
finished = true;
}
break;
default:
element.append(1, c);
if (!get(in, c))
{
finished = true;
}
break;
}
break;
case ELEMENT_ESCAPE:
switch (c)
{
case 0x74: // 't'
element.append(1, 0x09);
lexemType = ELEMENT;
break;
case 0x6E: // 'n'
element.append(1, 0x0A);
lexemType = ELEMENT;
break;
case 0x72: // 'r'
element.append(1, 0x0D);
lexemType = ELEMENT;
break;
case 0x0A: // '\n'
lexemType = ELEMENT_CONTINUE;
break;
case 0x0D: // '\r'
lexemType = ELEMENT_CONTINUE2;
break;
default:
element.append(1, c);
lexemType = ELEMENT;
break;
}
if (!get(in, c))
{
finished = true;
}
break;
case ELEMENT_CONTINUE:
switch (c)
{
case 0x20: // ' '
case 0x09: // '\t'
if (!get(in, c))
{
finished = true;
}
break;
default:
lexemType = ELEMENT;
break;
}
break;
case ELEMENT_CONTINUE2:
switch (c)
{
case 0x0A: // '\n'
if (!get(in, c))
{
finished = true;
}
lexemType = ELEMENT_CONTINUE;
break;
default:
lexemType = ELEMENT_CONTINUE;
break;
}
break;
case COMMENT:
if (c == 0x0A || c == 0x0D)
{
lexemType = BEGIN;
}
if (!get(in, c))
{
finished = true;
}
break;
}
}
if (!key.empty())
{
properties.setProperty(key, element);
}
}