#!/usr/bin/ruby class App def initialize file @file = file @cntl = {} end def getrec(fp) irec = 1 loop do head = fp.read(16) break if head.nil? recl, recn, vrecl, update = head.unpack('Na4NN') body = fp.read(recl - 8) attrs = { :nr => irec, :precl => recl, :name => recn, :vrecl => vrecl, :update => Time.at(update).utc } yield(head + body[0, vrecl - 12], attrs) irec = irec.succ end end def nwptime i Time.at((i - 61726 * 1440) * 60).utc end def dumpfile fp getrec(fp) do |rec, attrs| case attrs[:name] when 'CNTL' type, bts, bt, ftu, nm, nv, nz, ne = rec.unpack('x16a16a12Na4N4') @cntl[:type] = type @cntl[:bt] = nwptime(bt) proj, nx, ny, ir, jr, latr, lonr, di, dj = rec.unpack('x68a4NNg6') lats, lons, latt, lont, lato, lono, latp, lonp, v = rec.unpack('x104g8a4') puts <<-EOL ##{attrs[:nr]} CNTL type=#{type.inspect} bt=#{@cntl[:bt].strftime('%Y-%m-%dT%H:%M:%SZ')} ftu=#{ftu} nm=#{nm} nv=#{nv} nz=#{nz} ne=#{ne} proj=#{proj} nx=#{nx} ny=#{ny} basepoint=(#{ir}, #{jr}; #{latr}, #{lonr}) distance=(#{di}, #{dj}) standard=(#{lats}, #{lons}; #{latt}, #{lont}) others=(#{lato}, #{lono}; #{latp}, #{lonp}) value=#{v} EOL when 'DATA' m, vt, vt2, z, z2, e, nx, ny, pa, mi = rec.unpack('x16a4NNa6a6a6x2NNa4a4') ft = (nwptime(vt) - @cntl[:bt]) / 3600.0 vt2 = (vt2 == 1) ? '' : "/vt2=#{vt2}" puts <<-EOL ##{attrs[:nr]} m=#{m.inspect} ft=#{ft}#{vt2} z=#{z} e=#{e.inspect} nx=#{nx} ny=#{ny} pack=#{pa} miss=#{mi} EOL else printf("#%u rec=%04s size=%u\n", attrs[:nr], attrs[:name], rec.size) unless 'DATA' == attrs[:name] end end end def run File.open(@file, 'r') {|fp| fp.binmode dumpfile fp } end end for file in ARGV App.new(file).run end