/** * Transform a Stringset to a string in the binary mo format. * @param Stringset $set * @return string */ public static function toString(Stringset $set, $add_hash_table = true) { $set->sort(); if ($add_hash_table) { $hash_table_size = self::nextPrime((int) ($set->size() * 4 / 3)); if ($hash_table_size <= 2) { $hash_table_size = 3; } } else { $hash_table_size = 0; } $ostart = 7 * 4; $tstart = $ostart + $set->size() * 8; $hstart = $tstart + $set->size() * 8; $ovstart = $hstart + $hash_table_size * (self::INT_SIZE / 8); $str = ''; $str .= pack('LL', self::MAGIC_NUMBER, self::REVISION); // magic number and revision $str .= pack('L', $set->size()); // number of strings $str .= pack('L', $ostart); // start of original strings at 7 words $str .= pack('L', $tstart); // start of translated strings, 2 words per entry $str .= pack('L', $hash_table_size); // size of hashtable $str .= pack('L', $hstart); // start of hashtable $ids = ''; $lengths = array(); for ($i = 0; $i < $set->size(); $i += 1) { $item = $set->item($i); $id = $item['id']; if ($item['context'] !== null) { $id = $item['context'] . self::EOT . $id; } if ($item['plural'] !== null) { $id = $id . self::NUL . $item['plural']; } $str .= pack('LL', strlen($id), $ovstart + strlen($ids)); $ids .= $id . self::NUL; } $tvstart = $ovstart + strlen($ids); $values = ''; for ($i = 0; $i < $set->size(); $i += 1) { $item = $set->item($i); $value = implode(self::NUL, $item['strings']); $str .= pack('LL', strlen($value), $tvstart + strlen($values)); $values .= $value . self::NUL; } if ($add_hash_table) { $hashtable = self::makeHashTable($set, $hash_table_size); foreach ($hashtable as $hash) { $str .= pack('L', $hash); } } $str .= $ids; $str .= $values; return $str; }