Logo Search packages:      
Sourcecode: ksh version File versions  Download package

sfdcbzip.c

/***********************************************************************
*                                                                      *
*              This software is part of the bzip package               *
*                       Copyright (c) 1996-2007                        *
*                                                                      *
* This software is provided 'as-is', without any express or implied    *
* warranty. In no event will the authors be held liable for any        *
* damages arising from the use of this software.                       *
*                                                                      *
* Permission is granted to anyone to use this software for any         *
* purpose, including commercial applications, and to alter it and      *
* redistribute it freely, subject to the following restrictions:       *
*                                                                      *
*  1. The origin of this software must not be misrepresented;          *
*     you must not claim that you wrote the original software. If      *
*     you use this software in a product, an acknowledgment in the     *
*     product documentation would be appreciated but is not            *
*     required.                                                        *
*                                                                      *
*  2. Altered source versions must be plainly marked as such,          *
*     and must not be misrepresented as being the original             *
*     software.                                                        *
*                                                                      *
*  3. This notice may not be removed or altered from any source        *
*     distribution.                                                    *
*                                                                      *
* This program, "bzip2" and associated library "libbzip2", are         *
* copyright (C) 1996-1998 Julian R Seward.  All rights reserved.       *
*                                                                      *
* Redistribution and use in source and binary forms, with or without   *
* modification, are permitted provided that the following conditions   *
* are met:                                                             *
*                                                                      *
* 1. Redistributions of source code must retain the above copyright    *
*    notice, this list of conditions and the following disclaimer.     *
*                                                                      *
* 2. The origin of this software must not be misrepresented; you must  *
*    not claim that you wrote the original software.  If you use this  *
*    software in a product, an acknowledgment in the product           *
*    documentation would be appreciated but is not required.           *
*                                                                      *
* 3. Altered source versions must be plainly marked as such, and must  *
*    not be misrepresented as being the original software.             *
*                                                                      *
* 4. The name of the author may not be used to endorse or promote      *
*    products derived from this software without specific prior written*
*    permission.                                                       *
*                                                                      *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS      *
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED    *
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE   *
* ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY      *
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL   *
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE    *
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS        *
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,         *
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING            *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS   *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.         *
*                                                                      *
* Julian Seward, Guildford, Surrey, UK.                                *
* jseward@acm.org                                                      *
* bzip2/libbzip2 version 0.9.0 of 28 June 1998                         *
*                                                                      *
*                           Julian R Seward                            *
*                                                                      *
***********************************************************************/
#pragma prototyped

/*
 * sfio bzip discipline
 */

#include <sfio_t.h>
#include <ast.h>
#include <bzlib.h>
#include <sfdcbzip.h>

#define bzsync(p,o)     (-1)

typedef struct
{
      Sfdisc_t    disc;       /* sfio discipline            */
      Bz_t*       bz;         /* bz handle                  */
} Sfbzip_t;

/*
 * bzip exception handler
 * free on close
 */

static int
sfbzexcept(Sfio_t* sp, int op, void* val, Sfdisc_t* dp)
{
      register Sfbzip_t*      bz = (Sfbzip_t*)dp;
      int               r;

      NoP(sp);
#if 1
      {
            static char aha[] = "AHA sfdcbzip event 0\n";
            static int  init;

            if (!init)
                  init = getenv("SFBZ_DEBUG") ? 1 : -1;
            if (init > 0)
            {
                  aha[sizeof(aha) - 3] = '0' + op;
                  write(2, aha, sizeof(aha) - 1);
            }
      }
#endif
      switch (op)
      {
      case SF_ATEXIT:
            sfdisc(sp, SF_POPDISC);
            return 0;
      case SF_CLOSING:
      case SF_DPOP:
      case SF_FINAL:
            if (bz->bz)
            {
                  r = bzclose(bz->bz) ? -1 : 0;
                  bz->bz = 0;
            }
            else
                  r = 0;
            if (op != SF_CLOSING)
                  free(dp);
            return r;
      case SF_DBUFFER:
            return 1;
      case SF_READ:
      case SF_WRITE:
            return *((ssize_t*)val) < 0 ? -1 : 0;
      case SF_SYNC:
            return val ? 0 : bzflush(bz->bz);
      case SFBZ_HANDLE:
            return (*((Bz_t**)val) = bz->bz) ? 1 : -1;
      case SFBZ_GETPOS:
            return (*((Sfoff_t*)val) = bzsync(bz->bz, (z_off_t)(-1))) == -1 ? -1 : 0;
      case SFBZ_SETPOS:
            return bzsync(bz->bz, (z_off_t)(*((Sfoff_t*)val))) == -1 ? -1 : 0;
      }
      return 0;
}

/*
 * sfio bzip discipline read
 */

static ssize_t
sfbzread(Sfio_t* fp, Void_t* buf, size_t size, Sfdisc_t* dp)
{
      register Sfbzip_t*      bz = (Sfbzip_t*)dp;

      return bzread(bz->bz, buf, size);
}

/*
 * sfio bzip discipline write
 */

static ssize_t
sfbzwrite(Sfio_t* fp, const Void_t* buf, size_t size, Sfdisc_t* dp)
{
      register Sfbzip_t*      bz = (Sfbzip_t*)dp;

      return (bzwrite(bz->bz, (void*)buf, size) < 0) ? -1 : size;
}

/*
 * create and push the sfio bzip discipline
 *
 * (flags&SFBZ_VERIFY) return
 *    >0    is a bzip file
 *     0    not a bzip file
 *    <0    error
 * otherwise return
 *    >0    discipline pushed
 *     0    discipline not needed
 *    <0    error
 */

int
sfdcbzip(Sfio_t* sp, int flags)
{
      char*       m;
      Sfbzip_t*   bz;
      char        mode[10];

      if (sfset(sp, 0, 0) & SF_READ)
      {
            register unsigned char* s;
            register int            n;

            /*
             * peek the first 4 bytes to verify the magic
             *
             *    BZh[0-9]    sfdcbzip    bzip  
             */
            
            if (!(n = sfset(sp, 0, 0) & SF_SHARE))
                  sfset(sp, SF_SHARE, 1);
            s = (unsigned char*)sfreserve(sp, 4, 1);
            if (!n)
                  sfset(sp, SF_SHARE, 0);
            if (!s)
                  return -1;
            n = s[0] == 'B' && s[1] == 'Z' && s[2] == 'h' && (s[3] >= '0' && s[3] <= '9');
            sfread(sp, s, 0);
            if (!n || (flags & SFBZ_VERIFY))
                  return n;
      }
      else if (flags & SFBZ_VERIFY)
            return -1;
      if (!(bz = newof(0, Sfbzip_t, 1, 0)))
            return -1;
      bz->disc.exceptf = sfbzexcept;
      if (sfset(sp, 0, 0) & SF_READ)
            bz->disc.readf = sfbzread;
      else
            bz->disc.writef = sfbzwrite;
      m = mode;
      *m++ = (sfset(sp, 0, 0) & SF_READ) ? 'r' : 'w';
      *m++ = 'o';
      if ((flags &= 0xf) > 0 && flags <= 9)
            *m++ = '0' + flags;
      *m = 0;
      if (sfdisc(sp, &bz->disc) != &bz->disc || !(bz->bz = bzdopen(sffileno(sp), mode)))
      {
            free(bz);
            return -1;
      }
      sfsetbuf(sp, NiL, SF_BUFSIZE);
      if (!(sfset(sp, 0, 0) & SF_READ))
            sfset(sp, SF_IOCHECK, 1);
      return 1;
}

Generated by  Doxygen 1.6.0   Back to index