initial commit
This commit is contained in:
commit
1615b45d78
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
.#*
|
||||||
|
build
|
||||||
|
result
|
||||||
|
result-*
|
15
LICENSE
Normal file
15
LICENSE
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
ISC License
|
||||||
|
|
||||||
|
Copyright 2018 - 2023 Alain Zscheile <zseri.devel@ytrizja.de>
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any purpose
|
||||||
|
with or without fee is hereby granted, provided that the above copyright notice
|
||||||
|
and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||||
|
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||||
|
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||||
|
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||||
|
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
THIS SOFTWARE.
|
22
meson.build
Normal file
22
meson.build
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
project('y16t 16-field quad tree library', 'c',
|
||||||
|
default_options : ['c_std=c17'],
|
||||||
|
version : '0.0.0'
|
||||||
|
license : 'Apache-2.0',
|
||||||
|
meson_version : '>=0.50')
|
||||||
|
|
||||||
|
install_headers('y16t.h')
|
||||||
|
|
||||||
|
liby16t = shared_library('y16t',
|
||||||
|
files('y16t.c'),
|
||||||
|
version : '0.0.0',
|
||||||
|
c_args : ['-fno-plt', '-fno-unwind-tables', '-fno-exceptions', '-Werror=return-type'],
|
||||||
|
include_directories : include_directories('.')
|
||||||
|
install : true)
|
||||||
|
|
||||||
|
pkg_mod = import('pkgconfig')
|
||||||
|
pkg_mod.generate(
|
||||||
|
libraries : [liby16t],
|
||||||
|
version : meson.project_version(),
|
||||||
|
name : 'liby16t',
|
||||||
|
filebase : 'y16t',
|
||||||
|
description : 'y16t 16-field quad tree library')
|
38
y16t.c
Normal file
38
y16t.c
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
// SPDX-License-Identifier: ISC
|
||||||
|
#include "y16t.h"
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
// conversion to ις-points interleaved coordinates
|
||||||
|
static __attribute__((pure))
|
||||||
|
uint8_t y16t_loc2blk_coords(
|
||||||
|
const y16t_location_t loc, const uint32_t offset
|
||||||
|
) {
|
||||||
|
const uint32_t byteoffset = offset / 4;
|
||||||
|
const uint8_t shiftval = 2 * (3 - offset % 4);
|
||||||
|
const uint8_t xres = (loc.x[byteoffset] >> shiftval) & 3;
|
||||||
|
const uint8_t yres = (loc.y[byteoffset] >> shiftval) & 3;
|
||||||
|
return (xres << 2) | yres;
|
||||||
|
}
|
||||||
|
|
||||||
|
void y16t_lookup(
|
||||||
|
y16t_lookup_t * ret,
|
||||||
|
const uint32_t * data,
|
||||||
|
const size_t datalen,
|
||||||
|
const y16t_location_t * loc
|
||||||
|
) {
|
||||||
|
// data_endblk is set to the first byte which doesn't constitute a full block
|
||||||
|
const size_t datalen_blks = datalen / 16;
|
||||||
|
const y16t_location_t loc_ = *loc;
|
||||||
|
size_t datoffset = ret->datoffset;
|
||||||
|
|
||||||
|
for ( ; /* bounds checks */ ret->inpoffset < loc_.xylen && datoffset < datalen_blks; ) {
|
||||||
|
datoffset = ntohl(data[16 * datoffset + y16t_loc2blk_coords(loc_, ret->inpoffset)]);
|
||||||
|
ret->inpoffset += 1;
|
||||||
|
if(0 == datoffset) {
|
||||||
|
// NULL pointer
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret->datoffset = datoffset;
|
||||||
|
}
|
34
y16t.h
Normal file
34
y16t.h
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
// SPDX-License-Identifier: ISC
|
||||||
|
#pragma once
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t *x;
|
||||||
|
uint8_t *y;
|
||||||
|
// x and y should have the same length, and xylen = bytescount * 4
|
||||||
|
uint32_t xylen;
|
||||||
|
} y16t_location_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
// the offset indicates how far the lookup could traverse the tree
|
||||||
|
uint32_t inpoffset;
|
||||||
|
|
||||||
|
// the final data pointer, it doesn't have to be aligned to block boundaries
|
||||||
|
// if it ends up at the starting point, but the offset isn't 0,
|
||||||
|
// then a NULL pointer was hit
|
||||||
|
size_t datoffset;
|
||||||
|
} y16t_lookup_t;
|
||||||
|
|
||||||
|
// @param ret ... the starting point; gets updated to the latest via the given path
|
||||||
|
// reachable point
|
||||||
|
// @param data ... a pointer to a mmap-ed file. we convert pointers inside of the file
|
||||||
|
// from network byte order to host byte order before following them.
|
||||||
|
// @param datalen ... the length of the block that data points to, in 4 byte units (= file size in bytes / 4)
|
||||||
|
__attribute__((pure, nonnull))
|
||||||
|
void y16t_lookup(
|
||||||
|
y16t_lookup_t * ret,
|
||||||
|
const uint32_t * data,
|
||||||
|
const size_t datalen,
|
||||||
|
const y16t_location_t * loc
|
||||||
|
);
|
Loading…
Reference in a new issue