protected function getCompaction($mode, $code, $addmode = true)
{
$cw = array();
// array of codewords to return
switch ($mode) {
case 900:
// Text Compaction mode latch
$submode = 0;
// default Alpha sub-mode
$txtarr = array();
// array of characters and sub-mode switching characters
$codelen = strlen($code);
for ($i = 0; $i < $codelen; ++$i) {
$chval = ord($code[$i]);
if (($k = array_search($chval, $this->textsubmodes[$submode])) !== false) {
// we are on the same sub-mode
$txtarr[] = $k;
} else {
// the sub-mode is changed
for ($s = 0; $s < 4; ++$s) {
// search new sub-mode
if ($s != $submode and ($k = array_search($chval, $this->textsubmodes[$s])) !== false) {
// $s is the new submode
if (($i + 1 == $codelen or $i + 1 < $codelen and array_search(ord($code[$i + 1]), $this->textsubmodes[$submode]) !== false) and ($s == 3 or $s == 0 and $submode == 1)) {
// shift (temporary change only for this char)
if ($s == 3) {
// shift to puntuaction
$txtarr[] = 29;
} else {
// shift from lower to alpha
$txtarr[] = 27;
}
} else {
// latch
$txtarr = array_merge($txtarr, $this->textlatch['' . $submode . $s]);
// set new submode
$submode = $s;
}
// add characted code to array
$txtarr[] = $k;
break;
}
}
}
}
$txtarrlen = count($txtarr);
if ($txtarrlen % 2 != 0) {
// add padding
$txtarr[] = 29;
++$txtarrlen;
}
// calculate codewords
for ($i = 0; $i < $txtarrlen; $i += 2) {
$cw[] = 30 * $txtarr[$i] + $txtarr[$i + 1];
}
break;
case 901:
case 924:
// Byte Compaction mode latch
while (($codelen = strlen($code)) > 0) {
if ($codelen > 6) {
$rest = substr($code, 6);
$code = substr($code, 0, 6);
$sublen = 6;
} else {
$rest = '';
$sublen = strlen($code);
}
if ($sublen == 6) {
$t = bcmul('' . ord($code[0]), '1099511627776');
$t = bcadd($t, bcmul('' . ord($code[1]), '4294967296'));
$t = bcadd($t, bcmul('' . ord($code[2]), '16777216'));
$t = bcadd($t, bcmul('' . ord($code[3]), '65536'));
$t = bcadd($t, bcmul('' . ord($code[4]), '256'));
$t = bcadd($t, '' . ord($code[5]));
do {
$d = bcmod($t, '900');
$t = bcdiv($t, '900');
array_unshift($cw, $d);
} while ($t != '0');
} else {
for ($i = 0; $i < $sublen; ++$i) {
$cw[] = ord($code[$i]);
}
}
$code = $rest;
}
break;
case 902:
// Numeric Compaction mode latch
while (($codelen = strlen($code)) > 0) {
if ($codelen > 44) {
$rest = substr($code, 44);
$code = substr($code, 0, 44);
} else {
$rest = '';
}
$t = '1' . $code;
do {
$d = bcmod($t, '900');
$t = bcdiv($t, '900');
array_unshift($cw, $d);
} while ($t != '0');
$code = $rest;
}
break;
case 913:
// Byte Compaction mode shift
$cw[] = ord($code);
break;
}
if ($addmode) {
// add the compaction mode codeword at the beginning
array_unshift($cw, $mode);
}
return $cw;
}