int spb_read_header(binstream_t *stream, geom_blob_header_t *spb, errorstream_t *error) { uint8_t start; if (binstream_read_u8(stream, &start) != SQLITE_OK) { return SQLITE_IOERR; } if (start != 0x00) { if (error) { error_append(error, "Incorrect SPB START value [expected: 00, actual:%x]", start); } return SQLITE_IOERR; } uint8_t endian; if (binstream_read_u8(stream, &endian)) { return SQLITE_IOERR; } if (endian != SPB_BIG_ENDIAN && endian != SPB_LITTLE_ENDIAN) { if (error) { error_append(error, "Incorrect SPB ENDIAN value [expected: 00 or 01, actual:%x]", endian); } return SQLITE_IOERR; } binstream_set_endianness(stream, endian == SPB_BIG_ENDIAN ? BIG : LITTLE); if (binstream_read_i32(stream, &spb->srid) != SQLITE_OK) { return SQLITE_IOERR; } spb->envelope.has_env_x = 1; spb->envelope.has_env_y = 1; spb->envelope.has_env_z = 0; spb->envelope.has_env_m = 0; if (binstream_read_double(stream, &spb->envelope.min_x)) { return SQLITE_IOERR; } if (binstream_read_double(stream, &spb->envelope.min_y)) { return SQLITE_IOERR; } if (binstream_read_double(stream, &spb->envelope.max_x)) { return SQLITE_IOERR; } if (binstream_read_double(stream, &spb->envelope.max_y)) { return SQLITE_IOERR; } spb->empty = fp_isnan(spb->envelope.min_x) && fp_isnan(spb->envelope.max_x) && fp_isnan(spb->envelope.min_y) && fp_isnan(spb->envelope.max_y); CHECK_ENV(spb, error) return SQLITE_OK; }
int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, char sign) { char *s = buf; if (buf_size <= FPMIN_BUF_SIZE) { // FPMIN_BUF_SIZE is the minimum size needed to store any FP number. // If the buffer does not have enough room for this (plus null terminator) // then don't try to format the float. if (buf_size >= 2) { *s++ = '?'; } if (buf_size >= 1) { *s++ = '\0'; } return buf_size >= 2; } if (fp_signbit(f)) { *s++ = '-'; f = -f; } else { if (sign) { *s++ = sign; } } // buf_remaining contains bytes available for digits and exponent. // It is buf_size minus room for the sign and null byte. int buf_remaining = buf_size - 1 - (s - buf); if (fp_isspecial(f)) { char uc = fmt & 0x20; if (fp_isinf(f)) { *s++ = 'I' ^ uc; *s++ = 'N' ^ uc; *s++ = 'F' ^ uc; goto ret; } else if (fp_isnan(f)) { *s++ = 'N' ^ uc; *s++ = 'A' ^ uc; *s++ = 'N' ^ uc; ret: *s = '\0'; return s - buf; } } if (prec < 0) { prec = 6; } char e_char = 'E' | (fmt & 0x20); // e_char will match case of fmt fmt |= 0x20; // Force fmt to be lowercase char org_fmt = fmt; if (fmt == 'g' && prec == 0) { prec = 1; } int e, e1; int dec = 0; char e_sign = '\0'; int num_digits = 0; const FPTYPE *pos_pow = g_pos_pow; const FPTYPE *neg_pow = g_neg_pow; if (fp_iszero(f)) { e = 0; if (fmt == 'f') { // Truncate precision to prevent buffer overflow if (prec + 2 > buf_remaining) { prec = buf_remaining - 2; } num_digits = prec + 1; } else { // Truncate precision to prevent buffer overflow if (prec + 6 > buf_remaining) { prec = buf_remaining - 6; } if (fmt == 'e') { e_sign = '+'; } } } else if (fp_isless1(f)) { // We need to figure out what an integer digit will be used // in case 'f' is used (or we revert other format to it below). // As we just tested number to be <1, this is obviously 0, // but we can round it up to 1 below. char first_dig = '0'; if (f >= FPROUND_TO_ONE) { first_dig = '1'; } // Build negative exponent for (e = 0, e1 = FPDECEXP; e1; e1 >>= 1, pos_pow++, neg_pow++) { if (*neg_pow > f) { e += e1; f *= *pos_pow; } } char e_sign_char = '-'; if (fp_isless1(f) && f >= FPROUND_TO_ONE) { f = FPCONST(1.0); if (e == 0) { e_sign_char = '+'; } } else if (fp_isless1(f)) { e++; f *= FPCONST(10.0); } // If the user specified 'g' format, and e is <= 4, then we'll switch // to the fixed format ('f') if (fmt == 'f' || (fmt == 'g' && e <= 4)) { fmt = 'f'; dec = -1; *s++ = first_dig; if (org_fmt == 'g') { prec += (e - 1); } // truncate precision to prevent buffer overflow if (prec + 2 > buf_remaining) { prec = buf_remaining - 2; } num_digits = prec; if (num_digits) { *s++ = '.'; while (--e && num_digits) { *s++ = '0'; num_digits--; } } } else { // For e & g formats, we'll be printing the exponent, so set the // sign. e_sign = e_sign_char; dec = 0; if (prec > (buf_remaining - FPMIN_BUF_SIZE)) { prec = buf_remaining - FPMIN_BUF_SIZE; if (fmt == 'g') { prec++; } } } } else { // Build positive exponent for (e = 0, e1 = FPDECEXP; e1; e1 >>= 1, pos_pow++, neg_pow++) {