Bladeren bron

Feat(Read): load xlsx file

viest 5 jaren geleden
bovenliggende
commit
7e23816db5

+ 4 - 0
.gitmodules

@@ -6,3 +6,7 @@
 	path = library/libexpat
 	url = https://github.com/libexpat/libexpat.git
 	branch = R_2_2_7
+[submodule "library/libxlsxio"]
+	path = library/libxlsxio
+	url = https://github.com/brechtsanders/xlsxio.git
+	branch = 0.2.21

+ 24 - 0
config.m4

@@ -14,6 +14,7 @@ if test "$PHP_XLSWRITER" != "no"; then
     kernel/write.c \
     kernel/format.c \
     kernel/chart.c \
+    kernel/read.c \
     "
     libxlsxwriter_sources="
     library/libxlsxwriter/third_party/minizip/ioapi.c \
@@ -40,6 +41,20 @@ if test "$PHP_XLSWRITER" != "no"; then
     library/libxlsxwriter/src/xmlwriter.c \
     "
 
+    libexpat="
+    library/libexpat/expat/lib/loadlibrary.c \
+    library/libexpat/expat/lib/xmlparse.c \
+    library/libexpat/expat/lib/xmlrole.c \
+    library/libexpat/expat/lib/xmltok.c \
+    library/libexpat/expat/lib/xmltok_impl.c \
+    library/libexpat/expat/lib/xmltok_ns.c \
+    "
+
+    libxlsxio="
+    library/libxlsxio/lib/xlsxio_read.c \
+    library/libxlsxio/lib/xlsxio_read_sharedstrings.c \
+    "
+
     AC_MSG_CHECKING([Check libxlsxwriter library])
     if test "$PHP_LIBXLSXWRITER" != "no"; then
 
@@ -107,6 +122,15 @@ if test "$PHP_XLSWRITER" != "no"; then
         LIBOPT="-DNOCRYPT -DNOUNCRYPT"
     fi
 
+    xls_writer_sources="$xls_writer_sources $libexpat"
+    PHP_ADD_INCLUDE([$srcdir/library/libexpat/expat/lib])
+    PHP_ADD_BUILD_DIR([$ext_builddir/library/libexpat/expat/lib])
+    LIBOPT="$LIBOPT -DXML_POOR_ENTROPY"
+
+    xls_writer_sources="$xls_writer_sources $libxlsxio"
+    PHP_ADD_INCLUDE([$srcdir/library/libxlsxio/include])
+    PHP_ADD_BUILD_DIR([$ext_builddir/library/libxlsxio/lib])
+
     if test -z "$PHP_DEBUG"; then
         AC_ARG_ENABLE(debug, [--enable-debug compile with debugging system], [PHP_DEBUG=$enableval],[PHP_DEBUG=no])
     fi

+ 208 - 0
include/minizip/ioapi.h

@@ -0,0 +1,208 @@
+/* ioapi.h -- IO base function header for compress/uncompress .zip
+   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Modifications for Zip64 support
+         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+         For more info read MiniZip_info.txt
+
+         Changes
+
+    Oct-2009 - Defined ZPOS64_T to fpos_t on windows and u_int64_t on linux. (might need to find a better why for this)
+    Oct-2009 - Change to fseeko64, ftello64 and fopen64 so large files would work on linux.
+               More if/def section may be needed to support other platforms
+    Oct-2009 - Defined fxxxx64 calls to normal fopen/ftell/fseek so they would compile on windows.
+                          (but you should use iowin32.c for windows instead)
+
+*/
+
+#ifndef _ZLIBIOAPI64_H
+#define _ZLIBIOAPI64_H
+
+#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__))
+
+  // Linux needs this to support file operation on files larger then 4+GB
+  // But might need better if/def to select just the platforms that needs them.
+
+        #ifndef __USE_FILE_OFFSET64
+                #define __USE_FILE_OFFSET64
+        #endif
+        #ifndef __USE_LARGEFILE64
+                #define __USE_LARGEFILE64
+        #endif
+        #ifndef _LARGEFILE64_SOURCE
+                #define _LARGEFILE64_SOURCE
+        #endif
+        #ifndef _FILE_OFFSET_BIT
+                #define _FILE_OFFSET_BIT 64
+        #endif
+
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "zlib.h"
+
+#if defined(USE_FILE32API)
+#define fopen64 fopen
+#define ftello64 ftell
+#define fseeko64 fseek
+#else
+#if defined(__FreeBSD__) || defined(__OpenBSD__)
+#define fopen64 fopen
+#define ftello64 ftello
+#define fseeko64 fseeko
+#endif
+#ifdef _MSC_VER
+ #define fopen64 fopen
+ #if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC)))
+  #define ftello64 _ftelli64
+  #define fseeko64 _fseeki64
+ #else // old MSC
+  #define ftello64 ftell
+  #define fseeko64 fseek
+ #endif
+#endif
+#endif
+
+/*
+#ifndef ZPOS64_T
+  #ifdef _WIN32
+                #define ZPOS64_T fpos_t
+  #else
+    #include <stdint.h>
+    #define ZPOS64_T uint64_t
+  #endif
+#endif
+*/
+
+#ifdef HAVE_MINIZIP64_CONF_H
+#include "mz64conf.h"
+#endif
+
+/* a type choosen by DEFINE */
+#ifdef HAVE_64BIT_INT_CUSTOM
+typedef  64BIT_INT_CUSTOM_TYPE ZPOS64_T;
+#else
+#ifdef HAS_STDINT_H
+#include "stdint.h"
+typedef uint64_t ZPOS64_T;
+#else
+
+/* Maximum unsigned 32-bit value used as placeholder for zip64 */
+#define MAXU32 0xffffffff
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+typedef unsigned __int64 ZPOS64_T;
+#else
+typedef unsigned long long int ZPOS64_T;
+#endif
+#endif
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define ZLIB_FILEFUNC_SEEK_CUR (1)
+#define ZLIB_FILEFUNC_SEEK_END (2)
+#define ZLIB_FILEFUNC_SEEK_SET (0)
+
+#define ZLIB_FILEFUNC_MODE_READ      (1)
+#define ZLIB_FILEFUNC_MODE_WRITE     (2)
+#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3)
+
+#define ZLIB_FILEFUNC_MODE_EXISTING (4)
+#define ZLIB_FILEFUNC_MODE_CREATE   (8)
+
+
+#ifndef ZCALLBACK
+ #if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK)
+   #define ZCALLBACK CALLBACK
+ #else
+   #define ZCALLBACK
+ #endif
+#endif
+
+
+
+
+typedef voidpf   (ZCALLBACK *open_file_func)      OF((voidpf opaque, const char* filename, int mode));
+typedef uLong    (ZCALLBACK *read_file_func)      OF((voidpf opaque, voidpf stream, void* buf, uLong size));
+typedef uLong    (ZCALLBACK *write_file_func)     OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
+typedef int      (ZCALLBACK *close_file_func)     OF((voidpf opaque, voidpf stream));
+typedef int      (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream));
+
+typedef long     (ZCALLBACK *tell_file_func)      OF((voidpf opaque, voidpf stream));
+typedef long     (ZCALLBACK *seek_file_func)      OF((voidpf opaque, voidpf stream, uLong offset, int origin));
+
+
+/* here is the "old" 32 bits structure structure */
+typedef struct zlib_filefunc_def_s
+{
+    open_file_func      zopen_file;
+    read_file_func      zread_file;
+    write_file_func     zwrite_file;
+    tell_file_func      ztell_file;
+    seek_file_func      zseek_file;
+    close_file_func     zclose_file;
+    testerror_file_func zerror_file;
+    voidpf              opaque;
+} zlib_filefunc_def;
+
+typedef ZPOS64_T (ZCALLBACK *tell64_file_func)    OF((voidpf opaque, voidpf stream));
+typedef long     (ZCALLBACK *seek64_file_func)    OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));
+typedef voidpf   (ZCALLBACK *open64_file_func)    OF((voidpf opaque, const void* filename, int mode));
+
+typedef struct zlib_filefunc64_def_s
+{
+    open64_file_func    zopen64_file;
+    read_file_func      zread_file;
+    write_file_func     zwrite_file;
+    tell64_file_func    ztell64_file;
+    seek64_file_func    zseek64_file;
+    close_file_func     zclose_file;
+    testerror_file_func zerror_file;
+    voidpf              opaque;
+} zlib_filefunc64_def;
+
+void fill_fopen64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def));
+void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
+
+/* now internal definition, only for zip.c and unzip.h */
+typedef struct zlib_filefunc64_32_def_s
+{
+    zlib_filefunc64_def zfile_func64;
+    open_file_func      zopen32_file;
+    tell_file_func      ztell32_file;
+    seek_file_func      zseek32_file;
+} zlib_filefunc64_32_def;
+
+
+#define ZREAD64(filefunc,filestream,buf,size)     ((*((filefunc).zfile_func64.zread_file))   ((filefunc).zfile_func64.opaque,filestream,buf,size))
+#define ZWRITE64(filefunc,filestream,buf,size)    ((*((filefunc).zfile_func64.zwrite_file))  ((filefunc).zfile_func64.opaque,filestream,buf,size))
+/* #define ZTELL64(filefunc,filestream)            ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream)) */
+/* #define ZSEEK64(filefunc,filestream,pos,mode)   ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode)) */
+#define ZCLOSE64(filefunc,filestream)             ((*((filefunc).zfile_func64.zclose_file))  ((filefunc).zfile_func64.opaque,filestream))
+#define ZERROR64(filefunc,filestream)             ((*((filefunc).zfile_func64.zerror_file))  ((filefunc).zfile_func64.opaque,filestream))
+
+voidpf call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode));
+long    call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin));
+ZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream));
+
+void    fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32);
+
+#define ZOPEN64(filefunc,filename,mode)         (call_zopen64((&(filefunc)),(filename),(mode)))
+#define ZTELL64(filefunc,filestream)            (call_ztell64((&(filefunc)),(filestream)))
+#define ZSEEK64(filefunc,filestream,pos,mode)   (call_zseek64((&(filefunc)),(filestream),(pos),(mode)))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 437 - 0
include/minizip/unzip.h

