| |
NOTE - Use your Browsers BACK Button to return to prior page or
CLICK here.
READ, WRITE, PACK Comp-3 Fields |
|
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) |
|
I would appreciate any feedback you may have on this site.
Send mail to tdelia@erols.com or click on the
Octopus. |
|
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
|