Хорошо, потому что я не нашел более хорошее решение, я сделал PHP-класс для обрабатывать записи из этого набора данных:
<?php
namespace Mainframe;
/**
* Mainframe main function
*
* @author vp1zag4
*
*/
class Mainframe
{
/**
* Data string for reading
*
* @var string | null
*/
protected $data = null;
/**
* Default ouput charset
*
* @var string
*/
const OUTPUT_CHARSET = 'latin1';
/**
* Record length of dataset
*
* @var integer
*/
protected $recordLength = 10;
/**
* Inits the
*
* @param unknown $data
*/
public function __construct($data = null)
{
if (! is_null($data)) {
$this->setData($data);
}
}
/**
* Sets the data string and validates
*
* @param unknown $data
* @throws \LengthException
*/
public function setData($data)
{
if (strlen($data) != $this->recordLength) {
throw new \LengthException('Given data does not fit to dataset record length');
}
$this->data = $data;
}
/**
* Unpack packed decimal (BCD) from mainframe format to integer
*
* @param unknown $str
* @return number
*/
public static function unpackBCD($str)
{
$num = unpack('H*', $str);
$num = array_shift($num);
$sign = strtoupper(substr($num, - 1));
$num = (int) substr($num, 0, - 1);
if ($sign == 'D') {
$num = $num * - 1;
}
return (int) $num;
}
/**
* convert EBCDIC to default output charset
*
* @param string $str
* @return string
*/
public static function conv($str, $optionalCharset = null)
{
$charset = (is_string($optionalCharset)) ? $optionalCharset : self::OUTPUT_CHARSET;
return iconv('IBM037', $charset, $str);
}
/**
* Reads part of data string and converts or unpacks
*
* @param integer $start
* @param integer $length
* @param bool $unpack
* @param bool | string $conv
*/
public function read($start, $length, $unpack = false, $conv = true)
{
if (empty($this->data)) {
return null;
}
$result = substr($this->data, $start, $length);
if($unpack) {
return self::unpackBCD($result);
}
if ($conv) {
return self::conv($result, $conv);
}
return $result;
}
}
С $ class-> read (1, 3, True) можно прочитать часть данных и конвертировать/распаковать ее в одно и то же время.
Возможно, это тоже поможет любому в любое время.
Но, конечно же, я попытаюсь настроить какой-то Job, который будет делать это для меня непосредственно на мэйнфрейме с некоторыми данными JSON в качестве вывода.
Более приятное решение - заставить людей мэйнфрейма предоставить вам все «только текст». Затем вы можете выполнить преобразование кода на уровне файлов/записей и не иметь никаких проблем ни с чем. Это означает «отдельный знак», а также коэффициент масштабирования или фактическую десятичную точку, в зависимости от того, что вам будет легче.Если программа «Майнфрейм» не была закодирована в «Ассемблере», для них тривиально создавать такие данные, а затем экономить на вас. См. Также другие вопросы, помеченные упакованными десятичными знаками. –
TL; DR «Мейнфрейм. Но, может быть, есть более приятное решение?» Да. Пусть вместо этого используют обработчики динозавров. –
@Rhymoid ты имел в виду TS: DR? Там не выясняется. Нада. Нуль. Никто. Вам не нужно было придумывать интересные эпитеты, чтобы мы могли понять, что у вас трудности с чтением. Просто напиши что-нибудь. –