@@ -0,0 +1,437 @@
+/* unzip.h -- IO for uncompress .zip files using zlib
+   Version 1.1, February 14h, 2010
+   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Modifications of Unzip for Zip64
+         Copyright (C) 2007-2008 Even Rouault
+
+         Modifications for Zip64 support on both zip and unzip
+         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+         For more info read MiniZip_info.txt
+
+         ---------------------------------------------------------------------------------
+
+        Condition of use and distribution are the same than zlib :
+
+  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.
+
+  ---------------------------------------------------------------------------------
+
+        Changes
+
+        See header of unzip64.c
+
+*/
+
+#ifndef _unz64_H
+#define _unz64_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _ZLIB_H
+#include "zlib.h"
+#endif
+
+#ifndef  _ZLIBIOAPI_H
+#include "ioapi.h"
+#endif
+
+#ifdef HAVE_BZIP2
+#include "bzlib.h"
+#endif
+
+#define Z_BZIP2ED 12
+
+#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
+/* like the STRICT of WIN32, we define a pointer that cannot be converted
+    from (void*) without cast */
+typedef struct TagunzFile__ { int unused; } unzFile__;
+typedef unzFile__ *unzFile;
+#else
+typedef voidp unzFile;
+#endif
+
+
+#define UNZ_OK                          (0)
+#define UNZ_END_OF_LIST_OF_FILE         (-100)
+#define UNZ_ERRNO                       (Z_ERRNO)
+#define UNZ_EOF                         (0)
+#define UNZ_PARAMERROR                  (-102)
+#define UNZ_BADZIPFILE                  (-103)
+#define UNZ_INTERNALERROR               (-104)
+#define UNZ_CRCERROR                    (-105)
+
+/* tm_unz contain date/time info */
+typedef struct tm_unz_s
+{
+    uInt tm_sec;            /* seconds after the minute - [0,59] */
+    uInt tm_min;            /* minutes after the hour - [0,59] */
+    uInt tm_hour;           /* hours since midnight - [0,23] */
+    uInt tm_mday;           /* day of the month - [1,31] */
+    uInt tm_mon;            /* months since January - [0,11] */
+    uInt tm_year;           /* years - [1980..2044] */
+} tm_unz;
+
+/* unz_global_info structure contain global data about the ZIPfile
+   These data comes from the end of central dir */
+typedef struct unz_global_info64_s
+{
+    ZPOS64_T number_entry;         /* total number of entries in
+                                     the central dir on this disk */
+    uLong size_comment;         /* size of the global comment of the zipfile */
+} unz_global_info64;
+
+typedef struct unz_global_info_s
+{
+    uLong number_entry;         /* total number of entries in
+                                     the central dir on this disk */
+    uLong size_comment;         /* size of the global comment of the zipfile */
+} unz_global_info;
+
+/* unz_file_info contain information about a file in the zipfile */
+typedef struct unz_file_info64_s
+{
+    uLong version;              /* version made by                 2 bytes */
+    uLong version_needed;       /* version needed to extract       2 bytes */
+    uLong flag;                 /* general purpose bit flag        2 bytes */
+    uLong compression_method;   /* compression method              2 bytes */
+    uLong dosDate;              /* last mod file date in Dos fmt   4 bytes */
+    uLong crc;                  /* crc-32                          4 bytes */
+    ZPOS64_T compressed_size;   /* compressed size                 8 bytes */
+    ZPOS64_T uncompressed_size; /* uncompressed size               8 bytes */
+    uLong size_filename;        /* filename length                 2 bytes */
+    uLong size_file_extra;      /* extra field length              2 bytes */
+    uLong size_file_comment;    /* file comment length             2 bytes */
+
+    uLong disk_num_start;       /* disk number start               2 bytes */
+    uLong internal_fa;          /* internal file attributes        2 bytes */
+    uLong external_fa;          /* external file attributes        4 bytes */
+
+    tm_unz tmu_date;
+} unz_file_info64;
+
+typedef struct unz_file_info_s
+{
+    uLong version;              /* version made by                 2 bytes */
+    uLong version_needed;       /* version needed to extract       2 bytes */
+    uLong flag;                 /* general purpose bit flag        2 bytes */
+    uLong compression_method;   /* compression method              2 bytes */
+    uLong dosDate;              /* last mod file date in Dos fmt   4 bytes */
+    uLong crc;                  /* crc-32                          4 bytes */
+    uLong compressed_size;      /* compressed size                 4 bytes */
+    uLong uncompressed_size;    /* uncompressed size               4 bytes */
+    uLong size_filename;        /* filename length                 2 bytes */
+    uLong size_file_extra;      /* extra field length              2 bytes */
+    uLong size_file_comment;    /* file comment length             2 bytes */
+
+    uLong disk_num_start;       /* disk number start               2 bytes */
+    uLong internal_fa;          /* internal file attributes        2 bytes */
+    uLong external_fa;          /* external file attributes        4 bytes */
+
+    tm_unz tmu_date;
+} unz_file_info;
+
+extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,
+                                                 const char* fileName2,
+                                                 int iCaseSensitivity));
+/*
+   Compare two filename (fileName1,fileName2).
+   If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
+   If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
+                                or strcasecmp)
+   If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
+    (like 1 on Unix, 2 on Windows)
+*/
+
+
+extern unzFile ZEXPORT unzOpen OF((const char *path));
+extern unzFile ZEXPORT unzOpen64 OF((const void *path));
+/*
+  Open a Zip file. path contain the full pathname (by example,
+     on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer
+     "zlib/zlib113.zip".
+     If the zipfile cannot be opened (file don't exist or in not valid), the
+       return value is NULL.
+     Else, the return value is a unzFile Handle, usable with other function
+       of this unzip package.
+     the "64" function take a const void* pointer, because the path is just the
+       value passed to the open64_file_func callback.
+     Under Windows, if UNICODE is defined, using fill_fopen64_filefunc, the path
+       is a pointer to a wide unicode string (LPCTSTR is LPCWSTR), so const char*
+       does not describe the reality
+*/
+
+
+extern unzFile ZEXPORT unzOpen2 OF((const char *path,
+                                    zlib_filefunc_def* pzlib_filefunc_def));
+/*
+   Open a Zip file, like unzOpen, but provide a set of file low level API
+      for read/write the zip file (see ioapi.h)
+*/
+
+extern unzFile ZEXPORT unzOpen2_64 OF((const void *path,
+                                    zlib_filefunc64_def* pzlib_filefunc_def));
+/*
+   Open a Zip file, like unz64Open, but provide a set of file low level API
+      for read/write the zip file (see ioapi.h)
+*/
+
+extern int ZEXPORT unzClose OF((unzFile file));
+/*
+  Close a ZipFile opened with unzOpen.
+  If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
+    these files MUST be closed with unzCloseCurrentFile before call unzClose.
+  return UNZ_OK if there is no problem. */
+
+extern int ZEXPORT unzGetGlobalInfo OF((unzFile file,
+                                        unz_global_info *pglobal_info));
+
+extern int ZEXPORT unzGetGlobalInfo64 OF((unzFile file,
+                                        unz_global_info64 *pglobal_info));
+/*
+  Write info about the ZipFile in the *pglobal_info structure.
+  No preparation of the structure is needed
+  return UNZ_OK if there is no problem. */
+
+
+extern int ZEXPORT unzGetGlobalComment OF((unzFile file,
+                                           char *szComment,
+                                           uLong uSizeBuf));
+/*
+  Get the global comment string of the ZipFile, in the szComment buffer.
+  uSizeBuf is the size of the szComment buffer.
+  return the number of byte copied or an error code <0
+*/
+
+
+/***************************************************************************/
+/* Unzip package allow you browse the directory of the zipfile */
+
+extern int ZEXPORT unzGoToFirstFile OF((unzFile file));
+/*
+  Set the current file of the zipfile to the first file.
+  return UNZ_OK if there is no problem
+*/
+
+extern int ZEXPORT unzGoToNextFile OF((unzFile file));
+/*
+  Set the current file of the zipfile to the next file.
+  return UNZ_OK if there is no problem
+  return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
+*/
+
+extern int ZEXPORT unzLocateFile OF((unzFile file,
+                     const char *szFileName,
+                     int iCaseSensitivity));
+/*
+  Try locate the file szFileName in the zipfile.
+  For the iCaseSensitivity signification, see unzStringFileNameCompare
+
+  return value :
+  UNZ_OK if the file is found. It becomes the current file.
+  UNZ_END_OF_LIST_OF_FILE if the file is not found
+*/
+
+
+/* ****************************************** */
+/* Ryan supplied functions */
+/* unz_file_info contain information about a file in the zipfile */
+typedef struct unz_file_pos_s
+{
+    uLong pos_in_zip_directory;   /* offset in zip file directory */
+    uLong num_of_file;            /* # of file */
+} unz_file_pos;
+
+extern int ZEXPORT unzGetFilePos(
+    unzFile file,
+    unz_file_pos* file_pos);
+
+extern int ZEXPORT unzGoToFilePos(
+    unzFile file,
+    unz_file_pos* file_pos);
+
+typedef struct unz64_file_pos_s
+{
+    ZPOS64_T pos_in_zip_directory;   /* offset in zip file directory */
+    ZPOS64_T num_of_file;            /* # of file */
+} unz64_file_pos;
+
+extern int ZEXPORT unzGetFilePos64(
+    unzFile file,
+    unz64_file_pos* file_pos);
+
+extern int ZEXPORT unzGoToFilePos64(
+    unzFile file,
+    const unz64_file_pos* file_pos);
+
+/* ****************************************** */
+
+extern int ZEXPORT unzGetCurrentFileInfo64 OF((unzFile file,
+                         unz_file_info64 *pfile_info,
+                         char *szFileName,
+                         uLong fileNameBufferSize,
+                         void *extraField,
+                         uLong extraFieldBufferSize,
+                         char *szComment,
+                         uLong commentBufferSize));
+
+extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,
+                         unz_file_info *pfile_info,
+                         char *szFileName,
+                         uLong fileNameBufferSize,
+                         void *extraField,
+                         uLong extraFieldBufferSize,
+                         char *szComment,
+                         uLong commentBufferSize));
+/*
+  Get Info about the current file
+  if pfile_info!=NULL, the *pfile_info structure will contain somes info about
+        the current file
+  if szFileName!=NULL, the filemane string will be copied in szFileName
+            (fileNameBufferSize is the size of the buffer)
+  if extraField!=NULL, the extra field information will be copied in extraField
+            (extraFieldBufferSize is the size of the buffer).
+            This is the Central-header version of the extra field
+  if szComment!=NULL, the comment string of the file will be copied in szComment
+            (commentBufferSize is the size of the buffer)
+*/
+
+
+/** Addition for GDAL : START */
+
+extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64 OF((unzFile file));
+
+/** Addition for GDAL : END */
+
+
+/***************************************************************************/
+/* for reading the content of the current zipfile, you can open it, read data
+   from it, and close it (you can close it before reading all the file)
+   */
+
+extern int ZEXPORT unzOpenCurrentFile OF((unzFile file));
+/*
+  Open for reading data the current file in the zipfile.
+  If there is no error, the return value is UNZ_OK.
+*/
+
+extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file,
+                                                  const char* password));
+/*
+  Open for reading data the current file in the zipfile.
+  password is a crypting password
+  If there is no error, the return value is UNZ_OK.
+*/
+
+extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file,
+                                           int* method,
+                                           int* level,
+                                           int raw));
+/*
+  Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
+    if raw==1
+  *method will receive method of compression, *level will receive level of
+     compression
+  note : you can set level parameter as NULL (if you did not want known level,
+         but you CANNOT set method parameter as NULL
+*/
+
+extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file,
+                                           int* method,
+                                           int* level,
+                                           int raw,
+                                           const char* password));
+/*
+  Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
+    if raw==1
+  *method will receive method of compression, *level will receive level of
+     compression
+  note : you can set level parameter as NULL (if you did not want known level,
+         but you CANNOT set method parameter as NULL
+*/
+
+
+extern int ZEXPORT unzCloseCurrentFile OF((unzFile file));
+/*
+  Close the file in zip opened with unzOpenCurrentFile
+  Return UNZ_CRCERROR if all the file was read but the CRC is not good
+*/
+
+extern int ZEXPORT unzReadCurrentFile OF((unzFile file,
+                      voidp buf,
+                      unsigned len));
+/*
+  Read bytes from the current file (opened by unzOpenCurrentFile)
+  buf contain buffer where data must be copied
+  len the size of buf.
+
+  return the number of byte copied if somes bytes are copied
+  return 0 if the end of file was reached
+  return <0 with error code if there is an error
+    (UNZ_ERRNO for IO error, or zLib error for uncompress error)
+*/
+
+extern z_off_t ZEXPORT unztell OF((unzFile file));
+
+extern ZPOS64_T ZEXPORT unztell64 OF((unzFile file));
+/*
+  Give the current position in uncompressed data
+*/
+
+extern int ZEXPORT unzeof OF((unzFile file));
+/*
+  return 1 if the end of file was reached, 0 elsewhere
+*/
+
+extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,
+                                             voidp buf,
+                                             unsigned len));
+/*
+  Read extra field from the current file (opened by unzOpenCurrentFile)
+  This is the local-header version of the extra field (sometimes, there is
+    more info in the local-header version than in the central-header)
+
+  if buf==NULL, it return the size of the local extra field
+
+  if buf!=NULL, len is the size of the buffer, the extra header is copied in
+    buf.
+  the return value is the number of bytes copied in buf, or (if <0)
+    the error code
+*/
+
+/***************************************************************************/
+
+/* Get the current file offset */
+extern ZPOS64_T ZEXPORT unzGetOffset64 (unzFile file);
+extern uLong ZEXPORT unzGetOffset (unzFile file);
+
+/* Set the current file offset */
+extern int ZEXPORT unzSetOffset64 (unzFile file, ZPOS64_T pos);
+extern int ZEXPORT unzSetOffset (unzFile file, uLong pos);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _unz64_H */

+ 27 - 0
include/read.h

@@ -0,0 +1,27 @@
+/*
+  +----------------------------------------------------------------------+
+  | XlsWriter Extension                                                  |
+  +----------------------------------------------------------------------+
+  | Copyright (c) 2017-2018 The Viest                                    |
+  +----------------------------------------------------------------------+
+  | http://www.viest.me                                                  |
+  +----------------------------------------------------------------------+
+  | Author: viest <[email protected]>                                 |
+  +----------------------------------------------------------------------+
+*/
+
+#ifndef PHP_EXT_EXCEL_EXPORT_READ_H
+#define PHP_EXT_EXCEL_EXPORT_READ_H
+
+#define READ_SKIP_ROW 0
+#define READ_ROW 0x01
+
+int sheet_read_row(xlsxioreadersheet sheet);
+char* sheet_read_column(xlsxioreadersheet sheet);
+xlsxioreader file_open(const char *directory, const char *file_name);
+void load_sheet_all_data(xlsxioreadersheet sheet_t, zval *zv_result_t);
+xlsxioreadersheet sheet_open(xlsxioreader file, const zend_string *zs_sheet_name_t);
+unsigned int load_sheet_current_row_data(xlsxioreadersheet sheet_t, zval *zv_result_t, unsigned int flag);
+
+
+#endif //PHP_EXT_EXCEL_EXPORT_READ_H

+ 40 - 20
include/xlswriter.h

@@ -28,16 +28,24 @@
 #include "xlsxwriter/packager.h"
 #include "xlsxwriter/format.h"
 
+#include "xlsxio_read.h"
+
 #include "php_xlswriter.h"
 #include "excel.h"
 #include "exception.h"
 #include "format.h"
 #include "chart.h"
+#include "read.h"
+
+enum xlswriter_boolean {
+    XLSWRITER_FALSE,
+    XLSWRITER_TRUE
+};
 
 typedef struct {
     lxw_workbook  *workbook;
     lxw_worksheet *worksheet;
-} xls_resource_t;
+} xls_resource_write_t;
 
 typedef struct {
     lxw_format  *format;
@@ -48,10 +56,16 @@ typedef struct {
     lxw_chart_series *series;
 } xls_resource_chart_t;
 
+typedef struct {
+    xlsxioreader      file_t;
+    xlsxioreadersheet sheet_t;
+} xls_resource_read_t;
+
 typedef struct _vtiful_xls_object {
-    xls_resource_t ptr;
-    zend_long      line;
-    zend_object    zo;
+    xls_resource_read_t  read_ptr;
+    xls_resource_write_t write_ptr;
+    zend_long            write_line;
+    zend_object          zo;
 } xls_object;
 
 typedef struct _vtiful_format_object {
@@ -93,18 +107,24 @@ static inline chart_object *php_vtiful_chart_fetch_object(zend_object *obj) {
     lxw_name_to_row(range), lxw_name_to_row_2(range)
 
 #define SHEET_LINE_INIT(obj_p) \
-    obj_p->line = 0;
+    obj_p->write_line = 0;
 
 #define SHEET_LINE_ADD(obj_p) \
-    ++obj_p->line;
+    ++obj_p->write_line;
 
 #define SHEET_LINE_SET(obj_p, current_line) \
-    obj_p->line = current_line;
+    obj_p->write_line = current_line;
+
+#define SHEET_CURRENT_LINE(obj_p) obj_p->write_line
 
-#define SHEET_CURRENT_LINE(obj_p) obj_p->line
+#ifdef LXW_HAS_SNPRINTF
+#define lxw_snprintf snprintf
+#else
+#define lxw_snprintf __builtin_snprintf
+#endif
 
 lxw_format           * zval_get_format(zval *handle);
-xls_resource_t       * zval_get_resource(zval *handle);
+xls_resource_write_t       * zval_get_resource(zval *handle);
 xls_resource_chart_t *zval_get_chart(zval *resource);
 
 STATIC lxw_error _store_defined_name(lxw_workbook *self, const char *name, const char *app_name, const char *formula, int16_t index, uint8_t hidden);
@@ -117,17 +137,17 @@ STATIC void _populate_range(lxw_workbook *self, lxw_series_range *range);
 STATIC void _populate_range_dimensions(lxw_workbook *self, lxw_series_range *range);
 
 void format_copy(lxw_format *new_format, lxw_format *other_format);
-void type_writer(zval *value, zend_long row, zend_long columns, xls_resource_t *res, zend_string *format, lxw_format *format_handle);
-void chart_writer(zend_long row, zend_long columns, xls_resource_chart_t *chart_resource, xls_resource_t *res);
-void url_writer(zend_long row, zend_long columns, xls_resource_t *res, zend_string *url, lxw_format *format);
-void image_writer(zval *value, zend_long row, zend_long columns, double width, double height, xls_resource_t *res);
-void formula_writer(zval *value, zend_long row, zend_long columns, xls_resource_t *res);
-void auto_filter(zend_string *range, xls_resource_t *res);
-void merge_cells(zend_string *range, zend_string *value, xls_resource_t *res);
-void set_column(zend_string *range, double width, xls_resource_t *res, lxw_format *format);
-void set_row(zend_string *range, double height, xls_resource_t *res, lxw_format *format);
-void worksheet_set_rows(lxw_row_t start, lxw_row_t end, double height, xls_resource_t *res, lxw_format *format);
-lxw_error workbook_file(xls_resource_t *self);
+void type_writer(zval *value, zend_long row, zend_long columns, xls_resource_write_t *res, zend_string *format, lxw_format *format_handle);
+void chart_writer(zend_long row, zend_long columns, xls_resource_chart_t *chart_resource, xls_resource_write_t *res);
+void url_writer(zend_long row, zend_long columns, xls_resource_write_t *res, zend_string *url, lxw_format *format);
+void image_writer(zval *value, zend_long row, zend_long columns, double width, double height, xls_resource_write_t *res);
+void formula_writer(zval *value, zend_long row, zend_long columns, xls_resource_write_t *res);
+void auto_filter(zend_string *range, xls_resource_write_t *res);
+void merge_cells(zend_string *range, zend_string *value, xls_resource_write_t *res);
+void set_column(zend_string *range, double width, xls_resource_write_t *res, lxw_format *format);
+void set_row(zend_string *range, double height, xls_resource_write_t *res, lxw_format *format);
+void worksheet_set_rows(lxw_row_t start, lxw_row_t end, double height, xls_resource_write_t *res, lxw_format *format);
+lxw_error workbook_file(xls_resource_write_t *self);
 
 void xls_file_path(zend_string *file_name, zval *dir_path, zval *file_path);
 

+ 3 - 1
kernel/chart.c

@@ -95,7 +95,7 @@ PHP_METHOD(vtiful_chart, __construct)
     zval *handle;
     zend_long type;
     chart_object *obj;
-    xls_resource_t *xls_res;
+    xls_resource_write_t *xls_res;
 
     ZEND_PARSE_PARAMETERS_START(2, 2)
             Z_PARAM_RESOURCE(handle)
@@ -260,6 +260,7 @@ zend_function_entry chart_methods[] = {
 };
 /* }}} */
 
+/* {{{ */
 VTIFUL_STARTUP_FUNCTION(chart)
 {
     zend_class_entry ce;
@@ -278,3 +279,4 @@ VTIFUL_STARTUP_FUNCTION(chart)
 
     return SUCCESS;
 }
+/* }}} */

+ 3 - 1
kernel/common.c

@@ -12,6 +12,7 @@
 
 #include "xlswriter.h"
 
+/* {{{ */
 void xls_file_path(zend_string *file_name, zval *dir_path, zval *file_path)
 {
     zend_string *full_path, *zstr_path;
@@ -28,4 +29,5 @@ void xls_file_path(zend_string *file_name, zval *dir_path, zval *file_path)
     }
 
     ZVAL_STR(file_path, full_path);
-}
+}
+/* }}} */

+ 108 - 29
kernel/excel.c

@@ -35,6 +35,9 @@ PHP_VTIFUL_API zend_object *vtiful_xls_objects_new(zend_class_entry *ce)
 
     intern->zo.handlers = &vtiful_xls_handlers;
 
+    intern->read_ptr.file_t = NULL;
+    intern->read_ptr.sheet_t = NULL;
+
     return &intern->zo;
 }
 /* }}} */
