2022-12-18 02:15:58 +00:00
|
|
|
// SPDX-License-Identifier: ISC
|
|
|
|
#include "y16t.h"
|
2023-01-02 08:55:12 +00:00
|
|
|
#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;
|
2023-01-02 08:55:12 +00:00
|
|
|
*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);
|
2023-01-02 08:55:12 +00:00
|
|
|
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;
|
2023-01-02 08:55:12 +00:00
|
|
|
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;
|
2023-01-02 08:55:12 +00:00
|
|
|
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;
|
2023-01-02 08:55:12 +00:00
|
|
|
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
|
|
|
}
|