#include<kcreddbinternal.h>
#include<assert.h>
void kcdb_buf_new(kcdb_buf * buf, khm_size n_fields)
{
buf->buffer = PMALLOC(KCDB_BUF_CBBUF_INITIAL);
buf->cb_buffer = KCDB_BUF_CBBUF_INITIAL;
buf->cb_used = 0;
if(n_fields == KCDB_BUF_DEFAULT)
n_fields = KCDB_BUF_FIELDS_INITIAL;
assert(n_fields < KCDB_BUF_MAX_SLOTS);
buf->n_fields = n_fields;
buf->nc_fields = UBOUNDSS(n_fields, KCDB_BUF_FIELDS_INITIAL, KCDB_BUF_FIELDS_GROWTH);
buf->fields = PMALLOC(sizeof(buf->fields[0]) * buf->n_fields);
ZeroMemory(buf->fields, sizeof(buf->fields[0]) * buf->n_fields);
}
void kcdb_buf_delete(kcdb_buf * buf)
{
buf->cb_buffer = 0;
buf->cb_used = 0;
if(buf->buffer)
PFREE(buf->buffer);
buf->buffer = NULL;
buf->n_fields = 0;
buf->nc_fields = 0;
if(buf->fields)
PFREE(buf->fields);
buf->fields = NULL;
}
static void kcdb_buf_assert_size(kcdb_buf * buf, khm_size cbsize)
{
khm_size new_size;
void * new_buf;
assert(cbsize <= KHM_INT32_MAX);
if(cbsize <= buf->cb_buffer)
return;
new_size = UBOUNDSS(cbsize, KCDB_BUF_CBBUF_INITIAL, KCDB_BUF_CBBUF_GROWTH);
assert(new_size > buf->cb_buffer && new_size > 0);
new_buf = PMALLOC(new_size);
assert(new_buf != NULL);
memcpy(new_buf, buf->buffer, buf->cb_used);
PFREE(buf->buffer);
buf->buffer = new_buf;
}
void kcdb_buf_alloc(kcdb_buf * buf, khm_size slot, khm_ui_2 id, khm_size cbsize)
{
khm_size cbnew;
khm_ssize cbdelta;
khm_size cbold;
kcdb_buf_field * f;
cbnew = UBOUND32(cbsize);
assert(slot <= KCDB_BUF_APPEND);
if(slot == KCDB_BUF_APPEND) {
slot = kcdb_buf_slot_by_id(buf, id);
if(slot == KCDB_BUF_INVALID_SLOT)
slot = buf->n_fields;
}
assert(slot < KCDB_BUF_MAX_SLOTS);
if((slot + 1) > buf->nc_fields) {
kcdb_buf_field * nf;
khm_size ns;
ns = UBOUNDSS((slot + 1), KCDB_BUF_FIELDS_INITIAL, KCDB_BUF_FIELDS_GROWTH);
nf = PMALLOC(sizeof(buf->fields[0]) * ns);
memcpy(nf, buf->fields, sizeof(buf->fields[0]) * buf->n_fields);
if(ns > buf->n_fields)
memset(&(nf[buf->n_fields]), 0, sizeof(buf->fields[0]) * (ns - buf->n_fields));
PFREE(buf->fields);
buf->fields = nf;
buf->nc_fields = ns;
}
if((slot + 1) > buf->n_fields)
buf->n_fields = slot + 1;
f = &(buf->fields[slot]);
if(f->flags & KCDB_CREDF_FLAG_ALLOCD) {
cbold = UBOUND32(f->cbsize);
cbdelta = ((khm_ssize) cbnew) - (khm_ssize) cbold;
if(cbnew > cbold) {
kcdb_buf_assert_size(buf, buf->cb_used + cbdelta);
}
if(buf->cb_used > f->offset + cbold) {
khm_size i;
memmove(
((BYTE *) buf->buffer) + (f->offset + cbnew),
((BYTE *) buf->buffer) + (f->offset + cbold),
buf->cb_used - (f->offset + cbold));
for(i=0; i < (int) buf->n_fields; i++) {
if(i != slot &&
(buf->fields[i].flags & KCDB_CREDF_FLAG_ALLOCD) &&
buf->fields[i].offset > f->offset)
{
buf->fields[i].offset =
(khm_ui_4)(((khm_ssize) buf->fields[i].offset) + cbdelta);
}
}
}
buf->cb_used = (khm_size)(((khm_ssize) buf->cb_used) + cbdelta);
f->cbsize = (khm_ui_4) cbsize;
} else {
kcdb_buf_assert_size(buf, buf->cb_used + cbnew);
f->offset = (khm_ui_4) buf->cb_used;
f->cbsize = (khm_ui_4) cbsize;
buf->cb_used += cbnew;
}
if(cbsize == 0) {
f->flags &= ~KCDB_CREDF_FLAG_ALLOCD;
f->flags &= ~KCDB_CREDF_FLAG_DATA;
f->id = KCDB_BUFF_ID_INVALID;
} else {
f->flags |= KCDB_CREDF_FLAG_ALLOCD;
f->id = id;
}
}
void kcdb_buf_dup(kcdb_buf * dest, const kcdb_buf * src)
{
khm_size cb_buf;
khm_size nc_fields;
cb_buf = UBOUNDSS(src->cb_used, KCDB_BUF_CBBUF_INITIAL, KCDB_BUF_CBBUF_GROWTH);
#if 0
(src->cb_used <= kcdb_cred_initial_size)? kcdb_cred_initial_size:
kcdb_cred_initial_size +
(((src->cb_used - (kcdb_cred_initial_size + 1)) / kcdb_cred_growth_factor + 1) * kcdb_cred_growth_factor);
#endif
kcdb_buf_delete(dest);
dest->cb_buffer = cb_buf;
dest->cb_used = src->cb_used;
dest->buffer = PMALLOC(cb_buf);
memcpy(dest->buffer, src->buffer, src->cb_used);
nc_fields = UBOUNDSS(src->n_fields, KCDB_BUF_FIELDS_INITIAL, KCDB_BUF_FIELDS_GROWTH);
dest->nc_fields = nc_fields;
dest->n_fields = src->n_fields;
dest->fields = PMALLOC(nc_fields * sizeof(dest->fields[0]));
memcpy(dest->fields, src->fields, src->n_fields * sizeof(dest->fields[0]));
if(dest->n_fields < dest->nc_fields)
memset(&(dest->fields[dest->n_fields]), 0, (src->nc_fields - src->n_fields) * sizeof(dest->fields[0]));
}
void kcdb_buf_set_value(kcdb_buf * buf, khm_size slot, khm_ui_2 id, void * src, khm_size cb_src)
{
void * dest;
kcdb_buf_alloc(buf, slot, id, cb_src);
if(slot == KCDB_BUF_APPEND) {
slot = kcdb_buf_slot_by_id(buf, id);
if(slot == KCDB_BUF_INVALID_SLOT) {
#ifdef DEBUG
assert(FALSE);
#else
return;
#endif
}
}
if(kcdb_buf_exist(buf, slot)) {
dest = kcdb_buf_get(buf, slot);
memcpy(dest, src, cb_src);
buf->fields[slot].flags |= KCDB_CREDF_FLAG_DATA;
}
}
int kcdb_buf_exist(kcdb_buf * buf, khm_size slot)
{
if(slot >= buf->n_fields)
return 0;
return (buf->fields[slot].flags & KCDB_CREDF_FLAG_ALLOCD);
}
int kcdb_buf_val_exist(kcdb_buf * buf, khm_size slot)
{
if(slot >= buf->n_fields)
return 0;
return (buf->fields[slot].flags & KCDB_CREDF_FLAG_DATA);
}
void * kcdb_buf_get(kcdb_buf * buf, khm_size slot)
{
if(slot >= buf->n_fields ||
!(buf->fields[slot].flags & KCDB_CREDF_FLAG_ALLOCD))
return NULL;
return (((BYTE *) buf->buffer) + buf->fields[slot].offset);
}
khm_size kcdb_buf_size(kcdb_buf * buf, khm_size slot)
{
if(slot >= buf->n_fields ||
!(buf->fields[slot].flags & KCDB_CREDF_FLAG_ALLOCD))
return 0;
return (buf->fields[slot].cbsize);
}
void kcdb_buf_set_value_flag(kcdb_buf * buf, khm_size slot)
{
if(slot >= buf->n_fields ||
!(buf->fields[slot].flags & KCDB_CREDF_FLAG_ALLOCD))
return;
(buf->fields[slot].flags |= KCDB_CREDF_FLAG_DATA);
}
khm_size kcdb_buf_slot_by_id(kcdb_buf * buf, khm_ui_2 id)
{
int i;
for(i=0; i < (int) buf->n_fields; i++) {
if(buf->fields[i].id == id)
break;
}
if(i < (int) buf->n_fields)
return i;
else
return KCDB_BUF_INVALID_SLOT;
}
KHMEXP khm_int32 KHMAPI kcdb_buf_get_attr(
khm_handle record,
khm_int32 attr_id,
khm_int32 * attr_type,
void * buffer,
khm_size * pcb_buf)
{
if(kcdb_cred_is_active_cred(record))
return kcdb_cred_get_attr(record, attr_id, attr_type, buffer, pcb_buf);
else if(kcdb_is_active_identity(record))
return kcdb_identity_get_attr(record, attr_id, attr_type, buffer, pcb_buf);
else
return KHM_ERROR_INVALID_PARAM;
}
KHMEXP khm_int32 KHMAPI kcdb_buf_get_attrib(
khm_handle record,
const wchar_t * attr_name,
khm_int32 * attr_type,
void * buffer,
khm_size * pcb_buf)
{
if(kcdb_cred_is_active_cred(record))
return kcdb_cred_get_attrib(record, attr_name, attr_type, buffer, pcb_buf);
else if(kcdb_is_active_identity(record))
return kcdb_identity_get_attrib(record, attr_name, attr_type, buffer, pcb_buf);
else
return KHM_ERROR_INVALID_PARAM;
}
KHMEXP khm_int32 KHMAPI kcdb_buf_get_attr_string(
khm_handle record,
khm_int32 attr_id,
wchar_t * buffer,
khm_size * pcbbuf,
khm_int32 flags)
{
if(kcdb_cred_is_active_cred(record))
return kcdb_cred_get_attr_string(record, attr_id, buffer, pcbbuf, flags);
else if(kcdb_is_active_identity(record))
return kcdb_identity_get_attr_string(record, attr_id, buffer, pcbbuf, flags);
else
return KHM_ERROR_INVALID_PARAM;
}
KHMEXP khm_int32 KHMAPI kcdb_buf_get_attrib_string(
khm_handle record,
const wchar_t * attr_name,
wchar_t * buffer,
khm_size * pcbbuf,
khm_int32 flags)
{
if(kcdb_cred_is_active_cred(record))
return kcdb_cred_get_attrib_string(record, attr_name, buffer, pcbbuf, flags);
else if(kcdb_is_active_identity(record))
return kcdb_identity_get_attrib_string(record, attr_name, buffer, pcbbuf, flags);
else
return KHM_ERROR_INVALID_PARAM;
}
KHMEXP khm_int32 KHMAPI kcdb_buf_set_attr(
khm_handle record,
khm_int32 attr_id,
void * buffer,
khm_size cbbuf)
{
if(kcdb_cred_is_active_cred(record))
return kcdb_cred_set_attr(record, attr_id, buffer, cbbuf);
else if(kcdb_is_active_identity(record))
return kcdb_identity_set_attr(record, attr_id, buffer, cbbuf);
else
return KHM_ERROR_INVALID_PARAM;
}
KHMEXP khm_int32 KHMAPI kcdb_buf_set_attrib(
khm_handle record,
const wchar_t * attr_name,
void * buffer,
khm_size cbbuf)
{
if(kcdb_cred_is_active_cred(record))
return kcdb_cred_set_attrib(record, attr_name, buffer, cbbuf);
else if(kcdb_is_active_identity(record))
return kcdb_identity_set_attrib(record, attr_name, buffer, cbbuf);
else
return KHM_ERROR_INVALID_PARAM;
}
KHMEXP khm_int32 KHMAPI kcdb_buf_hold(khm_handle record)
{
if(kcdb_cred_is_active_cred(record))
return kcdb_cred_hold(record);
else if(kcdb_is_active_identity(record))
return kcdb_identity_hold(record);
else
return KHM_ERROR_INVALID_PARAM;
}
KHMEXP khm_int32 KHMAPI kcdb_buf_release(khm_handle record)
{
if(kcdb_cred_is_active_cred(record))
return kcdb_cred_release(record);
else if(kcdb_is_active_identity(record))
return kcdb_identity_release(record);
else
return KHM_ERROR_INVALID_PARAM;
}