… | |
… | |
162 | #endif |
162 | #endif |
163 | } |
163 | } |
164 | } |
164 | } |
165 | |
165 | |
166 | /* adds two STRLENs together, slow, and with paranoia */ |
166 | /* adds two STRLENs together, slow, and with paranoia */ |
167 | STRLEN |
167 | static STRLEN |
168 | strlen_sum (STRLEN l1, STRLEN l2) |
168 | strlen_sum (STRLEN l1, STRLEN l2) |
169 | { |
169 | { |
170 | size_t sum = l1 + l2; |
170 | size_t sum = l1 + l2; |
171 | |
171 | |
172 | if (sum < (size_t)l2 || sum != (size_t)(STRLEN)sum) |
172 | if (sum < (size_t)l2 || sum != (size_t)(STRLEN)sum) |
… | |
… | |
918 | if (SvIsUV (sv) ? SvUVX (sv) <= 59000 |
918 | if (SvIsUV (sv) ? SvUVX (sv) <= 59000 |
919 | : SvIVX (sv) <= 59000 && SvIVX (sv) >= -59000) |
919 | : SvIVX (sv) <= 59000 && SvIVX (sv) >= -59000) |
920 | { |
920 | { |
921 | // optimise the "small number case" |
921 | // optimise the "small number case" |
922 | // code will likely be branchless and use only a single multiplication |
922 | // code will likely be branchless and use only a single multiplication |
923 | // works for numbers up to 59074 |
923 | // 4.28 works for numbers up to 59074 |
924 | I32 i = SvIVX (sv); |
924 | I32 i = SvIVX (sv); |
925 | U32 u; |
925 | U32 u; |
926 | char digit, nz = 0; |
926 | char digit, nz = 0; |
927 | |
927 | |
928 | need (enc, 6); |
928 | need (enc, 6); |
929 | |
929 | |
930 | *enc->cur = '-'; enc->cur += i < 0 ? 1 : 0; |
930 | *enc->cur = '-'; enc->cur += i < 0 ? 1 : 0; |
931 | u = i < 0 ? -i : i; |
931 | u = i < 0 ? -i : i; // not undefined due to range check above |
932 | |
932 | |
933 | // convert to 4.28 fixed-point representation |
933 | // convert to 4.28 fixed-point representation |
934 | u = u * ((0xfffffff + 10000) / 10000); // 10**5, 5 fractional digits |
934 | u = u * ((0xfffffff + 10000) / 10000); // 10**5, 5 fractional digits |
935 | |
935 | |
936 | // now output digit by digit, each time masking out the integer part |
936 | // now output digit by digit, each time masking out the integer part |
… | |
… | |
1038 | else |
1038 | else |
1039 | break; |
1039 | break; |
1040 | } |
1040 | } |
1041 | else if (ch != 0x20 && ch != 0x0a && ch != 0x0d && ch != 0x09) |
1041 | else if (ch != 0x20 && ch != 0x0a && ch != 0x0d && ch != 0x09) |
1042 | break; // parse error, but let higher level handle it, gives better error messages |
1042 | break; // parse error, but let higher level handle it, gives better error messages |
1043 | |
1043 | else |
1044 | ++dec->cur; |
1044 | ++dec->cur; |
1045 | } |
1045 | } |
1046 | } |
1046 | } |
1047 | |
1047 | |
1048 | #define ERR(reason) SB dec->err = reason; goto fail; SE |
1048 | #define ERR(reason) SB dec->err = reason; goto fail; SE |
1049 | |
1049 | |