#include "V.h"
/*
* These routines implement 3/4 and 4/3 packing. The idea is to convert
* binary  data  to  and from a form that will pass safely over a 7-bit
* ASCII data path.  The resulting code avoids:
*   1. values over  0x7E.
*   2. values under 0x31.
*
* The scheme is to represent 3 binary 8-bit bytes as 4 ASCII printable
* characters.   The 6 bits 000000 are represented by the lo value, and
* the remaining 63 other values follow it.
*
* There are two routines here:
*   p34(b1,b2) unpacks b1 to b2;
*   p43(b1,b2) pack2 b1 to b2.
*
*/
static char lo =  49;	/* Start of 64-byte printable sequence */
static char hi = 112;	/* End of 64-byte printable sequence */
#define X 0x100

FCT p34(b1,b2)
	Blk *b1, *b2;
{	int r=0;
	int i=0;
	U32 x=0;
	int i1=0, i2=0;
	int c0=0, c1=0, c2=0;
	int x0=0, x1=0, x2=0, x3=0;
:3	Fenter("p34");
:6	V6 "Called %08X/%d/%d",b1->v,b1->l,b1->m D;
:6	H6(b1->v,b1->l,"p34-i");
:4	V4 "Unpack size: %d.",(4 * (b1->l + 3))/3,"b2" D;

	MinBlkM(b2,(4 * (b1->l + 3))/3,"b2");

	i1 = i2 = 0;
	while ((i = (b1->l - i1)) > 0) {
		c0 = (i1 < b1->l) ? b1->v[i1++] : 0;
		c1 = (i1 < b1->l) ? b1->v[i1++] : 0;
		c2 = (i1 < b1->l) ? b1->v[i1++] : 0;
:6		V6 "%02X %02X %02X",c0,c1,c2 D;
		b2->v[i2++] = (i >= 1) ? lo + (x0 = (c0 >> 2))                      : ' ';
		b2->v[i2++] = (i >= 1) ? lo + (x1 = (c1 >> 4) + ((c0 & 0x03) << 4)) : ' ';
		b2->v[i2++] = (i >= 2) ? lo + (x2 = (c2 >> 6) + ((c1 & 0x0F) << 2)) : ' ';
		b2->v[i2++] = (i >= 3) ? lo + (x3 =              (c2 & 0x3F))       : ' ';
:5		V5 "%02X %02X %02X => %02o %02o %02o %02o",c0,c1,c2,x0,x1,x2,x3 D;
	}
	r = i2;
	b2->v[r] = '\n';
	b2->l = ++r;
:2	b2->v[r] = 0;
:6	H6(b2->v,b2->l,"p34-o");
fail:
:3	FExit;
	return b2->l;
}

FCT p43(b2,b1)
	Blk *b1, *b2;
{	int r=0;
	int i1=0, i2=0;
	int c0=0, c1=0, c2=0, c=0;
	int x0=0, x1=0, x2=0, x3=0;
:3	Fenter("p43");
:6	V6 "Called %08X/%d/%d",b1->v,b1->l,b1->m D;
:5	V5 "Packed size:: %d",(3 * (b2->l + 3))/4,"b1" D;

	MinBlkM(b1,(3 * (b2->l + 3))/4,"b1");

	i1 = i2 = 0;
	while (i2 < b2->l) {
		x0 = (i2 < b2->l && (c = b2->v[i2++]) && lo <= c && c <= hi) ? (c - lo) : -1;
		x1 = (i2 < b2->l && (c = b2->v[i2++]) && lo <= c && c <= hi) ? (c - lo) : -1;
		x2 = (i2 < b2->l && (c = b2->v[i2++]) && lo <= c && c <= hi) ? (c - lo) : -1;
		x3 = (i2 < b2->l && (c = b2->v[i2++]) && lo <= c && c <= hi) ? (c - lo) : -1;
:5		V5 "%02o %02o %02o %02o",x0,x1,x2,x3 D;
		if (x1 >= 0) b1->v[i1++] = c0 = (x0 << 2) + (x1 >> 4);
		if (x2 >= 0) b1->v[i1++] = c1 = (x2 >> 2) + ((x1 & 0x0F) << 4);
		if (x3 >= 0) b1->v[i1++] = c2 = ((x2 & 0x03) << 6) + x3;
:5		V5 "%02X %02X %02X <= %02o %02o %02o %02o",c0,c1,c2,x0,x1,x2,x3 D;
	}
	b1->l = r = i1;
:2	b1->v[r] = 0;
fail:
:3	FExit;
	return r;
}
