spb.h
/*
* Copyright 2009 Red Hat Inc., Durham, North Carolina.
* All Rights Reserved.
*
* This library 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 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Authors:
* "Daniel Kopecek" <dkopecek@redhat.com>
*/
#pragma once
#ifndef SPB_H
#define SPB_H
#include <stddef.h>
#include <inttypes.h>
#include <common/util.h>
#define __XC(a, b) OSCAP_CONCAT(a, b)
#define _sym(n) __XC(__XC(_sym, __LINE__), n)
typedef uint32_t spb_flags_t;
#define SPB_FLAG_FREE 0x00000001
#define SPB_FLAG_JOIN 0x00000002
#define SPB_FLAG_FILE 0x00000004
typedef uint64_t spb_size_t;
#define SPB_SZ_FMT "%"PRIo64
typedef struct {
void *base; /* buffer base address */
spb_size_t gend; /* sparse buffer index of the last byte of this buffer */
} spb_item_t;
typedef struct {
spb_item_t *buffer; /* array of buffers representing the sparse buffer */
uint32_t btotal; /* number of buffer */
uint32_t balloc; /* number of allocated slots */
uint32_t bflags; /* flags - not used at the moment */
} spb_t;
#define SPB_DEFAULT_BALLOC 32 /* default number of pre-allocated slots */
#define SPB_BALLOC_HIGHTRESH 512 /* the number of new slots is doubled until this limit is reached */
#define SPB_BALLOC_ADD 32 /* number of slot to add when we reached the high threshold */
spb_t *spb_new (void *buffer, size_t buflen, uint32_t balloc);
void spb_free (spb_t *spb, spb_flags_t flags);
uint32_t spb_bindex (spb_t *spb, spb_size_t index);
spb_size_t spb_size (spb_t *spb);
#define spb_iterate_oct(spb, start, end, name) /* TODO */ while(0)
#define spb_iterate(spb, start, name, icode) \
do { \
spb_size_t _sym(istart) = (start); \
spb_t *_sym(ispb) = (spb); \
uint32_t _sym(idx) = spb_bindex(_sym(ispb), _sym(istart)); \
size_t _sym(l_off) = (size_t)(_sym(idx) > 0 ? start - _sym(ispb)->buffer[_sym(idx) - 1].gend - 1 : start); \
\
for (; _sym(idx) < _sym(ispb)->btotal; ++_sym(idx)) { \
register size_t _sym(l); \
register uint8_t *_sym(b); \
\
_sym(l) = (size_t)(_sym(idx) > 0 ? \
_sym(ispb)->buffer[_sym(idx)].gend - _sym(ispb)->buffer[_sym(idx) - 1].gend : \
_sym(ispb)->buffer[_sym(idx)].gend + 1) - _sym(l_off); \
_sym(b) = ((uint8_t *)(_sym(ispb)->buffer[_sym(idx)].base)) + _sym(l_off); \
\
for (; _sym(l) > 0; --_sym(l), ++_sym(b)) { \
(name) = *_sym(b); \
icode; \
} \
\
if (_sym(l) > 0) \
break; \
\
_sym(l_off) = 0; \
} \
} while (0)
int spb_add (spb_t *spb, void *buffer, size_t buflen);
int spb_pick (spb_t *spb, spb_size_t start, spb_size_t size, void *dst);
int spb_pick_raw (spb_t *spb, uint32_t bindex, spb_size_t start, spb_size_t size, void *dst);
int spb_pick_cb (spb_t *spb, spb_size_t start, spb_size_t size, void *cb (void *, void *, size_t), void *cbarg);
spb_size_t spb_drop_head (spb_t *spb, spb_size_t size, spb_flags_t flags);
uint8_t spb_octet (spb_t *spb, spb_size_t idx);
const uint8_t *spb_direct (spb_t *spb, spb_size_t start, spb_size_t size);
#endif /* SPB_H */