/** * Takes a string in the format of a po file and returns a Stringset * @param string $str * @return Stringset */ public static function fromString($str) { $stringset = new Stringset(); $entry = array(); $state = null; $line = 1; foreach (explode("\n", $str) as $line) { $line = trim($line); if (strlen($line) === 0) { if (count($entry) > 0) { $stringset->add($entry); $entry = array(); $state = null; } continue; } if ($line[0] === '#' && $line[1] === ',') { $entry['flags'] = array_map('trim', explode(',', substr($line, 2))); } else { if ($line[0] !== '#') { // non-comment list($key, $rest) = explode(' ', $line, 2); switch ($key) { case 'msgid': case 'msgid_plural': case 'msgstr': case 'msgctxt': if (strpos($state, 'msgstr') === 0 && $key !== 'msgstr' && count($entry) > 0) { $stringset->add($entry); $entry = array(); } $state = $key; $entry[$key] = self::parseString($rest); break; default: if (strpos($key, 'msgstr[') === 0) { $state = $key; $entry[$key] = self::parseString($rest); } else { $entry[$state] .= self::parseString(trim($line)); } } } } $line += 1; } return $stringset; }
/** * Generate the hashtable. * Uses an array which is... a hashtable. Clearly this is a * case of hashtableception. * @param Stringset $set * @param integer $size * @return integer[] */ private static function makeHashTable(Stringset $set, $size) { $table = array(); // by default everything points to zero for ($i = 0; $i < $size; $i += 1) { $table[$i] = 0; } for ($i = 0; $i < $set->size(); $i += 1) { $item = $set->item($i); $hash = self::hash($item['id']); $index = $hash % $size; $inc = $hash % ($size - 2) + 1; // check for collisions while ($table[$index] !== 0) { if ($index < $size - $inc) { $index += $inc; } else { // out of bounds, start at the bottom $index -= $size - $inc; } } // and insert it $table[$index] = $i + 1; } return $table; }