I found a solution to the problem of converting reports coming off of a mainframe stored in EBCDIC to ASCII format. These particular reports are stored as VBA (Variable Blocked with ASA carriage control). Basically this means that each record is of variable length and so the first two bytes specify the length of the record. There are also "printer control characters" that specify form-feeds and line-feeds and such.
Since EBCDIC contains a lot of garbage characters that I will not be using in the ASCII representation, a straight ebcdic2ascii conversion would not have done me any good.
So....I wrote my own!
I'm posting the code here in case anyone is interested (still interested, Nigel?). What follows is the Convert class that I created. I got the translate tables from:
http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=438&lngWId=3
Basically, I added another array that contains all of the EBCDIC values that I need to ignore. Anyway, here's the code for the class:
<?php
// Conversion Utility for converting mainframe reports
// stored in EBCDIC using variable-length records to ASCII
define("CR", 13); // ascii carriage return
define("LF", 10); // ascii line feed
class Convert {
var $arrE2A = array( 0, 1, 2, 3,156, 9,134,127,151,141,142, 11, 12, 13, 14, 15,
16, 17, 18, 19,157,133, 8,135, 24, 25,146,143, 28, 29, 30, 31,
128,129,130,131,132, 10, 23, 27,136,137,138,139,140, 5, 6, 7,
144,145, 22,147,148,149,150, 4,152,153,154,155, 20, 21,158, 26,
32,160,161,162,163,164,165,166,167,168, 91, 46, 60, 40, 43, 33,
38,169,170,171,172,173,174,175,176,177, 93, 36, 42, 41, 59, 94,
45, 47,178,179,180,181,182,183,184,185,124, 44, 37, 95, 62, 63,
186,187,188,189,190,191,192,193,194, 96, 58, 35, 64, 39, 61, 34,
195, 97, 98, 99,100,101,102,103,104,105,196,197,198,199,200,201,
202,106,107,108,109,110,111,112,113,114,203,204,205,206,207,208,
209,126,115,116,117,118,119,120,121,122,210,211,212,213,214,215,
216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,
123, 65, 66, 67, 68, 69, 70, 71, 72, 73,232,233,234,235,236,237,
125, 74, 75, 76, 77, 78, 79, 80, 81, 82,238,239,240,241,242,243,
92,159, 83, 84, 85, 86, 87, 88, 89, 90,244,245,246,247,248,249,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57,250,251,252,253,254,255);
// ebcdic character codes that will be ignored
var $arrENP = array( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
33, 34, 35, 36, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
65, 66, 67, 68, 69, 70, 71, 72, 73, 81, 82, 83, 84, 85, 86, 87,
88, 89, 98, 99,100,101,102,103,104,105,112,113,114,115,116,117,
118,119,120,128,138,139,140,141,142,143,144,154,155,156,157,158,
159,160,170,171,172,173,174,175,176,177,178,179,180,181,182,183,
184,185,186,187,188,189,190,191,202,203,204,205,206,207,218,219,
220,221,222,223,225,234,235,236,237,238,239,250,251,252,253,254,255);
function ebc2asc($ebcdicFile) {
$fp = fopen($ebcdicFile, "r");
while (!feof($fp)) {
// read record length (first two bytes)
$reclen = ord(fgetc($fp)) + ord(fgetc($fp));
// read $reclen bytes
for ($i=0; $i < $reclen; $i++) {
if (!in_array($val=ord(fgetc($fp)), $this->arrENP))
$asciiString .= chr($this->arrE2A[$val]);
}
$asciiString .= chr(CR) . chr(LF);
}
return $asciiString;
}
} // Convert
?>
And the calling code:
<?php
require_once("include/convert.class.php");
$cvt = new Convert;
$file = "ebcdic.out";
// open ebcdic file
$fp = fopen("ebcdic.txt", "w");
// write ascii file
fwrite($fp, $cvt->ebc2asc($file));
printf("file written");
?>
Works pretty well, I think! Hope this is useful and legible in the forum. Sorry for the long post!