/* * DbRecord_field -- * Fill in an individual field of the DbRecord. */ static int DbRecord_field( DbRecord *recordp, u_int field, void *addr, datatype type) { size_t len; char number_buf[20]; /* * The offset table is 0-based, the field numbers are 1-based. * Correct. */ --field; switch (type) { case NOTSET: /* NOTREACHED */ abort(); break; case STRING: *((u_char **)addr) = recordp->record + recordp->offset[field]; recordp->record[recordp->offset[field] + OFFSET_LEN(recordp->offset, field)] = '\0'; break; case DOUBLE: case UNSIGNED_LONG: /* This shouldn't be possible -- 2^32 is only 10 digits. */ len = OFFSET_LEN(recordp->offset, field); if (len > sizeof(number_buf) - 1) { dbenv->errx(dbenv, "record %lu field %lu: numeric field is %lu bytes and too large to copy", recordp->recno, field, (u_long)len); return (1); } memcpy(number_buf, recordp->record + recordp->offset[field], len); number_buf[len] = '\0'; if (type == DOUBLE) { if (len == 0) *(double *)addr = 0; else if (strtod_err(number_buf, (double *)addr) != 0) goto fmt_err; } else if (len == 0) *(u_long *)addr = 0; else if (strtoul_err(number_buf, (u_long *)addr) != 0) { fmt_err: dbenv->errx(dbenv, "record %lu: numeric field %u error: %s", recordp->recno, field, number_buf); return (1); } break; } return (0); }
/* * entry_print -- * Display the primary database's data item. */ int entry_print(void *data, size_t len, u_int32_t field_count) { u_int32_t a, *offset; u_int i; char *raw; memcpy(&a, data, sizeof(u_int32_t)); printf("\tversion: %lu\n", (u_long)a); offset = (u_int32_t *)data + 1; if (field_count == 0) { memcpy(&a, offset++, sizeof(u_int32_t)); printf("\tcolumn map: %lu fields: {%.*s}\n", (u_long)a, (int)(len - 2 * sizeof(u_int32_t)), (u_int8_t *)data + 2 * sizeof(u_int32_t)); } else { raw = (char *)(offset + (field_count + 1)); for (i = 0; i < field_count; ++i) { memcpy(&a, &offset[i], sizeof(u_int32_t)); len = OFFSET_LEN(offset, i); printf("\toffset %4lu: len %4lu: {%.*s}\n", (u_long)offset[i], (u_long)len, (int)len, raw + a); } } return (0); }
/* * input_set_offset -- * Build an offset table and record combination. */ static int input_set_offset(u_int32_t *put_line, char *input_line, size_t len, u_int32_t field_count) { u_int32_t *op; int quoted; char *p, *endp; op = put_line; /* The first field is the version number. */ *op++ = version; /* * Walk the input line, looking for comma separators. It's an error * to have too many or too few fields. */ *op++ = 0; quoted = 0; for (p = input_line, endp = input_line + len;; ++p) { if (ifmt == FORMAT_EXCEL && p < endp) { if (*p == '"') quoted = !quoted; if (quoted) continue; } if (*p == ',' || p == endp) { if (field_count == 0) { dbenv->errx(dbenv, "record %lu: too many fields in the record", record_count); return (1); } --field_count; *op++ = (u_int32_t)(p - input_line) + 1; if (verbose > 1) dbenv->errx(dbenv, "offset %lu: {%.*s}", op[-1], OFFSET_LEN(op, -2), input_line + op[-2]); /* * Don't insert a new field if the input lines ends * in a comma. */ if (p == endp || p + 1 == endp) break; } } *op++ = (u_int32_t)(p - input_line); if (field_count != 0) { dbenv->errx(dbenv, "record %lu: not enough fields in the record", record_count); return (1); } memcpy(op, input_line, len); return (0); }