/*
   minibz2
      libbz2.dll test program.
      by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp)
      This file is Public Domain.  Welcome any email to me.

   usage: minibz2 [-d] [-{1,2,..9}] [[srcfilename] destfilename]
*/

#define BZ_IMPORT
#include <stdio.h>
#include <stdlib.h>
#include "bzlib.h"
#ifdef _WIN32
#include <io.h>
#endif


#ifdef _WIN32

#define BZ2_LIBNAME "libbz2-1.0.2.DLL" 

#include <windows.h>
static int BZ2DLLLoaded = 0;
static HINSTANCE BZ2DLLhLib;
int BZ2DLLLoadLibrary(void)
{
   HINSTANCE hLib;

   if(BZ2DLLLoaded==1){return 0;}
   hLib=LoadLibrary(BZ2_LIBNAME);
   if(hLib == NULL){
      fprintf(stderr,"Can't load %s\n",BZ2_LIBNAME);
      return -1;
   }
   BZ2_bzlibVersion=GetProcAddress(hLib,"BZ2_bzlibVersion");
   BZ2_bzopen=GetProcAddress(hLib,"BZ2_bzopen");
   BZ2_bzdopen=GetProcAddress(hLib,"BZ2_bzdopen");
   BZ2_bzread=GetProcAddress(hLib,"BZ2_bzread");
   BZ2_bzwrite=GetProcAddress(hLib,"BZ2_bzwrite");
   BZ2_bzflush=GetProcAddress(hLib,"BZ2_bzflush");
   BZ2_bzclose=GetProcAddress(hLib,"BZ2_bzclose");
   BZ2_bzerror=GetProcAddress(hLib,"BZ2_bzerror");

   if (!BZ2_bzlibVersion || !BZ2_bzopen || !BZ2_bzdopen
       || !BZ2_bzread || !BZ2_bzwrite || !BZ2_bzflush
       || !BZ2_bzclose || !BZ2_bzerror) {
      fprintf(stderr,"GetProcAddress failed.\n");
      return -1;
   }
   BZ2DLLLoaded=1;
   BZ2DLLhLib=hLib;
   return 0;

}
int BZ2DLLFreeLibrary(void)
{
   if(BZ2DLLLoaded==0){return 0;}
   FreeLibrary(BZ2DLLhLib);
   BZ2DLLLoaded=0;
}
#endif /* WIN32 */

void usage(void)
{
   puts("usage: minibz2 [-d] [-{1,2,..9}] [[srcfilename] destfilename]");
}

int main(int argc,char *argv[])
{
   int decompress = 0;
   int level = 9;
   char *fn_r = NULL;
   char *fn_w = NULL;

#ifdef _WIN32
   if(BZ2DLLLoadLibrary()<0){
      fprintf(stderr,"Loading of %s failed.  Giving up.\n", BZ2_LIBNAME);
      exit(1);
   }
   printf("Loading of %s succeeded.  Library version is %s.\n",
          BZ2_LIBNAME, BZ2_bzlibVersion() );
#endif
   while(++argv,--argc){
      if(**argv =='-' || **argv=='/'){
         char *p;

         for(p=*argv+1;*p;p++){
            if(*p=='d'){
               decompress = 1;
            }else if('1'<=*p && *p<='9'){
               level = *p - '0';
            }else{
               usage();
               exit(1);
            }
         }
      }else{
         break;
      }
   }
   if(argc>=1){
      fn_r = *argv;
      argc--;argv++;
   }else{
      fn_r = NULL;
   }
   if(argc>=1){
      fn_w = *argv;
      argc--;argv++;
   }else{
      fn_w = NULL;
   }
   {
      int len;
      char buff[0x1000];
      char mode[10];

      if(decompress){
         BZFILE *BZ2fp_r = NULL;
         FILE *fp_w = NULL;

         if(fn_w){
            if((fp_w = fopen(fn_w,"wb"))==NULL){
               printf("can't open [%s]\n",fn_w);
               perror("reason:");
               exit(1);
            }
         }else{
            fp_w = stdout;
         }
         if((fn_r == NULL && (BZ2fp_r = BZ2_bzdopen(fileno(stdin),"rb"))==NULL)
            || (fn_r != NULL && (BZ2fp_r = BZ2_bzopen(fn_r,"rb"))==NULL)){
            printf("can't bz2openstream\n");
            exit(1);
         }
         while((len=BZ2_bzread(BZ2fp_r,buff,0x1000))>0){
            fwrite(buff,1,len,fp_w);
         }
         BZ2_bzclose(BZ2fp_r);
         if(fp_w != stdout) fclose(fp_w);
      }else{
         BZFILE *BZ2fp_w = NULL;
         FILE *fp_r = NULL;

         if(fn_r){
            if((fp_r = fopen(fn_r,"rb"))==NULL){
               printf("can't open [%s]\n",fn_r);
               perror("reason:");
               exit(1);
            }
         }else{
            fp_r = stdin;
         }
         mode[0]='w';
         mode[1] = '0' + level;
         mode[2] = '\0';

         if((fn_w == NULL && (BZ2fp_w = BZ2_bzdopen(fileno(stdout),mode))==NULL)
            || (fn_w !=NULL && (BZ2fp_w = BZ2_bzopen(fn_w,mode))==NULL)){
            printf("can't bz2openstream\n");
            exit(1);
         }
         while((len=fread(buff,1,0x1000,fp_r))>0){
            BZ2_bzwrite(BZ2fp_w,buff,len);
         }
         BZ2_bzclose(BZ2fp_w);
         if(fp_r!=stdin)fclose(fp_r);
      }
   }
#ifdef _WIN32
   BZ2DLLFreeLibrary();
#endif
   return 0;
}
