예제 #1
0
    void do_double_value(double value, uint8_t precision) override
    {
        begin_value();

        if (is_nan(value) && format_.replace_nan())
        {
            bos_.write(format_.nan_replacement());
        }
        else if (is_pos_inf(value) && format_.replace_pos_inf())
        {
            bos_.write(format_.pos_inf_replacement());
        }
        else if (is_neg_inf(value) && format_.replace_neg_inf())
        {
            bos_.write(format_.neg_inf_replacement());
        }
        //else if (format_.floatfield() != 0)
        //{
            //std::basic_ostringstream<CharT> os;
            //os.imbue(std::locale::classic());
            //os.setf(format_.floatfield(), std::ios::floatfield);
            //os << std::showpoint << std::setprecision(format_.precision()) << value;
            //*os_ << os.str();
        //}
        else
        {
            fp_.print(value,precision,bos_);
        }

        end_value();
    }
예제 #2
0
    void print(double val, buffered_ostream<CharT>& os)
    {
        vs_.reset();
        vs_ << val;

        const CharT* s = vs_.data();
        const CharT* se = s + vs_.length();

        bool dot = false;
        while (s < se)
        {
            if (*s == '.')
            {
                dot = true;
            }
            else if (*s == 'e')
            {
                if (!dot)
                {
                    os.put('.');
                    os.put('0');
                    dot = true;
                }
            }
            os.put(*s);
            ++s;
        }
        if (!dot)
        {
            os.put('.');
            os.put('0');
        }
    }
예제 #3
0
 void do_name(const CharT* name, size_t length) override
 {
     begin_element();
     bos_.put('\"');
     escape_string<CharT>(name, length, format_, bos_);
     bos_.put('\"');
     bos_.put(':');
 }
예제 #4
0
void print_float(double val, int precision, buffered_ostream<Char>& os)
{
    std::basic_ostringstream<Char> ss;
    ss.imbue(std::locale::classic());
    ss << std::showpoint << std::setprecision(precision) << val;
    std::basic_string<Char> s(ss.str());

    typename std::basic_string<Char>::size_type exp_pos= s.find('e');
    std::basic_string<Char> exp;
    if (exp_pos != std::basic_string<Char>::npos)
    {
        exp = s.substr(exp_pos);
        s.erase(exp_pos);
    }

    int len = (int)s.size();
    while (len >= 2 && s[len - 1] == '0' && s[len - 2] != '.')
    {
        --len;
    }
    s.erase(len);
    if (exp_pos != std::basic_string<Char>::npos)
    {
        s.append(exp);
    }

    os.write(s.c_str(),s.length());
}
예제 #5
0
    void do_bool_value(bool value) override
    {
        begin_value();

        if (value)
        {
            auto buf = json_literals<CharT>::true_literal();
            bos_.write(buf.first,buf.second);
        }
        else
        {
            auto buf = json_literals<CharT>::false_literal();
            bos_.write(buf.first,buf.second);
        }

        end_value();
    }
예제 #6
0
    void do_null_value() override
    {
        begin_value();

        auto buf = json_literals<CharT>::null_literal();
        bos_.write(buf.first,buf.second);

        end_value();
    }
예제 #7
0
    void do_end_array() override
    {
        unindent();
        if (indenting_ && !stack_.empty() && stack_.back().content_indented_)
        {
            write_indent();
        }
        stack_.pop_back();
        bos_.put(']');

        end_value();
    }
예제 #8
0
    void do_begin_array() override
    {
        begin_structure();

        if (indenting_ && !stack_.empty() && stack_.back().is_object())
        {
            write_indent();
        }
        stack_.push_back(stack_item(false));
        bos_.put('[');
        indent();
    }
예제 #9
0
    void do_end_object() override
    {
        unindent();
        if (indenting_ && !stack_.empty())
        {
            write_indent();
        }
        stack_.pop_back();
        bos_.put('}');

        end_value();
    }
예제 #10
0
    void print(double val, buffered_ostream<CharT>& os)
    {
        char buf[_CVTBUFSIZE];
        int decimal_point = 0;
        int sign = 0;

        if (precision_ >= _CVTBUFSIZE)
        {
            precision_ = _CVTBUFSIZE - 1;
        }

        int err = _ecvt_s(buf, _CVTBUFSIZE, val, precision_, &decimal_point, &sign);
        if (err != 0)
        {
            throw std::runtime_error("Failed attempting double to string conversion");
        }
        char* s = buf;
        char* se = s + precision_;

        int i, k;
        int j;

        if (sign)
        {
            os.put('-');
        }
        if (decimal_point <= -4 || decimal_point > se - s + 5) 
        {
            os.put(*s++);
            if (s < se) 
            {
                os.put('.');
                while ((se-1) > s && *(se-1) == '0')
                {
                    --se;
                }

                while(s < se)
                {
                    os.put(*s++);
                }
            }
            os.put('e');
            /* sprintf(b, "%+.2d", decimal_point - 1); */
            if (--decimal_point < 0) {
                os.put('-');
                decimal_point = -decimal_point;
                }
            else
                os.put('+');
            for(j = 2, k = 10; 10*k <= decimal_point; j++, k *= 10);
            for(;;) 
            {
                i = decimal_point / k;
                os.put(i + '0');
                if (--j <= 0)
                    break;
                decimal_point -= i*k;
                decimal_point *= 10;
            }
        }
        else if (decimal_point <= 0) 
        {
            os.put('0');
            os.put('.');
            while ((se-1) > s && *(se-1) == '0')
            {
                --se;
            }
            for(; decimal_point < 0; decimal_point++)
            {
                os.put('0');
            }
            while(s < se)
            {
                os.put(*s++);
            }
        }
        else {
            while(s < se) 
            {
                os.put(*s++);
                if ((--decimal_point == 0) && s < se)
                {
                    os.put('.');
                    while ((se-1) > s && *(se-1) == '0')
                    {
                        --se;
                    }
                }
            }
            for(; decimal_point > 0; decimal_point--)
            {
                os.put('0');
            }
        }
    }
예제 #11
0
 void do_end_json() override
 {
     bos_.flush();
 }