Commit 3dc7521c authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Convert to use ObjIterate()

parent b924bdf6
......@@ -516,30 +516,178 @@ ved_pretend_gzip(struct req *req, enum vdp_action act, void **priv,
* much cheaper than running a gunzip instance.
*/
struct ved_foo {
unsigned magic;
#define VED_FOO_MAGIC 0x6a5a262d
struct req *req;
struct req *preq;
ssize_t start, last, stop, lpad;
ssize_t ll;
uint64_t olen;
uint8_t *dbits;
uint8_t tailbuf[8];
};
static int
ved_objiterate(void *priv, int flush, const void *ptr, ssize_t len)
{
struct ved_foo *foo;
const uint8_t *pp;
ssize_t dl;
ssize_t l;
CAST_OBJ_NOTNULL(foo, priv, VED_FOO_MAGIC);
(void)flush;
pp = ptr;
if (len > 0) {
/* Skip over the GZIP header */
dl = foo->start / 8 - foo->ll;
if (dl > 0) {
/* Before foo.start, skip */
if (dl > len)
dl = len;
foo->ll += dl;
len -= dl;
pp += dl;
}
}
if (len > 0) {
/* The main body of the object */
dl = foo->last / 8 - foo->ll;
if (dl > 0) {
if (dl > len)
dl = len;
if (ved_bytes(foo->req, foo->preq, VDP_NULL, pp, dl))
return(-1);
foo->ll += dl;
len -= dl;
pp += dl;
}
}
if (len > 0 && foo->ll == foo->last / 8) {
/* Remove the "LAST" bit */
foo->dbits[0] = *pp;
foo->dbits[0] &= ~(1U << (foo->last & 7));
if (ved_bytes(foo->req, foo->preq, VDP_NULL, foo->dbits, 1))
return (-1);
foo->ll++;
len--;
pp++;
}
if (len > 0) {
/* Last block */
dl = foo->stop / 8 - foo->ll;
if (dl > 0) {
if (dl > len)
dl = len;
if (ved_bytes(foo->req, foo->preq, VDP_NULL, pp, dl))
return (-1);
foo->ll += dl;
len -= dl;
pp += dl;
}
}
if (len > 0 && (foo->stop & 7) && foo->ll == foo->stop / 8) {
/* Add alignment to byte boundary */
foo->dbits[1] = *pp;
foo->ll++;
len--;
pp++;
switch((int)(foo->stop & 7)) {
case 1: /*
* x000....
* 00000000 00000000 11111111 11111111
*/
case 3: /*
* xxx000..
* 00000000 00000000 11111111 11111111
*/
case 5: /*
* xxxxx000
* 00000000 00000000 11111111 11111111
*/
foo->dbits[2] = 0x00; foo->dbits[3] = 0x00;
foo->dbits[4] = 0xff; foo->dbits[5] = 0xff;
foo->lpad = 5;
break;
case 2: /* xx010000 00000100 00000001 00000000 */
foo->dbits[1] |= 0x08;
foo->dbits[2] = 0x20;
foo->dbits[3] = 0x80;
foo->dbits[4] = 0x00;
foo->lpad = 4;
break;
case 4: /* xxxx0100 00000001 00000000 */
foo->dbits[1] |= 0x20;
foo->dbits[2] = 0x80;
foo->dbits[3] = 0x00;
foo->lpad = 3;
break;
case 6: /* xxxxxx01 00000000 */
foo->dbits[1] |= 0x80;
foo->dbits[2] = 0x00;
foo->lpad = 2;
break;
case 7: /*
* xxxxxxx0
* 00......
* 00000000 00000000 11111111 11111111
*/
foo->dbits[2] = 0x00;
foo->dbits[3] = 0x00; foo->dbits[4] = 0x00;
foo->dbits[5] = 0xff; foo->dbits[6] = 0xff;
foo->lpad = 6;
break;
case 0: /* xxxxxxxx */
default:
WRONG("compiler must be broken");
}
if (ved_bytes(foo->req, foo->preq,
VDP_NULL, foo->dbits + 1, foo->lpad))
return (-1);
}
if (len > 0) {
/* Recover GZIP tail */
dl = foo->olen - foo->ll;
assert(dl >= 0);
if (dl > len)
dl = len;
if (dl > 0) {
assert(dl <= 8);
l = foo->ll - (foo->olen - 8);
assert(l >= 0);
assert(l <= 8);
assert(l + dl <= 8);
memcpy(foo->tailbuf + l, pp, dl);
foo->ll += dl;
len -= dl;
}
}
assert(len == 0);
return (0);
}
static void
ved_stripgzip(struct req *req, struct busyobj *bo)
{
ssize_t start, last, stop, lpad;
ssize_t l;
char *p;
uint32_t icrc;
uint32_t ilen;
uint64_t olen;
uint8_t *dbits;
uint8_t *pp;
uint8_t tailbuf[8];
enum objiter_status ois;
void *oi;
void *sp;
ssize_t sl, ll, dl;
struct ecx *ecx;
struct req *preq;
struct ved_foo foo;
CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
CHECK_OBJ_NOTNULL(req->objcore, OBJCORE_MAGIC);
CAST_OBJ_NOTNULL(ecx, req->transport_priv, ECX_MAGIC);
preq = ecx->preq;
INIT_OBJ(&foo, VED_FOO_MAGIC);
foo.req = req;
foo.preq = ecx->preq;
memset(foo.tailbuf, 0xdd, sizeof foo.tailbuf);
/* XXX: Is this really required ? */
if (bo != NULL)
VBO_waitstate(bo, BOS_FINISHED);
......@@ -554,162 +702,28 @@ ved_stripgzip(struct req *req, struct busyobj *bo)
p = ObjGetattr(req->wrk, req->objcore, OA_GZIPBITS, &l);
AN(p);
assert(l == 32);
start = vbe64dec(p);
last = vbe64dec(p + 8);
stop = vbe64dec(p + 16);
olen = ObjGetLen(req->wrk, req->objcore);
assert(start > 0 && start < olen * 8);
assert(last > 0 && last < olen * 8);
assert(stop > 0 && stop < olen * 8);
assert(last >= start);
assert(last < stop);
foo.start = vbe64dec(p);
foo.last = vbe64dec(p + 8);
foo.stop = vbe64dec(p + 16);
foo.olen = ObjGetLen(req->wrk, req->objcore);
assert(foo.start > 0 && foo.start < foo.olen * 8);
assert(foo.last > 0 && foo.last < foo.olen * 8);
assert(foo.stop > 0 && foo.stop < foo.olen * 8);
assert(foo.last >= foo.start);
assert(foo.last < foo.stop);
/* The start bit must be byte aligned. */
AZ(start & 7);
/*
* XXX: optimize for the case where the 'last'
* XXX: bit is in a empty copy block
*/
AZ(foo.start & 7);
memset(tailbuf, 0xdd, sizeof tailbuf);
dbits = WS_Alloc(req->ws, 8);
AN(dbits);
ll = 0;
oi = ObjIterBegin(req->wrk, req->objcore);
do {
ois = ObjIter(req->objcore, oi, &sp, &sl);
pp = sp;
if (sl > 0) {
/* Skip over the GZIP header */
dl = start / 8 - ll;
if (dl > 0) {
/* Before start, skip */
if (dl > sl)
dl = sl;
ll += dl;
sl -= dl;
pp += dl;
}
}
if (sl > 0) {
/* The main body of the object */
dl = last / 8 - ll;
if (dl > 0) {
if (dl > sl)
dl = sl;
if (ved_bytes(req, preq, VDP_NULL, pp, dl))
break;
ll += dl;
sl -= dl;
pp += dl;
}
}
if (sl > 0 && ll == last / 8) {
/* Remove the "LAST" bit */
dbits[0] = *pp;
dbits[0] &= ~(1U << (last & 7));
if (ved_bytes(req, preq, VDP_NULL, dbits, 1))
break;
ll++;
sl--;
pp++;
}
if (sl > 0) {
/* Last block */
dl = stop / 8 - ll;
if (dl > 0) {
if (dl > sl)
dl = sl;
if (ved_bytes(req, preq, VDP_NULL, pp, dl))
break;
ll += dl;
sl -= dl;
pp += dl;
}
}
if (sl > 0 && (stop & 7) && ll == stop / 8) {
/* Add alignment to byte boundary */
dbits[1] = *pp;
ll++;
sl--;
pp++;
switch((int)(stop & 7)) {
case 1: /*
* x000....
* 00000000 00000000 11111111 11111111
*/
case 3: /*
* xxx000..
* 00000000 00000000 11111111 11111111
*/
case 5: /*
* xxxxx000
* 00000000 00000000 11111111 11111111
*/
dbits[2] = 0x00; dbits[3] = 0x00;
dbits[4] = 0xff; dbits[5] = 0xff;
lpad = 5;
break;
case 2: /* xx010000 00000100 00000001 00000000 */
dbits[1] |= 0x08;
dbits[2] = 0x20;
dbits[3] = 0x80;
dbits[4] = 0x00;
lpad = 4;
break;
case 4: /* xxxx0100 00000001 00000000 */
dbits[1] |= 0x20;
dbits[2] = 0x80;
dbits[3] = 0x00;
lpad = 3;
break;
case 6: /* xxxxxx01 00000000 */
dbits[1] |= 0x80;
dbits[2] = 0x00;
lpad = 2;
break;
case 7: /*
* xxxxxxx0
* 00......
* 00000000 00000000 11111111 11111111
*/
dbits[2] = 0x00;
dbits[3] = 0x00; dbits[4] = 0x00;
dbits[5] = 0xff; dbits[6] = 0xff;
lpad = 6;
break;
case 0: /* xxxxxxxx */
default:
WRONG("compiler must be broken");
}
if (ved_bytes(req, preq, VDP_NULL, dbits + 1, lpad))
break;
}
if (sl > 0) {
/* Recover GZIP tail */
dl = olen - ll;
assert(dl >= 0);
if (dl > sl)
dl = sl;
if (dl > 0) {
assert(dl <= 8);
l = ll - (olen - 8);
assert(l >= 0);
assert(l <= 8);
assert(l + dl <= 8);
memcpy(tailbuf + l, pp, dl);
ll += dl;
sl -= dl;
pp += dl;
}
}
} while (ois == OIS_DATA || ois == OIS_STREAM);
ObjIterEnd(req->objcore, &oi);
(void)ved_bytes(req, preq, VDP_FLUSH, NULL, 0);
foo.dbits = dbits;
(void)ObjIterate(req->wrk, req->objcore, &foo, ved_objiterate);
/* XXX: error check ?? */
(void)ved_bytes(req, foo.preq, VDP_FLUSH, NULL, 0);
icrc = vle32dec(tailbuf);
ilen = vle32dec(tailbuf + 4);
icrc = vle32dec(foo.tailbuf);
ilen = vle32dec(foo.tailbuf + 4);
ecx->crc = crc32_combine(ecx->crc, icrc, ilen);
ecx->l_crc += ilen;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment