Imported Upstream version 0.7.5
[platform/upstream/libsolv.git] / ext / solv_xfopen.c
index a74762f..9aab68b 100644 (file)
 #include <string.h>
 #include <fcntl.h>
 
+#ifdef _WIN32
+  #include "fmemopen.c"
+#endif
+
 #include "solv_xfopen.h"
 #include "util.h"
 
+#ifndef WITHOUT_COOKIEOPEN
 
 static FILE *cookieopen(void *cookie, const char *mode,
        ssize_t (*cread)(void *, char *, size_t),
@@ -504,7 +509,69 @@ static inline FILE *myzstdfdopen(int fd, const char *mode)
 
 #ifdef ENABLE_ZCHUNK_COMPRESSION
 
+#ifdef WITH_SYSTEM_ZCHUNK
+/* use the system's zchunk library that supports reading and writing of zchunk files */
+
+#include <zck.h>
+
+static ssize_t cookie_zckread(void *cookie, char *buf, size_t nbytes)
+{
+  return zck_read((zckCtx *)cookie, buf, nbytes);
+}
+
+static ssize_t cookie_zckwrite(void *cookie, const char *buf, size_t nbytes)
+{
+  return zck_write((zckCtx *)cookie, buf, nbytes);
+}
+
+static int cookie_zckclose(void *cookie)
+{
+  zckCtx *zck = (zckCtx *)cookie;
+  int fd = zck_get_fd(zck);
+  if (fd != -1)
+    close(fd);
+  zck_free(&zck);
+  return 0;
+}
+
+static void *zchunkopen(const char *path, const char *mode, int fd)
+{
+  zckCtx *f;
+
+  if (!path && fd < 0)
+    return 0;
+  if (fd == -1)
+    {
+      if (*mode != 'w')
+        fd = open(path, O_RDONLY);
+      else
+        fd = open(path, O_WRONLY | O_CREAT, 0666);
+      if (fd == -1)
+       return 0;
+    }
+  f = zck_create();
+  if (!f)
+    {
+      close(fd);
+      return 0;
+    }
+  if (*mode != 'w')
+    {
+      if(!zck_init_read(f, fd))
+        return 0;
+    }
+   else
+    {
+      if(!zck_init_write(f, fd))
+        return 0;
+    }
+  return cookieopen(f, mode, cookie_zckread, cookie_zckwrite, cookie_zckclose);
+}
+
+#else
+
 #include "solv_zchunk.h"
+/* use the libsolv's limited zchunk implementation that only supports reading of zchunk files */
 
 static void *zchunkopen(const char *path, const char *mode, int fd)
 {
@@ -512,20 +579,22 @@ static void *zchunkopen(const char *path, const char *mode, int fd)
   void *f;
   if (!path && fd < 0)
     return 0;
-  if (strcmp(mode, "r") != 0)
-    return 0;
   if (fd != -1)
     fp = fdopen(fd, mode);
   else
     fp = fopen(path, mode);
   if (!fp)
     return 0;
+  if (strcmp(mode, "r") != 0)
+    return 0;
   f = solv_zchunk_open(fp, 1);
   if (!f)
     fclose(fp);
   return cookieopen(f, mode, (ssize_t (*)(void *, char *, size_t))solv_zchunk_read, 0, (int (*)(void *))solv_zchunk_close);
 }
 
+#endif
+
 static inline FILE *myzchunkfopen(const char *fn, const char *mode)
 {
   return zchunkopen(fn, mode, -1);
@@ -536,8 +605,19 @@ static inline FILE *myzchunkfdopen(int fd, const char *mode)
   return zchunkopen(0, mode, fd);
 }
 
+#endif /* ENABLE_ZCHUNK_COMPRESSION */
+
+#else
+/* no cookies no compression */
+#undef ENABLE_ZLIB_COMPRESSION
+#undef ENABLE_LZMA_COMPRESSION
+#undef ENABLE_BZIP2_COMPRESSION
+#undef ENABLE_ZSTD_COMPRESSION
+#undef ENABLE_ZCHUNK_COMPRESSION
 #endif
 
+
+
 FILE *
 solv_xfopen(const char *fn, const char *mode)
 {
@@ -584,7 +664,7 @@ solv_xfopen(const char *fn, const char *mode)
   if (suf && !strcmp(suf, ".zck"))
     return myzchunkfopen(fn, mode);
 #else
-  if (suf && !strcmp(suf, ".zst"))
+  if (suf && !strcmp(suf, ".zck"))
     return 0;
 #endif
   return fopen(fn, mode);
@@ -599,7 +679,15 @@ solv_xfopen_fd(const char *fn, int fd, const char *mode)
   suf = fn ? strrchr(fn, '.') : 0;
   if (!mode)
     {
+      #ifndef _WIN32
       int fl = fcntl(fd, F_GETFL, 0);
+      #else
+      HANDLE handle = (HANDLE) _get_osfhandle(fd);
+      BY_HANDLE_FILE_INFORMATION file_info;
+      if (!GetFileInformationByHandle(handle, &file_info))
+        return 0;
+      int fl = file_info.dwFileAttributes;
+      #endif
       if (fl == -1)
        return 0;
       fl &= O_RDONLY|O_WRONLY|O_RDWR;
@@ -649,7 +737,7 @@ solv_xfopen_fd(const char *fn, int fd, const char *mode)
   if (suf && !strcmp(suf, ".zck"))
     return myzchunkfdopen(fd, simplemode);
 #else
-  if (suf && !strcmp(suf, ".zst"))
+  if (suf && !strcmp(suf, ".zck"))
     return 0;
 #endif
   return fdopen(fd, mode);
@@ -694,6 +782,9 @@ solv_xfopen_iscompressed(const char *fn)
   return 0;
 }
 
+
+#ifndef WITHOUT_COOKIEOPEN
+
 struct bufcookie {
   char **bufp;
   size_t *buflp;
@@ -770,3 +861,33 @@ solv_xfopen_buf(const char *fn, char **bufp, size_t *buflp, const char *mode)
     }
   return fp;
 }
+
+#else
+
+FILE *
+solv_xfopen_buf(const char *fn, char **bufp, size_t *buflp, const char *mode)
+{
+  FILE *fp;
+  size_t l;
+  if (*mode != 'r')
+    return 0;
+  l = buflp ? *buflp : strlen(*bufp);
+  if (!strcmp(mode, "rf"))
+    {
+      if (!(fp = fmemopen(0, l, "r+")))
+       return 0;
+      if (l && fwrite(*bufp, l, 1, fp) != 1)
+       {
+         fclose(fp);
+         return 0;
+       }
+      solv_free(*bufp);
+      rewind(fp);
+    }
+  else
+    fp = fmemopen(*bufp, l, "r");
+  return fp;
+}
+
+#endif
+