/* 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 */ /* * 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 #include "guppi-hash.h" #include #include 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; }