43 mStringValue(rToken.mStringValue),
44 mOptionValue(rToken.mOptionValue),
45 mIntegerValue(rToken.mIntegerValue),
46 mFloatValue(rToken.mFloatValue),
47 mPreceedingSpace(rToken.mPreceedingSpace),
48 mAttributes(rToken.mAttributes),
49 mAttributeCount(rToken.mAttributeCount)
359 if(ait->second.mType &
String)
return true;
369 if(ait->second.mType &
Integer)
return true;
379 if(ait->second.mType &
Float)
return true;
386 static const std::string emptystr=
"";
390 if(!(ait->second.mType &
String))
return emptystr;
391 return ait->second.mStringValue;
400 if(!(ait->second.mType &
Integer))
return 0;
401 return ait->second.mIntegerValue;
410 if(!(ait->second.mType &
Float))
return 0;
411 return ait->second.mFloatValue;
418 *pStream <<
"<![CDATA[";
420 if(lfflag) *pStream << std::endl;
422 std::string esc=
"]]>";
425 while(pos < rData.size()) {
426 std::size_t next= rData.find(esc,pos);
427 if(next==std::string::npos) next=rData.size()+1;
429 *pStream << rData.substr(pos,next-pos);
431 if(next<=rData.size())
432 *pStream <<
"]]]]><![CDATA[>";
437 if(lfflag) *pStream << std::endl;
448 static char Base64EncodingTable[]=
449 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
455 const char* src = pData;
458 unsigned char c0=0,c1=0,c2=0,c3=0;
465 c0= ((*src & 0xFC) >> 2);
466 c1= ((*src & 0x03) << 4);
473 c1|= ((*src & 0xF0) >> 4);
474 c2|= ((*src & 0x0F) << 2);
479 c2|= ((*src & 0xC0) >> 6);
481 *pStream << Base64EncodingTable[c0] << Base64EncodingTable[c1] <<
482 Base64EncodingTable[c2] << Base64EncodingTable[c3];
496 *pStream << Base64EncodingTable[c0] << Base64EncodingTable[c1] <<
"=== ";
499 *pStream << Base64EncodingTable[c0] << Base64EncodingTable[c1] <<
500 Base64EncodingTable[c2] <<
"== ";
519 char c1=pStream->get();
520 if(c1!=
'=')
return -1;
527 if(c1!=
'=')
return -1;
530 while(!pStream->eof()) {
531 if(pStream->peek()!=
'=')
break;
540 int c=0, d0=0, d1=0, d2=0;
554 if(c>=
'A' && c <=
'Z') { c-=
'A';
break; }
555 if(c>=
'a' && c <=
'z') { c-=
'a'; c+= (
'Z'-
'A')+1;
break; }
556 if(c>=
'0' && c <=
'9') { c-=
'0'; c+= 2*(
'Z'-
'A')+2;
break; }
557 if(c==
'+') {c= 62;
break; }
558 if(c==
'/') {c= 63;
break; }
559 if(c==
'=') {c= 0xFF;
break; };
565 if(step<=3)
continue;
568 d0= ((cs[0] << 2) & 0xFC) | ((cs[1] >> 4) & 0x03);
569 d1= ((cs[1] << 4) & 0xF0) | ((cs[2] >> 2) & 0x0F);
570 d2= ((cs[2] << 6) & 0xC0) | (cs[3] & 0x3F);
572 if(cs[0]!= 0xFF && cs[1]!=0xFF) {*(dst++)=d0; cnt++;}
573 if(cs[1]!= 0xFF && cs[2]!=0xFF) {*(dst++)=d1; cnt++;}
574 if(cs[2]!= 0xFF && cs[3]!=0xFF) {*(dst++)=d2; cnt++;}
576 if(cs[3]==0xFF)
break;
583 return step==0 ? lc : -1;
592 FD_DV(
"Token::ReadSpace()");
598 if(pStream->eof())
return lc;
624 if(!fcomments)
break;
628 if(pStream->eof()) {
return(lc);};
634 if (c ==
'\n')
break;
635 if (c ==
'\r')
break;
639 FD_DV(
"Token::ReadSpace(): lc " << lc <<
" c " << c);
645 if(ait->second.mType !=
None)
return;
647 ait->second.mStringValue, ait->second.mType,
648 ait->second.mIntegerValue, ait->second.mFloatValue);
649 ait->second.mType |=
String;
669 if(numstr==
"inf" || numstr==
"+inf") {
670 ival = std::numeric_limits<Int>::max();
671 fval = std::numeric_limits<faudes::Float>::max();
677 ival=std::numeric_limits<Int>::min()+1;
678 fval = -1* std::numeric_limits<faudes::Float>::max();
683 if(numstr==
"true" || numstr==
"True") {
690 if(numstr==
"false" || numstr==
"False") {
697 std::string::const_iterator cit=numstr.begin();
698 for(;cit!=numstr.end(); cit++) {
703 if(c==
'x' && iv==0 && cnt==2 && comma<0 && !minus)
704 {base = 16;
continue;}
707 {minus =
true;
continue;}
709 if(c==
'.' && comma<0 && base==10)
710 {comma = 0;
continue;}
712 if(!isdigit(c) && base==10)
break;
713 if(!isxdigit(c) && base==16)
break;
716 if(c>=
'0' && c<=
'9') vc = c-
'0';
717 else if(c>=
'a' && c<=
'f') vc = c-
'a' + 10;
718 else if(c>=
'A' && c<=
'F') vc = c-
'A' + 10;
722 if(comma>=0) comma++;
726 if(cit!=numstr.end()) ok=
false;
733 for(;comma>0;comma--) {
742 if(comma<=0 && !minus) type |=
Integer;
743 if(comma<=0 && !minus && base==16) type |=
Integer16;
765 std::map<int,caiterator> sortnames;
767 sortnames[ait->second.mSort]=ait;
768 std::map<int,caiterator>::iterator sit;
769 for(sit=sortnames.begin(); sit!=sortnames.end(); sit++) {
799 static const std::string white=
" \n\r\t\f";
800 if(
mStringValue.find_first_of(white)!=std::string::npos)
814 std::string escstr=
"<>&\"";
816 if(outstr.find_first_of(escstr)==std::string::npos) {
818 return outstr.size();
822 std::string::const_iterator cit=outstr.begin();
823 for(;cit!=outstr.end(); cit++) {
825 { *pStream <<
"<"; cc+=4;
continue;}
827 { *pStream <<
">"; cc+=4;
continue;}
829 { *pStream <<
"&"; cc+=5;
continue;}
831 { *pStream <<
"""; cc+=6;
continue;}
832 *pStream << *cit; cc++;
843 *pStream << delim <<
" ";
846 *pStream <<
" "; cc++;
860 std::string entref=
"";
861 bool ctrlblank =
false;
866 if(pStream->eof())
return -1;
874 if(isblank(c) && stop==
' ')
break;
875 if(iscntrl(c) && stop==
' ')
break;
881 if(iscntrl(c) && ctrlblank)
continue;
883 if(iscntrl(c)) { c=
' '; ctrlblank=
true;}
885 if(entref.size()!=0) {
889 if(c ==
' ')
return -1;
892 if(entref==
"&") rString.append(1,
'&');
893 else if(entref==
""") rString.append(1,
'"');
894 else if(entref==
"'") rString.append(1,
'\'');
895 else if(entref==
"<") rString.append(1,
'<');
896 else if(entref==
">") rString.append(1,
'>');
898 else rString.append(entref);
904 if(c ==
'&') entref.append(1,c);
906 if(c !=
'&') rString.append(1,c);
910 FD_DV(
"Token::ReadEscapedString(): lc=" << lc <<
" val=" << rString);
912 if(stop==
' ' && rString.size()==0)
return -1;
921 if(pStream->eof())
return 0;
928 if(!pStream->good()) { rString=
"I/O error";
return -1; }
932 if(pStream->eof())
break;
935 if((c==
'<') || (c==
'>')) { rString=
"'<' or '>' in faudes comment";
return -1; }
939 if(pStream->bad()) { rString=
"I/O error";
return -1; }
946 if(c==
'\n') cm=
false;
948 if(!(fcomments && cm))
960 FD_DV(
"Token::ReadAttributes()");
965 if(pStream->eof())
return -1;
967 if(!(isblank(c) || iscntrl(c)))
break;
974 if(pStream->eof())
return -1;
976 if(isblank(c) || iscntrl(c))
break;
983 FD_DV(
"Token::ReadAttributes(): aname " << aname);
985 if(aname.size()==0) {
990 if(pStream->eof())
return -1;
992 if(!(isblank(c) || iscntrl(c)))
break;
997 if(c!=
'=')
return -1;
1001 if(pStream->eof())
return -1;
1002 c = pStream->peek();
1003 if(!(isblank(c) || iscntrl(c)))
break;
1016 else if(c ==
'\'') {
1030 FD_DV(
"Token::ReadAttributes(): aval " << aval);
1049 if(pStream->eof())
return -1;
1050 c = pStream->peek();
1051 if(!(isalpha(c) || c==
'_' || c==
':')) {
1052 p1 = pStream->get();
1053 if(pStream->eof())
return -1;
1054 p2 = pStream->peek();
1056 FD_DV(
"Token::ReadMarkup: " << c <<
"-" << p1 <<
"-" << p2);
1059 FD_DV(
"Token::ReadMarkup: sensed XML tag");
1063 if(pStream->eof())
return -1;
1064 c = pStream->peek();
1067 if(isblank(c) || iscntrl(c))
break;
1071 if(name.size()==0)
return -1;
1075 if(pStream->eof())
return -1;
1076 c = pStream->peek();
1088 if(pStream->eof())
return -1;
1089 c = pStream->peek();
1092 if(isblank(c) || iscntrl(c))
break;
1096 if(name.size()==0)
return -1;
1097 if(c!=
'>')
return -1;
1102 if(p1==
'!' && p2==
'-') {
1103 FD_DV(
"Token::ReadMarkup: sensed XML comment <" << p1 << p2);
1105 if(pStream->eof())
return -1;
1107 if(c!=
'-')
return -1;
1112 if(pStream->eof())
return -1;
1113 c = pStream->peek();
1114 if(c3==
'-' && c2==
'-' && c ==
'>')
break;
1118 FD_DV(
"Token::ReadMarkup: sensed XML comment end " << c3 << c2 << c);
1121 if(p1==
'!' && (p2==
'D' || p2==
'd')) {
1122 FD_DV(
"Token::ReadMarkup doc.type.dec. not implemented (!)");
1125 if(pStream->eof())
return -1;
1126 c = pStream->peek();
1133 if(p1==
'!' && p2==
'[' ) {
1134 FD_DV(
"Token::ReadMarkup: sense CDATA?");
1137 if(pStream->eof())
return -1;
1138 if(pStream->get()!=
'C')
return -1;
1139 if(pStream->eof())
return -1;
1140 if(pStream->get()!=
'D')
return -1;
1141 if(pStream->eof())
return -1;
1142 if(pStream->get()!=
'A')
return -1;
1143 if(pStream->eof())
return -1;
1144 if(pStream->get()!=
'T')
return -1;
1145 if(pStream->eof())
return -1;
1146 if(pStream->get()!=
'A')
return -1;
1147 if(pStream->eof())
return -1;
1148 if(pStream->get()!=
'[')
return -1;
1150 FD_DV(
"Token::ReadMarkup: sense CDATA!");
1155 if(pStream->eof())
return -1;
1156 c = pStream->peek();
1157 if(c3==
']' && c2==
']' && c ==
'>')
break;
1158 if(pStream->eof())
return -1;
1173 if(pStream->eof())
return -1;
1178 if(pStream->eof())
return -1;
1179 c = pStream->peek();
1180 if(c2==
'?' && c ==
'>')
break;
1186 if(pStream->eof())
return -1;
1187 c = pStream->peek();
1191 if(pStream->eof())
return -1;
1192 c = pStream->peek();
1206 FD_DV(
"Token::Read(): fcomments=" << fcomments);
1213 if(pStream->eof())
return(lc);
1217 if(pStream->eof())
return(lc);
1232 else if(c1 ==
'\'') {
1243 else if(c1 ==
'+') {
1256 else if(c1 ==
'=') {
1265 else if(c1 ==
'<') {
1268 if(pStream->eof())
return(lc);
1278 else if(c1 !=
'%') {
1287 FD_DV(
"Token::Read(): failed with '" << c1 <<
"'");
1297 std::stringstream ostr;
1298 ostr <<
"Token(--- Type=";
1299 if(
IsNone()) ostr <<
"None";
1303 if(
IsFloat()) ostr <<
"Float";
1305 if(
IsEmpty()) ostr <<
"Begin/End";
1306 if(
IsBegin()) ostr <<
"Begin";
1307 if(
IsEnd()) ostr <<
"End";
1309 ostr <<
" Value=\"";
1318 ostr <<
" attr[" << ait->first <<
"=\"" << ait->second.mStringValue <<
"\"]";
#define FD_NAMELEN
Length of strings for text fields in token output.
#define FD_DV(message)
Debug: optional low-level report on iterations and token IO.
Tokens model atomic data for stream IO.
std::map< std::string, AttributeValue >::iterator aiterator
Convenience typedef.
bool IsCdata(void) const
Test token Type.
bool IsBinary(void) const
Test token Type.
bool IsInteger16(void) const
Test token Type.
void SetNone(void)
Initialize None token.
int ReadMarkup(std::istream *pStream)
Read and interpret markup an input file stream.
~Token(void)
Token destructor.
Token & operator=(const Token &rOther)
Assignment operator.
const std::string & PreceedingSpace(void) const
Preceeding space when writing to stream.
std::string Str(void) const
Pretty print string representation.
void SetBinary(const char *data, std::size_t len)
Initialize Binary token.
void WriteString(std::ostream *pStream, const std::string &delim) const
Write a std::string value to an output stream.
void SetInteger16(const Int number)
Initialize as Integer16 token.
const std::string & StringValue(void) const
Get string value of a name token.
Int AttributeIntegerValue(const std::string &name)
Access attribute value.
void ClrEnd(void)
Clear End type (resolve empty section)
void SetInteger(const Int number)
Initialize as Integer token.
void SetBoolean(const Int number)
Initialize as Boolean token.
bool ExistsAttributeFloat(const std::string &name)
Test attibute existence.
@ Integer
1234 (non-negative integer)
@ Option
+xyZ+ (option string, may not contain a "+")
@ Float
-12.34 ("-" or "." turns an integer to a float)
@ Cdata
... verbatim markup
@ End
<\label> (end of section)
@ Integer16
0x12fff ("0x" makes an integer an Integer16)
@ Begin
<label> (begin of section)
@ String
any string, space separated or quoted, must start with a letter
@ Binary
=ABhlkjj= (base64 encoded binary data)
@ None
Invalid/empty token
bool IsString(void) const
Test token Type.
static void WriteVerbatim(std::ostream *pStream, const std::string &rString, bool lfflag=0)
Write a std::string value to an output stream.
void Write(std::ostream *pStream) const
Write Token to output stream.
Int mIntegerValue
Token integer value (if Token is of type Integer or Integer16)
faudes::Float mFloatValue
Token float value (if Token is of type Float or Integer)
Int IntegerValue(void) const
Get integer value of a numeric token.
bool IsNone(void) const
Test token Type.
void InsAttributeBoolean(const std::string &name, Int value)
Insert named attribute with boolean value.
bool IsInteger(void) const
Test token Type.
std::string mOptionValue
Token std::string value (if token is of type Option)
void SetString(const std::string &rName)
Initialize as String token.
int ReadSpace(std::istream *pStream, bool fcomments=true)
Read (ignore) spaces on input file stream.
faudes::Float AttributeFloatValue(const std::string &name)
Access attribute value.
static int ReadCharacterData(std::istream *pStream, std::string &rString, bool fcomments)
Read chracter data from an input file stream.
static int ReadEscapedString(std::istream *pStream, char stop, std::string &rString)
Read a std::string value from an input file stream.
bool ExistsAttributeString(const std::string &name)
Test attibute existence.
void SetOption(const std::string &rName)
Initialize as Option token.
bool IsEmpty(void) const
Test token Type.
bool IsBegin(void) const
Test token Type.
void SetFloat(const faudes::Float number)
Initialize as Float token.
void SetEmpty(const std::string &rName)
Initialize as empty-tag token.
void InsAttribute(const std::string &name, const std::string &value)
Insert named attribute, no type.
Token(void)
Empty constructor, constructs None token.
bool IsBoolean(void) const
Test token Type.
static void WriteBinary(std::ostream *pStream, const char *pData, std::size_t len)
Write specified binary data as base64 string to output stream.
int ReadAttributes(std::istream *pStream)
Read and interpret attribute definitions of begin tags from an input file stream.
int ReadBinary(std::istream *pStream)
Read a base64 binary string from an input file stream.
void InsAttributeFloat(const std::string &name, faudes::Float value)
Insert named attribute with integer value.
void ClrAttribute(const std::string &name)
Clear attribute.
void ClearAttributes()
Clear all attributes.
static int WriteEscapedString(std::ostream *pStream, const std::string &outstr)
Write a std::string value to an output stream.
std::map< std::string, AttributeValue >::const_iterator caiterator
const std::string & OptionValue(void) const
Get option value of a name token.
void SetBegin(const std::string &rName)
Initialize as Begin token.
int mAttributeCount
Attribute sort index (for nice output only)
bool ExistsAttributeInteger(const std::string &name)
Test attibute existence.
void InsAttributeInteger(const std::string &name, Int value)
Insert named attribute with integer value.
bool InterpretNumber(void)
Interpret string a s number.
int Read(std::istream *pStream, bool fcomments=true)
Read Token from input stream.
void InsAttributeString(const std::string &name, const std::string &value)
Insert named attribute with string value.
std::map< std::string, AttributeValue > mAttributes
Attribute value map.
bool IsEnd(void) const
Test token Type.
bool IsFloat(void) const
Test token Type.
int ReadString(std::istream *pStream, char stop)
Read a std::string value from an input file stream.
std::string mPreceedingSpace
Preceeding space (cosmetic)
bool IsOption(void) const
Test token Type.
void SetEnd(const std::string &rName)
Initialize as End token.
const std::string & AttributeStringValue(const std::string &name)
Access attribute value.
void InterpretAttribute(aiterator ait)
Interpret attribute value from string.
void InsAttributeInteger16(const std::string &name, Int value)
Insert named attribute with integer value.
faudes::Float FloatValue(void) const
Get float value of a numeric token.
std::string mStringValue
Token std::string value (for any token type)
TokenType Type(void) const
Get token Type.
libFAUDES resides within the namespace faudes.
std::string ExpandString(const std::string &rString, unsigned int len)
Fill string with spaces up to a given length if length of the string is smaller than given length par...
std::string ToStringFloat(Float number)
float to string
std::string ToStringInteger16(Int number)
integer to string base 16
double Float
Type definition for real type.
std::string ToStringInteger(Int number)
integer to string
long int Int
Type definition for integer type (let target system decide, minimum 32bit)