Statement TextParser::parse()
{
- return parse_statement(0);
+ return parse_statement(nullptr);
}
Statement TextParser::parse_statement(const Token *t)
if(t)
{
token = *t;
- t = 0;
+ t = nullptr;
}
else
token = parse_token();
FLOATEXPSIGN,
STRING,
STRING_ESCAPE,
+ STRING_BASE64,
ACCEPT,
ZERO,
DECIMAL,
FLOAT,
FLOATEXP,
STRING_END,
+ STRING_BASE64_PAD,
IDENTIFIER
};
Token::SPECIAL,
Token::SPECIAL,
Token::SPECIAL,
+ Token::SPECIAL,
Token::INTEGER,
Token::INTEGER,
Token::INTEGER,
Token::FLOAT,
Token::FLOAT,
Token::STRING,
+ Token::STRING,
Token::IDENTIFIER
};
state = FLOAT;
else if(c=='"')
state = STRING;
+ else if(c=='=')
+ state = STRING_BASE64;
else if(c=='{' || c=='}' || c==';')
return Token(Token::SPECIAL, string(1, c));
else if(isdigit(c))
state = STRING;
break;
+ case STRING_BASE64:
+ if(c=='=')
+ state = STRING_BASE64_PAD;
+ else if(!isalnum(c) && c!='+' && c!='/')
+ throw parse_error(buf);
+ break;
+
+ case STRING_BASE64_PAD:
+ if(c!='=')
+ throw parse_error(buf);
+ break;
+
case IDENTIFIER:
if(!isalpha(c) && !isdigit(c) && c!='_' && c!='-' && c!='/')
throw parse_error(buf);
return Token(Token::IDENTIFIER, buf.substr(1));
else if(state==STRING_END)
return Token(Token::STRING, c_unescape(buf.substr(1, buf.size()-2)));
+ else if(state==STRING_BASE64 || state==STRING_BASE64_PAD)
+ return Token(Token::STRING, base64_decode(buf));
else
return Token(token_type[state], buf);
}
return (c>='0' && c<='7');
}
+string TextParser::base64_decode(const string &data)
+{
+ string bin;
+ bin.reserve(data.size()*3/4);
+ unsigned accum = 0;
+ unsigned a_bits = 0;
+ for(char c: data)
+ {
+ unsigned d;
+ if(c>='A' && c<='Z')
+ d = c-'A';
+ else if(c>='a' && c<='z')
+ d = 26+(c-'a');
+ else if(c>='0' && c<='9')
+ d = 52+(c-'0');
+ else if(c=='+')
+ d = 62;
+ else if(c=='/')
+ d = 63;
+ else if(c=='=')
+ continue;
+ else
+ throw invalid_argument("TextParser::base64_decode");
+
+ accum = (accum<<6)|d;
+ a_bits += 6;
+
+ if(a_bits>=8)
+ {
+ bin += (accum>>(a_bits-8))&0xFF;
+ a_bits -= 8;
+ }
+ }
+
+ return bin;
+}
+
} // namespace DataFile
} // namespace Msp