src/XmlHandler.h
branchv_0
changeset 2 13a41e435ea0
parent 1 82ba555a97d1
child 3 878648aa663f
equal deleted inserted replaced
1:82ba555a97d1 2:13a41e435ea0
    27 	std::ostream &output;
    27 	std::ostream &output;
    28 
    28 
    29 	std::vector<TypeId> columnTypes;
    29 	std::vector<TypeId> columnTypes;
    30 	std::vector<string_t> columnTypeCodes;
    30 	std::vector<string_t> columnTypeCodes;
    31 	std::vector<string_t> columnNames;
    31 	std::vector<string_t> columnNames;
    32 	std::vector<integer_t> columnWidths;
    32 	integer_t valueCount = 0;
    33 	std::vector<string_t> values; // all values are saved here and processed at the end of the relation
       
    34 	integer_t columnCount = 0;
    33 	integer_t columnCount = 0;
       
    34 	integer_t relationCount = 0;
    35 
    35 
    36 	
    36 	const std::string escapeXmlText(const string_t &value) {
    37 
       
    38 	const string_t escapeXmlText(const string_t &value, const char* color) {
       
    39 		std::wstringstream result;
    37 		std::wstringstream result;
    40 
    38 
    41 		for (auto & ch : value) {
    39 		for (auto & ch : value) {
    42 			switch (ch) {
    40 			switch (ch) {
    43 				// FIXME: xml escaping
       
    44 				case L'&': result << L"&amp;";
    41 				case L'&': result << L"&amp;";
       
    42 					break;
       
    43 				case L'<': result << L"&lt;";
       
    44 					break;
       
    45 				case L'>': result << L"&gt;";
       
    46 					break;
       
    47 				case L'\'': result << L"&apos;"; // TODO: escape ' and " only in attributes
       
    48 					break;
       
    49 				case L'"': result << L"&quot;"; // TODO: escape ' and " only in attributes
    45 					break;
    50 					break;
    46 				default: result << ch;
    51 				default: result << ch;
    47 			}
    52 			}
    48 		}
    53 		}
    49 
    54 
    50 		return result.str();
    55 		return convertor.to_bytes(result.str());
    51 	}
    56 	}
    52 
    57 
    53 public:
    58 public:
    54 
    59 
    55 	XmlHandler(std::ostream& output) : output(output) {
    60 	XmlHandler(std::ostream& output) : output(output) {
    56 	}
    61 	}
    57 
    62 
    58 	void startRelation(string_t name, std::vector<handlers::AttributeMetadata> attributes) override {
    63 	void startRelation(string_t name, std::vector<handlers::AttributeMetadata> attributes) override {
    59 		output << convertor.to_bytes(name) << ": (XML)" << endl;
    64 		// TODO: refactor and move common XML functions to relpipe-lib-xml
       
    65 
       
    66 		valueCount = 0;
       
    67 		columnCount = 0;
       
    68 
       
    69 		if (relationCount == 0) {
       
    70 			output << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl;
       
    71 			output << "<pipe>" << std::endl;
       
    72 			// TODO: xmlns
       
    73 		} else {
       
    74 			output << INDENT << INDENT << "</record>" << std::endl;
       
    75 			output << INDENT << "</relation>" << std::endl;
       
    76 		}
       
    77 		relationCount++;
       
    78 		output << INDENT << "<relation>" << std::endl;
       
    79 
       
    80 		output << INDENT << INDENT << "<name>" << escapeXmlText(name) << "</name>" << std::endl;
       
    81 
       
    82 
    60 		columnCount = attributes.size();
    83 		columnCount = attributes.size();
    61 		columnTypes.resize(columnCount);
    84 		columnTypes.resize(columnCount);
    62 		columnTypeCodes.resize(columnCount);
    85 		columnTypeCodes.resize(columnCount);
    63 		columnNames.resize(columnCount);
    86 		columnNames.resize(columnCount);
    64 		columnWidths.resize(columnCount, 0);
       
    65 		for (int i = 0; i < attributes.size(); i++) {
    87 		for (int i = 0; i < attributes.size(); i++) {
    66 			columnNames[i] = attributes[i].getAttributeName();
    88 			columnNames[i] = attributes[i].getAttributeName();
    67 			columnTypes[i] = attributes[i].getTypeId();
    89 			columnTypes[i] = attributes[i].getTypeId();
    68 			columnTypeCodes[i] = attributes[i].getTypeName();
    90 			columnTypeCodes[i] = attributes[i].getTypeName();
    69 		}
    91 		}
       
    92 		
       
    93 		// TODO: print attribute metadata
    70 	}
    94 	}
    71 
    95 
    72 	void attribute(const string_t& value) override {
    96 	void attribute(const string_t& value) override {
    73 		integer_t i = values.size() % columnCount;
    97 		integer_t i = valueCount % columnCount;
    74 		values.push_back(value);
    98 
    75 		columnWidths[i] = max(columnWidths[i], value.length());
    99 		if (i == 0 && valueCount) output << INDENT << INDENT << "</record>" << std::endl;
       
   100 		if (i == 0) output << INDENT << INDENT << "<record>" << std::endl;
       
   101 
       
   102 		valueCount++;
       
   103 
       
   104 		// TODO: print attribute metadata (optional)
       
   105 		output << INDENT << INDENT << INDENT << "<attribute>";
       
   106 		output << escapeXmlText(value);
       
   107 		output << "</attribute>" << std::endl;
       
   108 
    76 	}
   109 	}
    77 
   110 
    78 	void endOfPipe() {
   111 	void endOfPipe() {
    79 		
   112 		if (valueCount) output << INDENT << INDENT << "</record>" << std::endl;
       
   113 		if (relationCount) output << INDENT << "</relation>" << std::endl;
       
   114 		output << "</pipe>" << std::endl;
       
   115 
    80 	}
   116 	}
    81 
   117 
    82 };
   118 };
    83 
   119 
    84 }
   120 }