Here a whole program that illlustrates the error. I'm running under
Windows Ruby 1.8.5. (it's ugly and chopped up, but it works... er...
doesn't work... er... you know what I mean)
···
#
# Ruby program to convert a z/OS EBCDIC to ASCII.
#
class Record
#
# The Record.report_values() method used the Record Layout info and
parses a record at a time, building the output ASCII row.
#
def Record.report_values(edata) ; # ebcdic data
adata = edata.tr($ebcdic_chars, $ascii_chars) ; # ascii data
puts "ebcdic data = #{edata}" ;
puts ;
puts "ascii data = #{adata}" ;
puts ;
end ; # def report_values
#
# This Record.to_h() method converts a hex byte into a displayable,
human readable value. i.e. X'F5' to "F5".
#
def Record.to_h(str)
str.unpack('H64').to_s.upcase ;
end ;
#
# This method called to dump the data in hex format.
#
def Record.dump_area(data) ;
fsize = data.size ;
lines,last = fsize.divmod(32) # get # of full lines and figure the
remainder.
i = 0
while lines > 0
str = data[i..i+31]
hexdata = Record.to_h(str) # .unpack('H64').to_s.upcase
printf( "%08X %8s %8s %8s %8s %8s %8s %8s %8s %s\n",
i, hexdata[0..7], hexdata[8..15],
hexdata[16..23], hexdata[24..31],
hexdata[32..39], hexdata[40..47],
hexdata[48..55], hexdata[56..63],
str.tr("\000-\037\177-\377",'.'))
i += 32; lines -= 1
end
# Write out the partial line.
str = data[i..fsize]
line = sprintf("%08x ",i)
i.upto(fsize) {|x|
line << sprintf("%2s",data[x..x].unpack('H2').to_s.upcase)
if (((x+1)% 4)==0) then line << " " end
if (((x+1)%16)==0) then line << " " end
}
line << " "*(2+90-line.length)
line << sprintf("%s\n", str.tr("\000-\037\177-\377",'.'))
printf(line)
end ;
end ; # class Record. This is the end of all the method defintions for
class Record.
def doit(data) ;
#
# Now starts the translate table definitions. They are order-sensitive.
Do not change the order unless you have a real reason to.
#
# $ebcdic_chars (global variable) is the "from string" portion of the
translate process.
# $ascii_chars is the "to string" portion.
#
# $ebcdic_nums is the "from string" for converting from X'F0' through
X'F9' (0-9 ebcdic)
# $ascii_nums is the "to string" for converting to X'30' through
X'39' (0-9 ascii)
#
$ebcdic_chars = 0x40.chr ; # blank
###$ebcdic_chars += 0xFF.chr ; # unprintable
###$ebcdic_chars += 0x00.chr ; # unprintable
$ebcdic_chars += 0XC1.chr + 0xC2.chr + 0xC3.chr + 0xC4.chr + 0xC5.chr +
0xC6.chr + 0xC7.chr + 0xC8.chr + 0xC9.chr ; # A-I
$ebcdic_chars += 0XD1.chr + 0xD2.chr + 0xD3.chr + 0xD4.chr + 0xD5.chr +
0xD6.chr + 0xD7.chr + 0xD8.chr + 0xD9.chr ; # J-R
$ebcdic_chars += 0xE2.chr + 0xE3.chr + 0xE4.chr + 0xE5.chr +
0xE6.chr + 0xE7.chr + 0xE8.chr + 0xE9.chr ; # S-Z
$ebcdic_chars += 0X81.chr + 0x82.chr + 0x83.chr + 0x84.chr + 0x85.chr +
0x86.chr + 0x87.chr + 0x88.chr + 0x89.chr ; # a-i
$ebcdic_chars += 0X91.chr + 0x92.chr + 0x93.chr + 0x94.chr + 0x95.chr +
0x96.chr + 0x97.chr + 0x98.chr + 0x99.chr ; # j-r
$ebcdic_chars += 0xA2.chr + 0xA3.chr + 0xA4.chr + 0xA5.chr +
0xA6.chr + 0xA7.chr + 0xA8.chr + 0xA9.chr ; # s-z
$ebcdic_chars += 0x4B.chr ; # .
$ebcdic_chars += 0x4C.chr ; # <
$ebcdic_chars += 0x4D.chr ; # (
$ebcdic_chars += 0x4E.chr ; # +
$ebcdic_chars += 0x4F.chr ; # |
$ebcdic_chars += 0x50.chr ; # &
$ebcdic_chars += 0x5A.chr ; # !
$ebcdic_chars += 0x5B.chr ; # $
$ebcdic_chars += 0x5C.chr ; # *
$ebcdic_chars += 0x5D.chr ; # )
$ebcdic_chars += 0x5E.chr ; # ;
$ebcdic_chars += 0x5F.chr ; # ^
$ebcdic_chars += 0x60.chr ; # -
$ebcdic_chars += 0x61.chr ; # /
$ebcdic_chars += 0x6B.chr ; # ,
$ebcdic_chars += 0x6C.chr ; # %
$ebcdic_chars += 0x6D.chr ; # _
$ebcdic_chars += 0x6E.chr ; # >
$ebcdic_chars += 0x6F.chr ; # ?
$ebcdic_chars += 0X79.chr ; # `
$ebcdic_chars += 0x7A.chr ; # :
$ebcdic_chars += 0x7B.chr ; # #
$ebcdic_chars += 0x7C.chr ; # @
$ebcdic_chars += 0x7D.chr ; # '
$ebcdic_chars += 0x7E.chr ; # =
$ebcdic_chars += 0x7F.chr ; # "
$ebcdic_chars += 0xBA.chr ; # [
$ebcdic_chars += 0xBB.chr ; # ]
$ebcdic_chars += 0xC0.chr ; # {
$ebcdic_chars += 0xD0.chr ; # }
$ebcdic_chars += 0xE0.chr ; # \
$ascii_chars = " " ; # blank
###$ascii_chars += " " ; # make ebcdic 0XFF into a blank
###$ascii_chars += ' ' ; # make ebcdic 0X00 into a blank
$ascii_chars += ('A'..'Z').to_a.to_s ; # A-Z
$ascii_chars += ('a'..'z').to_a.to_s ; # a-z
$ascii_chars += '.' ;
$ascii_chars += '<' ;
$ascii_chars += '(' ;
$ascii_chars += '+' ;
$ascii_chars += '|' ;
$ascii_chars += '&' ;
$ascii_chars += '!' ;
$ascii_chars += '$' ;
$ascii_chars += '*' ;
$ascii_chars += ')' ;
$ascii_chars += ';' ;
$ascii_chars += '^' ;
$ascii_chars += '-' ;
$ascii_chars += '/' ;
$ascii_chars += ',' ;
$ascii_chars += '%' ;
$ascii_chars += '_' ;
$ascii_chars += '>' ;
$ascii_chars += '?' ;
$ascii_chars += '`' ;
$ascii_chars += ':' ;
$ascii_chars += '#' ;
$ascii_chars += '@' ;
$ascii_chars += '\'';
$ascii_chars += '=' ;
$ascii_chars += '"' ;
$ascii_chars += '[' ;
$ascii_chars += ']' ;
$ascii_chars += '{' ;
$ascii_chars += '}' ;
$ascii_chars += '\\' ; # escape char is special - must be doubled
$ebcdic_nums = 0xF0.chr + 0XF1.chr + 0xF2.chr + 0xF3.chr + 0xF4.chr +
0xF5.chr + 0xF6.chr + 0xF7.chr + 0xF8.chr + 0xF9.chr ;
$ascii_nums = "0123456789" ;
$ebcdic_chars += $ebcdic_nums ;
$ascii_chars += $ascii_nums ;
# true if the record was
as expected, or false if not.
Record.report_values(data)
Record.dump_area( data ) ; # write offending record, in hex dump
format, to the INVALID_FORMAT file.
end ; # def doit()
instring = 0XC1.chr + 0xC2.chr + 0x6E.chr + 0xC1.chr + 0xC1.chr +
0x4C.chr + 0xC1.chr + 0xC3.chr ; # EBCDIC for "AB>AA<AC"
doit(instring) ; # run the program.
--
Posted via http://www.ruby-forum.com/.