2 #include "../Common/Common.h"
11 // Track memory leaks on Windows to the line that new'd the memory
14 #define DEBUG_NEW new( _NORMAL_BLOCK, THIS_FILE, __LINE__ )
17 static char THIS_FILE
[] = __FILE__
;
21 bool XMLUtil::IsWhiteSpace(char cLetter
)
23 if ((cLetter
== ' ') ||
32 // See if a character is 0 - 9
33 bool XMLUtil::IsDigit(char cLetter
)
35 if ((cLetter
>= '0') && (cLetter
<= '9'))
40 // Strip the leading and trailing white space off a string.
41 string
XMLUtil::StripWhiteSpace(const string
& strText
)
43 string strResult
= "";
45 strResult
.reserve(strText
.length());
48 while ((iStart
< (int) strText
.length()) && (IsWhiteSpace(strText
[iStart
])))
51 int iEnd
= strText
.length() - 1;
52 while ((iEnd
> 0) && (IsWhiteSpace(strText
[iEnd
])))
55 strResult
= strText
.substr(iStart
, iEnd
- iStart
+ 1);
60 // Return a string containing the contents of a file
61 string
XMLUtil::LoadFile(const string
& strFilename
, unsigned int iSizeHint
)
63 string strResult
= "";
65 char szBuffer
[XML_UTIL_READ_BUFFER_SIZE
];
67 fp
= fopen(strFilename
.c_str(), "r");
73 result
= _stat64(strFilename
.c_str(), &buf
);
74 strResult
.reserve((unsigned long) buf
.st_size
+ 256);
76 // On unix, we default to 128,000 bytes or whatever the caller passed in as a hint
77 strResult
.reserve(iSizeHint
);
82 memset(szBuffer
, 0, XML_UTIL_READ_BUFFER_SIZE
);
83 fread(szBuffer
, 1, XML_UTIL_READ_BUFFER_SIZE
- 1, fp
);
84 strResult
+= szBuffer
;
95 // Returns what is between the given tag in the passed XML. We only return the first matching
96 // tag if there are multiple in the XML. Tags are case sensitive.
97 string
XMLUtil::GetElementString(const string
& strTag
, const string
& strXML
, bool bStripWhiteSpace
)
99 string strResult
= "";
100 string strStart
= "";
111 int iPosStart
= strXML
.find(strStart
);
112 int iPosEnd
= strXML
.find(strEnd
);
114 if ((iPosStart
!= -1) && (iPosEnd
!= -1))
116 strResult
= strXML
.substr(iPosStart
+ strStart
.length(), iPosEnd
- (iPosStart
+ strStart
.length()));
119 if (bStripWhiteSpace
)
120 strResult
= StripWhiteSpace(strResult
);
125 // Return the integer representing an element
126 int XMLUtil::GetElementInt(const string
& strTag
, const string
& strXML
, bool* pFound
)
128 string strElement
= GetElementString(strTag
, strXML
);
131 for (i
= 0; i
< strElement
.size(); i
++)
135 if ((!IsDigit(strElement
[i
])) && ((strElement
[i
] != '-')))
139 if (!IsDigit(strElement
[i
]))
143 // Only try and convert something that is all digits
144 if (i
== strElement
.size())
148 return atoi(strElement
.c_str());
158 int64
XMLUtil::GetElementLongLong(const string
& strTag
, const string
& strXML
, bool* pFound
)
160 string strElement
= GetElementString(strTag
, strXML
);
163 for (i
= 0; i
< strElement
.size(); i
++)
167 if ((!IsDigit(strElement
[i
])) && ((strElement
[i
] != '-')))
171 if (!IsDigit(strElement
[i
]))
175 // Only try and convert something that is all digits
176 if ((i
> 0) && (i
== strElement
.size()))
181 return _atoi64(strElement
.c_str());
183 return atoll(strElement
.c_str());
194 // Optionally can pass back a bool that tell us if the tag was found
195 float XMLUtil::GetElementFloat(const string
& strTag
, const string
& strXML
, bool* pFound
)
197 string strElement
= GetElementString(strTag
, strXML
);
199 bool bFoundDot
= false;
202 for (i
= 0; i
< strElement
.size(); i
++)
206 if ((!IsDigit(strElement
[i
])) && ((strElement
[i
] != '-')))
211 if (!IsDigit(strElement
[i
]))
213 if ((strElement
[i
] == '.') && (!bFoundDot
))
221 // Only try and convert something that is all digits
222 if ((i
> 0) && (i
== strElement
.size()))
226 return (float) atof(strElement
.c_str());
236 // Return a vector containing all the text inside all tags matching the passed one
237 VECTOR_STRING
XMLUtil::GetElementStrings(const string
& strTag
, const string
& strXML
, bool bStripWhiteSpace
)
239 VECTOR_STRING vResult
;
240 vResult
.reserve(XML_UTIL_DEFAULT_VECTOR_SIZE
);
242 string strStart
= "";
244 string strResult
= "";
254 size_t iPosStart
= strXML
.find(strStart
);
255 size_t iPosEnd
= strXML
.find(strEnd
);
257 while ((iPosStart
!= string::npos
) && (iPosEnd
!= string::npos
))
259 // We want to be able to handle having the same tag emedded in itself.
260 // So between the start tag and the first instance of the end tag,
261 // we'll count any other instances of the start tag. If we find some
262 // then we require that we continue until we get that number more of
264 size_t iCurrentStart
= iPosStart
+ strStart
.length();
265 size_t iEmbedCount
= 0;
266 while ((iCurrentStart
!= string::npos
) && (iCurrentStart
< iPosEnd
))
268 iCurrentStart
= strXML
.find(strStart
, iCurrentStart
);
269 if ((iCurrentStart
!= string::npos
) && (iCurrentStart
< iPosEnd
))
272 iCurrentStart
+= strStart
.length();
275 // Now look for end tag to balance the start tags
276 for (size_t i
= 0; i
< iEmbedCount
; i
++)
278 iPosEnd
= strXML
.find(strEnd
, iPosEnd
+ strEnd
.length());
280 // Check to make sure we're still matching tags
281 if (iPosEnd
== string::npos
)
285 strResult
= strXML
.substr(iPosStart
+ strStart
.length(), iPosEnd
- (iPosStart
+ strStart
.length()));
287 if (bStripWhiteSpace
)
288 strResult
= StripWhiteSpace(strResult
);
290 iPosStart
= strXML
.find(strStart
, iPosEnd
+ strEnd
.length());
292 if (iPosStart
!= string::npos
)
293 iPosEnd
= strXML
.find(strEnd
, iPosStart
);
295 vResult
.push_back(strResult
);
301 VECTOR_NAME_VALUE_PAIR
XMLUtil::GetNameValuePairs(const string
& strXML
, bool bStripWhiteSpace
)
303 VECTOR_NAME_VALUE_PAIR vResult
;
304 vResult
.reserve(XML_UTIL_DEFAULT_VECTOR_SIZE
);
306 bool bInStartTag
= false;
308 string strValue
= "";
311 while (i
< strXML
.length())
313 if ((!bInStartTag
) && (strXML
[i
] == '<'))
315 // Starting a new tag
318 else if (bInStartTag
)
320 if (strXML
[i
] == '>')
322 // Hit the end of the start tag, get everything
323 // until we find the end tag.
325 string strFind
= "</";
329 size_t iPos
= string::npos
;
330 iPos
= strXML
.find(strFind
, i
);
332 if (iPos
!= string::npos
)
334 strValue
= strXML
.substr(i
+ 1, iPos
- i
- 1);
337 sPair
.strName
= strName
;
338 sPair
.strValue
= strValue
;
340 vResult
.push_back(sPair
);
342 i
= iPos
+ strFind
.length();
353 strName
+= strXML
[i
];