📄 pgpaddhdr.c
字号:
*(context->bufptr) = 0xE0 + BLOCK_SIZE;
continue;
}
} while (size);
return size0 - size;
}
/* This is only used in V3 mode */
static size_t
Write(PGPPipeline *myself, PGPByte const *buf, size_t size, PGPError *error)
{
AddHdrContext *context;
pgpAssert(myself);
pgpAssert(myself->magic == ADDHEADERMAGIC);
pgpAssert(error);
context = (AddHdrContext *)myself->priv;
pgpAssert(context);
pgpAssert(context->tail);
pgpAssert(context->fifo);
if (!context->dowrite) {
/* Buffer into the fifo until we get a sizeadvise */
return pgpFifoWrite (context->fifod, context->fifo, buf, size);
}
/*
* Ok, we've been given our size. Flush the fifo and then be
* a write-through
*/
*error = DoFlush(context);
if (*error)
return 0;
if (context->sizeknown && size > context->bytes) {
pgpAssert(0);
*error = kPGPError_SizeAdviseFailure;
return 0;
}
size = context->tail->write(context->tail, buf, size, error);
context->bytes -= size;
return size;
}
static PGPError
Annotate(PGPPipeline *myself, PGPPipeline *origin, int type,
PGPByte const *string, size_t size)
{
AddHdrContext *context;
PGPError error;
pgpAssert(myself);
pgpAssert(myself->magic == ADDHEADERMAGIC);
context = (AddHdrContext *)myself->priv;
pgpAssert(context);
pgpAssert(context->tail);
error = context->tail->annotate(context->tail, origin, type,
string, size);
if (!error)
PGP_SCOPE_DEPTH_UPDATE(context->scope_depth, type);
pgpAssert(context->scope_depth != -1);
return error;
}
/* This is only used in V4 mode */
static PGPError
BufferSizeAdvise(PGPPipeline *myself, PGPFileOffset size)
{
AddHdrContext *context;
PGPError error;
int i;
pgpAssert(myself);
pgpAssert(myself->magic == ADDHEADERMAGIC);
context = (AddHdrContext *)myself->priv;
pgpAssert(context);
pgpAssert(context->tail);
pgpAssert(context->buffer);
/* Do not pass non-zero sizeAdvise -- I can't do that! */
if (size || context->scope_depth)
return( kPGPError_NoErr );
/* Okay, we're at end of input. */
if (context->buflen) {
/* We have a bug when file length is zero; we get here without having
* flushed the header. We can't easily distinguish between a zero
* length file and the EOF sizeadvise, but we don't need to.
*/
error = FlushHeader(context);
if (error)
return error;
if (context->dowrite) {
/* Ready to output a partial body length full buffer */
/* However the last block must not use partial body length */
/* Take out pbl header byte and output it normally */
/* This assumes that the buffer size is less than 8383 bytes,
* so this fix will not work with BIGBLOCKS. We will need
* a different fix for that.
*/
context->bufptr++;
context->buflen--;
context->dowrite = 0;
#ifndef BIGBLOCKS
}
if (context->midflush) {
error = ForceFlush(context);
} else {
i = context->buflen;
if (PKTLEN_ONE_BYTE(i)) {
context->bufptr--;
context->buflen++;
context->bufptr[0] = PKTLEN_1BYTE(i);
} else {
context->bufptr -= 2;
context->buflen += 2;
context->bufptr[0] = PKTLEN_BYTE0(i);
context->bufptr[1] = PKTLEN_BYTE1(i);
}
context->midflush = context->buflen;
#else /* BIGBLOCKS */
} else {
context->lastblock = 1;
#endif /* BIGBLOCKS */
error = ForceFlush(context);
}
if (error)
return error;
}
return context->tail->sizeAdvise(context->tail, 0);
}
/* This is only used in V3 mode */
static PGPError
SizeAdvise(PGPPipeline *myself, PGPFileOffset len)
{
AddHdrContext *context;
PGPFileOffset size;
PGPError error;
int i;
pgpAssert(myself);
pgpAssert(myself->magic == ADDHEADERMAGIC);
context = (AddHdrContext *)myself->priv;
pgpAssert(context);
pgpAssert(context->tail);
pgpAssert(context->fifo);
if (context->scope_depth)
return( kPGPError_NoErr ); /* Can't pass it through */
/*
* The actual size myself module will output is the byte size
* passed in (size), plus the size of the buffered header,
* plus the size of the data in the fifo. However the packet
* size does not include the header size, so add in the header
* size after we compute the header.
*/
/*
* Set the header packet up properly, if we haven't already
* done so. We know how long the length-of-length should be,
* so fill that many bytes of the header in MSB-first order.
*/
if (!context->dowrite) {
size = len + pgpFifoSize (context->fifod, context->fifo);
i = PKTBYTE_LLEN(context->header[0]);
if (size >= 0x10000 && i <= 2)
i = 2;
else if (size >= 0x100 && i <= 1)
i = 1;
context->header[0] = (context->header[0] & ~3) | i;
i = LLEN_TO_BYTES(i);
context->hdrlen = i+1;
while (i--) {
context->header[i+1] = (PGPByte)(size & 0xff);
size >>= 8;
}
}
if (!context->sizeknown) {
context->bytes = len;
context->sizeknown = 1;
} else if (context->bytes != len) {
return kPGPError_SizeAdviseFailure;
}
/*
* Now add in the header size, sizeAdvise the next module, and
* if everything is ok, set the state to dowrite and flush.
*/
size = len + pgpFifoSize (context->fifod, context->fifo)
+ context->hdrlen;
error = context->tail->sizeAdvise(context->tail, size);
if (error)
return error;
context->dowrite = 1;
error = DoFlush(context);
/*
* Just in case we got a sizeAdvise(0) without anything else.
* calling sizeAdvise(0) twice is ok!
*/
if (!error && !len)
error = context->tail->sizeAdvise(context->tail, 0);
return error;
}
static PGPError
Teardown(PGPPipeline *myself)
{
AddHdrContext *context;
PGPContextRef cdkContext;
pgpAssertAddrValid( myself, PGPPipeline );
cdkContext = myself->cdkContext;
pgpAssert(myself);
pgpAssert(myself->magic == ADDHEADERMAGIC);
context = (AddHdrContext *)myself->priv;
pgpAssert(context);
if (context->tail)
context->tail->teardown(context->tail);
if (context->fifo)
pgpFifoDestroy (context->fifod, context->fifo);
if (context->buffer) {
pgpClearMemory(context->buffer, BUFFER_SIZE+2);
pgpContextMemFree( cdkContext, context->buffer);
}
pgpClearMemory(context, sizeof(*context));
pgpContextMemFree( cdkContext, context);
return kPGPError_NoErr;
}
PGPPipeline **
pgpAddHeaderCreate(
PGPContextRef cdkContext,
PGPPipeline ** head,
PgpVersion vers,
PGPFifoDesc const * fd,
PGPByte pkttype,
PGPByte llen,
PGPByte *hdr,
size_t headerlen)
{
PGPPipeline *mod;
PGPFifoContext *fifop = NULL;
AddHdrContext *context;
PGPByte *buf = NULL;
PGPByte pktbite;
if (!head)
return NULL;
pgpAssert(fd);
/* XXX If we have versions > 2.6, ignore llen */
if (vers > PGPVERSION_3)
pktbite = PKTBYTE_BUILD_NEW(pkttype);
else
pktbite = PKTBYTE_BUILD(pkttype, llen);
context = (AddHdrContext *)pgpContextMemAlloc( cdkContext,
sizeof(*context), kPGPMemoryMgrFlags_Clear );
if (!context)
return NULL;
mod = &context->pipe;
if (vers > PGPVERSION_3) {
buf = (PGPByte *)pgpContextMemAlloc( cdkContext,
BUFFER_SIZE + 2, kPGPMemoryMgrFlags_Clear);
if (!buf) {
pgpContextMemFree( cdkContext, context);
return NULL;
}
memcpy(buf+2, hdr, headerlen);
} else {
fifop = pgpFifoCreate ( cdkContext, fd);
if (!fifop) {
pgpContextMemFree( cdkContext, context);
return NULL;
}
if (pgpFifoWrite (fd, fifop, hdr, headerlen) != headerlen) {
pgpContextMemFree( cdkContext, context);
pgpFifoDestroy (fd, fifop);
return NULL;
}
}
mod->magic = ADDHEADERMAGIC;
mod->flush = Flush;
mod->write = Write;
mod->sizeAdvise = SizeAdvise;
mod->annotate = Annotate;
mod->teardown = Teardown;
mod->name = "Add Header Module";
mod->priv = context;
mod->cdkContext = cdkContext;
if (buf) {
mod->write = BufferWrite;
mod->sizeAdvise = BufferSizeAdvise;
}
context->fifod = fd;
context->fifo = fifop;
context->ptr = context->header;
context->header[0] = pktbite;
context->hdrlen = 1;
context->version = vers;
context->buffer = buf;
context->bufptr = buf + 2;
context->bufwrite = context->bufptr + headerlen;
if (vers > PGPVERSION_3)
context->buflen = headerlen;
else if (llen == 3)
context->dowrite = 1;
context->tail = *head;
*head = mod;
return &context->tail;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -