int ds_var_field_init(struct ds_var_field *dsvf, const char *filename) { if (0 > ds_var_field_free(dsvf)) return -1; if (0 > file_mapper_init(&dsvf->data, filename)) return -1; size_t file_size = file_mapper_size(&dsvf->data); struct ds_var_field_header *header; if (file_size < sizeof(struct ds_var_field_header) || (header = file_mapper_data(&dsvf->data))->ofs_table >= file_size) return LOGGER_ERROR("wrong size: %s", filename), file_mapper_free(&dsvf->data), -1; size_t ofs_table_size = file_size - header->ofs_table; if ((ofs_table_size & 7) > 0 || ofs_table_size < 8) return LOGGER_ERROR_FUNC("%s: corrupted data detected", filename), file_mapper_free(&dsvf->data), -1; dsvf->num_elements = (ofs_table_size / sizeof(size_t)) - 1; dsvf->ofs_table = file_mapper_data(&dsvf->data) + header->ofs_table; size_t ofs_table = dsvf->ofs_table[dsvf->num_elements] + (size_t)7; ofs_table &= ~((size_t)7); if (ofs_table != header->ofs_table) return LOGGER_ERROR_FUNC("%s: corrupted data detected", filename), file_mapper_free(&dsvf->data), -1; if (ds_type_var != header->type && ds_type_array != header->type) return LOGGER_ERROR_FUNC("%s: corrupted data detected, wrong type or unsupported", filename), file_mapper_free(&dsvf->data), -1; dsvf->array_el_size = (ds_type_array == header->type ? ds_type_to_size(header->element_type) : 0); return 0; }
int file_mapper_init(struct file_mapper *fm, const char *filename) { if (0 > file_mapper_free(fm)) return -1; int fd = open(filename, O_RDONLY | O_CLOEXEC); if (fd < 0) return LOGGER_PERROR_FUNC("open: %s", filename), -1; struct stat st; if (0 > fstat(fd, &st)) return LOGGER_PERROR_FUNC("fstat %s", filename), close(fd), -1; fm->size = st.st_size; fm->mem = (char *)mmap(NULL, vmbuf_align(fm->size), PROT_READ, MAP_SHARED, fd, 0); close(fd); if (MAP_FAILED == fm->mem) return LOGGER_PERROR_FUNC("mmap %s", filename), close(fd), fm->mem = NULL, -1; return 0; }
int ds_var_field_free(struct ds_var_field *dsvf) { return file_mapper_free(&dsvf->data); }