Пример #1
0
    void write_json_helper(std::basic_ostream<typename Ptree::char_type> &stream, 
                           const Ptree &pt, 
                           int indent)
    {

        typedef typename Ptree::char_type Ch;
        typedef typename std::basic_string<Ch> Str;
        
        // Value or object or array
        if (indent > 0 && pt.empty())
        {
            
            // Write value
            Str data = create_escapes(pt.template get_own<Str>(), stream.getloc());
            stream << Ch('"') << data << Ch('"');

        }
        else if (indent > 0 && pt.count(Str()) == pt.size())
        {
                
            // Write array
            stream << Ch('[') << Ch('\n');
            typename Ptree::const_iterator it = pt.begin();
            for (; it != pt.end(); ++it)
            {
                stream << Str(4 * (indent + 1), Ch(' '));
                write_json_helper(stream, it->second, indent + 1);
                if (boost::next(it) != pt.end())
                    stream << Ch(',');
                stream << Ch('\n');
            }
            stream << Str(4 * indent, Ch(' ')) << Ch(']');

        }
        else
        {
        
            // Write object
            stream << Ch('{') << Ch('\n');
            typename Ptree::const_iterator it = pt.begin();
            for (; it != pt.end(); ++it)
            {
                stream << Str(4 * (indent + 1), Ch(' '));
                stream << Ch('"') << create_escapes(it->first, stream.getloc()) << Ch('"') << Ch(':');
                if (it->second.empty())
                    stream << Ch(' ');
                else
                    stream << Ch('\n') << Str(4 * (indent + 1), Ch(' '));
                write_json_helper(stream, it->second, indent + 1);
                if (boost::next(it) != pt.end())
                    stream << Ch(',');
                stream << Ch('\n');
            }
            stream << Str(4 * indent, Ch(' ')) << Ch('}');

        }

    }
Пример #2
0
 ///
 /// Translate message and write to stream \a out, using imbued locale and domain set to the 
 /// stream
 ///
 void write(std::basic_ostream<char_type> &out) const
 {
     std::locale const &loc = out.getloc();
     int id = ios_info::get(out).domain_id();
     string_type buffer;
     out << write(loc,id,buffer);
 }
Пример #3
0
inline void fprint(std::basic_ostream<Char, Trait>& out, const Char* str, Args&&... arguments) {
    // %[parameter][flags][width][.precision]verb
    // if it's *n$ instead of %n$ then it'll use the specific parameter number
    // n starts at 1 to sizeof...(Args)
    // at the moment I'm too lazy to do * at all.
    auto&& args = std::make_tuple(std::forward<Args>(arguments)...);
    stream_state<Char, Trait> original{out};
    stream_state<Char, Trait> changed;
    printer<Char, Trait> func(out);
    const Char percent = out.widen('%');
    const Char zero    = out.widen('0');
    auto&& loc = out.getloc();
    size_t index = 0;
    size_t position = 0;
    bool has_positional = false;

    while(*str != 0) {
        // not a %
        if(!Trait::eq(*str, percent)) {
            out << *str++;
            continue;
        }

        // at this point -- *str == '%'
        // so just increment it to get to the format-spec
        ++str;

        // escaped %
        if(*str && Trait::eq(*str, percent)) {
            out << percent;
            ++str;
            continue;
        }

        // beginning of format-spec
        changed = original;

        // check for [parameter], i.e. n$
        // or a numeric value for [width]
        position = parse_integer(str, zero, loc);

        // check if it's [parameter] rather than [width]
        if(Trait::eq(*str, out.widen('$'))) {
            has_positional = true;
            ++str;
        }

        // check for [flags]
        // they are as follows:
        // +       - equivalent to std::showpos
        // -       - left aligns instead of right align, i.e. std::left
        // 0       - pad with 0s instead of spaces
        // '[char] - pad with [char] instead of spaces
        while(*str) {
            if(Trait::eq(*str, out.widen('+'))) {
                changed.flags |= out.showpos;
            }
            else if(Trait::eq(*str, out.widen('-'))) {
                changed.flags |= out.left;
            }
            else if(Trait::eq(*str, out.widen('0'))) {
                changed.fill = out.widen('0');
            }
            else if(Trait::eq(*str, out.widen('\''))) {
                // the next character is unconditionally the fill character
                changed.fill = *(++str);
            }
            else {
                // unknown flag, so just exit
                break;
            }
            ++str;
        }

        // check for [width]
        changed.width = parse_integer(str, zero, loc);

        // check for [precision]
        if(Trait::eq(*str, out.widen('.'))) {
            changed.precision = parse_integer(++str, zero, loc);
        }


        size_t final_index = has_positional ? position - 1 : index++;

        // check for verb
        if(Trait::eq(*str, out.widen('s')) || Trait::eq(*str, out.widen('c'))) {
            // do nothing since these don't add any extra format specifiers.
            // many of these are provided as a thin compatibility layer for
            // the original printf -- albeit strict compatibility is not a requirement here.
        }
        else if(Trait::eq(*str, out.widen('f')) || Trait::eq(*str, out.widen('F'))) {
            changed.flags |= out.fixed;
        }
        else if(Trait::eq(*str, out.widen('e'))) {
            changed.flags |= out.scientific;
        }
        else if(Trait::eq(*str, out.widen('E'))) {
            changed.flags |= out.scientific;
            changed.flags |= out.uppercase;
        }
        else if(Trait::eq(*str, out.widen('g'))) {
            changed.flags &= ~out.floatfield;
        }
        else if(Trait::eq(*str, out.widen('G'))) {
            changed.flags &= ~out.floatfield;
            changed.flags |= out.uppercase;
        }
        else if(Trait::eq(*str, out.widen('x')) || Trait::eq(*str, out.widen('p'))) {
            changed.flags |= out.hex;
        }
        else if(Trait::eq(*str, out.widen('X'))) {
            changed.flags |= out.hex;
            changed.flags |= out.uppercase;
        }
        else if(Trait::eq(*str, out.widen('d')) || Trait::eq(*str, out.widen('i')) || Trait::eq(*str, out.widen('u'))) {
            changed.flags |= out.dec;
        }
        else if(Trait::eq(*str, out.widen('o'))) {
            changed.flags |= out.oct;
        }
        else {
            std::string error = "invalid verb given ";
            auto narrowed = out.narrow(*str, 0x00);
            if(narrowed == 0x00) {
                error.push_back('\'');
                error.push_back(narrowed);
                error.push_back('\'');
            }
            else {
                error.append(" (unable to convert to char)");
            }
            throw std::runtime_error(error);
        }

        changed.apply(out);
        apply(args, final_index, func);
        original.apply(out);

        ++str;
    }
}