1<?php
2
3namespace Cdb;
4
5/**
6 * This is a port of D.J. Bernstein's CDB to PHP. It's based on the copy that
7 * appears in PHP 5.3. Changes are:
8 *    * Error returns replaced with exceptions
9 *    * Exception thrown if sizes or offsets are between 2GB and 4GB
10 *    * Some variables renamed
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along
23 * with this program; if not, write to the Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25 * http://www.gnu.org/copyleft/gpl.html
26 *
27 * @file
28 */
29
30/**
31 * Common functions for readers and writers
32 */
33class Util {
34	/**
35	 * Take a modulo of a signed integer as if it were an unsigned integer.
36	 * $b must be less than 0x40000000 and greater than 0
37	 *
38	 * @param int $a
39	 * @param int $b
40	 *
41	 * @return int
42	 */
43	public static function unsignedMod( $a, $b ) {
44		if ( $a & 0x80000000 ) {
45			$m = ( $a & 0x7fffffff ) % $b + 2 * ( 0x40000000 % $b );
46
47			return $m % $b;
48		} else {
49			return $a % $b;
50		}
51	}
52
53	/**
54	 * Shift a signed integer right as if it were unsigned
55	 * @param int $a
56	 * @param int $b
57	 * @return int
58	 */
59	public static function unsignedShiftRight( $a, $b ) {
60		if ( $b == 0 ) {
61			return $a;
62		}
63		if ( $a & 0x80000000 ) {
64			return ( ( $a & 0x7fffffff ) >> $b ) | ( 0x40000000 >> ( $b - 1 ) );
65		} else {
66			return $a >> $b;
67		}
68	}
69
70	/**
71	 * The CDB hash function.
72	 *
73	 * @param string $s
74	 *
75	 * @return int
76	 */
77	public static function hash( $s ) {
78		$h = 5381;
79		$len = strlen( $s );
80		for ( $i = 0; $i < $len; $i++ ) {
81			$h5 = ( $h << 5 ) & 0xffffffff;
82			// Do a 32-bit sum
83			// Inlined here for speed
84			$sum = ( $h & 0x3fffffff ) + ( $h5 & 0x3fffffff );
85			$h =
86				(
87					( $sum & 0x40000000 ? 1 : 0 )
88					+ ( $h & 0x80000000 ? 2 : 0 )
89					+ ( $h & 0x40000000 ? 1 : 0 )
90					+ ( $h5 & 0x80000000 ? 2 : 0 )
91					+ ( $h5 & 0x40000000 ? 1 : 0 )
92				) << 30
93				| ( $sum & 0x3fffffff );
94			$h ^= ord( $s[$i] );
95			$h &= 0xffffffff;
96		}
97
98		return $h;
99	}
100}
101