src/RecfileHandler.h
branchv_0
changeset 16 1731e8dff446
parent 15 e5421eea0583
child 17 f67047a1e19e
equal deleted inserted replaced
15:e5421eea0583 16:1731e8dff446
    70 
    70 
    71 	void writeSeparator() {
    71 	void writeSeparator() {
    72 		output << std::endl;
    72 		output << std::endl;
    73 	}
    73 	}
    74 
    74 
       
    75 	bool between(wchar_t ch, wchar_t start, wchar_t end) {
       
    76 		return ch >= start && ch <= end;
       
    77 	}
       
    78 
       
    79 	bool isValidNameCharacter(wchar_t ch, bool first) {
       
    80 		if (first) {
       
    81 			// also '%' is technically valid here, but it is used for special
       
    82 			// purposes like the relation name or attribute types
       
    83 			return /**/between(ch, L'a', L'z')
       
    84 					|| between(ch, L'A', L'Z');
       
    85 		} else {
       
    86 			return ch == L'_'
       
    87 					|| between(ch, L'a', L'z')
       
    88 					|| between(ch, L'A', L'Z')
       
    89 					|| between(ch, L'0', L'9');
       
    90 		}
       
    91 	}
       
    92 
    75 	void writeAttribute(const string_t& name, const TypeId& type, const string_t& value) {
    93 	void writeAttribute(const string_t& name, const TypeId& type, const string_t& value) {
    76 		// FIXME: escaping/filtering
    94 		// TODO: multiple escapting mode - including one that is not lossless
    77 		output << convertor.to_bytes(name) << ": ";
    95 		// but allows writing a single '_' inside the name
       
    96 		for (size_t i = 0, limit = name.size(); i < limit; i++) {
       
    97 			wchar_t ch = name[i];
       
    98 			bool valid = isValidNameCharacter(ch, i == 0);
       
    99 
       
   100 			// Not a lossless round-trip
       
   101 			// (maybe we could sacrifice some reserved prefix):
       
   102 			if (i == 0 && !valid) output << 'x';
       
   103 
       
   104 			if (ch == '_') output << "__";
       
   105 			else if (valid) output << convertor.to_bytes(ch);
       
   106 			else output << '_' << ((uint32_t) ch) << '_';
       
   107 		}
       
   108 		output << ": ";
    78 
   109 
    79 		for (char ch : convertor.to_bytes(value)) {
   110 		for (char ch : convertor.to_bytes(value)) {
    80 			output << ch;
   111 			output << ch;
    81 			if (ch == '\n') output << "+ ";
   112 			if (ch == '\n') output << "+ ";
    82 		}
   113 		}