@@ -45,7 +48,7 @@ static void vtiful_xls_objects_free(zend_object *object)
 {
     xls_object *intern = php_vtiful_xls_fetch_object(object);
 
-    lxw_workbook_free(intern->ptr.workbook);
+    lxw_workbook_free(intern->write_ptr.workbook);
 
     zend_object_std_dtor(&intern->zo);
 }
@@ -186,15 +189,15 @@ PHP_METHOD(vtiful_xls, fileName)
 
     xls_object *obj = Z_XLS_P(getThis());
 
-    if(obj->ptr.workbook == NULL) {
+    if(obj->write_ptr.workbook == NULL) {
         xls_file_path(zs_file_name, dir_path, &file_path);
 
         if(zs_sheet_name != NULL) {
             sheet_name = ZSTR_VAL(zs_sheet_name);
         }
 
-        obj->ptr.workbook  = workbook_new(Z_STRVAL(file_path));
-        obj->ptr.worksheet = workbook_add_worksheet(obj->ptr.workbook, sheet_name);
+        obj->write_ptr.workbook  = workbook_new(Z_STRVAL(file_path));
+        obj->write_ptr.worksheet = workbook_add_worksheet(obj->write_ptr.workbook, sheet_name);
 
         add_property_zval(return_value, V_XLS_FIL, &file_path);
 
@@ -221,7 +224,7 @@ PHP_METHOD(vtiful_xls, addSheet)
 
     SHEET_LINE_INIT(obj)
 
-    if(obj->ptr.workbook == NULL) {
+    if(obj->write_ptr.workbook == NULL) {
         zend_throw_exception(vtiful_exception_ce, "Please create a file first, use the filename method", 130);
         return;
     }
@@ -230,7 +233,7 @@ PHP_METHOD(vtiful_xls, addSheet)
         sheet_name = ZSTR_VAL(zs_sheet_name);
     }
 
-    obj->ptr.worksheet = workbook_add_worksheet(obj->ptr.workbook, sheet_name);
+    obj->write_ptr.worksheet = workbook_add_worksheet(obj->write_ptr.workbook, sheet_name);
 }
 /* }}} */
 
@@ -250,12 +253,12 @@ PHP_METHOD(vtiful_xls, checkoutSheet)
 
     xls_object *obj = Z_XLS_P(getThis());
 
-    if(obj->ptr.workbook == NULL) {
+    if(obj->write_ptr.workbook == NULL) {
         zend_throw_exception(vtiful_exception_ce, "Please create a file first, use the filename method", 130);
         return;
     }
 
-    if ((sheet_t = workbook_get_worksheet_by_name(obj->ptr.workbook, ZSTR_VAL(zs_sheet_name))) == NULL) {
+    if ((sheet_t = workbook_get_worksheet_by_name(obj->write_ptr.workbook, ZSTR_VAL(zs_sheet_name))) == NULL) {
         zend_throw_exception(vtiful_exception_ce, "Sheet not fund", 140);
         return;
     }
@@ -264,7 +267,7 @@ PHP_METHOD(vtiful_xls, checkoutSheet)
 
     SHEET_LINE_SET(obj, line);
 
-    obj->ptr.worksheet = sheet_t;
+    obj->write_ptr.worksheet = sheet_t;
 }
 /* }}} */
 
@@ -288,7 +291,7 @@ PHP_METHOD(vtiful_xls, constMemory)
 
     xls_object *obj = Z_XLS_P(getThis());
 
-    if(obj->ptr.workbook == NULL) {
+    if(obj->write_ptr.workbook == NULL) {
         xls_file_path(zs_file_name, dir_path, &file_path);
 
         lxw_workbook_options options = {.constant_memory = LXW_TRUE, .tmpdir = NULL};
@@ -297,8 +300,8 @@ PHP_METHOD(vtiful_xls, constMemory)
             sheet_name = ZSTR_VAL(zs_sheet_name);
         }
 
-        obj->ptr.workbook  = workbook_new_opt(Z_STRVAL(file_path), &options);
-        obj->ptr.worksheet = workbook_add_worksheet(obj->ptr.workbook, sheet_name);
+        obj->write_ptr.workbook  = workbook_new_opt(Z_STRVAL(file_path), &options);
+        obj->write_ptr.worksheet = workbook_add_worksheet(obj->write_ptr.workbook, sheet_name);
 
         add_property_zval(return_value, V_XLS_FIL, &file_path);
 
@@ -324,7 +327,7 @@ PHP_METHOD(vtiful_xls, header)
     xls_object *obj = Z_XLS_P(getThis());
 
     ZEND_HASH_FOREACH_NUM_KEY_VAL(Z_ARRVAL_P(header), header_l_key, header_value)
-         type_writer(header_value, 0, header_l_key, &obj->ptr, NULL, NULL);
+         type_writer(header_value, 0, header_l_key, &obj->write_ptr, NULL, NULL);
          zval_ptr_dtor(header_value);
     ZEND_HASH_FOREACH_END();
 }
@@ -349,7 +352,7 @@ PHP_METHOD(vtiful_xls, data)
             SHEET_LINE_ADD(obj)
 
             ZEND_HASH_FOREACH_BUCKET(Z_ARRVAL_P(data_r_value), Bucket *bucket)
-                type_writer(&bucket->val, SHEET_CURRENT_LINE(obj), bucket->h, &obj->ptr, NULL, NULL);
+                type_writer(&bucket->val, SHEET_CURRENT_LINE(obj), bucket->h, &obj->write_ptr, NULL, NULL);
                 zval_ptr_dtor(&bucket->val);
             ZEND_HASH_FOREACH_END();
         }
@@ -367,7 +370,7 @@ PHP_METHOD(vtiful_xls, output)
 
     xls_object *obj = Z_XLS_P(getThis());
 
-    workbook_file(&obj->ptr);
+    workbook_file(&obj->write_ptr);
 
     add_property_null(getThis(), V_XLS_HANDLE);
     add_property_null(getThis(), V_XLS_PAT);
@@ -382,7 +385,7 @@ PHP_METHOD(vtiful_xls, getHandle)
 {
     xls_object *obj = Z_XLS_P(getThis());
 
-    RETURN_RES(zend_register_resource(&obj->ptr, le_xls_writer));
+    RETURN_RES(zend_register_resource(&obj->write_ptr, le_xls_writer));
 }
 /* }}} */
 
@@ -410,9 +413,9 @@ PHP_METHOD(vtiful_xls, insertText)
     SHEET_LINE_SET(obj, row);
 
     if (format_handle) {
-        type_writer(data, row, column, &obj->ptr, format, zval_get_format(format_handle));
+        type_writer(data, row, column, &obj->write_ptr, format, zval_get_format(format_handle));
     } else {
-        type_writer(data, row, column, &obj->ptr, format, NULL);
+        type_writer(data, row, column, &obj->write_ptr, format, NULL);
     }
 
 }
