Как я могу обрабатывать упакованные данные из Perl / PHP в C ++? - PullRequest
1 голос
/ 29 января 2010

У меня проблема с реализацией PHP-программы на C ++. Речь идет о функции PHP / Perl unpack . Я не знаю, как сделать следующее в C ++ (без проблем при чтении файла ... но как распаковать ("C *") прочитанное содержимое).

<?php
$file = fopen("bitmaskt.dat", "rb");
//create the data stream
$matrix_x           = unpack("C*", fread($file, 286));
$matrix_y           = unpack("C*", fread($file, 286));
$mask_data          = unpack("C*", fread($file, 286));
$reed_ecc_codewords = ord(fread($file, 1));
$reed_blockorder    = unpack("C*", fread($file, 128));
fclose($file);
?>

В настоящее время я безнадежно решаю эту проблему самостоятельно - я ищу дни, все, что я нашел, это вопросы ... Есть ли какая-нибудь бесплатная реализация unpack () c ++? :-(

Ответы [ 2 ]

2 голосов
/ 29 января 2010

Документация Perl для pack охватывает шаблоны, используемые для pack и unpack.

Скажем, вы сгенерировали bitmaskt.dat с

#! /usr/bin/perl

use warnings;
use strict;

open my $fh, ">", "bitmaskt.dat" or die "$0: open: $!";

my @data = (42) x 286;

print $fh pack("C*" => @data);
print $fh pack("C*" => @data);
print $fh pack("C*" => @data);
print $fh pack("C"  => 7);
print $fh pack("C*" => (1) x 128);

close $fh or warn "$0: close";

Вы можете прочитать это с

#include <fstream>
#include <iostream>
#include <iterator>
#include <vector>

typedef unsigned char datum_t;
typedef std::vector<datum_t> buf_t;

std::istream &read_data(std::istream &in, buf_t &buf, size_t n)
{
  std::istreambuf_iterator<char> it(in.rdbuf()), eos;
  while (it != eos && n-- != 0)
    buf.push_back(static_cast<datum_t>(*it++));

  return in;
}

Например:

int main()
{
  std::ifstream bm("bitmaskt.dat", std::ifstream::binary | std::ifstream::in);

  struct {
    buf_t buf;
    size_t len;
    std::string name;
  } sections[] = {
    { buf_t(), 286, "matrix_x" },
    { buf_t(), 286, "matrix_y" },
    { buf_t(), 286, "mask_data" },
    { buf_t(),   1, "reed_ecc_codewords" },
    { buf_t(), 128, "reed_blockorder" },
  };
  const int n = sizeof(sections) / sizeof(sections[0]);

  for (int i = 0; n - i > 0; i++) {
    if (!read_data(bm, sections[i].buf, sections[i].len)) {
      std::cerr << "Read " << sections[i].name << " failed" << std::endl;
      return 1;
    }
  }

  const int codeword = 3;
  std::cout << (unsigned int) sections[codeword].buf[0] << '\n';

  return 0;
}

Выход:

7
1 голос
/ 29 января 2010

Я не знаю о какой-либо общей реализации распаковки для C ++, но, похоже, это не то, что вам нужно.

, если matrix_x определен где-то как unsigned char matrix_x[286], и у вас есть открытый поток ввода inFile то, что вам нужно сделать, это inFile.get(matrix_x, 286). Это читает 286 байт из ввода и помещает их в массив, на который указывает matrix_x.

...