Parse the input text to generate a number, and populate the result into item. */
| 115 | |
| 116 | /* Parse the input text to generate a number, and populate the result into item. */ |
| 117 | static const char *parse_number(cJSON *item, const char *num) |
| 118 | { |
| 119 | int64 n = 0; |
| 120 | long double d = 0.0; |
| 121 | double base = 0.0; |
| 122 | double point = 0.1; |
| 123 | int scale = 0.0; |
| 124 | int subscale = 0; |
| 125 | int signsubscale = 1; |
| 126 | item->sign = 1; |
| 127 | |
| 128 | /* Could use sscanf for this? */ |
| 129 | if (*num == '-') |
| 130 | item->sign = -1, num++; /* Has sign? */ |
| 131 | if (*num == '0') |
| 132 | num++; /* is zero */ |
| 133 | while (*num >= '0' && *num <= '9') |
| 134 | { |
| 135 | n = (n * 10) + (*num++ - '0'); |
| 136 | } |
| 137 | d = n; |
| 138 | if (*num == '.' && num[1] >= '0' && num[1] <= '9') |
| 139 | { |
| 140 | num++; |
| 141 | base = d; |
| 142 | do |
| 143 | { |
| 144 | d += point * (*num - '0'); |
| 145 | point *= 0.1; |
| 146 | base = (base * 10.0) + (*num - '0'), scale--; |
| 147 | ++num; |
| 148 | } |
| 149 | while (*num >= '0' && *num <= '9'); |
| 150 | } /* Fractional part? */ |
| 151 | if (*num == 'e' || *num == 'E') /* Exponent? */ |
| 152 | { |
| 153 | num++; |
| 154 | if (*num == '+') |
| 155 | num++; |
| 156 | else if (*num == '-') |
| 157 | signsubscale = -1, num++; /* With sign? */ |
| 158 | while (*num >= '0' && *num <= '9') |
| 159 | subscale = (subscale * 10) + (*num++ - '0'); /* Number? */ |
| 160 | } |
| 161 | |
| 162 | if (scale == 0 && subscale == 0) |
| 163 | { |
| 164 | item->valuedouble = item->sign * d; |
| 165 | item->valueint = item->sign * n; |
| 166 | item->type = cJSON_Int; |
| 167 | } |
| 168 | else |
| 169 | { |
| 170 | if (subscale != 0) |
| 171 | { |
| 172 | d = item->sign * base * pow(10.0, (scale + subscale * signsubscale)); /* number = +/- number.fraction * 10^+/- exponent */ |
| 173 | } else { |
| 174 | d = item->sign * d; |