/** * 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; }
/** * Read a string in MO format and create a Stringset from it. * @param string $str * @return Stringset */ public static function fromString($str) { $set = new Stringset(); $data = str_split($str, 1); $pos = 0; list(, $magic) = unpack('L', self::mergechars($data, $pos, 4)); if ($magic !== self::MAGIC_NUMBER) { throw new Exception("This is not a MO string."); } list(, $version) = unpack('L', self::mergechars($data, $pos, 4)); if ($version !== self::REVISION) { throw new Exception("This file format revision is not supported."); } list(, $nstrings) = unpack('L', self::mergechars($data, $pos, 4)); list(, $ostart) = unpack('L', self::mergechars($data, $pos, 4)); list(, $tstart) = unpack('L', self::mergechars($data, $pos, 4)); for ($i = 0; $i < $nstrings; $i += 1) { $original = $ostart + $i * 8; $translated = $tstart + $i * 8; $original = unpack('Llength/Loffset', self::mergechars($data, $original, 8)); $translated = unpack('Llength/Loffset', self::mergechars($data, $translated, 8)); $id = self::mergechars($data, $original['offset'], $original['length'] + 1, false); $value = self::mergechars($data, $translated['offset'], $translated['length'] + 1, false); if ($id[strlen($id) - 1] !== self::NUL || $value[strlen($value) - 1] !== self::NUL) { throw new Exception("String wasn't NUL-terminated"); } $result = array(); $id = explode(self::NUL, $id); if (count($id) === 3) { $result['msgid_plural'] = $id[1]; } $id = explode(self::EOT, $id[0]); if (count($id) === 2) { $result['msgctxt'] = $id[0]; $result['msgid'] = $id[1]; } else { $result['msgid'] = $id[0]; } $value = explode(self::NUL, $value); array_pop($value); $result['msgstr'] = $value; $set->add($result); } return $set; }