Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/MariaDB/storage/connect/   (MariaDB Server Version 8.1-8.4©)  Datei vom 1.9.2026 mit Größe 45 kB image not shown  

Quelle  filamzip.cpp   Sprache: C

 

/*********** File AM Zip C++ Program Source Code File (.CPP) ***********/
/* PROGRAM NAME: FILAMZIP                                              */
/* -------------                                                       */
/*  Version 1.4                                                        */
/*                                                                     */
/* COPYRIGHT:                                                          */
/* ----------                                                          */
/*  (C) Copyright to the author Olivier BERTRAND          2016-2020    */
/*                                                                     */
/* WHAT THIS PROGRAM DOES:                                             */
/* -----------------------                                             */
/*  This program are the ZIP file access method classes.               */
/*                                                                     */
/***********************************************************************/

/***********************************************************************/
/*  Include relevant sections of the System header files.              */
/***********************************************************************/
#include "my_global.h"
#if !defined(_WIN32)
#if defined(UNIX)
#include <fnmatch.h>
#include <errno.h>
#include <dirent.h>
#include <unistd.h>
#else    // !UNIX
#include <io.h>
#endif  // !UNIX
#include <fcntl.h>
#endif  // !_WIN32
#include <time.h>
#include <m_string.h>

/***********************************************************************/
/*  Include application header files:                                  */
/*  global.h    is header containing all global declarations.          */
/*  plgdbsem.h  is header containing the DB application declarations.  */
/***********************************************************************/
#include "global.h"
#include "plgdbsem.h"
#include "osutil.h"
#include "filamtxt.h"
#include "tabfmt.h"
//#include "tabzip.h"
#include "filamzip.h"

#define WRITEBUFFERSIZE (16384)

/****************************************************************************/
/*  Definitions used for DBF tables.                                        */
/****************************************************************************/
#define HEADLEN       32            /* sizeof ( mainhead or thisfield )     */
//efine MEMOLEN       10            /* length of memo field in .dbf         */
#define DBFTYPE        3            /* value of bits 0 and 1 if .dbf        */
#define EOH         0x0D            /* end-of-header marker in .dbf file    */

/****************************************************************************/
/*  First 32 bytes of a DBF table.                                          */
/*  Note: some reserved fields are used here to store info (Fields)         */
/****************************************************************************/
typedef struct _dbfheader {
 uchar  Version;                   /*  Version information flags           */
 char   Filedate[3];               /*  date, YYMMDD, binary. YY=year-1900  */
private:
 /* The following four members are stored in little-endian format on disk  */
 char   m_RecordsBuf[4];           /*  records in the file                 */
 char   m_HeadlenBuf[2];           /*  bytes in the header                 */
 char   m_ReclenBuf[2];            /*  bytes in a record                   */
 char   m_FieldsBuf[2];            /*  Reserved but used to store fields   */
public:
 char   Incompleteflag;            /*  01 if incomplete, else 00           */
 char   Encryptflag;               /*  01 if encrypted, else 00            */
 char   Reserved2[12];             /*  for LAN use                         */
 char   Mdxflag;                   /*  01 if production .mdx, else 00      */
 char   Language;                  /*  Codepage                            */
 char   Reserved3[2];

 uint   Records(void) const { return uint4korr(m_RecordsBuf); }
 ushort Headlen(void) const { return uint2korr(m_HeadlenBuf); }
 ushort Reclen(void)  const { return uint2korr(m_ReclenBuf); }
 ushort Fields(void)  const { return uint2korr(m_FieldsBuf); }

 void   SetHeadlen(ushort num) { int2store(m_HeadlenBuf, num); }
 void   SetReclen(ushort num) { int2store(m_ReclenBuf, num); }
 void   SetFields(ushort num) { int2store(m_FieldsBuf, num); }
} DBFHEADER;

/****************************************************************************/
/*  Column field descriptor of a .dbf file.                                 */
/****************************************************************************/
typedef struct _descriptor {
 char  Name[11];                   /*  field name, in capitals, null filled*/
 char  Type;                       /*  field type, C, D, F, L, M or N      */
 uint  Offset;                     /*  used in memvars, not in files.      */
 uchar Length;                     /*  field length                        */
 uchar Decimals;                   /*  number of decimal places            */
 short Reserved4;
 char  Workarea;                   /*  ???                                 */
 char  Reserved5[2];
 char  Setfield;                   /*  ???                                 */
 char  Reserved6[7];
 char  Mdxfield;                   /* 01 if tag field in production .mdx   */
} DESCRIPTOR;

bool ZipLoadFile(PGLOBAL g, PCSZ zfn, PCSZ fn, PCSZ entry, bool append, bool mul);

/***********************************************************************/
/*  Compress a file in zip when creating a table.                      */
/***********************************************************************/
static bool ZipFile(PGLOBAL g, ZIPUTIL *zutp, PCSZ fn, PCSZ entry, char *buf)
{
 int   rc = RC_OK, size_read, size_buf = WRITEBUFFERSIZE;
 FILE *fin;

 if (zutp->addEntry(g, entry))
  return true;
 else if (!(fin = fopen(fn, "rb"))) {
  snprintf(g->Message, sizeof(g->Message), "error in opening %s for reading", fn);
  return true;
 } // endif fin

 do {
  size_read = (int)fread(buf, 1, size_buf, fin);

  if (size_read < size_buf && feof(fin) == 0) {
   snprintf(g->Message, sizeof(g->Message), "error in reading %s", fn);
   rc = RC_FX;
  } // endif size_read

  if (size_read > 0) {
   rc = zutp->writeEntry(g, buf, size_read);

   if (rc == RC_FX)
    snprintf(g->Message, sizeof(g->Message), "error in writing %s in the zipfile", fn);

  } // endif size_read

 } while (rc == RC_OK && size_read > 0);

 fclose(fin);
 zutp->closeEntry();
 return rc != RC_OK;
} // end of ZipFile