@@ -435,7 +438,7 @@ PHP_METHOD(vtiful_xls, insertChart)
 
     xls_object *obj = Z_XLS_P(getThis());
 
-    chart_writer(row, column, zval_get_chart(chart_resource), &obj->ptr);
+    chart_writer(row, column, zval_get_chart(chart_resource), &obj->write_ptr);
 }
 /* }}} */
 
@@ -462,11 +465,11 @@ PHP_METHOD(vtiful_xls, insertUrl)
     xls_object *obj = Z_XLS_P(getThis());
 
     if (argc == 4) {
-        url_writer(row, column, &obj->ptr, url, zval_get_format(format_handle));
+        url_writer(row, column, &obj->write_ptr, url, zval_get_format(format_handle));
     }
 
     if (argc == 3) {
-        url_writer(row, column, &obj->ptr, url, NULL);
+        url_writer(row, column, &obj->write_ptr, url, NULL);
     }
 }
 /* }}} */
@@ -492,7 +495,7 @@ PHP_METHOD(vtiful_xls, insertImage)
 
     xls_object *obj = Z_XLS_P(getThis());
 
-    image_writer(image, row, column, width, height,  &obj->ptr);
+    image_writer(image, row, column, width, height,  &obj->write_ptr);
 }
 /* }}} */
 
@@ -513,7 +516,7 @@ PHP_METHOD(vtiful_xls, insertFormula)
 
     xls_object *obj = Z_XLS_P(getThis());
 
-    formula_writer(formula, row, column, &obj->ptr);
+    formula_writer(formula, row, column, &obj->write_ptr);
 }
 /* }}} */
 
@@ -531,7 +534,7 @@ PHP_METHOD(vtiful_xls, autoFilter)
 
     xls_object *obj = Z_XLS_P(getThis());
 
-    auto_filter(range, &obj->ptr);
+    auto_filter(range, &obj->write_ptr);
 }
 /* }}} */
 
@@ -550,7 +553,7 @@ PHP_METHOD(vtiful_xls, mergeCells)
 
     xls_object *obj = Z_XLS_P(getThis());
 
-    merge_cells(range, data, &obj->ptr);
+    merge_cells(range, data, &obj->write_ptr);
 }
 /* }}} */
 
@@ -576,11 +579,11 @@ PHP_METHOD(vtiful_xls, setColumn)
     xls_object *obj = Z_XLS_P(getThis());
 
     if (argc == 3) {
-        set_column(range, width, &obj->ptr, zval_get_format(format_handle));
+        set_column(range, width, &obj->write_ptr, zval_get_format(format_handle));
     }
 
     if (argc == 2) {
-        set_column(range, width, &obj->ptr, NULL);
+        set_column(range, width, &obj->write_ptr, NULL);
     }
 }
 /* }}} */
@@ -607,12 +610,84 @@ PHP_METHOD(vtiful_xls, setRow)
     xls_object *obj = Z_XLS_P(getThis());
 
     if (argc == 3) {
-        set_row(range, height, &obj->ptr, zval_get_format(format_handle));
+        set_row(range, height, &obj->write_ptr, zval_get_format(format_handle));
     }
 
     if (argc == 2) {
-        set_row(range, height, &obj->ptr, NULL);
+        set_row(range, height, &obj->write_ptr, NULL);
+    }
+}
+/* }}} */
+
+/** {{{ \Vtiful\Kernel\xls::openFile()
+ */
+PHP_METHOD(vtiful_xls, openFile)
+{
+    zval *zv_config_path = NULL;
+    zend_string *zs_file_name = NULL;
+
+    ZEND_PARSE_PARAMETERS_START(1, 1)
+        Z_PARAM_STR(zs_file_name)
+    ZEND_PARSE_PARAMETERS_END();
+
+    ZVAL_COPY(return_value, getThis());
+
+    GET_CONFIG_PATH(zv_config_path, vtiful_xls_ce, return_value);
+
+    xls_object* obj = Z_XLS_P(getThis());
+
+    obj->read_ptr.file_t = file_open(Z_STRVAL_P(zv_config_path), ZSTR_VAL(zs_file_name));
+}
+/* }}} */
+
+/** {{{ \Vtiful\Kernel\xls::openSheet()
+ */
+PHP_METHOD(vtiful_xls, openSheet)
+{
+    zend_string *sheet_name = NULL;
+
+    ZEND_PARSE_PARAMETERS_START(0, 1)
+            Z_PARAM_OPTIONAL
+            Z_PARAM_STR(sheet_name)
+    ZEND_PARSE_PARAMETERS_END();
+
+    ZVAL_COPY(return_value, getThis());
+
+    xls_object* obj = Z_XLS_P(getThis());
+
+    if (obj->read_ptr.file_t == NULL) {
+        RETURN_NULL();
     }
+
+    obj->read_ptr.sheet_t = sheet_open(obj->read_ptr.file_t, sheet_name);
+}
+/* }}} */
+
+/** {{{ \Vtiful\Kernel\xls::getSheetData()
+ */
+PHP_METHOD(vtiful_xls, getSheetData)
+{
+    xls_object *obj = Z_XLS_P(getThis());
+
+    if (!obj->read_ptr.sheet_t) {
+        RETURN_FALSE;
+    }
+
+    load_sheet_all_data(obj->read_ptr.sheet_t, return_value);
+}
+/* }}} */
+
+/** {{{ \Vtiful\Kernel\xls::nextRow()
+ */
+PHP_METHOD(vtiful_xls, nextRow)
+{
+    xls_object *obj  = Z_XLS_P(getThis());
+
+    if (!obj->read_ptr.sheet_t) {
+        RETURN_FALSE;
+    }
+
+    load_sheet_current_row_data(obj->read_ptr.sheet_t, return_value, READ_ROW);
 }
 /* }}} */
 
