#include "emitterutils.h" #include "exp.h" #include "indentation.h" #include "exceptions.h" #include "stringsource.h" #include #include #include namespace YAML { namespace Utils { namespace { bool IsPrintable(char ch) { return (0x20 <= ch && ch <= 0x7E); } bool IsValidPlainScalar(const std::string& str, bool inFlow) { // first check the start const RegEx& start = (inFlow ? Exp::PlainScalarInFlow : Exp::PlainScalar); if(!start.Matches(str)) return false; // and check the end for plain whitespace (which can't be faithfully kept in a plain scalar) if(!str.empty() && *str.rbegin() == ' ') return false; // then check until something is disallowed const RegEx& disallowed = (inFlow ? Exp::EndScalarInFlow : Exp::EndScalar) || (Exp::BlankOrBreak + Exp::Comment) || (!Exp::Printable) || Exp::Break || Exp::Tab; StringCharSource buffer(str.c_str(), str.size()); while(buffer) { if(disallowed.Matches(buffer)) return false; ++buffer; } return true; } typedef unsigned char byte; byte ToByte(char ch) { return static_cast(ch); } typedef std::string::const_iterator StrIter; std::string WriteUnicode(unsigned value) { std::stringstream str; // TODO: for the common escaped characters, give their usual symbol if(value <= 0xFF) str << "\\x" << std::hex << std::setfill('0') << std::setw(2) << value; else if(value <= 0xFFFF) str << "\\u" << std::hex << std::setfill('0') << std::setw(4) << value; else str << "\\U" << std::hex << std::setfill('0') << std::setw(8) << value; return str.str(); } // GetBytesToRead // . Returns the length of the UTF-8 sequence starting with 'signal' int GetBytesToRead(byte signal) { if(signal <= 0x7F) // ASCII return 1; else if(signal <= 0xBF) // invalid first characters return 0; else if(signal <= 0xDF) // Note: this allows "overlong" UTF8 (0xC0 - 0xC1) to pass unscathed. OK? return 2; else if(signal <= 0xEF) return 3; else return 4; } // ReadBytes // . Reads the next 'bytesToRead', if we can. // . Returns zero if we fail, otherwise fills the byte buffer with // the data and returns the number of bytes read. int ReadBytes(byte bytes[4], StrIter start, StrIter end, int bytesToRead) { for(int i=0;i= 1) it += (bytesRead - 1); } } out << "\""; return true; } bool WriteLiteralString(ostream& out, const std::string& str, int indent) { out << "|\n"; out << IndentTo(indent); for(std::size_t i=0;i