Skip to content

Instantly share code, notes, and snippets.

@GeeLaw
Created March 16, 2019 21:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save GeeLaw/6761e976a3ae6804084a7c24452e1357 to your computer and use it in GitHub Desktop.
Save GeeLaw/6761e976a3ae6804084a7c24452e1357 to your computer and use it in GitHub Desktop.
Format converter
#include<cstdio>
#include<cstdlib>
using namespace std;
/*
Example input:
{"root1"{"item1""1""item2""abc""item3"{"cell"{"cell1"
{"cell1Name""99"}"cell2"{"cell2Name""cdb"}}}"item4""valueI"}
"root2"{"item1""88""item2""tg""item3"{"cell"{"cell1"{"cell1Name"
"99"}"cell2"{"cell2Name""ujh"}}}"item4""valueb"}}
Example output:
{"root1":{"item1":"1","item2":"abc","item3":{"cell":{
"cell1":{"cell1Name":"99"},"cell2":{"cell2Name":"cdb"}}},
"item4":"valueI"},"root2":{"item1":"88","item2":"tg","item3":{"cell":{
"cell1":{"cell1Name":"99"},"cell2":{"cell2Name":"ujh"}}},"item4":"valueb"}}
*/
enum RecordStatus
{
// Awaiting left brace
RS_AWAIT_LB,
// Awaiting key or right brace
RS_AWAIT_NAME_RB,
// Awaiting key or right brace, not the first key
RS_AWAIT_NAME_RB_2,
// Awaiting value
RS_AWAIT_VALUE
};
enum StringStatus
{
// Awaiting opening quotation mark
SS_AWAIT_OPEN,
// Awaiting closing quotation mark or escape sequence or literal character
SS_AWAIT_CLOSE_ESCAPE,
// Escaping character
SS_ESCAPE
};
bool IsSpace(char ch)
{
return ch == ' ' || ch == '\t' || ch == '\v' || ch == '\r' || ch == '\n';
}
bool TransformString(StringStatus status = SS_AWAIT_OPEN)
{
int ch;
while ((ch = getchar()) != -1)
{
switch (status)
{
case SS_AWAIT_OPEN:
if (ch == '"')
{
putchar('"');
status = SS_AWAIT_CLOSE_ESCAPE;
}
else if (!IsSpace(ch))
{
return false;
}
break;
case SS_AWAIT_CLOSE_ESCAPE:
putchar(ch);
if (ch == '"')
return true;
else if (ch == '\\')
status = SS_ESCAPE;
break;
case SS_ESCAPE:
putchar(ch);
status = SS_AWAIT_CLOSE_ESCAPE;
break;
default:
return false;
}
}
return false;
}
bool TransformRecord(RecordStatus status = RS_AWAIT_LB)
{
int ch;
while ((ch = getchar()) != -1)
{
switch (status)
{
case RS_AWAIT_LB:
if (ch == '{')
{
putchar('{');
status = RS_AWAIT_NAME_RB;
}
else if (!IsSpace(ch))
{
return false;
}
break;
case RS_AWAIT_NAME_RB:
case RS_AWAIT_NAME_RB_2:
if (ch == '"')
{
if (status == RS_AWAIT_NAME_RB_2)
putchar(',');
putchar('"');
if (!TransformString(SS_AWAIT_CLOSE_ESCAPE))
return false;
putchar(':');
status = RS_AWAIT_VALUE;
}
else if (ch == '}')
{
putchar('}');
return true;
}
else if (!IsSpace(ch))
{
return false;
}
break;
case RS_AWAIT_VALUE:
if (ch == '"')
{
putchar('"');
if (!TransformString(SS_AWAIT_CLOSE_ESCAPE))
return false;
status = RS_AWAIT_NAME_RB_2;
}
else if (ch == '{')
{
putchar('{');
if (!TransformRecord(RS_AWAIT_NAME_RB))
return false;
status = RS_AWAIT_NAME_RB_2;
}
else if (!IsSpace(ch))
{
return false;
}
break;
default:
return false;
}
}
return false;
}
bool CheckTrailingSpaces()
{
int ch;
while ((ch = getchar()) != -1)
if (!IsSpace(ch))
return false;
return true;
}
int main()
{
return (TransformRecord() && CheckTrailingSpaces())
? EXIT_SUCCESS
: EXIT_FAILURE;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment