y16t/idx.c

104 lines
2 KiB
C
Raw Normal View History

2022-12-18 02:15:58 +00:00
// SPDX-License-Identifier: ISC
#include "y16t.h"
#include "y16t_internal.h"
2022-12-18 02:15:58 +00:00
#include <arpa/inet.h>
2023-01-01 00:26:17 +00:00
#include <errno.h>
2022-12-18 02:15:58 +00:00
2023-01-01 00:26:17 +00:00
static __attribute__((pure))
uint32_t y16t_table_at(const uint8_t x, const uint8_t y)
{
2023-01-02 08:33:51 +00:00
return y16t_hilbert_xy2d(1 << 16, x, y) << 2;
2023-01-01 00:26:17 +00:00
}
int y16t_idx_lookup(
FILE *fh,
uint8_t x,
uint8_t y,
uint32_t *result
) {
2023-01-02 08:33:51 +00:00
const long key = y16t_table_at(x, y);
2023-01-01 00:26:17 +00:00
2023-01-02 08:33:51 +00:00
if(key && fseek(fh, key, SEEK_CUR) == -1)
2023-01-01 00:26:17 +00:00
return -EIO;
if(fread(result, 4, 1, fh) != 1)
return -EIO;
*result = ntohl(*result);
2023-01-02 08:33:51 +00:00
if(key && fseek(fh, -key, SEEK_CUR) == -1)
return -EIO;
2023-01-01 00:26:17 +00:00
return 0;
}
int y16t_idx_update(
FILE *fh,
const uint8_t x,
const uint8_t y,
const uint32_t newval
2022-12-18 02:15:58 +00:00
) {
2023-01-02 08:33:51 +00:00
const long key = y16t_table_at(x, y);
const uint32_t odval = htonl(newval);
2023-01-01 00:26:17 +00:00
2023-01-02 08:33:51 +00:00
if(key && fseek(fh, key, SEEK_CUR) == -1)
2023-01-01 00:26:17 +00:00
return -EIO;
if(fwrite(&odval, 4, 1, fh) != 1)
2023-01-01 00:26:17 +00:00
return -EIO;
2023-01-02 08:33:51 +00:00
if(key && fseek(fh, -key, SEEK_CUR) == -1)
return -EIO;
2023-01-01 00:26:17 +00:00
return 0;
2022-12-18 02:15:58 +00:00
}
2023-01-01 00:26:17 +00:00
int y16t_idx_foreach_x(
FILE *fh,
uint8_t y,
int (*callback)(uint32_t, void*),
void *context
2022-12-18 02:15:58 +00:00
) {
2023-01-02 08:33:51 +00:00
long offset = 0;
2023-01-01 00:26:17 +00:00
for (uint16_t x = 0; x < 0xff; ++x) {
uint32_t value = 0;
2023-01-02 08:33:51 +00:00
const uint32_t key = y16t_table_at(x, y);
const long delta = ((long)key) - offset;
if(delta && fseek(fh, delta, SEEK_CUR) == -1)
return -EIO;
offset = key;
if(fread(&value, 4, 1, fh) != 1)
return -EIO;
int tmp = callback(ntohl(value), context);
if(tmp) return tmp;
2022-12-18 02:15:58 +00:00
}
2023-01-02 08:33:51 +00:00
if(offset && fseek(fh, -offset, SEEK_CUR) == -1)
return -EIO;
2023-01-01 00:26:17 +00:00
return 0;
}
2022-12-18 02:15:58 +00:00
2023-01-01 00:26:17 +00:00
int y16t_idx_foreach_y(
FILE *fh,
uint8_t x,
int (*callback)(uint32_t, void*),
void *context
) {
2023-01-02 08:33:51 +00:00
long offset = 0;
2023-01-01 00:26:17 +00:00
for (uint16_t y = 0; y < 0xff; ++y) {
uint32_t value = 0;
2023-01-02 08:33:51 +00:00
const uint32_t key = y16t_table_at(x, y);
const long delta = ((long)key) - offset;
if(delta && fseek(fh, delta, SEEK_CUR) == -1)
return -EIO;
offset = key;
if(fread(&value, 4, 1, fh) != 1)
return -EIO;
int tmp = callback(ntohl(value), context);
if(tmp) return tmp;
2023-01-01 00:26:17 +00:00
}
2023-01-02 08:33:51 +00:00
if(offset && fseek(fh, -offset, SEEK_CUR) == -1)
return -EIO;
2023-01-01 00:26:17 +00:00
return 0;
2022-12-18 02:15:58 +00:00
}