COMP-3 Functions

 

 

NOTE - Use your Browsers BACK Button to return to prior page or CLICK here.

   READ, WRITE, PACK Comp-3 Fields
Zzebra.jpg (25433 bytes) The topic of reading/writing COMP-3 (packed) fields occasionally springs up on the  SQRUG list... it's best to avoid COMP-3 fields entirely with SQR... if it's not possible you can use a series of routines I developed (yesterday) to process packed data... all I/O (reads/writes) must be handled 1 byte at a time (not just packed fields)... see examples (along with my zebra and monkeys)...

You can find the COMP-3 functions in my custom SQR library TDFUNC.SQC

See READ-Func, WRITE-func and PACK-Func for parameters and samples.

To Use the READ/WRITE/PACK functions the associated input/output files
must be opened with the record=1:fixed_nolf attribute.

   Example - Writing Packed Data (along with other data types)
!**********************************************************************
!*       Process Write                                                *
!**********************************************************************

begin-procedure Process-Write

let #O_no     = 1
let $O_file   = 'c:\temp\tdpckout.out'

let $cr       = chr(13)
let $lf       = chr(10)

open $O_file as #O_no for-writing record=1:fixed_nolf

!   Record #1
let #pack = 10000234
do NL-Func(#pack, $lit)
do WRITE-Func-Str(#O_no, 'Record 1:', 15)
do WRITE-Func-Chr(#O_no, '$')
do WRITE-Func-Chr(#O_no, ' ')
do WRITE-Func-Pack(#O_no, #pack, 5)
do WRITE-Func-Str(#O_no, $lit, 50)
do WRITE-Func-Pack(#O_no, -2200012, 8)
do WRITE-Func-Chr(#O_no, $cr)
do WRITE-Func-Chr(#O_no, $lf)

!   Record #2
let #pack = -987000
do NL-Func(#pack, $lit)
do WRITE-Func-Str(#O_no, 'Record 2:', 15)
do WRITE-Func-Chr(#O_no, '$')
do WRITE-Func-Chr(#O_no, ' ')
do WRITE-Func-Pack(#O_no, #pack, 5)
do WRITE-Func-Str(#O_no, $lit, 50)
do WRITE-Func-Pack(#O_no, 123, 8)
do WRITE-Func-Chr(#O_no, $cr)
do WRITE-Func-Chr(#O_no, $lf)

!   Record #3
let #pack = -1000
do NL-Func(#pack, $lit)
do WRITE-Func-Str(#O_no, 'Record 3:', 15)
do WRITE-Func-Chr(#O_no, '$')
do WRITE-Func-Chr(#O_no, ' ')
do WRITE-Func-Pack(#O_no, #pack, 5)
do WRITE-Func-Str(#O_no, $lit, 50)
do WRITE-Func-Pack(#O_no, 0, 8)
do WRITE-Func-Chr(#O_no, $cr)
do WRITE-Func-Chr(#O_no, $lf)

close #O_no

end-procedure

!**********************************************************************
                         

   The procedure above produces a file (3 records) with this layout:
Field Pos Len Type
Record ID 1 15 Character String
Code ($) 16 1 Character
Filler 17 1 Character
Amount 18 5 COMP-3 (Packed)
Literal 23 50 Character String
Amount2 73 8 COMP-3 (Packed)
Carriage Return 81 1 Character
Line Feed 82 1 Character

These are actually 80-character records with a trailing carriage return/line feed.
We'll use the file we just created as INPUT into our READ example.

   Example - Reading Packed Data (along with other data types)
!**********************************************************************
!*       Process Read                                                 *
!**********************************************************************

begin-procedure Process-Read

let #I_no     = 1
let $I_file   = 'c:\temp\tdpckout.out'

let $cr       = chr(13)
let $lf       = chr(10)

open $I_file as #I_no for-reading record=1:fixed_nolf

let #ctr     = 0

let #I_eof   = 0

while #I_eof = 0

   do READ-Func-Str(#I_no, #I_eof, 15, $I_id)
   do READ-Func-Chr(#I_no, #I_eof, $I_code1)
   do READ-Func-Chr(#I_no, #I_eof, $I_code2)
   do READ-Func-Pack(#I_no, #I_eof, 5, #I_amount)
   do READ-Func-Str(#I_no, #I_eof, 50, $I_lit)
   do READ-Func-Pack(#I_no, #I_eof, 8, #I_test)

   if #I_eof   = 0

      let #ctr = #ctr + 1

      show '  No: ' #ctr
      show '  ID: ' $I_id
      show 'Code: ' $I_code1
      show ' Lit: ' $I_lit
      show ' Amt: ' #I_amount
      show 'Test: ' #I_test
      show ' '

   end-if

   do READ-Func-Chr(#I_no, #I_eof, $I_cr)
   do READ-Func-Chr(#I_no, #I_eof, $I_lf)

end-while

close #I_no

end-procedure

!**********************************************************************                         

   Sample SQR.LOG from above routine (reading packed data)

  No: 1.000000
  ID: Record 1:
Code: $
 Lit: Ten Million Two Hundred Thirty-Four
 Amt: 10000234.000000
Test: -2200012.000000
 
  No: 2.000000
  ID: Record 2:
Code: $
 Lit: Nine Hundred Eighty-Seven Thousand
 Amt: -987000.000000
Test: 123.000000
 
  No: 3.000000
  ID: Record 3:
Code: $
 Lit: One Thousand
 Amt: -1000.000000
Test: 0.000000

          
Notice the resulting fields match those in our original procedure that wrote the output file. When reading this same file we were able to parse the correct data fields and display them properly.
NOTE:

This procedure works fine when using fixed length records with the same record layout. Much more additional work needs to be performed when using multiple layouts with packed fields. As I mentioned at the top of the page it is best to avoid packed fields entirely.

   Download Sample Programs (requires TDFUNC.SQC as well)
TDPCKOUT.SQR Write File with Packed Data
TDPCKIN.SQR Read File with Packed Data

   Feedback
ftoct01.jpg (12389 bytes) I would appreciate any feedback you may have on this site. Send mail to tdelia@erols.com or click on the Octopus.

   Technical difficulties?
Zmonkey.jpg (21125 bytes) Please report any technical difficulties you may encounter to the address above OR click on the Octopus. Thanks.

NOTE - Use your Browsers BACK Button to return to prior page.

Tony DeLia - Updated December 15, 2000