Introdução
O mainframe que usa codificação EBCDIC internamente é usado por grandes corporações ao redor do mundo. No dia a dia, integrar esse tipo de sistema com a data warehouse envolve alguns desafios únicos.
Neste artigo, será abordado como ler dados do binário COBOL.
Cobol Data File
O binário COBOL é um arquivo posicional em que a sequência dos bytes representa um dado, que pode ser dos seguintes tipos:
"A" para caracteres alpha (A-Z, a-z, e espaços). "9" para um campo numérico (apenas números 0-9) . "X" qualquer caracter (incluindo binário).
O intuito deste artigo não é ensinar como programar em COBOL, é de apenas ensinar como ler. Quando um binário COBOL é gerado, não existe nenhuma informação que diga alguma informação sobre aquele dado. É necessário ter o que chamamos de COBOL Copy Book, que não é nada além de um texto que diz o tamanho de cada linha e o que os bytes representam. Dentro do binário COBOL não tem nada além de dados sem sentido. Para que eles façam sentido, é necessário um arquivo de “metainformação” dizendo o que cada posição representa.
Por exemplo, vamos criar um arquivo binário com as seguintes posições:
"Copy Book" 9(4) A(3) A(3)
Bom, lendo o copy book, podemos saber que o tamanho de cada linha é de 10 bytes (4+3+3).
Vamos criar um binário fictício:
perl -MEncode 'binmode STDOUT;print encode("posix-bc","1234foobar5678foobar8765foobaz7485foobar")' \ > arquivo.cobol
Vamos salvá-lo como arquivo.cobol e agora vamos ler o arquivo.
#!/usr/bin/perl use strict; use warnings; use Encode; open my $fh,'<','arquivo.cobol' or die $!; binmode $fh; # - Cada linha tem 10 bytes my ($buff,$length) = (undef,10); while(read($fh,$buff,$length)) { my $line = decode("posix-bc",$buff); print "Linha por linha $line\n"; }
Porém, no COBOL é comum comprimir os dados do tipo numérico pela metade (+1) usando Nibbles.
Nibbles
Se você estiver usando uma máquina byte addressable como a 80×86, para representar o número zero, por exemplo, será necessário usar 8 bits 00000000. Se você quiser manipular os bits individualmentes, será necessário pegar um byte inteiro e fazer isso manualmente. Um Nibble é o conjunto de 4 bits, portanto um byte tem dois nibbles.
Com 4 bits, temos a possibilidade de fazer 16 diferentes combinações (2*4), e com 8 bits podemos ter 256 combinações (2*8) diferentes.
Como é muito extenso ler um nibble usando binário, utilizamos o sistema hexadecimal:
0123456789ABCDEF (16 caracteres)
Comp-3
Quando criamos um arquivo binário COBOL, nós temos a opção de comprimir os campos numéricos (tamanho/2 + 1).
Por exemplo, o número 999787 em hexadecimal seria 39 39 39 37 38 37, que ocuparia 6 bytes e teria 12 nibbles.
O que o comp-3 faz é o sistema inverso, ele grava 99 97 87 hexadecimal mais uma letra que indica se o número é positivo ou negativo, por isso a fórmula é (tamanho / 2 + 1). Resumindo, quando um campo for do tipo comp-3, será necessário pegar o valor em hexadeciamal que já será o valor real do número.
Por exemplo, 99 97 87 44 em hexadecimal será o número 999787 positivo, onde o 44 representa a letra D que diz que o número é positivo; se fosse a letra C, o número seria negativo.
Convert::IBM390
Para não ter que ficar fazendo as conversões usando “unpack” manualmente, existe o seguinte módulo, Convert::IBM390.
Referências
- http://en.wikipedia.org/wiki/EBCDIC
- Art of Assembly Language Programming
- http://www.3480-3590-data-conversion.com/article-packed-fields.html
***
Artigo de Daniel de Oliveira Mantovani, publicado no Equinócio 2013 do grupo São Paulo Perl Mongers – http://sao-paulo.pm.org/equinocio/2013/mar/11-manipulando-binarios-cobol-com-perl
Texto sob Creative Commons – Atribuição – Partilha nos Mesmos Termos 3.0 Não Adaptada, mais informações em http://creativecommons.org/licenses/by-sa/3.0/