src/INIWriter.h
branchv_0
changeset 5 bee7acb57330
parent 4 372b161669e4
child 8 7c85dc9a310b
equal deleted inserted replaced
4:372b161669e4 5:bee7acb57330
    39 	std::string keyValueSeparator = " = ";
    39 	std::string keyValueSeparator = " = ";
    40 	std::string commentSeparatorForSections = " ; ";
    40 	std::string commentSeparatorForSections = " ; ";
    41 	std::string commentSeparatorForEntries = " ; ";
    41 	std::string commentSeparatorForEntries = " ; ";
    42 	std::string commentSeparatorStandalone = "; ";
    42 	std::string commentSeparatorStandalone = "; ";
    43 
    43 
       
    44 	relpipe::common::type::StringX hierarchySeparator = L"/";
       
    45 	bool allowSections = true;
       
    46 
    44 	bool hasContent = false;
    47 	bool hasContent = false;
       
    48 
       
    49 	std::vector<relpipe::common::type::StringX> currentSection;
       
    50 
       
    51 	relpipe::common::type::StringX getCurrentSectionFullName() {
       
    52 		std::wstringstream result;
       
    53 
       
    54 		// TODO: configurable hierarchy delimiter
       
    55 		// TODO: escape delimiter characters that are part of the section names
       
    56 		for (int i = 0; i < currentSection.size(); i++) {
       
    57 			if (i > 0)result << hierarchySeparator;
       
    58 			result << currentSection[i];
       
    59 		}
       
    60 
       
    61 		return result.str();
       
    62 	}
    45 
    63 
    46 	/**
    64 	/**
    47 	 * TODO: use a common method
    65 	 * TODO: use a common method
    48 	 */
    66 	 */
    49 	bool parseBoolean(const relpipe::common::type::StringX& value) {
    67 	bool parseBoolean(const relpipe::common::type::StringX& value) {
   174 		if (uri == option::Dialect) setDialect(value);
   192 		if (uri == option::Dialect) setDialect(value);
   175 		else if (uri == option::CommentSeparatorForSections) commentSeparatorForSections = convertor.to_bytes(value);
   193 		else if (uri == option::CommentSeparatorForSections) commentSeparatorForSections = convertor.to_bytes(value);
   176 		else if (uri == option::CommentSeparatorForEntries) commentSeparatorForEntries = convertor.to_bytes(value);
   194 		else if (uri == option::CommentSeparatorForEntries) commentSeparatorForEntries = convertor.to_bytes(value);
   177 		else if (uri == option::CommentSeparatorStandalone) commentSeparatorStandalone = convertor.to_bytes(value);
   195 		else if (uri == option::CommentSeparatorStandalone) commentSeparatorStandalone = convertor.to_bytes(value);
   178 		else if (uri == option::KeyValueSeparator) keyValueSeparator = convertor.to_bytes(value);
   196 		else if (uri == option::KeyValueSeparator) keyValueSeparator = convertor.to_bytes(value);
   179 		else if (uri == option::AllowSections); // TODO: allow sections
   197 		else if (uri == option::HierarchySeparator) hierarchySeparator = value;
       
   198 		else if (uri == option::AllowSections) allowSections = parseBoolean(value);
   180 		else if (uri == option::QuotesTypeForSections) quotingForSections.type = parseQuotingType(value);
   199 		else if (uri == option::QuotesTypeForSections) quotingForSections.type = parseQuotingType(value);
   181 		else if (uri == option::QuotesTypeForKeys) quotingForKeys.type = parseQuotingType(value);
   200 		else if (uri == option::QuotesTypeForKeys) quotingForKeys.type = parseQuotingType(value);
   182 		else if (uri == option::QuotesTypeForValues) quotingForValues.type = parseQuotingType(value);
   201 		else if (uri == option::QuotesTypeForValues) quotingForValues.type = parseQuotingType(value);
   183 		else if (uri == option::QuotesPatternForSections) quotingForSections.pattern = value;
   202 		else if (uri == option::QuotesPatternForSections) quotingForSections.pattern = value;
   184 		else if (uri == option::QuotesPatternForKeys) quotingForKeys.pattern = value;
   203 		else if (uri == option::QuotesPatternForKeys) quotingForKeys.pattern = value;
   198 
   217 
   199 	void startDocument() {
   218 	void startDocument() {
   200 	}
   219 	}
   201 
   220 
   202 	void endDocument() {
   221 	void endDocument() {
       
   222 		if (currentSection.size()) throw relpipe::reader::RelpipeReaderException(L"There are still " + std::to_wstring(currentSection.size()) + L" open sections during the endDocument() call. Need to call endSection() before.");
   203 		output.flush();
   223 		output.flush();
   204 	}
   224 	}
   205 
   225 
   206 	void startSection(const SectionStartEvent& event) {
   226 	void startSection(const SectionStartEvent& event) {
   207 		if (hasContent) output << std::endl;
   227 		currentSection.push_back(event.name);
   208 		output << "[" << escape(event.name, EscapingProcessor::TextType::SectionName) << "]";
   228 
   209 		if (event.tag.size()) output << "[" << escape(event.tag, EscapingProcessor::TextType::SectionTag) << "]";
   229 		if (allowSections) {
   210 		if (event.comment.size()) output << commentSeparatorForSections << escape(event.comment, EscapingProcessor::TextType::SectionComment);
   230 			if (hasContent) output << std::endl;
   211 		output << std::endl;
   231 			output << "[" << escape(getCurrentSectionFullName(), EscapingProcessor::TextType::SectionName) << "]";
       
   232 			if (event.tag.size()) output << "[" << escape(event.tag, EscapingProcessor::TextType::SectionTag) << "]";
       
   233 			if (event.comment.size()) output << commentSeparatorForSections << escape(event.comment, EscapingProcessor::TextType::SectionComment);
       
   234 			output << std::endl;
       
   235 		}
       
   236 
   212 		hasContent = true;
   237 		hasContent = true;
   213 	}
   238 	}
   214 
   239 
   215 	void endSection() {
   240 	void endSection() {
       
   241 		currentSection.pop_back();
   216 		output.flush();
   242 		output.flush();
   217 	}
   243 	}
   218 
   244 
   219 	void entry(const EntryEvent& event) {
   245 	void entry(const EntryEvent& event) {
       
   246 		// TODO: escape/quote parts separately + configurable quoting of parts or whole + the same for sub keys
       
   247 		if (!allowSections && currentSection.size()) output << escape(getCurrentSectionFullName(), EscapingProcessor::TextType::EntryKey) << convertor.to_bytes(hierarchySeparator);
   220 		output << escape(event.key, EscapingProcessor::TextType::EntryKey);
   248 		output << escape(event.key, EscapingProcessor::TextType::EntryKey);
   221 		if (event.subKey.size()) output << "[" << escape(event.subKey, EscapingProcessor::TextType::EntrySubKey) << "]";
   249 		if (event.subKey.size()) output << "[" << escape(event.subKey, EscapingProcessor::TextType::EntrySubKey) << "]";
   222 		output << keyValueSeparator << escape(event.value, EscapingProcessor::TextType::EntryValue);
   250 		output << keyValueSeparator << escape(event.value, EscapingProcessor::TextType::EntryValue);
   223 		if (event.comment.size()) output << commentSeparatorForEntries << escape(event.comment, EscapingProcessor::TextType::EntryComment);
   251 		if (event.comment.size()) output << commentSeparatorForEntries << escape(event.comment, EscapingProcessor::TextType::EntryComment);
   224 		output << std::endl;
   252 		output << std::endl;