X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Ftextparser.cpp;h=b8515a9b487fa2749d78c5c41a734c2f00c1b70f;hb=256b44a5009467171af53316141277027bcc0ba4;hp=7dc4bde7e46ed659368498798bf0b6b3b62fa246;hpb=cd3de49e76305a50ae61696210ce10804a59cef1;p=libs%2Fdatafile.git diff --git a/source/textparser.cpp b/source/textparser.cpp index 7dc4bde..b8515a9 100644 --- a/source/textparser.cpp +++ b/source/textparser.cpp @@ -113,6 +113,7 @@ Token TextParser::parse_token() FLOATEXPSIGN, STRING, STRING_ESCAPE, + STRING_BASE64, ACCEPT, ZERO, DECIMAL, @@ -121,6 +122,7 @@ Token TextParser::parse_token() FLOAT, FLOATEXP, STRING_END, + STRING_BASE64_PAD, IDENTIFIER }; @@ -133,6 +135,7 @@ Token TextParser::parse_token() Token::SPECIAL, Token::SPECIAL, Token::SPECIAL, + Token::SPECIAL, Token::INTEGER, Token::INTEGER, Token::INTEGER, @@ -140,6 +143,7 @@ Token TextParser::parse_token() Token::FLOAT, Token::FLOAT, Token::STRING, + Token::STRING, Token::IDENTIFIER }; @@ -165,6 +169,8 @@ Token TextParser::parse_token() 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)) @@ -255,6 +261,18 @@ Token TextParser::parse_token() 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); @@ -273,6 +291,8 @@ Token TextParser::parse_token() 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); } @@ -291,5 +311,42 @@ bool TextParser::isodigit(int c) 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