⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vms_im.c

📁 给出了 zip 压缩算法的完整实现过程。
💻 C
📖 第 1 页 / 共 2 页
字号:
    return strlen(verbuf) + 1;  /* Transmit ending 0 too */}#define CTXSIG ((ulg)('CtXx'))typedef struct user_context{    ulg sig;    struct FAB *fab;    struct RAB *rab;    unsigned int size;    unsigned int rest;    int status;} Ctx, *Ctxptr;Ctx init_ctx ={        CTXSIG,        NULL,        NULL,        0L,        0L,        0};#define CTXL    sizeof(Ctx)#define CHECK_RAB(_r) ( (_r) != NULL &&                         \                        (_r) -> rab$b_bid == RAB$C_BID &&       \                        (_r) -> rab$b_bln == RAB$C_BLN &&       \                        (_r) -> rab$l_ctx != 0         &&       \                        (_r) -> rab$l_fab != NULL )#define BLOCK_BYTES 512/************************** *   Function vms_open    * **************************/struct RAB *vms_open(name)    char *name;{    struct RAB *rab;    struct FAB *fab;    struct XABFHC *fhc;    Ctxptr ctx;    if ((fab = (struct FAB *) malloc(FABL)) == (struct FAB *)NULL)        return NULL;    if ((rab = (struct RAB *) malloc(RABL)) == (struct RAB *)NULL)    {        free(fab);        return (struct RAB *)NULL;    }    if ((fhc = (struct XABFHC *) malloc(XFHCL)) == (struct XABFHC *)NULL)    {        free(rab);        free(fab);        return (struct RAB *)NULL;    }    if ((ctx = (Ctxptr) malloc(CTXL)) == (Ctxptr)NULL)    {        free(fhc);        free(fab);        free(rab);        return (struct RAB *)NULL;    }    *fab = cc$rms_fab;    *rab = cc$rms_rab;    *fhc = cc$rms_xabfhc;    fab->fab$l_fna = name;    fab->fab$b_fns = strlen(name);    fab->fab$b_fac = FAB$M_GET | FAB$M_BIO;    fab->fab$l_xab = (char*)fhc;    if (ERR(sys$open(fab)))    {        sys$close(fab);        free(fhc);        free(fab);        free(rab);        free(ctx);        return (struct RAB *)NULL;    }    rab->rab$l_fab = fab;    rab->rab$l_rop = RAB$M_BIO;    if (ERR(sys$connect(rab)))    {        sys$close(fab);        free(fab);        free(rab);        free(ctx);        return (struct RAB *)NULL;    }    *ctx = init_ctx;    ctx->rab = rab;    ctx->fab = fab;    if (fhc->xab$l_ebk == 0)    {        /* Only known size is all allocated blocks.           (This occurs with a zero-length file, for example.)        */        ctx->size =        ctx->rest = (fhc->xab$l_hbk) * BLOCK_BYTES;    }    else    {        /* Store normal (used) size in ->size.           If only one -V, store normal (used) size in ->rest.           If -VV, store allocated-blocks size in ->rest.        */        ctx->size =         ((fhc->xab$l_ebk)- 1) * BLOCK_BYTES + fhc->xab$w_ffb;        if (vms_native < 2)            ctx->rest = ctx->size;        else            ctx->rest = (fhc->xab$l_hbk) * BLOCK_BYTES;    }    free(fhc);    fab->fab$l_xab = NULL;    rab->rab$l_ctx = (unsigned) ctx;    return rab;}/************************** *   Function vms_close   * **************************/int vms_close(rab)    struct RAB *rab;{    struct FAB *fab;    Ctxptr ctx;    if (!CHECK_RAB(rab))        return RET_ERROR;    fab = (ctx = (Ctxptr)(rab->rab$l_ctx))->fab;    sys$close(fab);    free(fab);    free(rab);    free(ctx);    return RET_SUCCESS;}/************************** *   Function vms_rewind  * **************************/int vms_rewind(rab)    struct RAB *rab;{    Ctxptr ctx;    int status;    if (!CHECK_RAB(rab))        return RET_ERROR;    ctx = (Ctxptr) (rab->rab$l_ctx);    if (ERR(status = sys$rewind(rab)))    {        ctx->status = status;        return RET_ERROR;    }    ctx->status = 0;    ctx->rest = ctx->size;    return RET_SUCCESS;}#define KByte (2 * BLOCK_BYTES)#define MAX_READ_BYTES (32 * KByte)/************************** *   Function vms_read    * **************************/size_t vms_read(rab, buf, size)struct RAB *rab;char *buf;size_t size;/* *      size must be greater or equal to 512 ! */{    int status;    Ctxptr ctx;    ctx = (Ctxptr)rab->rab$l_ctx;    if (!CHECK_RAB(rab))        return 0;    if (ctx -> rest == 0)        return 0;               /* Eof */    /* If request is smaller than a whole block, fail.       This really should never happen.  (assert()?)    */    if (size < BLOCK_BYTES)        return 0;    /* 2004-09-27 SMS.       Code here now resembles low-level QIO code in VMS_PK.C, but I       doubt that sys$read() will actually get past the official EOF.    */    /* Adjust request size as appropriate. */    if (size > MAX_READ_BYTES)    {        /* Restrict request to MAX_READ_BYTES. */        size = MAX_READ_BYTES;    }    else    {        /* Round odd-ball request up to the next whole block.           This really should never happen.  (assert()?)        */        size = (size + BLOCK_BYTES - 1)& ~(BLOCK_BYTES - 1);    }    /* Reduce "size" when next (last) read would overrun the EOF,       but never below one byte (so we'll always get a nice EOF).    */    if (size > ctx->rest)        size = ctx->rest;    if (size == 0)        size = 1;    rab->rab$l_ubf = buf;    rab->rab$w_usz = size;    status = sys$read(rab);    if (!ERR(status) && rab->rab$w_rsz > 0)    {        ctx -> status = 0;        ctx -> rest -= rab->rab$w_rsz;        return rab->rab$w_rsz;    }    else    {        ctx->status = (status==RMS$_EOF ? 0:status);        if (status == RMS$_EOF)                ctx -> rest = 0;        return 0;    }}/************************** *   Function vms_error   * **************************/int vms_error(rab)    struct RAB *rab;{    if (!CHECK_RAB(rab))        return RET_ERROR;    return ((Ctxptr) (rab->rab$l_ctx))->status;}#ifdef DEBUGstatic void dump_rms_block(p)    uch *p;{    uch bid, len;    int err;    char *type;    char buf[132];    int i;    err = 0;    bid = p[0];    len = p[1];    switch (bid)    {        case FAB$C_BID:            type = "FAB";            break;        case XAB$C_ALL:            type = "xabALL";            break;        case XAB$C_KEY:            type = "xabKEY";            break;        case XAB$C_DAT:            type = "xabDAT";            break;        case XAB$C_RDT:            type = "xabRDT";            break;        case XAB$C_FHC:            type = "xabFHC";            break;        case XAB$C_PRO:            type = "xabPRO";            break;        default:            type = "Unknown";            err = 1;            break;    }    printf("Block @%08X of type %s (%d).", p, type, bid);    if (err)    {        printf("\n");        return;    }    printf(" Size = %d\n", len);    printf(" Offset - Hex - Dec\n");    for (i = 0; i < len; i += 8)    {        int j;        printf("%3d - ", i);        for (j = 0; j < 8; j++)            if (i + j < len)                printf("%02X ", p[i + j]);            else                printf("   ");        printf(" - ");        for (j = 0; j < 8; j++)            if (i + j < len)                printf("%03d ", p[i + j]);            else                printf("    ");        printf("\n");    }}#endif /* DEBUG */#ifdef OLD_COMPRESS# define BC_METHOD      EB_IZVMS_BC00# define        COMP_BLK(to,tos,from,froms) _compress( from,to,froms )#else# define BC_METHOD      EB_IZVMS_BCDEFL# define        COMP_BLK(to,tos,from,froms) memcompress(to,tos,from,froms)#endifstatic uch *_compress_block(to,from,size,sig)register struct IZ_block *to;uch *from;int size;char *sig;{        ulg cl;        to -> sig =  *(ush*)IZ_SIGNATURE;        to -> bid =       *(ulg*)(sig);        to -> flags =           BC_METHOD;        to -> length =  size;#ifdef DEBUG        printf("\nmemcompr(%d,%d,%d,%d)\n",&(to->body[0]),size+PAD,from,size);#endif        cl = COMP_BLK( &(to->body[0]), size+PAD, from, size );#ifdef DEBUG        printf("Compressed to %d\n",cl);#endif        if (cl >= size)        {                memcpy(&(to->body[0]), from, size);                to->flags = EB_IZVMS_BCSTOR;                cl = size;#ifdef DEBUG                printf("Storing block...\n");#endif        }        return (uch*)(to) + (to->size = cl + EXTBSL + RESL) + EB_HEADSIZE;}#define NBITS 32static int _compress(from,to,size)uch *from,*to;int size;{    int off=0;    ulg bitbuf=0;    int bitcnt=0;    int i;#define _BIT(val,len)   {                       \        if (bitcnt + (len) > NBITS)             \            while(bitcnt >= 8)                  \            {                                   \                to[off++] = (uch)bitbuf;        \                bitbuf >>= 8;                   \                bitcnt -= 8;                    \            }                                   \        bitbuf |= ((ulg)(val))<<bitcnt;         \        bitcnt += len;                          \    }#define _FLUSH  {                               \            while(bitcnt>0)                     \            {                                   \                to[off++] = (uch)bitbuf;        \                bitbuf >>= 8;                   \                bitcnt -= 8;                    \            }                                   \        }    for (i=0; i<size; i++)    {        if (from[i])        {                _BIT(1,1);                _BIT(from[i],8);        }        else            _BIT(0,1);    }    _FLUSH;    return off;}#endif /* !UTIL */#endif /* ndef VMS_PK_EXTRA */#endif /* VMS */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -