44 mStringValue(rToken.mStringValue),
45 mOptionValue(rToken.mOptionValue),
46 mIntegerValue(rToken.mIntegerValue),
47 mFloatValue(rToken.mFloatValue),
48 mPreceedingSpace(rToken.mPreceedingSpace),
49 mAttributes(rToken.mAttributes),
50 mAttributeCount(rToken.mAttributeCount)
360 if(ait->second.mType &
String)
return true;
370 if(ait->second.mType &
Integer)
return true;
380 if(ait->second.mType &
Float)
return true;
387 static const std::string emptystr=
"";
391 if(!(ait->second.mType &
String))
return emptystr;
392 return ait->second.mStringValue;
401 if(!(ait->second.mType &
Integer))
return 0;
402 return ait->second.mIntegerValue;
411 if(!(ait->second.mType &
Float))
return 0;
412 return ait->second.mFloatValue;
419 *pStream <<
"<![CDATA[";
421 if(lfflag) *pStream << std::endl;
423 std::string esc=
"]]>";
426 while(pos < rData.size()) {
427 std::size_t next= rData.find(esc,pos);
428 if(next==std::string::npos) next=rData.size()+1;
430 *pStream << rData.substr(pos,next-pos);
432 if(next<=rData.size())
433 *pStream <<
"]]]]><![CDATA[>";
438 if(lfflag) *pStream << std::endl;
449 static char Base64EncodingTable[]=
450 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
456 const char* src = pData;
459 unsigned char c0=0,c1=0,c2=0,c3=0;
466 c0= ((*src & 0xFC) >> 2);
467 c1= ((*src & 0x03) << 4);
474 c1|= ((*src & 0xF0) >> 4);
475 c2|= ((*src & 0x0F) << 2);
480 c2|= ((*src & 0xC0) >> 6);
482 *pStream << Base64EncodingTable[c0] << Base64EncodingTable[c1] <<
483 Base64EncodingTable[c2] << Base64EncodingTable[c3];
497 *pStream << Base64EncodingTable[c0] << Base64EncodingTable[c1] <<
"=== ";
500 *pStream << Base64EncodingTable[c0] << Base64EncodingTable[c1] <<
501 Base64EncodingTable[c2] <<
"== ";
520 char c1=pStream->get();
521 if(c1!=
'=')
return -1;
528 if(c1!=
'=')
return -1;
531 while(!pStream->eof()) {
532 if(pStream->peek()!=
'=')
break;
541 int c=0, d0=0, d1=0, d2=0;
555 if(c>=
'A' && c <=
'Z') { c-=
'A';
break; }
556 if(c>=
'a' && c <=
'z') { c-=
'a'; c+= (
'Z'-
'A')+1;
break; }
557 if(c>=
'0' && c <=
'9') { c-=
'0'; c+= 2*(
'Z'-
'A')+2;
break; }
558 if(c==
'+') {c= 62;
break; }
559 if(c==
'/') {c= 63;
break; }
560 if(c==
'=') {c= 0xFF;
break; };
566 if(step<=3)
continue;
569 d0= ((cs[0] << 2) & 0xFC) | ((cs[1] >> 4) & 0x03);
570 d1= ((cs[1] << 4) & 0xF0) | ((cs[2] >> 2) & 0x0F);
571 d2= ((cs[2] << 6) & 0xC0) | (cs[3] & 0x3F);
573 if(cs[0]!= 0xFF && cs[1]!=0xFF) {*(dst++)=d0; cnt++;}
574 if(cs[1]!= 0xFF && cs[2]!=0xFF) {*(dst++)=d1; cnt++;}
575 if(cs[2]!= 0xFF && cs[3]!=0xFF) {*(dst++)=d2; cnt++;}
577 if(cs[3]==0xFF)
break;
584 return step==0 ? lc : -1;
593 FD_DV(
"Token::ReadSpace()");
599 if(pStream->eof())
return lc;
625 if(!fcomments)
break;
629 if(pStream->eof()) {
return(lc);};
635 if (c ==
'\n')
break;
636 if (c ==
'\r')
break;
640 FD_DV(
"Token::ReadSpace(): lc " << lc <<
" c " << c);
646 if(ait->second.mType !=
None)
return;
648 ait->second.mStringValue, ait->second.mType,
649 ait->second.mIntegerValue, ait->second.mFloatValue);
650 ait->second.mType |=
String;
670 if(numstr==
"inf" || numstr==
"+inf") {
671 ival = std::numeric_limits<Int>::max();
672 fval = std::numeric_limits<faudes::Float>::max();
678 ival=std::numeric_limits<Int>::min()+1;
679 fval = -1* std::numeric_limits<faudes::Float>::max();
684 if(numstr==
"true" || numstr==
"True") {
691 if(numstr==
"false" || numstr==
"False") {
698 std::string::const_iterator cit=numstr.begin();
699 for(;cit!=numstr.end(); cit++) {
704 if(c==
'x' && iv==0 && cnt==2 && comma<0 && !minus)
705 {base = 16;
continue;}
708 {minus =
true;
continue;}
710 if(c==
'.' && comma<0 && base==10)
711 {comma = 0;
continue;}
713 if(!isdigit(c) && base==10)
break;
714 if(!isxdigit(c) && base==16)
break;
717 if(c>=
'0' && c<=
'9') vc = c-
'0';
718 else if(c>=
'a' && c<=
'f') vc = c-
'a' + 10;
719 else if(c>=
'A' && c<=
'F') vc = c-
'A' + 10;
723 if(comma>=0) comma++;
727 if(cit!=numstr.end()) ok=
false;
734 for(;comma>0;comma--) {
743 if(comma<=0 && !minus) type |=
Integer;
744 if(comma<=0 && !minus && base==16) type |=
Integer16;
766 std::map<int,caiterator> sortnames;
768 sortnames[ait->second.mSort]=ait;
769 std::map<int,caiterator>::iterator sit;
770 for(sit=sortnames.begin(); sit!=sortnames.end(); sit++) {
800 static const std::string white=
" \n\r\t\f";
801 if(
mStringValue.find_first_of(white)!=std::string::npos)
815 std::string escstr=
"<>&\"";
817 if(outstr.find_first_of(escstr)==std::string::npos) {
819 return outstr.size();
823 std::string::const_iterator cit=outstr.begin();
824 for(;cit!=outstr.end(); cit++) {
826 { *pStream <<
"<"; cc+=4;
continue;}
828 { *pStream <<
">"; cc+=4;
continue;}
830 { *pStream <<
"&"; cc+=5;
continue;}
832 { *pStream <<
"""; cc+=6;
continue;}
833 *pStream << *cit; cc++;
844 *pStream << delim <<
" ";
847 *pStream <<
" "; cc++;
861 std::string entref=
"";
862 bool ctrlblank =
false;
867 if(pStream->eof())
return -1;
875 if(isblank(c) && stop==
' ')
break;
876 if(iscntrl(c) && stop==
' ')
break;
882 if(iscntrl(c) && ctrlblank)
continue;
884 if(iscntrl(c)) { c=
' '; ctrlblank=
true;}
886 if(entref.size()!=0) {
890 if(c ==
' ')
return -1;
893 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,
'<');
897 else if(entref==
">") rString.append(1,
'>');
899 else rString.append(entref);
905 if(c ==
'&') entref.append(1,c);
907 if(c !=
'&') rString.append(1,c);
911 FD_DV(
"Token::ReadEscapedString(): lc=" << lc <<
" val=" << rString);
913 if(stop==
' ' && rString.size()==0)
return -1;
922 if(pStream->eof())
return 0;
929 if(!pStream->good()) { rString=
"I/O error";
return -1; }
933 if(pStream->eof())
break;
936 if((c==
'<') || (c==
'>')) { rString=
"'<' or '>' in faudes comment";
return -1; }
940 if(pStream->bad()) { rString=
"I/O error";
return -1; }
947 if(c==
'\n') cm=
false;
949 if(!(fcomments && cm))
961 FD_DV(
"Token::ReadAttributes()");
966 if(pStream->eof())
return -1;
968 if(!(isblank(c) || iscntrl(c)))
break;
975 if(pStream->eof())
return -1;
977 if(isblank(c) || iscntrl(c))
break;
984 FD_DV(
"Token::ReadAttributes(): aname " << aname);
986 if(aname.size()==0) {
991 if(pStream->eof())
return -1;
993 if(!(isblank(c) || iscntrl(c)))
break;
998 if(c!=
'=')
return -1;
1002 if(pStream->eof())
return -1;
1003 c = pStream->peek();
1004 if(!(isblank(c) || iscntrl(c)))
break;
1017 else if(c ==
'\'') {
1031 FD_DV(
"Token::ReadAttributes(): aval " << aval);
1050 if(pStream->eof())
return -1;
1051 c = pStream->peek();
1052 if(!(isalpha(c) || c==
'_' || c==
':')) {
1053 p1 = pStream->get();
1054 if(pStream->eof())
return -1;
1055 p2 = pStream->peek();
1057 FD_DV(
"Token::ReadMarkup: " << c <<
"-" << p1 <<
"-" << p2);
1060 FD_DV(
"Token::ReadMarkup: sensed XML tag");
1064 if(pStream->eof())
return -1;
1065 c = pStream->peek();
1068 if(isblank(c) || iscntrl(c))
break;
1072 if(name.size()==0)
return -1;
1076 if(pStream->eof())
return -1;
1077 c = pStream->peek();
1089 if(pStream->eof())
return -1;
1090 c = pStream->peek();
1093 if(isblank(c) || iscntrl(c))
break;
1097 if(name.size()==0)
return -1;
1098 if(c!=
'>')
return -1;
1103 if(p1==
'!' && p2==
'-') {
1104 FD_DV(
"Token::ReadMarkup: sensed XML comment <" << p1 << p2);
1106 if(pStream->eof())
return -1;
1108 if(c!=
'-')
return -1;
1113 if(pStream->eof())
return -1;
1114 c = pStream->peek();
1115 if(c3==
'-' && c2==
'-' && c ==
'>')
break;
1119 FD_DV(
"Token::ReadMarkup: sensed XML comment end " << c3 << c2 << c);
1122 if(p1==
'!' && (p2==
'D' || p2==
'd')) {
1123 FD_DV(
"Token::ReadMarkup doc.type.dec. not implemented (!)");
1126 if(pStream->eof())
return -1;
1127 c = pStream->peek();
1134 if(p1==
'!' && p2==
'[' ) {
1135 FD_DV(
"Token::ReadMarkup: sense CDATA?");
1138 if(pStream->eof())
return -1;
1139 if(pStream->get()!=
'C')
return -1;
1140 if(pStream->eof())
return -1;
1141 if(pStream->get()!=
'D')
return -1;
1142 if(pStream->eof())
return -1;
1143 if(pStream->get()!=
'A')
return -1;
1144 if(pStream->eof())
return -1;
1145 if(pStream->get()!=
'T')
return -1;
1146 if(pStream->eof())
return -1;
1147 if(pStream->get()!=
'A')
return -1;
1148 if(pStream->eof())
return -1;
1149 if(pStream->get()!=
'[')
return -1;
1151 FD_DV(
"Token::ReadMarkup: sense CDATA!");
1156 if(pStream->eof())
return -1;
1157 c = pStream->peek();
1158 if(c3==
']' && c2==
']' && c ==
'>')
break;
1159 if(pStream->eof())
return -1;
1174 if(pStream->eof())
return -1;
1179 if(pStream->eof())
return -1;
1180 c = pStream->peek();
1181 if(c2==
'?' && c ==
'>')
break;
1187 if(pStream->eof())
return -1;
1188 c = pStream->peek();
1192 if(pStream->eof())
return -1;
1193 c = pStream->peek();
1207 FD_DV(
"Token::Read(): fcomments=" << fcomments);
1214 if(pStream->eof())
return(lc);
1218 if(pStream->eof())
return(lc);
1233 else if(c1 ==
'\'') {
1244 else if(c1 ==
'+') {
1257 else if(c1 ==
'=') {
1266 else if(c1 ==
'<') {
1269 if(pStream->eof())
return(lc);
1279 else if(c1 !=
'%') {
1288 FD_DV(
"Token::Read(): failed with '" << c1 <<
"'");
1298 std::stringstream ostr;
1299 ostr <<
"Token(--- Type=";
1300 if(
IsNone()) ostr <<
"None";
1304 if(
IsFloat()) ostr <<
"Float";
1306 if(
IsEmpty()) ostr <<
"Begin/End";
1307 if(
IsBegin()) ostr <<
"Begin";
1308 if(
IsEnd()) ostr <<
"End";
1310 ostr <<
" Value=\"";
1319 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)