2010-01-29 3 views
1

J'ai eu un problème lors de l'implémentation d'un programme PHP en C++. Il s'agit de la fonction PHP/Perl unpack. Je ne sais pas comment faire le suivant en C++ (pas de problème en lisant un fichier ... mais comment je déballe ("C *") le contenu lu).Comment puis-je gérer des données compressées à partir de Perl/PHP en 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); 
?> 

Actuellement, je suis très désespéré résoudre ce problème sur mon propre - Je cherche jours, tout ce que je trouve sont des questions ... Y at-il Déballez libre() C++ mise en œuvre là-bas? :-(

Répondre

1

Je ne sais pas toute mise en œuvre générale de déballer C++, mais cela ne semble pas être la chose dont vous avez besoin de toute façon.

si matrix_x est défini quelque part comme unsigned char matrix_x[286] et vous avez une flux d'entrée ouvert inFile alors ce que vous devez faire est inFile.get(matrix_x, 286). Ce lit 286 octets de l'entrée et les place dans le tableau pointé par matrix_x.

+0

H i cube, thx pour votre réponse, mais il y a binaire "crap" situé dans 'matrix_x' au lieu du nombre que je voudrais les obtenir en PHP et Perl par' unpack ("C *") '. "bitmaskt.dat" a été créé avec pack ("C *") en Perl. J'ai essayé un peu, typecasteing chaque élément de 'matrix_x' à' long int' semble avoir le même effet que PHP unpack ("C *") - quelqu'un peut-il confirmer cela? – Georg

+0

Je ne comprends pas très bien comment vous avez casté les nombres. Pourriez-vous montrer cette partie du code C++? – cube

2

Perl documentation for pack couvre les modèles utilisés pour pack et unpack.

Dites que vous avez généré bitmaskt.dat avec

#! /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"; 

Vous pouvez le lire avec

#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; 
} 

Par exemple:

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; 
} 

Sortie:

7
Questions connexes