00001
00002 #include <sstream>
00003
00004 #include "SDXTabBasedStreamReader.h"
00005 #include "SDXContentHandler.h"
00006
00007 using namespace std;
00008 using namespace SDX;
00009 using namespace SDX::Formats;
00010
00011 TabBasedStreamReader::TabBasedStreamReader(istream* iStream, ContentHandler* contentHandler) :
00012 StreamReader(iStream, contentHandler)
00013 {
00014
00015 }
00016
00017 void TabBasedStreamReader::startProcessing(){
00018 m_inExtendedAttrList = false;
00019 m_curLevel = 0;
00020 }
00021
00022 void TabBasedStreamReader::endProcessing(){
00023 for(int i = 0; i < m_curLevel; i++)
00024 m_contentHandler->endNode();
00025 }
00026
00027 bool TabBasedStreamReader::processLine(string& line){
00028 line.erase(line.find_last_not_of(" \t\n\r") + 1);
00029 if(line.empty())
00030 return true;
00031
00032 unsigned int nodeNameStartIndex = 0;
00033 unsigned int nodeNameEndIndex = 0;
00034
00035
00036 if(!m_inExtendedAttrList){
00037 int newLevel = line.find_first_not_of("\t") + 1;
00038 line.erase(0, line.find_first_not_of(" \t\n\r"));
00039
00040 int levelDiff = newLevel - m_curLevel;
00041 if(levelDiff == 0 && m_curLevel != 0)
00042 m_contentHandler->endNode();
00043 else if(levelDiff < 0){
00044 for(int i = 0, absDiff = levelDiff * -1; i <= absDiff; i++)
00045 m_contentHandler->endNode();
00046 } else if(levelDiff > 1){
00047 m_error = "Cannot indent more than one level at a time";
00048 return false;
00049 }
00050 m_curLevel = newLevel;
00051
00052 if(line.at(0) == '"' || line.at(0) == '\''){
00053 nodeNameStartIndex = 1;
00054 nodeNameEndIndex = line.find_first_of(line.at(0), 1);
00055 if(nodeNameEndIndex == string::npos)
00056 return false;
00057 } else {
00058 nodeNameEndIndex = line.find_first_of(" \t");
00059 if(nodeNameEndIndex == string::npos)
00060 nodeNameEndIndex = line.length();
00061 }
00062
00063 m_contentHandler->startNode(line.substr(nodeNameStartIndex, nodeNameEndIndex - nodeNameStartIndex));
00064 }
00065
00066
00067 line.erase(0, nodeNameEndIndex);
00068 if(line.empty())
00069 return true;
00070
00071 m_inExtendedAttrList = line.at(line.size() - 1) == '\\';
00072 if(m_inExtendedAttrList){
00073 line.erase(line.size() - 1);
00074 line.erase(line.find_last_not_of(" \t\n\r") + 1);
00075 }
00076
00077 return processAttrList(line);
00078 }
00079
00080 bool TabBasedStreamReader::processAttrList(string& attrList){
00081 attrList.erase(0, attrList.find_first_not_of(" \t"));
00082 while(!attrList.empty()){
00083
00084 string attrName, attrValue;
00085 bool extractionOk = false;
00086
00087
00088 attrName = extractFirstValue(attrList, " \t=", &extractionOk);
00089 if(!extractionOk)
00090 return false;
00091
00092
00093 if(!attrList.empty() && attrList.at(0) == '='){
00094 attrList.erase(0, 1);
00095
00096 attrValue = extractFirstValue(attrList, " \t", &extractionOk);
00097 if(!extractionOk)
00098 return false;
00099 } else {
00100 attrValue = attrName;
00101 attrName = "";
00102 }
00103
00104
00105 m_contentHandler->writeAttribute(attrName, attrValue);
00106
00107 attrList.erase(0, attrList.find_first_not_of(" \t"));
00108 }
00109
00110 return true;
00111 }
00112
00113 string TabBasedStreamReader::extractFirstValue(std::string& str, const char* unqoutedValueDelimiters, bool *ok){
00114 string retVal;
00115
00116 char firstChar = str.at(0);
00117 unsigned int valueEnd = 0;
00118 if(firstChar == '"' || firstChar == '\''){
00119 valueEnd = str.find_first_of(firstChar, 1);
00120 if(valueEnd == string::npos){
00121 setError(string("Unterminated ") + firstChar);
00122
00123 if(ok)
00124 *ok = false;
00125 return "";
00126 }
00127
00128 retVal = str.substr(1, valueEnd++ - 1);
00129 } else {
00130 valueEnd = str.find_first_of(unqoutedValueDelimiters);
00131 if(valueEnd == string::npos)
00132 retVal = str.substr(0, valueEnd - 2);
00133 else
00134 retVal = str.substr(0, valueEnd);
00135 }
00136 str.erase(0, valueEnd);
00137
00138 if(ok)
00139 *ok = true;
00140 return retVal;
00141 }