@@ -637,6 +712,10 @@ zend_function_entry xls_methods[] = {
         PHP_ME(vtiful_xls, mergeCells,    xls_merge_cells_arginfo,    ZEND_ACC_PUBLIC)
         PHP_ME(vtiful_xls, setColumn,     xls_set_column_arginfo,     ZEND_ACC_PUBLIC)
         PHP_ME(vtiful_xls, setRow,        xls_set_row_arginfo,        ZEND_ACC_PUBLIC)
+        PHP_ME(vtiful_xls, openFile,      NULL,                       ZEND_ACC_PUBLIC)
+        PHP_ME(vtiful_xls, openSheet,     NULL,                       ZEND_ACC_PUBLIC)
+        PHP_ME(vtiful_xls, getSheetData,  NULL,                       ZEND_ACC_PUBLIC)
+        //PHP_ME(vtiful_xls, nextRow,       NULL, ZEND_ACC_PUBLIC)
         PHP_FE_END
 };
 /* }}} */

+ 1 - 1
kernel/format.c

@@ -91,7 +91,7 @@ PHP_METHOD(vtiful_format, __construct)
 {
     zval *handle;
     format_object *obj;
-    xls_resource_t *xls_res;
+    xls_resource_write_t *xls_res;
 
     ZEND_PARSE_PARAMETERS_START(1, 1)
             Z_PARAM_RESOURCE(handle)

+ 94 - 0
kernel/read.c

@@ -0,0 +1,94 @@
+/*
+  +----------------------------------------------------------------------+
+  | XlsWriter Extension                                                  |
+  +----------------------------------------------------------------------+
+  | Copyright (c) 2017-2018 The Viest                                    |
+  +----------------------------------------------------------------------+
+  | http://www.viest.me                                                  |
+  +----------------------------------------------------------------------+
+  | Author: viest <[email protected]>                                 |
+  +----------------------------------------------------------------------+
+*/
+
+#include "xlswriter.h"
+
+/* {{{ */
+xlsxioreader file_open(const char *directory, const char *file_name) {
+    char path[strlen(directory) + strlen(file_name) + 2];
+    xlsxioreader file;
+
+    lxw_strcpy(path, directory);
+    strcat(path, "/");
+    strcat(path, file_name);
+
+    if ((file = xlsxioread_open(path)) == NULL) {
+        zend_throw_exception(vtiful_exception_ce, "Failed to open file", 100);
+        return NULL;
+    }
+
+    return file;
+}
+/* }}} */
+
+/* {{{ */
+xlsxioreadersheet sheet_open(xlsxioreader file, const zend_string *zs_sheet_name_t)
+{
+    if (zs_sheet_name_t == NULL) {
+        return xlsxioread_sheet_open(file, NULL, XLSXIOREAD_SKIP_EMPTY_ROWS);
+    }
+
+    return xlsxioread_sheet_open(file, ZSTR_VAL(zs_sheet_name_t), XLSXIOREAD_SKIP_EMPTY_ROWS);
+}
+/* }}} */
+
+/* {{{ */
+int sheet_read_row(xlsxioreadersheet sheet)
+{
+    return xlsxioread_sheet_next_row(sheet);
+}
+/* }}} */
+
+/* {{{ */
+char* sheet_read_column(xlsxioreadersheet sheet)
+{
+    return xlsxioread_sheet_next_cell(sheet);
+}
+/* }}} */
+
+/* {{{ */
+unsigned int load_sheet_current_row_data(xlsxioreadersheet sheet_t, zval *zv_result_t, unsigned int flag)
+{
+    char *_string_value = NULL;
+
+    if (flag && !sheet_read_row(sheet_t)) {
+        return XLSWRITER_FALSE;
+    }
+
+    if (Z_TYPE_P(zv_result_t) != IS_ARRAY) {
+        array_init(zv_result_t);
+    }
+
+    while ((_string_value = sheet_read_column(sheet_t)) != NULL)
+    {
+        add_next_index_stringl(zv_result_t, _string_value, strlen(_string_value));
+    }
+
+    return XLSWRITER_TRUE;
+}
+/* }}} */
+
+/* {{{ */
+void load_sheet_all_data(xlsxioreadersheet sheet_t, zval *zv_result_t)
+{
+    if (Z_TYPE_P(zv_result_t) != IS_ARRAY) {
+        array_init(zv_result_t);
+    }
+
+    while (sheet_read_row(sheet_t))
+    {
+        zval _zv_tmp_row;
+        load_sheet_current_row_data(sheet_t, &_zv_tmp_row, READ_SKIP_ROW);
+        add_next_index_zval(zv_result_t, &_zv_tmp_row);
+    }
+}
+/* }}} */

+ 3 - 3
kernel/resource.c

@@ -13,11 +13,11 @@
 #include "xlswriter.h"
 
 /* {{{ */
-xls_resource_t * zval_get_resource(zval *handle)
+xls_resource_write_t * zval_get_resource(zval *handle)
 {
-    xls_resource_t *res;
+    xls_resource_write_t *res;
 
-    if((res = (xls_resource_t *)zend_fetch_resource(Z_RES_P(handle), VTIFUL_RESOURCE_NAME, le_xls_writer)) == NULL) {
+    if((res = (xls_resource_write_t *)zend_fetch_resource(Z_RES_P(handle), VTIFUL_RESOURCE_NAME, le_xls_writer)) == NULL) {
         zend_throw_exception(vtiful_exception_ce, "XLS resources resolution fail", 210);
     }
 

+ 11 - 11
kernel/write.c

@@ -15,7 +15,7 @@
 /*
  * According to the zval type written to the file
  */
-void type_writer(zval *value, zend_long row, zend_long columns, xls_resource_t *res, zend_string *format, lxw_format *format_handle)
+void type_writer(zval *value, zend_long row, zend_long columns, xls_resource_write_t *res, zend_string *format, lxw_format *format_handle)
 {
     lxw_format *value_format = NULL;
 
@@ -160,7 +160,7 @@ void format_copy(lxw_format *new_format, lxw_format *other_format)
     new_format->font_only = other_format->font_only;
 }
 
-void url_writer(zend_long row, zend_long columns, xls_resource_t *res, zend_string *url, lxw_format *format)
+void url_writer(zend_long row, zend_long columns, xls_resource_write_t *res, zend_string *url, lxw_format *format)
 {
     worksheet_write_url(res->worksheet, row, columns, ZSTR_VAL(url), format);
 }
@@ -168,7 +168,7 @@ void url_writer(zend_long row, zend_long columns, xls_resource_t *res, zend_stri
 /*
  * Write the image to the file
  */
-void image_writer(zval *value, zend_long row, zend_long columns, double width, double height, xls_resource_t *res)
+void image_writer(zval *value, zend_long row, zend_long columns, double width, double height, xls_resource_write_t *res)
 {
     lxw_image_options options = {.x_scale = width, .y_scale = height};
 
@@ -178,12 +178,12 @@ void image_writer(zval *value, zend_long row, zend_long columns, double width, d
 /*
  * Write the image to the file
  */
-void formula_writer(zval *value, zend_long row, zend_long columns, xls_resource_t *res)
+void formula_writer(zval *value, zend_long row, zend_long columns, xls_resource_write_t *res)
 {
     worksheet_write_formula(res->worksheet, row, columns, ZSTR_VAL(zval_get_string(value)), NULL);
 }
 
-void chart_writer(zend_long row, zend_long columns, xls_resource_chart_t *chart_resource, xls_resource_t *res)
+void chart_writer(zend_long row, zend_long columns, xls_resource_chart_t *chart_resource, xls_resource_write_t *res)
 {
     worksheet_insert_chart(res->worksheet, row, columns, chart_resource->chart);
 }
@@ -191,7 +191,7 @@ void chart_writer(zend_long row, zend_long columns, xls_resource_chart_t *chart_
 /*
  * Add the autofilter.
  */
-void auto_filter(zend_string *range, xls_resource_t *res)
+void auto_filter(zend_string *range, xls_resource_write_t *res)
 {
     worksheet_autofilter(res->worksheet, RANGE(ZSTR_VAL(range)));
 }
@@ -199,7 +199,7 @@ void auto_filter(zend_string *range, xls_resource_t *res)
 /*
  * Merge cells.
  */
-void merge_cells(zend_string *range, zend_string *value, xls_resource_t *res)
+void merge_cells(zend_string *range, zend_string *value, xls_resource_write_t *res)
 {
     worksheet_merge_range(res->worksheet, RANGE(ZSTR_VAL(range)), ZSTR_VAL(value), NULL);
 }
@@ -207,7 +207,7 @@ void merge_cells(zend_string *range, zend_string *value, xls_resource_t *res)
 /*
  * Set column format
  */
-void set_column(zend_string *range, double width, xls_resource_t *res, lxw_format *format)
+void set_column(zend_string *range, double width, xls_resource_write_t *res, lxw_format *format)
 {
     worksheet_set_column(res->worksheet, COLS(ZSTR_VAL(range)), width, format);
 }
@@ -215,7 +215,7 @@ void set_column(zend_string *range, double width, xls_resource_t *res, lxw_forma
 /*
  * Set row format
  */
-void set_row(zend_string *range, double height, xls_resource_t *res, lxw_format *format)
+void set_row(zend_string *range, double height, xls_resource_write_t *res, lxw_format *format)
 {
     char *rows = ZSTR_VAL(range);
 
@@ -229,7 +229,7 @@ void set_row(zend_string *range, double height, xls_resource_t *res, lxw_format
 /*
  * Set rows format
  */
-void worksheet_set_rows(lxw_row_t start, lxw_row_t end, double height, xls_resource_t *res, lxw_format *format)
+void worksheet_set_rows(lxw_row_t start, lxw_row_t end, double height, xls_resource_write_t *res, lxw_format *format)
 {
     while (1) {
         worksheet_set_row(res->worksheet, end, height, format);
@@ -243,7 +243,7 @@ void worksheet_set_rows(lxw_row_t start, lxw_row_t end, double height, xls_resou
  * Call finalization code and close file.
  */
 lxw_error
-workbook_file(xls_resource_t *self)
+workbook_file(xls_resource_write_t *self)
 {
     lxw_worksheet *worksheet = NULL;
     lxw_packager *packager = NULL;

+ 1 - 0
library/libxlsxio

@@ -0,0 +1 @@
+Subproject commit b2b39b91c5005b4edc78ff8145226338aaea1c2c

+ 34 - 0
tests/open_xlsx_file.phpt

@@ -0,0 +1,34 @@
+--TEST--
+Check for vtiful presence
+--SKIPIF--
+<?php if (!extension_loaded("xlswriter")) print "skip"; ?>
+--FILE--
+<?php
+$config   = ['path' => './tests'];
+$excel    = new \Vtiful\Kernel\Excel($config);
+$filePath = $excel->fileName('tutorial.xlsx')
+    ->header(['Item', 'Cost'])
+    ->output();
+
+$data = $excel->openFile('tutorial.xlsx');
+
+var_dump($data);
+?>
+--CLEAN--
+<?php
+@unlink(__DIR__ . '/tutorial.xlsx');
+?>
+--EXPECT--
+object(Vtiful\Kernel\Excel)#1 (4) {
+  ["config":"Vtiful\Kernel\Excel":private]=>
+  array(1) {
+    ["path"]=>
+    string(7) "./tests"
+  }
+  ["fileName":"Vtiful\Kernel\Excel":private]=>
+  string(21) "./tests/tutorial.xlsx"
+  ["handle"]=>
+  NULL
+  ["path"]=>
+  NULL
+}

+ 30 - 0
tests/open_xlsx_get_data.phpt

@@ -0,0 +1,30 @@
+--TEST--
+Check for vtiful presence
+--SKIPIF--
+<?php if (!extension_loaded("xlswriter")) print "skip"; ?>
+--FILE--
+<?php
+$config   = ['path' => './tests'];
+$excel    = new \Vtiful\Kernel\Excel($config);
+$filePath = $excel->fileName('tutorial.xlsx')
+    ->header(['Item', 'Cost'])
+    ->output();
+
+$data = $excel->openFile('tutorial.xlsx')->openSheet()->getSheetData();
+
+var_dump($data);
+?>
+--CLEAN--
+<?php
+@unlink(__DIR__ . '/tutorial.xlsx');
+?>
+--EXPECT--
+array(1) {
+  [0]=>
+  array(2) {
+    [0]=>
+    string(4) "Item"
+    [1]=>
+    string(4) "Cost"
+  }
+}

+ 23 - 0
tests/open_xlsx_get_sheet_not_found_data.phpt

@@ -0,0 +1,23 @@
+--TEST--
+Check for vtiful presence
+--SKIPIF--
+<?php if (!extension_loaded("xlswriter")) print "skip"; ?>
+--FILE--
+<?php
+$config   = ['path' => './tests'];
+$excel    = new \Vtiful\Kernel\Excel($config);
+$filePath = $excel->fileName('tutorial.xlsx')
+    ->header(['Item', 'Cost'])
+    ->output();
+
+$data = $excel->openFile('tutorial.xlsx')->openSheet('not_found')->getSheetData();
+
+var_dump($data);
+?>
+--CLEAN--
+<?php
+@unlink(__DIR__ . '/tutorial.xlsx');
+?>
+--EXPECT--
+array(0) {
+}

+ 34 - 0
tests/open_xlsx_sheet.phpt

@@ -0,0 +1,34 @@
+--TEST--
+Check for vtiful presence
+--SKIPIF--
+<?php if (!extension_loaded("xlswriter")) print "skip"; ?>
+--FILE--
+<?php
+$config   = ['path' => './tests'];
+$excel    = new \Vtiful\Kernel\Excel($config);
+$filePath = $excel->fileName('tutorial.xlsx')
+    ->header(['Item', 'Cost'])
+    ->output();
+
+$data = $excel->openFile('tutorial.xlsx')->openSheet();
+
+var_dump($data);
+?>
+--CLEAN--
+<?php
+@unlink(__DIR__ . '/tutorial.xlsx');
+?>
+--EXPECT--
+object(Vtiful\Kernel\Excel)#1 (4) {
+  ["config":"Vtiful\Kernel\Excel":private]=>
+  array(1) {
+    ["path"]=>
+    string(7) "./tests"
+  }
+  ["fileName":"Vtiful\Kernel\Excel":private]=>
+  string(21) "./tests/tutorial.xlsx"
+  ["handle"]=>
+  NULL
+  ["path"]=>
+  NULL
+}