src/RecfileHandler.h
branchv_0
changeset 18 002077ecb17a
parent 17 f67047a1e19e
equal deleted inserted replaced
17:f67047a1e19e 18:002077ecb17a
   109 		}
   109 		}
   110 
   110 
   111 		return escaped.str();
   111 		return escaped.str();
   112 	}
   112 	}
   113 
   113 
       
   114 	integer_t computeWidth(const wchar_t ch) {
       
   115 		switch (ch) {
       
   116 			case L'\t':
       
   117 				// TODO: tabulator width?
       
   118 				return 4;
       
   119 			case L' ':
       
   120 				return 1;
       
   121 			default:
       
   122 				return std::max(0, wcwidth(ch));
       
   123 		}
       
   124 	}
       
   125 
       
   126 	/**
       
   127 	 * @param stringValue
       
   128 	 * @return the width that would the string occupy on the display (particular characters might be wider than 1 column)
       
   129 	 */
       
   130 	integer_t computeWidth(const string_t & stringValue) {
       
   131 		integer_t width = 0;
       
   132 		for (wchar_t ch : stringValue) width += computeWidth(ch);
       
   133 		return width;
       
   134 	}
       
   135 
   114 	void writeAttribute(const string_t& escapedName, const TypeId& type, const string_t& value) {
   136 	void writeAttribute(const string_t& escapedName, const TypeId& type, const string_t& value) {
   115 		output << convertor.to_bytes(escapedName) << ": ";
   137 		output << convertor.to_bytes(escapedName) << ": ";
   116 
   138 
   117 		for (char ch : convertor.to_bytes(value)) {
   139 		static const integer_t MAX_LINE_WIDTH = 80; // TODO: configuration
   118 			output << ch;
   140 		static const boolean_t unlimited = MAX_LINE_WIDTH == -1;
   119 			if (ch == '\n') output << "+ ";
   141 
       
   142 		integer_t currentWidth = computeWidth(escapedName) + 2; // 2 = ": " separator
       
   143 		integer_t valueWidth = computeWidth(value);
       
   144 		integer_t remainingWidth = valueWidth;
       
   145 
       
   146 
       
   147 		for (size_t i = 0, limit = value.size(); i < limit; i++) {
       
   148 			wchar_t ch = value[i];
       
   149 			integer_t characterWidth = computeWidth(ch);
       
   150 
       
   151 			if (ch == '\n') {
       
   152 				output << std::endl << "+ ";
       
   153 				currentWidth = 2; // 2 = "+ " prefix
       
   154 			} else {
       
   155 				if (unlimited || (currentWidth + remainingWidth) <= MAX_LINE_WIDTH) {
       
   156 					// all remaining characters fit the in the limit
       
   157 					currentWidth += characterWidth;
       
   158 					output << convertor.to_bytes(ch);
       
   159 				} else if ((currentWidth + characterWidth + 1) <= MAX_LINE_WIDTH) { // 1 = "\"
       
   160 					// we will wrap the line, but not yet
       
   161 					currentWidth += characterWidth;
       
   162 					output << convertor.to_bytes(ch);
       
   163 				} else {
       
   164 					output << "\\" << std::endl;
       
   165 					currentWidth = 0;
       
   166 					currentWidth += characterWidth;
       
   167 					output << convertor.to_bytes(ch);
       
   168 				}
       
   169 			}
       
   170 
       
   171 			remainingWidth -= characterWidth;
   120 		}
   172 		}
   121 
   173 
   122 		output << std::endl;
   174 		output << std::endl;
   123 	}
   175 	}
   124 
   176