/***********************************************************************/
/*  Find and Compress several files in zip when creating a table.      */
/***********************************************************************/
static bool ZipFiles(PGLOBAL g, ZIPUTIL *zutp, PCSZ pat, char *buf)
{
 char filename[_MAX_PATH];

 /*********************************************************************/
 /*  pat is a multiple file name with wildcard characters             */
 /*********************************************************************/
 snprintf(filename, sizeof(filename), "%s", pat);

#if defined(_WIN32)
 int  rc;
 char   drive[_MAX_DRIVE], direc[_MAX_DIR];
 WIN32_FIND_DATA FileData;
 HANDLE hSearch;

 _splitpath(filename, drive, direc, NULL, NULL);

 // Start searching files in the target directory.
 hSearch = FindFirstFile(filename, &FileData);

 if (hSearch == INVALID_HANDLE_VALUE) {
  rc = GetLastError();

  if (rc != ERROR_FILE_NOT_FOUND) {
   FormatMessage(FORMAT_MESSAGE_FLAGS,
    NULL, GetLastError(), 0, (LPTSTR)&filename, sizeof(filename), NULL);
   snprintf(g->Message, sizeof(g->Message), MSG(BAD_FILE_HANDLE), filename);
   return true;
  } else {
   snprintf(g->Message, sizeof(g->Message), "Cannot find any file to load");
   return true;
  } // endif rc

 } // endif hSearch

 while (true) {
  if (!(FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
   snprintf(filename, sizeof(filename), "%s%s%s",
     drive, direc, FileData.cFileName);

   if (ZipFile(g, zutp, filename, FileData.cFileName, buf)) {
    FindClose(hSearch);
    return true;
   } // endif ZipFile

  } // endif dwFileAttributes

  if (!FindNextFile(hSearch, &FileData)) {
   rc = GetLastError();

   if (rc != ERROR_NO_MORE_FILES) {
    snprintf(g->Message, sizeof(g->Message), MSG(NEXT_FILE_ERROR), rc);
    FindClose(hSearch);
    return true;
   } // endif rc

   break;
  } // endif FindNextFile

 } // endwhile n

 // Close the search handle.
 if (!FindClose(hSearch)) {
  snprintf(g->Message, sizeof(g->Message), MSG(SRCH_CLOSE_ERR));
  return true;
 } // endif FindClose

#else   // !_WIN32
 struct stat fileinfo;
 char   fn[FN_REFLEN], direc[FN_REFLEN], pattern[FN_HEADLEN], ftype[FN_EXTLEN];
 DIR   *dir;
 struct dirent *entry;

 _splitpath(filename, NULL, direc, pattern, ftype);
 safe_strcat(pattern, sizeof(pattern), ftype);

 // Start searching files in the target directory.
 if (!(dir = opendir(direc))) {
  snprintf(g->Message, sizeof(g->Message), MSG(BAD_DIRECTORY), direc, strerror(errno));
  return true;
 } // endif dir

 while ((entry = readdir(dir))) {
  snprintf(fn, sizeof(fn), "%s%s", direc, entry->d_name);

  if (lstat(fn, &fileinfo) < 0) {
   snprintf(g->Message, sizeof(g->Message), "%s: %s", fn, strerror(errno));
   closedir(dir);
   return true;
  } else if (!S_ISREG(fileinfo.st_mode))
   continue;      // Not a regular file (should test for links)

  /*******************************************************************/
  /*  Test whether the file name matches the table name filter.      */
  /*******************************************************************/
  if (fnmatch(pattern, entry->d_name, 0))
   continue;      // Not a match

  snprintf(filename, sizeof(filename), "%s%s", direc, entry->d_name);

  if (ZipFile(g, zutp, filename, entry->d_name, buf)) {
   closedir(dir);
   return true;
  } // endif ZipFile

 } // endwhile readdir

 // Close the dir handle.
 closedir(dir);
#endif  // !_WIN32

 return false;
} // end of ZipFiles

/***********************************************************************/
/*  Load and Compress a file in zip when creating a table.             */
/***********************************************************************/
bool ZipLoadFile(PGLOBAL g, PCSZ zfn, PCSZ fn, PCSZ entry, bool append, bool mul)
{
 char    *buf;
 bool     err;
 ZIPUTIL *zutp = new(g) ZIPUTIL(NULL);

 if (zutp->open(g, zfn, append))
  return true;

 buf = (char*)PlugSubAlloc(g, NULL, WRITEBUFFERSIZE);

 if (!mul) {
  PCSZ entp;

  if (!entry) {    // entry defaults to the file name
   char* p = strrchr((char*)fn, '/');
#if defined(_WIN32)
   if (!p) p = strrchr((char*)fn, '\\');
#endif  //  _WIN32
   entp = (p) ? p + 1 : entry;
  } else
   entp = entry;

  err = ZipFile(g, zutp, fn, entp, buf);
 } else
   err = ZipFiles(g, zutp, fn, buf);

 zutp->close();
 return err;
} // end of ZipLoadFile

/* -------------------------- class ZIPUTIL -------------------------- */

/***********************************************************************/
/*  Constructors.                                                      */
/***********************************************************************/
ZIPUTIL::ZIPUTIL(PCSZ tgt)
{
 zipfile = NULL;
 target = tgt;
 pwd = NULL;
 fp = NULL;
 entryopen = false;
} // end of ZIPUTIL standard constructor

#if 0
ZIPUTIL::ZIPUTIL(ZIPUTIL *zutp)
{
 zipfile = zutp->zipfile;
 target = zutp->target;
 pwd = zutp->pwd;
 fp = zutp->fp;
 entryopen = zutp->entryopen;
} // end of UNZIPUTL copy constructor
#endif // 0

/***********************************************************************/
/*  Fill the zip time structure  */
/*  param: tmZip time structure to be filled  */
/***********************************************************************/
void ZIPUTIL::getTime(tm_zip& tmZip)
{
 time_t rawtime;
 time(&rawtime);
 struct tm *timeinfo = localtime(&rawtime);
 tmZip.tm_sec = timeinfo->tm_sec;
 tmZip.tm_min = timeinfo->tm_min;
 tmZip.tm_hour = timeinfo->tm_hour;
 tmZip.tm_mday = timeinfo->tm_mday;
 tmZip.tm_mon = timeinfo->tm_mon;
 tmZip.tm_year = timeinfo->tm_year;
} // end of getTime

/***********************************************************************/
/*  open a zip file for deflate.  */
/*  param: filename path and the filename of the zip file to open.  */
/* append: set true to append the zip file  */
/*  return: true if open, false otherwise.  */
/***********************************************************************/
bool ZIPUTIL::open(PGLOBAL g, PCSZ filename, bool append)
{
 if (!zipfile && !(zipfile = zipOpen64(filename,
                                 append ? APPEND_STATUS_ADDINZIP
                         : APPEND_STATUS_CREATE)))
  snprintf(g->Message, sizeof(g->Message), "Zipfile open error on %s", filename);

 return (zipfile == NULL);
} // end of open

/***********************************************************************/
/*  Close the zip file.  */
/***********************************************************************/
void ZIPUTIL::close()
{
 if (zipfile) {
  closeEntry();
  zipClose(zipfile, 0);
  zipfile = NULL;
 } // endif zipfile

 if (fp)
  fp->Count = 0;

} // end of close

/***********************************************************************/
/*  OpenTableFile: Open a DOS/UNIX table file from a ZIP file.         */
/***********************************************************************/
bool ZIPUTIL::OpenTable(PGLOBAL g, MODE mode, PCSZ fn, bool append)
{
 /*********************************************************************/
 /*  The file will be compressed.                                     */
 /*********************************************************************/
 if (mode == MODE_INSERT) {
  bool b = open(g, fn, append);

  if (!b) {
   if (addEntry(g, target))
    return true;

   /*****************************************************************/
   /*  Link a Fblock. This make possible to automatically close it  */
   /*  in case of error g->jump.                                    */
   /*****************************************************************/
   PDBUSER dbuserp = (PDBUSER)g->Activityp->Aptr;

   fp = (PFBLOCK)PlugSubAlloc(g, NULL, sizeof(FBLOCK));
   fp->Type = TYPE_FB_ZIP;
   fp->Fname = PlugDup(g, fn);
   fp->Next = dbuserp->Openlist;
   dbuserp->Openlist = fp;
   fp->Count = 1;
   fp->Length = 0;
   fp->Memory = NULL;
   fp->Mode = mode;
   fp->File = this;
   fp->Handle = 0;
  } else
   return true;

 } else {
  snprintf(g->Message, sizeof(g->Message), "Only INSERT mode supported for ZIPPING files");
  return true;
 } // endif mode

 return false;
} // end of OpenTableFile

/***********************************************************************/
/*  Add target in zip file.             */
/***********************************************************************/
bool ZIPUTIL::addEntry(PGLOBAL g, PCSZ entry)
{
 //?? we dont need the stinking time
 zip_fileinfo zi = { {0, 0, 0, 0, 0, 0}, 0, 0, 0 };

 getTime(zi.tmz_date);
 target = entry;

 int err = zipOpenNewFileInZip(zipfile, target, &zi,
          NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION);

 return !(entryopen = (err == ZIP_OK));
} // end of addEntry

/***********************************************************************/
/*  writeEntry: Deflate the buffer to the zip file.                    */
/***********************************************************************/
int ZIPUTIL::writeEntry(PGLOBAL g, char *buf, int len)
{
 if (zipWriteInFileInZip(zipfile, buf, len) < 0) {
  snprintf(g->Message, sizeof(g->Message), "Error writing %s in the zipfile", target);
  return RC_FX;
 } // endif zipWriteInFileInZip

 return RC_OK;
} // end of writeEntry

/***********************************************************************/
/*  Close the zip file.  */
/***********************************************************************/
void ZIPUTIL::closeEntry()
{
 if (entryopen) {
  zipCloseFileInZip(zipfile);
  entryopen = false;
 } // endif entryopen

} // end of closeEntry

/* ------------------------- class UNZIPUTL -------------------------- */

/***********************************************************************/
/*  Constructors.                                                      */
/***********************************************************************/
UNZIPUTL::UNZIPUTL(PCSZ tgt, PCSZ pw, bool mul)
{
 zipfile = NULL;
 target = tgt;
 pwd = pw;
 fp = NULL;
 memory = NULL;
 size = 0;
 entryopen = false;
 multiple = mul;
 memset(fn, 0, sizeof(fn));

 // Init the case mapping table.
#if defined(_WIN32)
 for (int i = 0; i < 256; ++i) mapCaseTable[i] = toupper(i);
#else
 for (int i = 0; i < 256; ++i) mapCaseTable[i] = i;
#endif
} // end of UNZIPUTL standard constructor

UNZIPUTL::UNZIPUTL(PDOSDEF tdp)
{
 zipfile = NULL;
 target = tdp->GetEntry();
 pwd = tdp->Pwd;
 fp = NULL;
 memory = NULL;
 size = 0;
 entryopen = false;
 multiple = tdp->GetMul();
 memset(fn, 0, sizeof(fn));

 // Init the case mapping table.
#if defined(_WIN32)
 for (int i = 0; i < 256; ++i) mapCaseTable[i] = toupper(i);
#else
 for (int i = 0; i < 256; ++i) mapCaseTable[i] = i;
#endif
} // end of UNZIPUTL standard constructor

#if 0
UNZIPUTL::UNZIPUTL(PZIPUTIL zutp)
{
 zipfile = zutp->zipfile;
 target = zutp->target;
 fp = zutp->fp;
 finfo = zutp->finfo;
 entryopen = zutp->entryopen;
 multiple = zutp->multiple;
 for (int i = 0; i < 256; ++i) mapCaseTable[i] = zutp->mapCaseTable[i];
} // end of UNZIPUTL copy constructor
#endif // 0

/***********************************************************************/
/* This code is the copyright property of Alessandro Felice Cantatore. */
/* http://xoomer.virgilio.it/acantato/dev/wildcard/wildmatch.html  */
/***********************************************************************/
bool UNZIPUTL::WildMatch(PCSZ pat, PCSZ str) {
 PCSZ s, p;
 bool star = FALSE;

loopStart:
 for (s = str, p = pat; *s; ++s, ++p) {
  switch (*p) {
  case '?':
   if (*s == '.') goto starCheck;
   break;
  case '*':
   star = TRUE;
   str = s, pat = p;
   if (!*++pat) return TRUE;
   goto loopStart;
  default:
   if (mapCaseTable[(uint)*s] != mapCaseTable[(uint)*p])
    goto starCheck;
   break;
  } /* endswitch */
 } /* endfor */
 if (*p == '*') ++p;
 return (!*p);

starCheck:
 if (!star) return FALSE;
 str++;
 goto loopStart;
} // end of WildMatch

/***********************************************************************/
/*  open a zip file.  */
/*  param: filename path and the filename of the zip file to open.  */
/*  return: true if open, false otherwise.  */
/***********************************************************************/
bool UNZIPUTL::open(PGLOBAL g, PCSZ filename)
{
 if (!zipfile && !(zipfile = unzOpen64(filename)))
  snprintf(g->Message, sizeof(g->Message), "Zipfile open error on %s", filename);

 return (zipfile == NULL);
} // end of open

/***********************************************************************/
/*  Close the zip file.  */
/***********************************************************************/
void UNZIPUTL::close()
{
 if (zipfile) {
  closeEntry();
  unzClose(zipfile);
  zipfile = NULL;
 } // endif zipfile

 if (fp)
  fp->Count = 0;

} // end of close

/***********************************************************************/
/*  Find next entry matching target pattern.                           */
/***********************************************************************/
int UNZIPUTL::findEntry(PGLOBAL g, bool next)
{
 int  rc;

 do {
  if (next) {
   rc = unzGoToNextFile(zipfile);

   if (rc == UNZ_END_OF_LIST_OF_FILE)
    return RC_EF;
   else if (rc != UNZ_OK) {
    snprintf(g->Message, sizeof(g->Message), "unzGoToNextFile rc = %d", rc);
    return RC_FX;
   } // endif rc

  } // endif next

  if (target && *target) {
   rc = unzGetCurrentFileInfo(zipfile, NULL, fn, sizeof(fn),
    NULL, 0, NULL, 0);
   if (rc == UNZ_OK) {
    if (WildMatch(target, fn))
     return RC_OK;

   } else {
    snprintf(g->Message, sizeof(g->Message), "GetCurrentFileInfo rc = %d", rc);
    return RC_FX;
   } // endif rc

  } else
   return RC_OK;

  next = true;
 } while (true);

 snprintf(g->Message, sizeof(g->Message), "FindNext logical error");
 return RC_FX;
} // end of FindEntry


/***********************************************************************/
/*  Get the next used entry.                                           */
/***********************************************************************/
int UNZIPUTL::nextEntry(PGLOBAL g)
{
 if (multiple) {
  int rc;

  closeEntry();

  if ((rc = findEntry(g, true)) != RC_OK)
   return rc;

  if (openEntry(g))
   return RC_FX;

  return RC_OK;
 } else
  return RC_EF;

} // end of nextEntry


/***********************************************************************/
/*  OpenTableFile: Open a DOS/UNIX table file from a ZIP file.         */
/***********************************************************************/
bool UNZIPUTL::OpenTable(PGLOBAL g, MODE mode, PCSZ fn)
{
 /*********************************************************************/
 /*  The file will be decompressed into virtual memory.               */
 /*********************************************************************/
 if (mode == MODE_READ || mode == MODE_ANY) {
  bool b = open(g, fn);

  if (!b) {
   int rc;

   if (target && *target) {
    if (!multiple) {
     rc = unzLocateFile(zipfile, target, 0);

     if (rc == UNZ_END_OF_LIST_OF_FILE) {
      snprintf(g->Message, sizeof(g->Message), "Target file %s not in %s", target, fn);
      return true;
     } else if (rc != UNZ_OK) {
      snprintf(g->Message, sizeof(g->Message), "unzLocateFile rc=%d", rc);
      return true;
     } // endif's rc

    } else {
     if ((rc = findEntry(g, false)) == RC_FX)
      return true;
     else if (rc == RC_EF) {
      snprintf(g->Message, sizeof(g->Message), "No match of %s in %s", target, fn);
      return true;
     } // endif rc

    } // endif multiple

   } // endif target

   if (openEntry(g))
    return true;

   if (size > 0) {
    /*******************************************************************/
    /*  Link a Fblock. This make possible to automatically close it    */
    /*  in case of error g->jump.                                      */
    /*******************************************************************/
    PDBUSER dbuserp = (PDBUSER)g->Activityp->Aptr;

    fp = (PFBLOCK)PlugSubAlloc(g, NULL, sizeof(FBLOCK));
    fp->Type = TYPE_FB_ZIP;
    fp->Fname = PlugDup(g, fn);
    fp->Next = dbuserp->Openlist;
    dbuserp->Openlist = fp;
    fp->Count = 1;
    fp->Length = size;
    fp->Memory = memory;
    fp->Mode = mode;
    fp->File = this;
    fp->Handle = 0;
   } // endif fp

  } else
   return true;

 } else {
  snprintf(g->Message, sizeof(g->Message), "Only READ mode supported for ZIPPED tables");
  return true;
 } // endif mode

 return false;
} // end of OpenTableFile

/***********************************************************************/
/*  Insert only if the entry does not exist.     */
/***********************************************************************/
bool UNZIPUTL::IsInsertOk(PGLOBAL g, PCSZ fn)
{
 bool ok = true, b = open(g, fn);

 if (!b) {
  if (!target || *target == 0) {
   unz_global_info64 ginfo;
   int err = unzGetGlobalInfo64(zipfile, &ginfo);

   ok = !(err == UNZ_OK && ginfo.number_entry > 0);
  } else      // Check if the target exist
   ok = (unzLocateFile(zipfile, target, 0) != UNZ_OK);

  unzClose(zipfile);
 } // endif b

 return ok;
} // end of IsInsertOk

/***********************************************************************/
/*  Open target in zip file.         */
/***********************************************************************/
bool UNZIPUTL::openEntry(PGLOBAL g)
{
 int rc;

 rc = unzGetCurrentFileInfo(zipfile, &finfo, fn, sizeof(fn),
  NULL, 0, NULL, 0);

 if (rc != UNZ_OK) {
  snprintf(g->Message, sizeof(g->Message), "unzGetCurrentFileInfo64 rc=%d", rc);
  return true;
 } else if ((rc = unzOpenCurrentFilePassword(zipfile, pwd)) != UNZ_OK) {
  snprintf(g->Message, sizeof(g->Message), "unzOpen fn=%s rc=%d", fn, rc);
  return true;
 } // endif rc

 size = finfo.uncompressed_size;

 try {
  memory = new char[size + 1];
 } catch (...) {
  snprintf(g->Message, sizeof(g->Message), "Out of memory");
  return true;
 } // end try/catch

 if ((rc = unzReadCurrentFile(zipfile, memory, size)) < 0) {
  snprintf(g->Message, sizeof(g->Message), "unzReadCurrentFile rc = %d", rc);
  unzCloseCurrentFile(zipfile);
  delete[] memory;
  memory = NULL;
  entryopen = false;
 } else {
  memory[size] = 0;    // Required by some table types (XML)
  entryopen = true;
 } // endif rc

 if (trace(1))
  htrc("Opening entry%s %s\n", fn, (entryopen) ? "oked" : "failed");

 return !entryopen;
} // end of openEntry

/***********************************************************************/
/*  Close the zip file.  */
/***********************************************************************/
void UNZIPUTL::closeEntry()
{
 if (entryopen) {
  unzCloseCurrentFile(zipfile);
  entryopen = false;
 } // endif entryopen

 if (memory) {
  delete[] memory;
  memory = NULL;
 } // endif memory

} // end of closeEntry

/* -------------------------- class UNZFAM --------------------------- */

/***********************************************************************/
/*  Constructors.                                                      */
/***********************************************************************/
UNZFAM::UNZFAM(PDOSDEF tdp) : MAPFAM(tdp)
{
 zutp = NULL;
 tdfp = tdp;
  //target = tdp->GetEntry();
 //mul = tdp->GetMul();
} // end of UNZFAM standard constructor

UNZFAM::UNZFAM(PUNZFAM txfp) : MAPFAM(txfp)
{
 zutp = txfp->zutp;
 tdfp = txfp->tdfp;
 //target = txfp->target;
 //mul = txfp->mul;
} // end of UNZFAM copy constructor

/***********************************************************************/
/*  ZIP GetFileLength: returns file size in number of bytes.           */
/***********************************************************************/
int UNZFAM::GetFileLength(PGLOBAL g)
{
 int len = (zutp && zutp->entryopen) ? (int)(Top - Memory)
                                    : TXTFAM::GetFileLength(g) * 3;

 if (trace(1))
  htrc("Zipped file length=%d\n", len);

 return len;
} // end of GetFileLength

/***********************************************************************/
/*  ZIP Cardinality: return the number of rows if possible.            */
/***********************************************************************/
int UNZFAM::Cardinality(PGLOBAL g)
{
 if (!g)
  return 1;

 int card = -1;
 int len = GetFileLength(g);

 if (len) {
  // Estimated ???
  card = (len / (int)Lrecl) * 2;
  card = card ? card : 10;    // Lrecl can be too big 
 } else
  card = 0;

 return card;
} // end of Cardinality

/***********************************************************************/
/*  OpenTableFile: Open a DOS/UNIX table file from a ZIP file.         */
/***********************************************************************/
bool UNZFAM::OpenTableFile(PGLOBAL g)
{
 char    filename[_MAX_PATH];
 MODE    mode = Tdbp->GetMode();

 /*********************************************************************/
 /*  Allocate the ZIP utility class.                                  */
 /*********************************************************************/
 zutp = new(g) UNZIPUTL(tdfp);

 //  We used the file name relative to recorded datapath
 PlugSetPath(filename, To_File, Tdbp->GetPath());

 if (!zutp->OpenTable(g, mode, filename)) {
  // The pseudo "buffer" is here the entire real buffer
  Fpos = Mempos = Memory = zutp->memory;
  Top = Memory + zutp->size;
  To_Fb = zutp->fp;                           // Useful when closing
 } else
  return true;

 return false;
 } // end of OpenTableFile

/***********************************************************************/
/*  GetNext: go to next entry.                                         */
/***********************************************************************/
int UNZFAM::GetNext(PGLOBAL g)
{
 int rc = zutp->nextEntry(g);

 if (rc != RC_OK)
  return rc;

 Mempos = Memory = zutp->memory;
 Top = Memory + zutp->size;
 return RC_OK;
} // end of GetNext

#if 0
/***********************************************************************/
/*  ReadBuffer: Read one line for a ZIP file.                          */
/***********************************************************************/
int UNZFAM::ReadBuffer(PGLOBAL g)
{
 int rc, len;

 // Are we at the end of the memory
 if (Mempos >= Top) {
  if ((rc = zutp->nextEntry(g)) != RC_OK)
   return rc;

  Mempos = Memory = zutp->memory;
  Top = Memory + zutp->size;
 } // endif Mempos

#if 0
 if (!Placed) {
  /*******************************************************************/
  /*  Record file position in case of UPDATE or DELETE.              */
  /*******************************************************************/
  int rc;

 next:
  Fpos = Mempos;
  CurBlk = (int)Rows++;

  /*******************************************************************/
  /*  Check whether optimization on ROWID                            */
  /*  can be done, as well as for join as for local filtering.       */
  /*******************************************************************/
  switch (Tdbp->TestBlock(g)) {
  case RC_EF:
   return RC_EF;
  case RC_NF:
   // Skip this record
   if ((rc = SkipRecord(g, false)) != RC_OK)
    return rc;

   goto next;
  } // endswitch rc

 } else
  Placed = false;
#else
 // Perhaps unuseful
 Fpos = Mempos;
 CurBlk = (int)Rows++;
 Placed = false;
#endif

 // Immediately calculate next position (Used by DeleteDB)
 while (*Mempos++ != '\n');        // What about Unix ???

 // Set caller line buffer
 len = (Mempos - Fpos) - 1;

 // Don't rely on ENDING setting
 if (len > 0 && *(Mempos - 2) == '\r')
  len--;             // Line ends by CRLF

 memcpy(Tdbp->GetLine(), Fpos, len);
 Tdbp->GetLine()[len] = '\0';
 return RC_OK;
} // end of ReadBuffer

/***********************************************************************/
/*  Table file close routine for MAP access method.                    */
/***********************************************************************/
void UNZFAM::CloseTableFile(PGLOBAL g, bool)
{
 close();
} // end of CloseTableFile
#endif // 0

/* -------------------------- class UZXFAM --------------------------- */

/***********************************************************************/
/*  Constructors.                                                      */
/***********************************************************************/
UZXFAM::UZXFAM(PDOSDEF tdp) : MPXFAM(tdp)
{
 zutp = NULL;
 tdfp = tdp;
 //target = tdp->GetEntry();
 //mul = tdp->GetMul();
 //Lrecl = tdp->GetLrecl();
} // end of UZXFAM standard constructor

UZXFAM::UZXFAM(PUZXFAM txfp) : MPXFAM(txfp)
{
 zutp = txfp->zutp;
 tdfp = txfp->tdfp;
 //target = txfp->target;
 //mul = txfp->mul;
 //Lrecl = txfp->Lrecl;
} // end of UZXFAM copy constructor

/***********************************************************************/
/*  ZIP GetFileLength: returns file size in number of bytes.           */
/***********************************************************************/
int UZXFAM::GetFileLength(PGLOBAL g)
{
 int len;

 if (!zutp && OpenTableFile(g))
  return 0;

 if (zutp->entryopen)
  len = zutp->size;
 else
  len = 0;

 return len;
} // end of GetFileLength

/***********************************************************************/
/*  ZIP Cardinality: return the number of rows if possible.            */
/***********************************************************************/
int UZXFAM::Cardinality(PGLOBAL g)
{
 if (!g)
  return 1;

 int card = -1;
 int len = GetFileLength(g);

 if (!(len % Lrecl))
  card = len / (int)Lrecl;           // Fixed length file
 else
  snprintf(g->Message, sizeof(g->Message), MSG(NOT_FIXED_LEN), zutp->fn, len, Lrecl);

 // Set number of blocks for later use
 Block = (card > 0) ? (card + Nrec - 1) / Nrec : 0;
 return card;
} // end of Cardinality

/***********************************************************************/
/*  OpenTableFile: Open a FIX/UNIX table file from a ZIP file.         */
/***********************************************************************/
bool UZXFAM::OpenTableFile(PGLOBAL g)
{
 // May have been already opened in GetFileLength
 if (!zutp || !zutp->zipfile) {
  char    filename[_MAX_PATH];
  MODE    mode = Tdbp->GetMode();

  /*********************************************************************/
  /*  Allocate the ZIP utility class.                                  */
  /*********************************************************************/
  if (!zutp)
   zutp = new(g)UNZIPUTL(tdfp);

  //  We used the file name relative to recorded datapath
  PlugSetPath(filename, To_File, Tdbp->GetPath());

  if (!zutp->OpenTable(g, mode, filename)) {
   // The pseudo "buffer" is here the entire real buffer
   Memory = zutp->memory;
   Fpos = Mempos = Memory + Headlen;
   Top = Memory + zutp->size;
   To_Fb = zutp->fp;                           // Useful when closing
  } else
   return true;

 } else
  Reset();

 return false;
} // end of OpenTableFile

/***********************************************************************/
/*  GetNext: go to next entry.                                         */
/***********************************************************************/
int UZXFAM::GetNext(PGLOBAL g)
{
 int rc = zutp->nextEntry(g);

 if (rc != RC_OK)
   return rc;

 int len = zutp->size;

 if (len % Lrecl) {
  snprintf(g->Message, sizeof(g->Message), MSG(NOT_FIXED_LEN), zutp->fn, len, Lrecl);
  return RC_FX;
 } // endif size

 Memory = zutp->memory;
 Top = Memory + len;
 Rewind();
 return RC_OK;
} // end of GetNext

/* -------------------------- class UZDFAM --------------------------- */

/***********************************************************************/
/*  Constructors.                                                      */
/***********************************************************************/
UZDFAM::UZDFAM(PDOSDEF tdp) : DBMFAM(tdp)
{
 zutp = NULL;
 tdfp = tdp;
 //target = tdp->GetEntry();
 //mul = tdp->GetMul();
 //Lrecl = tdp->GetLrecl();
} // end of UZXFAM standard constructor

UZDFAM::UZDFAM(PUZDFAM txfp) : DBMFAM(txfp)
{
 zutp = txfp->zutp;
 tdfp = txfp->tdfp;
 //target = txfp->target;
 //mul = txfp->mul;
 //Lrecl = txfp->Lrecl;
} // end of UZXFAM copy constructor

#if 0
/****************************************************************************/
/*  dbfhead: Routine to analyze a DBF header.                               */
/*  Parameters:                                                             */
/*      PGLOBAL g       -- pointer to the CONNECT Global structure          */
/*      DBFHEADER *hdrp -- pointer to _dbfheader structure                  */
/*  Returns:                                                                */
/*      RC_OK, RC_NF, RC_INFO, or RC_FX if error.                           */
/*  Side effects:                                                           */
/*      Set the fields number in the header.                                */
/****************************************************************************/
int UZDFAM::dbfhead(PGLOBAL g, void* buf)
{
 char *endmark;
 int   dbc = 2, rc = RC_OK;
 DBFHEADER* hdrp = (DBFHEADER*)buf;

 *g->Message = '\0';

 // Check first byte to be sure of .dbf type
 if ((hdrp->Version & 0x03) != DBFTYPE) {
  snprintf(g->Message, sizeof(g->Message), MSG(NOT_A_DBF_FILE));
  rc = RC_INFO;

  if ((hdrp->Version & 0x30) == 0x30) {
   snprintf(g->Message, sizeof(g->Message), MSG(FOXPRO_FILE));
   dbc = 264;             // FoxPro database container
  } // endif Version

 } else
  snprintf(g->Message, sizeof(g->Message), MSG(DBASE_FILE));

 // Check last byte(s) of header
 endmark = (char*)hdrp + hdrp->Headlen() - dbc;

 // Some headers just have 1D others have 1D00 following fields
 if (endmark[0] != EOH && endmark[1] != EOH) {
  snprintf(g->Message, sizeof(g->Message), MSG(NO_0DH_HEAD), dbc);

  if (rc == RC_OK)
   return RC_FX;

 } // endif endmark

 // Calculate here the number of fields while we have the dbc info
 hdrp->SetFields((hdrp->Headlen() - dbc - 1) / 32);
 return rc;
} // end of dbfhead

/****************************************************************************/
/*  ScanHeader: scan the DBF file header for number of records, record size,*/
/*  and header length. Set Records, check that Reclen is equal to lrecl and */
/*  return the header length or 0 in case of error.                         */
/****************************************************************************/
int UZDFAM::ScanHeader(PGLOBAL g, int* rln)
{
 int       rc;
 DBFHEADER header;

 /************************************************************************/
 /*  Get the first 32 bytes of the header.                               */
 /************************************************************************/
 rc = dbfhead(g, &header);

 if (rc == RC_FX)
  return -1;

 *rln = (int)header.Reclen();
 Records = (int)header.Records();
 return (int)header.Headlen();
} // end of ScanHeader
#endif // 0

/***********************************************************************/
/*  ZIP GetFileLength: returns file size in number of bytes.           */
/***********************************************************************/
int UZDFAM::GetFileLength(PGLOBAL g)
{
 int len;

 if (!zutp && OpenTableFile(g))
  return 0;

 if (zutp->entryopen)
  len = zutp->size;
 else
  len = 0;

 return len;
} // end of GetFileLength

/***********************************************************************/
/*  ZIP Cardinality: return the number of rows if possible.            */
/***********************************************************************/
int UZDFAM::Cardinality(PGLOBAL g)
{
 if (!g)
  return 1;

 int card = -1;

 card = Records;

 // Set number of blocks for later use
 Block = (card > 0) ? (card + Nrec - 1) / Nrec : 0;
 return card;
} // end of Cardinality

/***********************************************************************/
/*  OpenTableFile: Open a DBF table file from a ZIP file.              */
/***********************************************************************/
bool UZDFAM::OpenTableFile(PGLOBAL g)
{
 // May have been already opened in GetFileLength
 if (!zutp || !zutp->zipfile) {
  char    filename[_MAX_PATH];
  MODE    mode = Tdbp->GetMode();

  /*********************************************************************/
  /*  Allocate the ZIP utility class.                                  */
  /*********************************************************************/
  if (!zutp)
   zutp = new(g)UNZIPUTL(tdfp);

  //  We used the file name relative to recorded datapath
  PlugSetPath(filename, To_File, Tdbp->GetPath());

  if (!zutp->OpenTable(g, mode, filename)) {
   // The pseudo "buffer" is here the entire real buffer
   Memory = zutp->memory;
   Top = Memory + zutp->size;
   To_Fb = zutp->fp;                           // Useful when closing
   return AllocateBuffer(g);
  } else
   return true;

 } else
  Reset();

 return false;
} // end of OpenTableFile

/***********************************************************************/
/*  GetNext: go to next entry.                                         */
/***********************************************************************/
int UZDFAM::GetNext(PGLOBAL g)
{
 int rc = zutp->nextEntry(g);

 if (rc != RC_OK)
  return rc;

 int len = zutp->size;

#if 0
 if (len % Lrecl) {
  snprintf(g->Message, sizeof(g->Message), MSG(NOT_FIXED_LEN), zutp->fn, len, Lrecl);
  return RC_FX;
 } // endif size
#endif // 0

 Memory = zutp->memory;
 Top = Memory + len;
 Rewind();
 return RC_OK;
} // end of GetNext

/* -------------------------- class ZIPFAM --------------------------- */

/***********************************************************************/
/*  Constructor.                                                       */
/***********************************************************************/
ZIPFAM::ZIPFAM(PDOSDEF tdp) : DOSFAM(tdp)
{
 zutp = NULL;
 target = tdp->GetEntry();
 append = tdp->GetAppend();
} // end of ZIPFAM standard constructor

/***********************************************************************/
/*  OpenTableFile: Open a DOS/UNIX table file from a ZIP file.         */
/***********************************************************************/
bool ZIPFAM::OpenTableFile(PGLOBAL g)
{
 char filename[_MAX_PATH];
 MODE mode = Tdbp->GetMode();
 int  len = TXTFAM::GetFileLength(g);

 //  We used the file name relative to recorded datapath
 PlugSetPath(filename, To_File, Tdbp->GetPath());

 if (len < 0)
  return true;
 else if (!append && len > 0) {
  snprintf(g->Message, sizeof(g->Message), "No insert into existing zip file");
  return true;
 } else if (append && len > 0) {
  UNZIPUTL *zutp = new(g) UNZIPUTL(target, NULL, false);

  if (!zutp->IsInsertOk(g, filename)) {
   snprintf(g->Message, sizeof(g->Message), "No insert into existing entry");
   return true;
  } // endif Ok

 } // endif's

 /*********************************************************************/
 /*  Allocate the ZIP utility class.                                  */
 /*********************************************************************/
 zutp = new(g) ZIPUTIL(target);

 //  We used the file name relative to recorded datapath
 PlugSetPath(filename, To_File, Tdbp->GetPath());

 if (!zutp->OpenTable(g, mode, filename, append)) {
  To_Fb = zutp->fp;                           // Useful when closing
 } else
  return true;

 return AllocateBuffer(g);
} // end of OpenTableFile

/***********************************************************************/
/*  ReadBuffer: Read one line for a ZIP file.                          */
/***********************************************************************/
int ZIPFAM::ReadBuffer(PGLOBAL g)
{
 snprintf(g->Message, sizeof(g->Message), "ReadBuffer should not been called when zipping");
 return RC_FX;
} // end of ReadBuffer

/***********************************************************************/
/*  WriteBuffer: Deflate the buffer to the zip file.                   */
/***********************************************************************/
int ZIPFAM::WriteBuffer(PGLOBAL g)
{
 int len;

 //  Prepare to write the new line
 strcat(strcpy(To_Buf, Tdbp->GetLine()), (Bin) ? CrLf : "\n");
 len = (int)(strchr(To_Buf, '\n') - To_Buf + 1);
 return zutp->writeEntry(g, To_Buf, len);
} // end of WriteBuffer

/***********************************************************************/
/*  Table file close routine for ZIP access method.                    */
/***********************************************************************/
void ZIPFAM::CloseTableFile(PGLOBAL g, bool)
{
 To_Fb->Count = 0;
 zutp->close();
} // end of CloseTableFile

/* -------------------------- class ZPXFAM --------------------------- */

/***********************************************************************/
/*  Constructor.                                                       */
/***********************************************************************/
ZPXFAM::ZPXFAM(PDOSDEF tdp) : FIXFAM(tdp)
{
 zutp = NULL;
 target = tdp->GetEntry();
 append = tdp->GetAppend();
 //Lrecl = tdp->GetLrecl();
} // end of ZPXFAM standard constructor

/***********************************************************************/
/*  OpenTableFile: Open a DOS/UNIX table file from a ZIP file.         */
/***********************************************************************/
bool ZPXFAM::OpenTableFile(PGLOBAL g)
{
 char filename[_MAX_PATH];
 MODE mode = Tdbp->GetMode();
 int  len = TXTFAM::GetFileLength(g);

 if (len < 0)
  return true;
 else if (!append && len > 0) {
  snprintf(g->Message, sizeof(g->Message), "No insert into existing zip file");
  return true;
 } else if (append && len > 0) {
  UNZIPUTL *zutp = new(g) UNZIPUTL(target, NULL, false);

  if (!zutp->IsInsertOk(g, filename)) {
   snprintf(g->Message, sizeof(g->Message), "No insert into existing entry");
   return true;
  } // endif Ok

 } // endif's

 /*********************************************************************/
 /*  Allocate the ZIP utility class.                                  */
 /*********************************************************************/
 zutp = new(g) ZIPUTIL(target);

 //  We used the file name relative to recorded datapath
 PlugSetPath(filename, To_File, Tdbp->GetPath());

 if (!zutp->OpenTable(g, mode, filename, append)) {
  To_Fb = zutp->fp;                           // Useful when closing
 } else
  return true;

 return AllocateBuffer(g);
} // end of OpenTableFile

/***********************************************************************/
/*  WriteBuffer: Deflate the buffer to the zip file.                   */
/***********************************************************************/
int ZPXFAM::WriteBuffer(PGLOBAL g)
{
 /*********************************************************************/
 /*  In Insert mode, we write only full blocks.                       */
 /*********************************************************************/
 if (++CurNum != Rbuf) {
  Tdbp->IncLine(Lrecl);            // Used by DOSCOL functions
  return RC_OK;
 } // endif CurNum

 //  Now start the compress process.
 if (zutp->writeEntry(g, To_Buf, Lrecl * Rbuf) != RC_OK) {
  Closing = true;
  return RC_FX;
 } // endif writeEntry

 CurBlk++;
 CurNum = 0;
 Tdbp->SetLine(To_Buf);
 return RC_OK;
} // end of WriteBuffer

/***********************************************************************/
/*  Table file close routine for ZIP access method.                    */
/***********************************************************************/
void ZPXFAM::CloseTableFile(PGLOBAL g, bool)
{
 if (CurNum && !Closing) {
  // Some more inserted lines remain to be written
  Rbuf = CurNum--;
  WriteBuffer(g);
 } // endif Curnum

 To_Fb->Count = 0;
 zutp->close();
} // end of CloseTableFile

Messung V0.5 in Prozent
C=69 H=94 G=82

¤ Dauer der Verarbeitung: 0.22 Sekunden  (vorverarbeitet am  2026-10-08) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.