IBM Mainframe Forum Index
 
Log In
 
IBM Mainframe Forum Index Mainframe: Search IBM Mainframe Forum: FAQ Register
 

Algorithm to unpack ISPF PACKED format


IBM Mainframe Forums -> TSO/ISPF
Post new topic   Reply to topic
View previous topic :: View next topic  
Author Message
Robert Robinson

New User


Joined: 28 Sep 2012
Posts: 5
Location: Canada

PostPosted: Sun Jan 06, 2013 1:42 am
Reply with quote

I must thank you all for most generously contributing to my little project - especially Enrico, Prino and thLucas.

I now have a functioning FTP downloader and unpacker integrated into my C# application. I ended up writing this from the comments in the assembler version that Enrico pointed me to in the CBT tape. It is limited in scope - it only handles variable length records up to 255 bytes and so doesn't handle any of the fixed-length control codes - but in my case I am always downloading a predictable LRECL/RECFM so it's Ok.

Please bear in mind then that this code only handles a subset of situations, but sufficient for my purposes. Thanks again for all your help, folks.

Here are the Unpack and Ebcdic conversion methods:

Code:

private StringBuilder Unpack(MemoryStream memStream, int readCount, char recFm, int lRecl)
{
   byte[] upkTxt = new byte[255];      // One unpacked line.
   int i = 0;
   int j = 0;
   int ll = 0;
   byte ch = 0;
   bool eol = false;

   byte[] txt = new byte[readCount];   // Create a byte array and read stream into it.
   memStream.Position = 0;
   memStream.Read(txt, 0, readCount);

   // Build an ASCII string - guess at 4x size of packed data.
   StringBuilder sb = new StringBuilder(txt.Length * 4);   
   while (i < txt.Length)
   {
      byte eb = txt[i++];     // eb = the next Ebcdic packed Byte
      if (eb == 0xff)         // FF = EOF
         break;

      /* Cloned from Rexx Unpack from ***READ FORUM RULES***.NET board */
      if (eb == 0xfc || eb == 0x7c)   // End of line
      {
         if (eb == 0xfc)             // FC has ll bytes of data following
         {
            ll = txt[i++];
            for (int k = 0; k <= ll; k++) // Length count is 1 less than should be so <=
               upkTxt[j++] = txt[i++];
         }
         if (eb == 0x7c)
            i++;        // Skipping over count of trailing blanks in line
         eol = true;
      }
      else
         if (eb == 0x7a || eb == 0x7e)  // Repetitions of the next character
         {
            // 7e = but at the end of a maximum lngth logical record
            ll = txt[i++];
            ch = txt[i++];
            for (int k = 0; k <= ll; k++) // Repeater count is 1 less than should be so <=
               upkTxt[j++] = ch;
         }
         else
            if (eb >= 0x80) // length = (value - 80 + 1) bytes of data following.
            {
               ll = eb - 0x80;
               for (int k = 0; k <= ll; k++) // length count is 1 less than should be so <=
                  upkTxt[j++] = txt[i++];
            }
            else
            {                           // Repeat blanks.
               ll = eb;
               ch = 0x40;
               for (int k = 0; k <= ll; k++) // Repeater count is 1 less than should be so <=
                  upkTxt[j++] = ch;
            }

      // Uncomment line below to have a look a the unpacked line so far.
      // string txtString = ConvertEbcdicToAscii(upkTxt, 0, j < 256 ? j : 255);


      if (eol || j >= lRecl)  // End of line or we've gone over the LRECL.
      {                       // Append to StringBuilder and start new line.
         sb.Append(ConvertEbcdicToAscii(upkTxt, 0, j) + Environment.NewLine);
         Array.Clear(upkTxt, 0, 255);
         j = 0;
         eol = false;
      }
   }
   return sb;
}

private string ConvertEbcdicToAscii(byte[] ebcdic_bytes, int index, int length)
{
   char[] chars = new char[length];
   EBCDICDecoder.GetChars(ebcdic_bytes, index, length, chars, 0);           
   return new String(chars);
}




Regards,
Back to top
View user's profile Send private message
thlucas

New User


Joined: 27 Dec 2012
Posts: 6
Location: United States

PostPosted: Sun Jan 06, 2013 4:28 am
Reply with quote

Sounds good Robert - as long as it fills the need at hand, then it's all good.

I moonlight writing code for a vendor (C-Cubed), so I had to account for other situations in my C# example that I posted. If you're interested, check out their web-site. It's full of C# friendly products that allow you to do quite a few things between your MVS systems and the Windows platform. We use their products quite extensively in the automation department at First Data Corp where I work. I'm not their pimp or anything - just like their products and support. icon_smile.gif
Back to top
View user's profile Send private message
View previous topic :: :: View next topic  
Post new topic   Reply to topic View Bookmarks
All times are GMT + 6 Hours
Forum Index -> TSO/ISPF

 


Similar Topics
Topic Forum Replies
No new posts Populate last day of the Month in MMD... SYNCSORT 2
No new posts Modifying Date Format Using DFSORT DFSORT/ICETOOL 9
No new posts Looking for a little history of ISPF ... TSO/ISPF 5
No new posts Adding QMF and SPUFI to the ISPF menu DB2 20
No new posts Need to convert date format DFSORT/ICETOOL 20
Search our Forums:

Back to Top