/* This is -*- C -*- */
/* vim: set sw=2: */
/* $Id: guppi-hash.c,v 1.5 2002/01/14 05:01:23 trow Exp $ */
/*
* guppi-hash.c
*
* Copyright (C) 2001 The Free Software Foundation, Inc.
*
* Developed by Jon Trowbridge <trow@gnu.org>
*/
/*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*/
#include <config.h>
#include "guppi-hash.h"
#include <string.h>
#include <guppi-memory.h>
struct _GuppiHash {
guint32 x;
guint32 y;
};
GuppiHash *
guppi_hash_new (void)
{
GuppiHash *hash = guppi_new (GuppiHash, 1);
guppi_hash_reset (hash);
return hash;
}
GuppiHash *
guppi_hash_copy (GuppiHash *hash)
{
if (hash == NULL) {
return NULL;
} else {
GuppiHash *new_hash = g_new (GuppiHash, 1);
new_hash->x = hash->x;
new_hash->y = hash->y;
return new_hash;
}
}
void
guppi_hash_free (GuppiHash *hash)
{
if (hash) {
guppi_free (hash);
}
}
/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
void
guppi_hash_reset (GuppiHash *hash)
{
g_return_if_fail (hash != NULL);
hash->x = 0x27182818;
hash->y = 0x31415926;
}
void
guppi_hash_raw (GuppiHash *hash, gconstpointer ptr, gsize N)
{
const guchar *p = ptr;
gsize N4 = N>>2, N1 = N & 3;
guint32 xx, yy, q;
gint i;
g_return_if_fail (hash != NULL);
for (i = 0; i < N4; ++i) {
xx = hash->x;
yy = hash->y;
q = *(guint32 *)p;
p += 4;
hash->x = (xx ^ q) + yy * q;
hash->y = (yy ^ q) - xx * q;
}
for (i = 0; i < N1; ++i) {
xx = hash->x;
yy = hash->y;
q = (guint) *p;
++p;
hash->x = 17 * xx + 19 * yy + (guint) q;
hash->y = 23 * xx + 29 * yy + (guint) q;
}
}
void
guppi_hash_string (GuppiHash *hash, const gchar *str)
{
g_return_if_fail (hash != NULL);
guppi_hash_raw (hash, str, strlen (str));
}
void
guppi_hash_double (GuppiHash *hash, double x)
{
g_return_if_fail (hash != NULL);
guppi_hash_raw (hash, &x, sizeof (double));
}
void
guppi_hash_int (GuppiHash *hash, gint x)
{
g_return_if_fail (hash != NULL);
guppi_hash_raw (hash, &x, sizeof (gint));
}
void
guppi_hash_uint (GuppiHash *hash, guint x)
{
g_return_if_fail (hash != NULL);
guppi_hash_raw (hash, &x, sizeof (guint));
}
void
guppi_hash_boolean (GuppiHash *hash, gboolean x)
{
if (x) {
gboolean hi_x = hash->x & (1<<31);
gboolean hi_y = hash->y & (1<<31);
hash->x = hash->x << 1;
hash->y = hash->y << 1;
if (hi_x)
hash->x = hash->x | 1;
if (hi_y)
hash->y = hash->y | 1;
} else {
gboolean lo_x = hash->x & 1;
gboolean lo_y = hash->y & 1;
hash->x = hash->x >> 1;
hash->y = hash->y >> 1;
if (lo_x)
hash->x = hash->x | (1<<31);
if (lo_y)
hash->y = hash->y | (1<<31);
}
}
/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
gint
guppi_hash_cmp (GuppiHash *a, GuppiHash *b)
{
g_return_val_if_fail (a != NULL, 0);
g_return_val_if_fail (b != NULL, 0);
if (a->x == b->x) {
return (a->y > b->y) - (a->y < b->y);
} else {
return (a->x > b->x) - (a->x < b->x);
}
}
gboolean
guppi_hash_eq (GuppiHash *a, GuppiHash *b)
{
g_return_val_if_fail (a != NULL, FALSE);
g_return_val_if_fail (b != NULL, FALSE);
return a->x == b->x && a->y == b->y;
}
gboolean
guppi_hash_neq (GuppiHash *a, GuppiHash *b)
{
g_return_val_if_fail (a != NULL, FALSE);
g_return_val_if_fail (b != NULL, FALSE);
return a->x != b->x || a->y != b->y;
}
guint
guppi_hash_to_uint (GuppiHash *hash)
{
g_return_val_if_fail (hash != NULL, 0);
return hash->x ^ hash->y;
}
syntax highlighted by Code2HTML, v. 0.9.1