universalservice/c89_relo.c

74 lines
1.7 KiB
C

/* Copyright (C) 2024 Peter McGoron
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program. If not, see
* <https://www.gnu.org/licenses/>.
*/
#include <string.h>
#include <assert.h>
#include "uns.h"
#include "internal/c89_relo.h"
typedef struct uns_c89_relo_hdr Hdr;
size_t uns_c89_relo_get_len(void *p)
{
Hdr *hdr = uns_c89_relo_get_hdr(p);
return (size_t)(hdr->len < 0 ? -hdr->len : hdr->len);
}
size_t uns_c89_relo_get_record_len(void *p)
{
Hdr *hdr = uns_c89_relo_get_hdr(p);
if (hdr->len > 0)
return 0;
return (size_t)(-hdr->len) / sizeof(void *);
}
void *uns_c89_relo_init(void *p, size_t len_size, int is_record)
{
Hdr *hdr = p;
assert(len_size < UNS_SWORD_MAX);
hdr->relo = NULL;
hdr->len = (uns_sword)len_size;
if (is_record)
hdr->len = -hdr->len;
return hdr + 1;
}
static void check_len(void *rec, size_t i)
{
assert(i * sizeof(void *) < uns_c89_relo_get_len(rec));
}
void uns_c89_relo_record_set(void *rec, size_t i, void *v)
{
check_len(rec, i);
memcpy((unsigned char *)rec + i*sizeof(void*), &v, sizeof(v));
}
void *uns_c89_relo_record_get(void *rec, size_t i)
{
void *v;
check_len(rec, i);
memcpy(&v, (unsigned char *)rec + i*sizeof(void*), sizeof(v));
return v;
}