⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 data.c

📁 PIXIL is a small footprint operating environment, complete with PDA PIM applications, a browser and
💻 C
字号:
/*                                                                        * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.      *                                                                        * This file is part of the PIXIL Operating Environment                  *                                                                        * The use, copying and distribution of this file is governed by one     * of two licenses, the PIXIL Commercial License, or the GNU General     * Public License, version 2.                                            *                                                                        * Licensees holding a valid PIXIL Commercial License may use this file  * in accordance with the PIXIL Commercial License Agreement provided    * with the Software. Others are governed under the terms of the GNU    * General Public License version 2.                                     *                                                                        * This file may be distributed and/or modified under the terms of the   * GNU General Public License version 2 as published by the Free         * Software Foundation and appearing in the file LICENSE.GPL included    * in the packaging of this file.                                       *                                                                        * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING   * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A             * PARTICULAR PURPOSE.                                                   *                                                                        * RESTRICTED RIGHTS LEGEND                                              *                                                                      * Use, duplication, or disclosure by the government is subject to       * restriction as set forth in paragraph (b)(3)(b) of the Rights in      * Technical Data and Computer Software clause in DAR 7-104.9(a).        *                                                                       * See http://www.pixil.org/gpl/ for GPL licensing        * information.                                                          *                                                                       * See http://www.pixil.org/license.html or               * email cetsales@centurysoftware.com for information about the PIXIL    * Commercial License Agreement, or if any conditions of this licensing  * are not clear to you.                                                 *//* Given a new data block, this will format the block for inital use */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <par/pardb.h>#include "database.h"#ifdef DEBUG#define DPRINT(str, args...) printf("DEBUG: " str, ## args)#else#define DPRINT(str, args...)#endif#define GET_DATA_INFO(block)  ((data_info_t *) block)#define GET_FREE_SPACE(db, offset) (db->blkSize - offset)voiddb_formatData(db_handle * db, void *block, int offset, int size){    void *start = (void *) (block + offset);    data_info_t *info = (data_info_t *) start;    bzero(start, size);    info->ident = DB_DATA_BLOCK;    info->free = offset + sizeof(data_info_t);    info->next = 0;}/* Add a new data node to the system */static data_t *db_newDataNode(db_handle * db, index_t * index, unsigned short size,	       unsigned short type){    void *block;    data_t *data;    data_info_t *info = 0;    int offset;#ifdef HAVE_MMAPBUG    /* We need to align the size so malloc accesses are correct */    if ((size % 4))	size += (4 - (size % 4));#endif    if (db->dataCache)	offset = db->dataCache;    else	offset = db->data;    while (offset) {	DPRINT("Mapping block %d in db_newDataNode()\n",	       GET_BLOCK(db, offset));	if (!(block = db_mapBlock(db, GET_BLOCK(db, offset))))	    return (0);	info = GET_DATA_INFO(block);	if (GET_FREE_SPACE(db, info->free) > (size + DATA_ITEM_LEN))	    goto initData;	offset = info->next;    }    if (!info)	return (0);    if (!(info->next = db_addBlock(db)))	return (0);    DPRINT("Mapping block %d in db_newDataNode()\n",	   GET_BLOCK(db, info->next));    block = db_mapBlock(db, GET_BLOCK(db, info->next));    if (!block)	return (0);    /* Format the new index block */    db_formatData(db, block, 0, db->blkSize);    info = GET_DATA_INFO(block);  initData:    data = (data_t *) ((ulong) block + info->free);    data->type = type;    data->size = (unsigned short) size;    data->index = db_getFileOffset(db, index);    index->data = db_getFileOffset(db, data);    info->free += size + DATA_ITEM_LEN;    SET_ERRNO(PARDB_SUCCESS);    return (data);}static data_t *db_getDataNode(db_handle * db, int offset){    void *block;    if (!offset)	return (0);    DPRINT("Mapping block %d in db_getDataNode()\n", GET_BLOCK(db, offset));    block = db_mapBlock(db, GET_BLOCK(db, offset));    if (!block)	return (0);    SET_ERRNO(PARDB_SUCCESS);    return ((data_t *) (block + GET_BLOCK_OFFSET(db, offset)));}/* Given a start and a offset, move the rest of the data block */static voiddb_moveData(db_handle * db, void *block, int start, int offset){    int ptr = start;    data_info_t *info = GET_DATA_INFO(block);    int length;    void *src, *dest;    /* First, go through and update all of the index blocks */    ptr = GET_BLOCK_OFFSET(db, start);    while (ptr < info->free) {	data_t *local = (data_t *) (block + ptr);	db_setIndexDataOffset(db, local->index,			      GET_BLOCK(db, start) + ptr + offset);	ptr += (local->size + DATA_ITEM_LEN);    }    length = info->free - GET_BLOCK_OFFSET(db, start);    src = (void *) (block + GET_BLOCK_OFFSET(db, start));    dest = (void *) (block + GET_BLOCK_OFFSET(db, start) + offset);    /* Now, actually move the block */    memmove(dest, src, length);    /* Update the free block here */    info->free += offset;}intdb_removeData(db_handle * db, int offset){    void *block;    data_t *data;    if (!offset) {	SET_ERRNO(PARDB_BADOFFSET);	return (-1);    }    DPRINT("Mapping block %d in db_removeData()\n", GET_BLOCK(db, offset));    block = db_mapBlock(db, GET_BLOCK(db, offset));    if (!block)	return (-1);    data = (data_t *) (block + GET_BLOCK_OFFSET(db, offset));    db_moveData(db, block, offset + data->size + DATA_ITEM_LEN,		-(data->size + DATA_ITEM_LEN));    SET_ERRNO(PARDB_SUCCESS);    return (0);}intdb_setData(db_handle * db, index_t * index, void *value, unsigned short size,	   unsigned short type){    data_t *data = 0;    if (!index->data) {	if (!(data = db_newDataNode(db, index, size, type)))	    return (-1);    } else {	/* Try to modify the existing node */	if (!(data = db_getDataNode(db, index->data)))	    return (-1);	if ((size > data->size)) {	    int diff = size - data->size;	    void *block = BLOCK_POINTER_START(db, data);	    data_info_t *info = GET_DATA_INFO(block);	    /* Check to see if we have the appropriate space available */	    if (GET_FREE_SPACE(db, info->free) > diff) {		db_moveData(db, block,			    index->data + data->size + DATA_ITEM_LEN, diff);		data->size = size;	    } else {		/* Delete the current data block */		db_removeData(db, index->data);		index->data = 0;		/* And get a new one */		data = db_newDataNode(db, index, size, type);		if (!data)		    return (-1);	    }	}    }    if ((data->type != type)) {	SET_ERRNO(PARDB_BADTYPE);	return (-1);    }    /* Zero out the existing space */    if (size) {	bzero((unsigned char *) &data->value, size);	memcpy(&data->value, value, size);    }    SET_ERRNO(PARDB_SUCCESS);    return (size);}intdb_getData(db_handle * db, index_t * index, void *value, unsigned short size,	   unsigned short *type){    unsigned short copy_size = 0;    data_t *data = 0;    if (!index->data) {	SET_ERRNO(PARDB_NODATA);	return (-1);    }    data = db_getDataNode(db, index->data);    if (!data) {	SET_ERRNO(PARDB_NODATA);	return (-1);    }    /* If there is no data, than thats not an error */    if (!value || !size) {	SET_ERRNO(PARDB_SUCCESS);	return (0);    }    if (data->size > size)	copy_size = size;    else	copy_size = data->size;    if (!copy_size) {	SET_ERRNO(PARDB_SUCCESS);	return (0);    }    memcpy(value, &data->value, copy_size);    if (type)	*type = data->type;    SET_ERRNO(PARDB_SUCCESS);    return (copy_size);}intdb_getDataInfo(db_handle * db, index_t * index, unsigned short *size,	       unsigned short *type){    data_t *data;    if (!index->data) {	SET_ERRNO(PARDB_NODATA);	return (-1);    }    data = db_getDataNode(db, index->data);    if (!data)	return (-1);    if (size)	*size = data->size;    if (type)	*type = data->type;    SET_ERRNO(PARDB_SUCCESS);    return (0);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -