2 * Copyright (c) 2005 Massachusetts Institute of Technology
\r
4 * Permission is hereby granted, free of charge, to any person
\r
5 * obtaining a copy of this software and associated documentation
\r
6 * files (the "Software"), to deal in the Software without
\r
7 * restriction, including without limitation the rights to use, copy,
\r
8 * modify, merge, publish, distribute, sublicense, and/or sell copies
\r
9 * of the Software, and to permit persons to whom the Software is
\r
10 * furnished to do so, subject to the following conditions:
\r
12 * The above copyright notice and this permission notice shall be
\r
13 * included in all copies or substantial portions of the Software.
\r
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
\r
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
\r
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
\r
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
\r
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
\r
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
\r
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
\r
27 #include<kcreddbinternal.h>
\r
30 void kcdb_buf_new(kcdb_buf * buf, khm_size n_fields)
\r
32 buf->buffer = PMALLOC(KCDB_BUF_CBBUF_INITIAL);
\r
33 buf->cb_buffer = KCDB_BUF_CBBUF_INITIAL;
\r
36 if(n_fields == KCDB_BUF_DEFAULT)
\r
37 n_fields = KCDB_BUF_FIELDS_INITIAL;
\r
39 assert(n_fields < KCDB_BUF_MAX_SLOTS);
\r
41 buf->n_fields = n_fields;
\r
42 buf->nc_fields = UBOUNDSS(n_fields, KCDB_BUF_FIELDS_INITIAL, KCDB_BUF_FIELDS_GROWTH);
\r
43 buf->fields = PMALLOC(sizeof(buf->fields[0]) * buf->n_fields);
\r
44 ZeroMemory(buf->fields, sizeof(buf->fields[0]) * buf->n_fields);
\r
47 void kcdb_buf_delete(kcdb_buf * buf)
\r
62 static void kcdb_buf_assert_size(kcdb_buf * buf, khm_size cbsize)
\r
67 /* should be less than or equal to the max signed 32 bit int */
\r
68 assert(cbsize <= KHM_INT32_MAX);
\r
69 if(cbsize <= buf->cb_buffer)
\r
72 new_size = UBOUNDSS(cbsize, KCDB_BUF_CBBUF_INITIAL, KCDB_BUF_CBBUF_GROWTH);
\r
74 assert(new_size > buf->cb_buffer && new_size > 0);
\r
76 new_buf = PMALLOC(new_size);
\r
77 assert(new_buf != NULL);
\r
79 memcpy(new_buf, buf->buffer, buf->cb_used);
\r
81 buf->buffer = new_buf;
\r
84 void kcdb_buf_alloc(kcdb_buf * buf, khm_size slot, khm_ui_2 id, khm_size cbsize)
\r
91 cbnew = UBOUND32(cbsize);
\r
93 assert(slot <= KCDB_BUF_APPEND);
\r
95 if(slot == KCDB_BUF_APPEND) {
\r
96 slot = kcdb_buf_slot_by_id(buf, id);
\r
97 if(slot == KCDB_BUF_INVALID_SLOT)
\r
98 slot = buf->n_fields;
\r
101 assert(slot < KCDB_BUF_MAX_SLOTS);
\r
103 if((slot + 1) > buf->nc_fields) {
\r
104 kcdb_buf_field * nf;
\r
107 ns = UBOUNDSS((slot + 1), KCDB_BUF_FIELDS_INITIAL, KCDB_BUF_FIELDS_GROWTH);
\r
109 nf = PMALLOC(sizeof(buf->fields[0]) * ns);
\r
110 memcpy(nf, buf->fields, sizeof(buf->fields[0]) * buf->n_fields);
\r
112 if(ns > buf->n_fields)
\r
113 memset(&(nf[buf->n_fields]), 0, sizeof(buf->fields[0]) * (ns - buf->n_fields));
\r
115 PFREE(buf->fields);
\r
117 buf->nc_fields = ns;
\r
120 if((slot + 1) > buf->n_fields)
\r
121 buf->n_fields = slot + 1;
\r
123 f = &(buf->fields[slot]);
\r
125 if(f->flags & KCDB_CREDF_FLAG_ALLOCD) {
\r
126 /* there's already an allocation. we have to resize it to
\r
127 accomodate the new size */
\r
128 cbold = UBOUND32(f->cbsize);
\r
129 /* demote before substraction */
\r
130 cbdelta = ((khm_ssize) cbnew) - (khm_ssize) cbold;
\r
132 if(cbnew > cbold) {
\r
133 kcdb_buf_assert_size(buf, buf->cb_used + cbdelta);
\r
136 if(buf->cb_used > f->offset + cbold) {
\r
140 ((BYTE *) buf->buffer) + (f->offset + cbnew),
\r
141 ((BYTE *) buf->buffer) + (f->offset + cbold),
\r
142 buf->cb_used - (f->offset + cbold));
\r
144 for(i=0; i < (int) buf->n_fields; i++) {
\r
146 (buf->fields[i].flags & KCDB_CREDF_FLAG_ALLOCD) &&
\r
147 buf->fields[i].offset > f->offset)
\r
149 buf->fields[i].offset =
\r
150 (khm_ui_4)(((khm_ssize) buf->fields[i].offset) + cbdelta);
\r
155 /* demote integer before adding signed quantity */
\r
156 buf->cb_used = (khm_size)(((khm_ssize) buf->cb_used) + cbdelta);
\r
158 f->cbsize = (khm_ui_4) cbsize;
\r
161 kcdb_buf_assert_size(buf, buf->cb_used + cbnew);
\r
162 f->offset = (khm_ui_4) buf->cb_used;
\r
163 f->cbsize = (khm_ui_4) cbsize;
\r
164 buf->cb_used += cbnew;
\r
168 f->flags &= ~KCDB_CREDF_FLAG_ALLOCD;
\r
169 f->flags &= ~KCDB_CREDF_FLAG_DATA;
\r
170 f->id = KCDB_BUFF_ID_INVALID;
\r
172 f->flags |= KCDB_CREDF_FLAG_ALLOCD;
\r
177 void kcdb_buf_dup(kcdb_buf * dest, const kcdb_buf * src)
\r
180 khm_size nc_fields;
\r
182 cb_buf = UBOUNDSS(src->cb_used, KCDB_BUF_CBBUF_INITIAL, KCDB_BUF_CBBUF_GROWTH);
\r
184 /* replaced by UBOUNDSS() above */
\r
185 (src->cb_used <= kcdb_cred_initial_size)? kcdb_cred_initial_size:
\r
186 kcdb_cred_initial_size +
\r
187 (((src->cb_used - (kcdb_cred_initial_size + 1)) / kcdb_cred_growth_factor + 1) * kcdb_cred_growth_factor);
\r
190 kcdb_buf_delete(dest);
\r
192 dest->cb_buffer = cb_buf;
\r
193 dest->cb_used = src->cb_used;
\r
194 dest->buffer = PMALLOC(cb_buf);
\r
195 memcpy(dest->buffer, src->buffer, src->cb_used);
\r
197 nc_fields = UBOUNDSS(src->n_fields, KCDB_BUF_FIELDS_INITIAL, KCDB_BUF_FIELDS_GROWTH);
\r
198 dest->nc_fields = nc_fields;
\r
199 dest->n_fields = src->n_fields;
\r
200 dest->fields = PMALLOC(nc_fields * sizeof(dest->fields[0]));
\r
201 memcpy(dest->fields, src->fields, src->n_fields * sizeof(dest->fields[0]));
\r
202 if(dest->n_fields < dest->nc_fields)
\r
203 memset(&(dest->fields[dest->n_fields]), 0, (src->nc_fields - src->n_fields) * sizeof(dest->fields[0]));
\r
206 void kcdb_buf_set_value(kcdb_buf * buf, khm_size slot, khm_ui_2 id, void * src, khm_size cb_src)
\r
209 kcdb_buf_alloc(buf, slot, id, cb_src);
\r
210 if(slot == KCDB_BUF_APPEND) {
\r
211 slot = kcdb_buf_slot_by_id(buf, id);
\r
212 if(slot == KCDB_BUF_INVALID_SLOT) {
\r
220 if(kcdb_buf_exist(buf, slot)) {
\r
221 dest = kcdb_buf_get(buf, slot);
\r
222 memcpy(dest, src, cb_src);
\r
224 buf->fields[slot].flags |= KCDB_CREDF_FLAG_DATA;
\r
228 int kcdb_buf_exist(kcdb_buf * buf, khm_size slot)
\r
230 if(slot >= buf->n_fields)
\r
232 return (buf->fields[slot].flags & KCDB_CREDF_FLAG_ALLOCD);
\r
235 int kcdb_buf_val_exist(kcdb_buf * buf, khm_size slot)
\r
237 if(slot >= buf->n_fields)
\r
239 return (buf->fields[slot].flags & KCDB_CREDF_FLAG_DATA);
\r
242 void * kcdb_buf_get(kcdb_buf * buf, khm_size slot)
\r
244 if(slot >= buf->n_fields ||
\r
245 !(buf->fields[slot].flags & KCDB_CREDF_FLAG_ALLOCD))
\r
247 return (((BYTE *) buf->buffer) + buf->fields[slot].offset);
\r
250 khm_size kcdb_buf_size(kcdb_buf * buf, khm_size slot)
\r
252 if(slot >= buf->n_fields ||
\r
253 !(buf->fields[slot].flags & KCDB_CREDF_FLAG_ALLOCD))
\r
255 return (buf->fields[slot].cbsize);
\r
258 void kcdb_buf_set_value_flag(kcdb_buf * buf, khm_size slot)
\r
260 if(slot >= buf->n_fields ||
\r
261 !(buf->fields[slot].flags & KCDB_CREDF_FLAG_ALLOCD))
\r
264 (buf->fields[slot].flags |= KCDB_CREDF_FLAG_DATA);
\r
267 khm_size kcdb_buf_slot_by_id(kcdb_buf * buf, khm_ui_2 id)
\r
271 for(i=0; i < (int) buf->n_fields; i++) {
\r
272 if(buf->fields[i].id == id)
\r
276 if(i < (int) buf->n_fields)
\r
279 return KCDB_BUF_INVALID_SLOT;
\r
282 /* API for accessing generic buffers */
\r
284 KHMEXP khm_int32 KHMAPI kcdb_buf_get_attr(
\r
285 khm_handle record,
\r
286 khm_int32 attr_id,
\r
287 khm_int32 * attr_type,
\r
289 khm_size * pcb_buf)
\r
291 if(kcdb_cred_is_active_cred(record))
\r
292 return kcdb_cred_get_attr(record, attr_id, attr_type, buffer, pcb_buf);
\r
293 else if(kcdb_is_active_identity(record))
\r
294 return kcdb_identity_get_attr(record, attr_id, attr_type, buffer, pcb_buf);
\r
296 return KHM_ERROR_INVALID_PARAM;
\r
299 KHMEXP khm_int32 KHMAPI kcdb_buf_get_attrib(
\r
301 wchar_t * attr_name,
\r
302 khm_int32 * attr_type,
\r
304 khm_size * pcb_buf)
\r
306 if(kcdb_cred_is_active_cred(record))
\r
307 return kcdb_cred_get_attrib(record, attr_name, attr_type, buffer, pcb_buf);
\r
308 else if(kcdb_is_active_identity(record))
\r
309 return kcdb_identity_get_attrib(record, attr_name, attr_type, buffer, pcb_buf);
\r
311 return KHM_ERROR_INVALID_PARAM;
\r
314 KHMEXP khm_int32 KHMAPI kcdb_buf_get_attr_string(
\r
321 if(kcdb_cred_is_active_cred(record))
\r
322 return kcdb_cred_get_attr_string(record, attr_id, buffer, pcbbuf, flags);
\r
323 else if(kcdb_is_active_identity(record))
\r
324 return kcdb_identity_get_attr_string(record, attr_id, buffer, pcbbuf, flags);
\r
326 return KHM_ERROR_INVALID_PARAM;
\r
329 KHMEXP khm_int32 KHMAPI kcdb_buf_get_attrib_string(
\r
331 wchar_t * attr_name,
\r
336 if(kcdb_cred_is_active_cred(record))
\r
337 return kcdb_cred_get_attrib_string(record, attr_name, buffer, pcbbuf, flags);
\r
338 else if(kcdb_is_active_identity(record))
\r
339 return kcdb_identity_get_attrib_string(record, attr_name, buffer, pcbbuf, flags);
\r
341 return KHM_ERROR_INVALID_PARAM;
\r
344 KHMEXP khm_int32 KHMAPI kcdb_buf_set_attr(
\r
350 if(kcdb_cred_is_active_cred(record))
\r
351 return kcdb_cred_set_attr(record, attr_id, buffer, cbbuf);
\r
352 else if(kcdb_is_active_identity(record))
\r
353 return kcdb_identity_set_attr(record, attr_id, buffer, cbbuf);
\r
355 return KHM_ERROR_INVALID_PARAM;
\r
358 KHMEXP khm_int32 KHMAPI kcdb_buf_set_attrib(
\r
360 wchar_t * attr_name,
\r
364 if(kcdb_cred_is_active_cred(record))
\r
365 return kcdb_cred_set_attrib(record, attr_name, buffer, cbbuf);
\r
366 else if(kcdb_is_active_identity(record))
\r
367 return kcdb_identity_set_attrib(record, attr_name, buffer, cbbuf);
\r
369 return KHM_ERROR_INVALID_PARAM;
\r
372 KHMEXP khm_int32 KHMAPI kcdb_buf_hold(khm_handle record)
\r
374 if(kcdb_cred_is_active_cred(record))
\r
375 return kcdb_cred_hold(record);
\r
376 else if(kcdb_is_active_identity(record))
\r
377 return kcdb_identity_hold(record);
\r
379 return KHM_ERROR_INVALID_PARAM;
\r
382 KHMEXP khm_int32 KHMAPI kcdb_buf_release(khm_handle record)
\r
384 if(kcdb_cred_is_active_cred(record))
\r
385 return kcdb_cred_release(record);
\r
386 else if(kcdb_is_active_identity(record))
\r
387 return kcdb_identity_release(record);
\r
389 return KHM_ERROR_INVALID_PARAM;
\r