kde-extraapps/okular/generators/plucker/unpluck/util.cpp

263 lines
7.4 KiB
C++
Raw Normal View History

/* -*- mode: c; indent-tabs-mode: nil; -*-
* $Id: util.c,v 1.3 2003/12/28 20:59:21 chrish Exp $
*
* util -- Some simple utility routines so we don't need GLib
* Copyright (c) 2002, Bill Janssen
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* 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 General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#if !defined(WIN32)
#include <unistd.h> /* for lseek, etc. */
#else
#include <io.h>
#endif
#include <stdlib.h>
#include <sys/types.h>
#include <stdarg.h> /* for _plkr_message */
#include <stdio.h> /* for stderr */
#include <sys/stat.h> /* for fstat() */
#include <string.h> /* for strndup() */
#include <errno.h> /* for errno */
#include <fcntl.h> /* for O_RDONLY */
#include <assert.h> /* for assert() */
#include <zlib.h>
#include "unpluck.h"
#include "unpluckint.h"
/***********************************************************************/
/***********************************************************************/
/***** *****/
/***** Messages *****/
/***** *****/
/***********************************************************************/
/***********************************************************************/
static int ShowMessages = 0;
void _plkr_message
(
const char* formatSpec,
...
)
{
va_list ap;
va_start (ap, formatSpec);
if (ShowMessages) {
(void) vfprintf (stderr, formatSpec, ap);
fprintf (stderr, "\n");
}
va_end (ap);
}
int plkr_ShowMessages
(
int val
)
{
int oldval = ShowMessages;
ShowMessages = val;
return oldval;
}
/***********************************************************************/
/***********************************************************************/
/***** *****/
/***** String Utilities *****/
/***** *****/
/***********************************************************************/
/***********************************************************************/
char* _plkr_strndup
(
char* str,
int len
)
{
char* dup;
dup = (char *) malloc (len + 1);
strncpy (dup, str, len);
dup[len] = 0;
return dup;
}
/***********************************************************************/
/***********************************************************************/
/***** *****/
/***** Simple hash table maps string keys to void * values *****/
/***** *****/
/***********************************************************************/
/***********************************************************************/
typedef struct {
char* he_key;
void* he_data;
} HashEntry;
typedef struct {
int hs_count;
int hs_allocated;
HashEntry* hs_entries;
} HashTableSlot;
struct HashTable {
int ht_size;
int ht_nPairs;
HashTableSlot* ht_slots;
};
#define HASH_INCREMENT_SIZE 5
#define hashtable_slot(ht,index) (&((ht)->ht_slots[index]))
#define hashtable_hash_index(ht,key) (HashString((key), (ht)->ht_size))
#define hashtable_compare_keys(ht,key1,key2) (CompareStrings((key1),(key2)))
static int CompareStrings
(
char* key1,
char* key2
)
{
return (strcmp (key1, key2) == 0);
}
static int HashString
(
char* str,
int size
)
{
unsigned long crc;
crc = crc32 (0L, NULL, 0);
crc = crc32 (crc, (const Bytef*)str, strlen (str));
return (crc % size);
}
void* _plkr_FindInTable
(
HashTable* ht,
char* key
)
{
HashTableSlot* slot;
int count;
if (ht == NULL)
return (NULL);
slot = hashtable_slot (ht, hashtable_hash_index (ht, key));
for (count = slot->hs_count; count > 0; count -= 1)
if (hashtable_compare_keys
(ht, key, slot->hs_entries[count - 1].he_key))
return (slot->hs_entries[count - 1].he_data);
return (NULL);
}
void* _plkr_RemoveFromTable
(
HashTable* ht,
char* key
)
{
HashTableSlot* slot;
int count;
if (ht == NULL)
return (NULL);
slot = hashtable_slot (ht, hashtable_hash_index (ht, key));
for (count = 0; count < slot->hs_count; count += 1)
if (hashtable_compare_keys
(ht, slot->hs_entries[count].he_key, key)) {
void *data = slot->hs_entries[count].he_data;
free (slot->hs_entries[count].he_key);
if ((1 + (unsigned) count) < (unsigned) slot->hs_count)
slot->hs_entries[count] =
slot->hs_entries[slot->hs_count - 1];
--ht->ht_nPairs;
if (--slot->hs_count <= 0) {
free (slot->hs_entries);
slot->hs_entries = NULL;
slot->hs_allocated = 0;
slot->hs_count = 0;
}
return (data);
}
return (NULL);
}
int _plkr_AddToTable
(
HashTable* ht,
char* key,
void* obj
)
{
HashTableSlot* slot;
int count;
if (ht == NULL)
return (0);
slot = hashtable_slot (ht, hashtable_hash_index (ht, key));
for (count = slot->hs_count; count > 0; count -= 1)
if (hashtable_compare_keys
(ht, key, slot->hs_entries[count - 1].he_key))
return (0);
if (slot->hs_allocated == 0) {
slot->hs_allocated = HASH_INCREMENT_SIZE;
slot->hs_entries =
(HashEntry *) malloc (sizeof (HashEntry) * slot->hs_allocated);
slot->hs_count = 0;
}
else if (slot->hs_count >= slot->hs_allocated)
slot->hs_entries = (HashEntry *) realloc (slot->hs_entries,
(slot->hs_allocated +=
HASH_INCREMENT_SIZE)
* sizeof (HashEntry));
slot->hs_entries[slot->hs_count].he_key =
_plkr_strndup (key, strlen (key));
slot->hs_entries[slot->hs_count].he_data = obj;
slot->hs_count += 1;
ht->ht_nPairs += 1;
return (1);
}
HashTable* _plkr_NewHashTable
(
int size
)
{
HashTable *newHash = (HashTable *) malloc (sizeof (HashTable));
newHash->ht_size = size;
newHash->ht_nPairs = 0;
newHash->ht_slots =
(HashTableSlot *) malloc (sizeof (HashTableSlot) * size);
memset ((void *) (newHash->ht_slots), 0, sizeof (HashTableSlot) * size);
return (newHash);
}