home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
OL.LZH
/
PROCS.LZH
/
PACKUNPK.ICN
< prev
next >
Wrap
Text File
|
1991-09-05
|
4KB
|
129 lines
############################################################################
#
# Name: packunpk.icn
#
# Title: Pack and unpack packed-decimal strings
#
# Author: C. Tenaglia (modified by Richard L. Goerwitz)
#
# Version: 1.2
#
# Date: June 1, 1991
#
############################################################################
#
# Integers written directly as strings occupy much more space
# than they need to. One easy way to shrink them a bit is to "pack"
# them, i.e. convert each decimal digit into a four-byte binary
# code, and pack these four-bit chunks into eight-bit characters,
# which can be written to a file.
#
# Interestingly, packing decimal strings in this manner lends
# itself to unpacking by treating each character as a base-10
# integer, and then converting it to base-16. Say we have an input
# string "99." Pack() would convert it to an internal representation
# of char(16*9 + 9), i.e. char(153). Unpack would treat this
# char(153) representation as a base-10 integer, and convert it to
# base 16 (i.e. 10r153 -> 16r99). The 99 is, of course, what we
# started with.
#
# Note that two unpack routines are provided here: The first, by
# Tanaglia, utilizes radcon.icn from the IPL. The second, by
# Goerwitz, does not. They utilize very different methods, but both
# amount to basically the same thing. Goerwitz's routine returns an
# integer, though, and has no "width" argument.
#
############################################################################
#
# Links: radcon.icn
#
############################################################################
link radcon
procedure pack(num,width)
local int, sign, prep, packed, word
int := integer(num) | fail
# There's really no need to store the sign if it's positive, UNLESS
# you are using this program to store packed decimal integers for
# access by other programs on certain mainframes that always store
# the sign.
# if int < 0 then sign := "=" else sign := "<"
if int < 0 then sign := "=" else sign := ""
prep := string(abs(int)) || sign
packed := ""
if (*prep % 2) ~= 0 then prep := "0" || prep
prep ? {
while word := move(2) do {
if pos(0)
then packed ||:= char(integer(word[1])*16 + ord(word[2])-48)
else packed ||:= char(integer(word[1])*16 + integer(word[2]))
}
}
/width := *packed
return right(packed, width, "\0")
end
procedure unpack(val,width)
# THIS PROCEDURE UNPACKS A VALUE INTO A STRING-INTEGER. USING THIS
# CODE SEGMENT REQUIRES LINKING WITH RADCON FROM THE IPL.
local tmp, number, tens, ones, sign
tmp := ""
sign := 1
every number := ord(!val) do
tmp ||:= right(map(radcon(number,10,16),&lcase,&ucase),2,"0")
if tmp[-1] == ("B" | "D") then {
sign := -1
# In this configuration, the sign field is only present if the
# integer is negative. If you have set up pack to register posi-
# tive values in the sign field, place the following line after
# the "if-then" expression.
tmp[-1] := ""
}
tmp *:= sign
/width := *string(tmp)
return right(string(tmp), width)
end
procedure unpack2(val)
# THIS PROCEDURE UNPACKS A VALUE INTO AN STRING-INTEGER.
# Note: Unpack2 assumes that pack is not recording positive
# sign values.
local unpacked, int
unpacked := ""
val ? {
while int := ord(move(1)) do {
unpacked ||:= string(iand(2r11110000,int) / 16)
if pos(0) then {
if iand(2r00001111,int) = 13 then {
unpacked := "-" || unpacked
break
}
}
unpacked ||:= string(iand(2r00001111,int))
}
}
return integer(unpacked)
end