]> git.mjollnir.org Git - moodle.git/commitdiff
pclzip 2.0 RC2 - hopefully better!
authormoodler <moodler>
Fri, 22 Aug 2003 12:35:43 +0000 (12:35 +0000)
committermoodler <moodler>
Fri, 22 Aug 2003 12:35:43 +0000 (12:35 +0000)
lib/pclzip/pclzip.lib.php
lib/pclzip/readme.txt

index 75d69929d6dadd8de6cf9ea013118385a3ada4b3..c31085633065e55d980304e35a939598a76381b7 100644 (file)
@@ -1,6 +1,6 @@
 <?php\r
 // --------------------------------------------------------------------------------\r
-// PhpConcept Library - Zip Module 2.0-rc1\r
+// PhpConcept Library - Zip Module 2.0-rc2\r
 // --------------------------------------------------------------------------------\r
 // License GNU/LGPL - Vincent Blavet - July 2003\r
 // http://www.phpconcept.net\r
@@ -63,7 +63,7 @@
 // --------------------------------------------------------------------------------\r
 \r
   // ----- Global variables\r
-  $g_pclzip_version = "2.0-rc1";\r
+  $g_pclzip_version = "2.0-rc2";\r
 \r
   // ----- Error codes\r
   //   -1 : Unable to open file in binary write mode\r
@@ -80,6 +80,7 @@
   //  -12 : Unable to rename file (rename)\r
   //  -13 : Invalid header checksum\r
   //  -14 : Invalid archive size\r
+  define( 'PCLZIP_ERR_NO_ERROR', 0 );\r
   define( 'PCLZIP_ERR_WRITE_OPEN_FAIL', -1 );\r
   define( 'PCLZIP_ERR_READ_OPEN_FAIL', -2 );\r
   define( 'PCLZIP_ERR_INVALID_PARAMETER', -3 );\r
   define( 'PCLZIP_OPT_SET_CHMOD', 77005 );\r
   define( 'PCLZIP_OPT_EXTRACT_AS_STRING', 77006 );\r
   define( 'PCLZIP_OPT_NO_COMPRESSION', 77007 );\r
+  define( 'PCLZIP_OPT_BY_NAME', 77008 );\r
+  define( 'PCLZIP_OPT_BY_INDEX', 77009 );\r
+  define( 'PCLZIP_OPT_BY_EREG', 77010 );\r
+  define( 'PCLZIP_OPT_BY_PREG', 77011 );\r
 \r
   // ----- Call backs values\r
   define( 'PCLZIP_CB_PRE_EXTRACT', 78001 );\r
     $v_add_path = "";\r
     $v_remove_path = "";\r
     $v_remove_all_path = false;\r
+    $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;\r
 \r
     // ----- Look for variable options arguments\r
     $v_size = func_num_args();\r
         if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {\r
           $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];\r
         }\r
-        if (!isset($v_options[PCLZIP_OPT_NO_COMPRESSION])) {\r
-          $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;\r
-          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Option PCLZIP_OPT_NO_COMPRESSION not set.");\r
-        }\r
-        else {\r
-            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Option PCLZIP_OPT_NO_COMPRESSION set.");\r
-        }\r
       }\r
 \r
       // ----- Look for 2 args\r
     $v_add_path = "";\r
     $v_remove_path = "";\r
     $v_remove_all_path = false;\r
+    $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;\r
 \r
     // ----- Look for variable options arguments\r
     $v_size = func_num_args();\r
         if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {\r
           $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];\r
         }\r
-        if (!isset($v_options[PCLZIP_OPT_NO_COMPRESSION])) {\r
-          $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;\r
-          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Option PCLZIP_OPT_NO_COMPRESSION not set.");\r
-        }\r
-        else {\r
-            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Option PCLZIP_OPT_NO_COMPRESSION set.");\r
-        }\r
       }\r
 \r
       // ----- Look for 2 args\r
   //function extract($p_path="./", $p_remove_path="")\r
   function extract(/* options */)\r
   {\r
-    //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip:extract", "");\r
+    //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::extract", "");\r
     $v_result=1;\r
 \r
     // ----- Reset the error handler\r
     $v_size = func_num_args();\r
     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method");\r
 \r
+    // ----- Default values for option\r
+    $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;\r
+\r
     // ----- Look for arguments\r
     if ($v_size > 0) {\r
       // ----- Get the arguments\r
                                                    PCLZIP_OPT_ADD_PATH => 'optional',\r
                                                    PCLZIP_CB_PRE_EXTRACT => 'optional',\r
                                                    PCLZIP_CB_POST_EXTRACT => 'optional',\r
-                                                   PCLZIP_OPT_SET_CHMOD => 'optional' ));\r
+                                                   PCLZIP_OPT_SET_CHMOD => 'optional',\r
+                                                   PCLZIP_OPT_BY_NAME => 'optional',\r
+                                                   PCLZIP_OPT_BY_EREG => 'optional',\r
+                                                   PCLZIP_OPT_BY_PREG => 'optional',\r
+                                                   PCLZIP_OPT_BY_INDEX => 'optional',\r
+                                                   PCLZIP_OPT_EXTRACT_AS_STRING => 'optional' ));\r
         if ($v_result != 1) {\r
           //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);\r
           return 0;\r
 \r
     // ----- Call the extracting fct\r
     $p_list = array();\r
-    if (($v_result = $this->privExtract($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) != 1)\r
+    if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) != 1)\r
     {\r
       unset($p_list);\r
       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());\r
   }\r
   // --------------------------------------------------------------------------------\r
 \r
+\r
   // --------------------------------------------------------------------------------\r
   // Function :\r
   //   extractByIndex($p_index, $p_path="./", $p_remove_path="")\r
     // ----- Trace\r
     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "index='$p_index', path='$v_path', remove_path='$v_remove_path', remove_all_path='".($v_remove_path?'true':'false')."'");\r
 \r
-    // ----- Look if the $p_index is really an integer\r
-    if (is_integer($p_index))\r
-    {\r
-      // ----- Call the extracting fct\r
-      if (($v_result = $this->privExtractByIndex($p_list, "$p_index", $v_path, $v_remove_path, $v_remove_all_path, $v_options)) != 1)\r
-      {\r
-        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());\r
-        return(0);\r
-      }\r
+    // ----- Trick\r
+    // Here I want to reuse extractByRule(), so I need to parse the $p_index\r
+    // with privParseOptions()\r
+    $v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index);\r
+    $v_options_trick = array();\r
+    $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick,\r
+                                        array (PCLZIP_OPT_BY_INDEX => 'optional' ));\r
+    if ($v_result != 1) {\r
+        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);\r
+        return 0;\r
     }\r
+    $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX];\r
 \r
-    // ----- Look if the index is a string\r
-    else if (is_string($p_index))\r
-    {\r
-      // ----- Call the extracting fct\r
-      if (($v_result = $this->privExtractByIndex($p_list, $p_index, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) != 1)\r
-      {\r
+    // ----- Call the extracting fct\r
+    if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) != 1) {\r
         //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());\r
         return(0);\r
-      }\r
-    }\r
-\r
-    // ----- Invalid variable\r
-    else\r
-    {\r
-      // ----- Error log\r
-      PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type $p_index");\r
-\r
-      // ----- Return\r
-      //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());\r
-      return 0;\r
     }\r
 \r
     // ----- Return\r
   // --------------------------------------------------------------------------------\r
 \r
   // --------------------------------------------------------------------------------\r
-  // Function : deleteByIndex()\r
+  // Function :\r
+  //   delete([$p_option, $p_option_value, ...])\r
   // Description :\r
-  //   This method delete somes files or folder entries from the zip archive.\r
-  //   The entries (files or folders) are identified by their index in the\r
-  //   archive (0-n).\r
-  //   Note that if the index identify a folder entry, only the folder entry\r
-  //   is deleted, and not all the files included in the folder.\r
   // Parameters :\r
-  //   $p_index : A single index (integer) or a string of indexes of files to\r
-  //              delete. The form of the string is "0,4-6,8-12" with only numbers\r
-  //              and '-' for range or ',' to separate ranges. No spaces or ';'\r
-  //              are allowed.\r
+  //   None\r
+  // Options :\r
+  //   PCLZIP_OPT_BY_INDEX :\r
   // Return Values :\r
   //   0 on failure,\r
   //   The list of the files which are still present in the archive.\r
   //   (see PclZip::listContent() for list entry format)\r
   // --------------------------------------------------------------------------------\r
-  function deleteByIndex($p_index)\r
+  function delete(/* options */)\r
   {\r
-    //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::deleteByIndex", "index='$p_index'");\r
+    //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::delete", "");\r
     $v_result=1;\r
 \r
     // ----- Reset the error handler\r
       return(0);\r
     }\r
 \r
-    // ----- Look if the $p_index is really an integer\r
-    if (is_integer($p_index))\r
-    {\r
-      // ----- Call the delete fct\r
-      if (($v_result = $this->privDeleteByIndex("$p_index", $p_list)) != 1)\r
-      {\r
+    // ----- Set default values\r
+    $v_options = array();\r
+\r
+    // ----- Look for variable options arguments\r
+    $v_size = func_num_args();\r
+    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method");\r
+\r
+    // ----- Look for no arguments\r
+    if ($v_size <= 0) {\r
+        // ----- Error log\r
+        PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing arguments");\r
+\r
+        // ----- Return\r
         //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());\r
-        return(0);\r
-      }\r
+        return 0;\r
     }\r
 \r
-    // ----- Look if the index is a string\r
-    else if (is_string($p_index))\r
-    {\r
-      // ----- Call the delete fct\r
-      if (($v_result = $this->privDeleteByIndex($p_index, $p_list)) != 1)\r
-      {\r
+    // ----- Get the arguments\r
+    $v_arg_list = &func_get_args();\r
+\r
+    // ----- Parse the options\r
+    $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,\r
+                                        array (PCLZIP_OPT_BY_NAME => 'optional',\r
+                                               PCLZIP_OPT_BY_EREG => 'optional',\r
+                                               PCLZIP_OPT_BY_PREG => 'optional',\r
+                                               PCLZIP_OPT_BY_INDEX => 'optional' ));\r
+    if ($v_result != 1) {\r
+        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);\r
+        return 0;\r
+    }\r
+\r
+    // ----- Check that at least one rule is set\r
+    if (   (!isset($v_options[PCLZIP_OPT_BY_NAME]))\r
+        && (!isset($v_options[PCLZIP_OPT_BY_EREG]))\r
+        && (!isset($v_options[PCLZIP_OPT_BY_PREG]))\r
+        && (!isset($v_options[PCLZIP_OPT_BY_INDEX]))) {\r
+        // ----- Error log\r
+        PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "At least one filtering rule must be set");\r
+\r
+        // ----- Return\r
         //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());\r
-        return(0);\r
-      }\r
+        return 0;\r
     }\r
 \r
-    // ----- Invalid variable\r
-    else\r
+    // ----- Call the delete fct\r
+    $v_list = array();\r
+    if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1)\r
     {\r
-      // ----- Error log\r
-      PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type $p_index");\r
-\r
-      // ----- Return\r
-      //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());\r
-      return 0;\r
+      unset($v_list);\r
+      //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());\r
+      return(0);\r
     }\r
 \r
+    // ----- Return\r
+    //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_list);\r
+    return $v_list;\r
+  }\r
+  // --------------------------------------------------------------------------------\r
+\r
+  // --------------------------------------------------------------------------------\r
+  // Function : deleteByIndex()\r
+  // Description :\r
+  //   ***** Deprecated *****\r
+  //   delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered.\r
+  // --------------------------------------------------------------------------------\r
+  function deleteByIndex($p_index)\r
+  {\r
+    //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::deleteByIndex", "index='$p_index'");\r
+    \r
+    $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index);\r
+\r
     // ----- Return\r
     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_list);\r
     return $p_list;\r
           $i++;\r
         break;\r
 \r
+        // ----- Look for options that request an array of string for value\r
+        case PCLZIP_OPT_BY_NAME :\r
+          // ----- Check the number of parameters\r
+          if (($i+1) >= $p_size) {\r
+            // ----- Error log\r
+            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");\r
+\r
+            // ----- Return\r
+            //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());\r
+            return PclZip::errorCode();\r
+          }\r
+\r
+          // ----- Get the value\r
+          if (is_string($p_options_list[$i+1])) {\r
+              $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1];\r
+          }\r
+          else if (is_array($p_options_list[$i+1])) {\r
+              $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];\r
+          }\r
+          else {\r
+            // ----- Error log\r
+            PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");\r
+\r
+            // ----- Return\r
+            //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());\r
+            return PclZip::errorCode();\r
+          }\r
+          ////--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");\r
+          $i++;\r
+        break;\r
+\r
+        // ----- Look for options that request an EREG or PREG expression\r
+        case PCLZIP_OPT_BY_EREG :\r
+        case PCLZIP_OPT_BY_PREG :\r
+          // ----- Check the number of parameters\r
+          if (($i+1) >= $p_size) {\r
+            // ----- Error log\r
+            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");\r
+\r
+            // ----- Return\r
+            //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());\r
+            return PclZip::errorCode();\r
+          }\r
+\r
+          // ----- Get the value\r
+          if (is_string($p_options_list[$i+1])) {\r
+              $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];\r
+          }\r
+          else {\r
+            // ----- Error log\r
+            PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");\r
+\r
+            // ----- Return\r
+            //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());\r
+            return PclZip::errorCode();\r
+          }\r
+          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");\r
+          $i++;\r
+        break;\r
+\r
+        // ----- Look for options that request an array of index\r
+        case PCLZIP_OPT_BY_INDEX :\r
+          // ----- Check the number of parameters\r
+          if (($i+1) >= $p_size) {\r
+            // ----- Error log\r
+            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");\r
+\r
+            // ----- Return\r
+            //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());\r
+            return PclZip::errorCode();\r
+          }\r
+\r
+          // ----- Get the value\r
+          $v_work_list = array();\r
+          if (is_string($p_options_list[$i+1])) {\r
+              //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Index value is a string '".$p_options_list[$i+1]."'");\r
+\r
+              // ----- Remove spaces\r
+              $p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', '');\r
+\r
+              // ----- Parse items\r
+              $v_work_list = explode(",", $p_options_list[$i+1]);\r
+          }\r
+          else if (is_integer($p_options_list[$i+1])) {\r
+              //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Index value is an integer '".$p_options_list[$i+1]."'");\r
+              $v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1];\r
+          }\r
+          else if (is_array($p_options_list[$i+1])) {\r
+              //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Index value is an array");\r
+              $v_work_list = $p_options_list[$i+1];\r
+          }\r
+          else {\r
+            // ----- Error log\r
+            PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'");\r
+\r
+            // ----- Return\r
+            //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());\r
+            return PclZip::errorCode();\r
+          }\r
+          \r
+          // ----- Reduce the index list\r
+          // each index item in the list must be a couple with a start and\r
+          // an end value : [0,3], [5-5], [8-10], ...\r
+          // ----- Check the format of each item\r
+          $v_sort_flag=false;\r
+          $v_sort_value=0;\r
+          for ($j=0; $j<sizeof($v_work_list); $j++) {\r
+              // ----- Explode the item\r
+              $v_item_list = explode("-", $v_work_list[$j]);\r
+              $v_size_item_list = sizeof($v_item_list);\r
+              \r
+              // ----- TBC : Here we might check that each item is a\r
+              // real integer ...\r
+              \r
+              // ----- Look for single value\r
+              if ($v_size_item_list == 1) {\r
+                  // ----- Set the option value\r
+                  $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];\r
+                  $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[0];\r
+              }\r
+              elseif ($v_size_item_list == 2) {\r
+                  // ----- Set the option value\r
+                  $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];\r
+                  $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[1];\r
+              }\r
+              else {\r
+                  // ----- Error log\r
+                  PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Too many values in index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");\r
+\r
+                  // ----- Return\r
+                  //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());\r
+                  return PclZip::errorCode();\r
+              }\r
+\r
+              //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extracted index item = [".$v_result_list[$p_options_list[$i]][$j]['start'].",".$v_result_list[$p_options_list[$i]][$j]['end']."]");\r
+\r
+              // ----- Look for list sort\r
+              if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) {\r
+                  //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The list should be sorted ...");\r
+                  $v_sort_flag=true;\r
+\r
+                  // ----- TBC : An automatic sort should be writen ...\r
+                  // ----- Error log\r
+                  PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Invalid order of index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");\r
+\r
+                  // ----- Return\r
+                  //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());\r
+                  return PclZip::errorCode();\r
+              }\r
+              $v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start'];\r
+          }\r
+          \r
+          // ----- Sort the items\r
+          if ($v_sort_flag) {\r
+              // TBC : To Be Completed\r
+              //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "List sorting is not yet write ...");\r
+          }\r
+\r
+          // ----- Next option\r
+          $i++;\r
+        break;\r
+\r
         // ----- Look for options that request no value\r
         case PCLZIP_OPT_REMOVE_ALL_PATH :\r
         case PCLZIP_OPT_EXTRACT_AS_STRING :\r
     $v_result=1;\r
     $v_list_detail = array();\r
 \r
-    // ----- Look if the archive exists\r
-    if (!is_file($this->zipname))\r
+    // ----- Look if the archive exists or is empty\r
+    if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0))\r
     {\r
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Archive does not exist, create it.");\r
+      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Archive does not exist, or is empty, create it.");\r
 \r
       // ----- Do a create\r
       $v_result = $this->privCreate($p_list, $p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, $p_options);\r
     $p_info['compressed_size'] = $p_header['compressed_size'];\r
     $p_info['mtime'] = $p_header['mtime'];\r
     $p_info['comment'] = $p_header['comment'];\r
-    $p_info['folder'] = ($p_header['external']==0x41FF0010);\r
+    $p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010);\r
     $p_info['index'] = $p_header['index'];\r
     $p_info['status'] = $p_header['status'];\r
 \r
   // --------------------------------------------------------------------------------\r
 \r
   // --------------------------------------------------------------------------------\r
-  // Function : privExtract()\r
+  // Function : privExtractByRule()\r
   // Description :\r
+  //   Extract a file or directory depending of rules (by index, by name, ...)\r
   // Parameters :\r
   //   $p_file_list : An array where will be placed the properties of each\r
   //                  extracted file\r
   // Return Values :\r
   //   1 on success,0 or less on error (see error code list)\r
   // --------------------------------------------------------------------------------\r
-  function privExtract(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)\r
+  function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)\r
   {\r
-    //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privExtract", "list, path=$p_path, remove_path='$p_remove_path', remove_all_path='".($p_remove_all_path?'true':'false')."'");\r
+    //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privExtractByRule", "path='$p_path', remove_path='$p_remove_path', remove_all_path='".($p_remove_all_path?'true':'false')."'");\r
     $v_result=1;\r
 \r
     // ----- Check the path\r
-    if (($p_path == "") || ((substr($p_path, 0, 1) != "/") && (substr($p_path, 0, 3) != "../")&& (substr($p_path,1,2)!= ":/")))\r
+    if (($p_path == "") || ((substr($p_path, 0, 1) != "/") && (substr($p_path, 0, 3) != "../") && (substr($p_path,1,2)!=":/")))\r
       $p_path = "./".$p_path;\r
 \r
     // ----- Reduce the path last (and duplicated) '/'\r
     $v_pos_entry = $v_central_dir['offset'];\r
 \r
     // ----- Read each entry\r
-    for ($i=0; $i<$v_central_dir['entries']; $i++)\r
+    $j_start = 0;\r
+    for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)\r
     {\r
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Read next file entry : $i'");\r
+      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Read next file header entry : '$i'");\r
 \r
       // ----- Read next Central dir entry\r
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position before rewind : ".ftell($this->zip_fd)."'");\r
+      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Position before rewind : ".ftell($this->zip_fd)."'");\r
       @rewind($this->zip_fd);\r
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position after rewind : ".ftell($this->zip_fd)."'");\r
+      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Position after rewind : ".ftell($this->zip_fd)."'");\r
       if (@fseek($this->zip_fd, $v_pos_entry))\r
       {\r
         // ----- Close the zip file\r
       // ----- Store the file position\r
       $v_pos_entry = ftell($this->zip_fd);\r
 \r
-      // ----- Go to the file position\r
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position before rewind : ".ftell($this->zip_fd)."'");\r
-      @rewind($this->zip_fd);\r
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position after rewind : ".ftell($this->zip_fd)."'");\r
-      if (@fseek($this->zip_fd, $v_header['offset']))\r
-      {\r
-        // ----- Close the zip file\r
-        $this->privCloseFd();\r
-\r
-        // ----- Error log\r
-        PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');\r
-\r
-        // ----- Return\r
-        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());\r
-        return PclZip::errorCode();\r
-      }\r
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position after fseek : ".ftell($this->zip_fd)."'");\r
-\r
-      // ----- Extracting the file\r
-      if (($v_result = $this->privExtractFile($v_header, $p_path, $p_remove_path, $p_remove_all_path, $p_options)) != 1)\r
-      {\r
-        // ----- Close the zip file\r
-        $this->privCloseFd();\r
-\r
-        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);\r
-        return $v_result;\r
-      }\r
-\r
-      // ----- Get the only interesting attributes\r
-      if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$i])) != 1)\r
-      {\r
-        // ----- Close the zip file\r
-        $this->privCloseFd();\r
+      // ----- Look for the specific extract rules\r
+      $v_extract = false;\r
 \r
-        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);\r
-        return $v_result;\r
+      // ----- Look for extract by name rule\r
+      if (   (isset($p_options[PCLZIP_OPT_BY_NAME]))\r
+          && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {\r
+          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByName'");\r
+\r
+          // ----- Look if the filename is in the list\r
+          for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_extract); $j++) {\r
+              //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Compare with file '".$p_options[PCLZIP_OPT_BY_NAME][$j]."'");\r
+\r
+              // ----- Look for a directory\r
+              if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {\r
+                  //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The searched item is a directory");\r
+\r
+                  // ----- Look if the directory is in the filename path\r
+                  if (   (strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))\r
+                      && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {\r
+                      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The directory is in the file path");\r
+                      $v_extract = true;\r
+                  }\r
+              }\r
+              // ----- Look for a filename\r
+              elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {\r
+                  //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The file is the right one.");\r
+                  $v_extract = true;\r
+              }\r
+          }\r
       }\r
-    }\r
 \r
-    // ----- Close the zip file\r
-    $this->privCloseFd();\r
+      // ----- Look for extract by ereg rule\r
+      else if (   (isset($p_options[PCLZIP_OPT_BY_EREG]))\r
+               && ($p_options[PCLZIP_OPT_BY_EREG] != "")) {\r
+          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract by ereg '".$p_options[PCLZIP_OPT_BY_EREG]."'");\r
 \r
-    // ----- Return\r
-    //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);\r
-    return $v_result;\r
-  }\r
-  // --------------------------------------------------------------------------------\r
-\r
-  // --------------------------------------------------------------------------------\r
-  // Function : privExtractByIndex()\r
-  // Description :\r
-  // Parameters :\r
-  //   $p_file_list : An array where will be placed the properties of each\r
-  //                  extracted file\r
-  //   $p_index : A single index (integer) or a string of indexes of files to\r
-  //              extract. The form of the string is "0,4-6,8-12" with only numbers\r
-  //              and '-' for range or ',' to separate ranges. No spaces or ';'\r
-  //              are allowed.\r
-  //   $p_path : Path to add while writing the extracted files\r
-  //   $p_remove_path : Path to remove (from the file memorized path) while writing the\r
-  //                    extracted files. If the path does not match the file path,\r
-  //                    the file is extracted with its memorized path.\r
-  //                    $p_remove_path does not apply to 'list' mode.\r
-  //                    $p_path and $p_remove_path are commulative.\r
-  // Return Values :\r
-  //   1 on success,0 or less on error (see error code list)\r
-  // --------------------------------------------------------------------------------\r
-  function privExtractByIndex(&$p_file_list, $p_index, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)\r
-  {\r
-    //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privExtractByIndex", "list, index='$p_index', path=$p_path, remove_path='$p_remove_path', remove_all_path='".($p_remove_all_path?'true':'false')."'");\r
-    $v_result=1;\r
-\r
-    // ----- Check the path\r
-    if (($p_path == "") || ((substr($p_path, 0, 1) != "/") && (substr($p_path, 0, 3) != "../")&& (substr($p_path,1,2)!=":/")))\r
-      $p_path = "./".$p_path;\r
-\r
-    // ----- Reduce the path last (and duplicated) '/'\r
-    if (($p_path != "./") && ($p_path != "/"))\r
-    {\r
-      // ----- Look for the path end '/'\r
-      while (substr($p_path, -1) == "/")\r
-      {\r
-        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Destination path [$p_path] ends by '/'");\r
-        $p_path = substr($p_path, 0, strlen($p_path)-1);\r
-        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Modified to [$p_path]");\r
+          if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename'])) {\r
+              //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename match the regular expression");\r
+              $v_extract = true;\r
+          }\r
       }\r
-    }\r
-\r
-    // ----- Look for path to remove format (should end by /)\r
-    if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/'))\r
-    {\r
-      $p_remove_path .= '/';\r
-    }\r
-    $p_remove_path_size = strlen($p_remove_path);\r
-\r
-    // ----- Open the zip file\r
-    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");\r
-    if (($v_result = $this->privOpenFd('rb')) != 1)\r
-    {\r
-      //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);\r
-      return $v_result;\r
-    }\r
 \r
-    // ----- Read the central directory informations\r
-    $v_central_dir = array();\r
-    if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)\r
-    {\r
-      // ----- Close the zip file\r
-      $this->privCloseFd();\r
-\r
-      //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);\r
-      return $v_result;\r
-    }\r
+      // ----- Look for extract by preg rule\r
+      else if (   (isset($p_options[PCLZIP_OPT_BY_PREG]))\r
+               && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {\r
+          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByEreg'");\r
 \r
-    // ----- Manipulate the index list\r
-    $p_index = strtr($p_index, ' ', '');\r
-    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Reduced index : '$p_index'");\r
-    $v_index_list = explode(",", $p_index);\r
-    // TBC : Here I should sort the index. However a simple sort is not enought.\r
-    // look for the use of usort()\r
-    //sort($v_index_list);\r
-\r
-    // ----- Start at beginning of Central Dir\r
-    $v_pos_entry = $v_central_dir['offset'];\r
-\r
-    // ----- Read each entry\r
-    for ($i=0, $j_start=0, $v_nb_extracted=0; ($i<$v_central_dir['entries']) && ($j_start<sizeof($v_index_list)); $i++)\r
-    {\r
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Read next file header entry : $i'");\r
-\r
-      // ----- Read next Central dir entry\r
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position before rewind : ".ftell($this->zip_fd)."'");\r
-      @rewind($this->zip_fd);\r
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position after rewind : ".ftell($this->zip_fd)."'");\r
-      if (@fseek($this->zip_fd, $v_pos_entry))\r
-      {\r
-        // ----- Close the zip file\r
-        $this->privCloseFd();\r
-\r
-        // ----- Error log\r
-        PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');\r
-\r
-        // ----- Return\r
-        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());\r
-        return PclZip::errorCode();\r
+          if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) {\r
+              //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename match the regular expression");\r
+              $v_extract = true;\r
+          }\r
       }\r
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position after fseek : ".ftell($this->zip_fd)."'");\r
-\r
-      // ----- Read the file header\r
-      $v_header = array();\r
-      if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)\r
-      {\r
-        // ----- Close the zip file\r
-        $this->privCloseFd();\r
 \r
-        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);\r
-        return $v_result;\r
+      // ----- Look for extract by index rule\r
+      else if (   (isset($p_options[PCLZIP_OPT_BY_INDEX]))\r
+               && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {\r
+          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByIndex'");\r
+          \r
+          // ----- Look if the index is in the list\r
+          for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) {\r
+              //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Look if index '$i' is in [".$p_options[PCLZIP_OPT_BY_INDEX][$j]['start'].",".$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']."]");\r
+\r
+              if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {\r
+                  //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Found as part of an index range");\r
+                  $v_extract = true;\r
+              }\r
+              if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {\r
+                  //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Do not look this index range for next loop");\r
+                  $j_start = $j+1;\r
+              }\r
+\r
+              if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {\r
+                  //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Index range is greater than index, stop loop");\r
+                  break;\r
+              }\r
+          }\r
       }\r
 \r
-      // ----- Store the index\r
-      $v_header['index'] = $i;\r
-\r
-      // ----- Store the file position\r
-      $v_pos_entry = ftell($this->zip_fd);\r
-\r
-      // ----- Look if the index is in the list\r
-      $v_extract = false;\r
-      for ($j=$j_start; ($j<sizeof($v_index_list)) && (!$v_extract); $j++)\r
-      {\r
-        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Look if index '$i' is in '".$v_index_list[$j]."'");\r
-\r
-        // ----- Extract range\r
-        $v_item_list = explode("-", $v_index_list[$j]);\r
-        $v_size_item_list = sizeof($v_item_list);\r
-        if ($v_size_item_list == 1)\r
-        {\r
-          if ($i==$v_item_list[0])\r
-          {\r
-            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Found as a single index");\r
-            $v_extract = true;\r
-          }\r
-          if ($i>=$v_item_list[0])\r
-          {\r
-            $j_start = $j+1;\r
-          }\r
-        }\r
-        else if ($v_size_item_list == 2)\r
-        {\r
-          if (($i>=$v_item_list[0]) && ($i<=$v_item_list[1]))\r
-          {\r
-            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Found as part of an index range");\r
-            $v_extract = true;\r
-          }\r
-          if ($i>=$v_item_list[1])\r
-          {\r
-            $j_start = $j+1;\r
-          }\r
-        }\r
-        if ($v_item_list[0]>$i)\r
-        {\r
-          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Range is greater than index, stop loop");\r
-          break;\r
-        }\r
+      // ----- Look for no rule, which means extract all the archive\r
+      else {\r
+          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with no rule (extract all)");\r
+          $v_extract = true;\r
       }\r
+      \r
 \r
       // ----- Look for real extraction\r
       if ($v_extract)\r
         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting file '".$v_header['filename']."', index '$i'");\r
 \r
         // ----- Go to the file position\r
-        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position before rewind : ".ftell($this->zip_fd)."'");\r
+        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position before rewind : ".ftell($this->zip_fd)."'");\r
         @rewind($this->zip_fd);\r
-        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position after rewind : ".ftell($this->zip_fd)."'");\r
+        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after rewind : ".ftell($this->zip_fd)."'");\r
         if (@fseek($this->zip_fd, $v_header['offset']))\r
         {\r
           // ----- Close the zip file\r
           //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());\r
           return PclZip::errorCode();\r
         }\r
-        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position after fseek : ".ftell($this->zip_fd)."'");\r
+        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after fseek : ".ftell($this->zip_fd)."'");\r
 \r
         // ----- Look for extraction as string\r
         if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) {\r
             //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);\r
             return $v_result;\r
           }\r
-          \r
+\r
           // ----- Set the file content\r
           $p_file_list[$v_nb_extracted]['content'] = $v_string;\r
-          \r
+\r
           // ----- Next extracted file\r
           $v_nb_extracted++;\r
         }\r
 \r
     // ----- Check the directory availability and create it if necessary\r
     else {\r
-      if (($p_entry['external']==0x41FF0010) || (substr($p_entry['filename'], -1) == '/'))\r
+      if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/'))\r
         $v_dir_to_check = $p_entry['filename'];\r
       else if (!strstr($p_entry['filename'], "/"))\r
         $v_dir_to_check = "";\r
       else\r
         $v_dir_to_check = dirname($p_entry['filename']);\r
 \r
-      if (($v_result = $this->privDirCheck($v_dir_to_check, ($p_entry['external']==0x41FF0010))) != 1) {\r
+      if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) {\r
         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unable to create path for '".$p_entry['filename']."'");\r
 \r
         // ----- Change the file status\r
     if ($p_entry['status'] == 'ok') {\r
 \r
       // ----- Do the extraction (if not a folder)\r
-      if (!($p_entry['external']==0x41FF0010))\r
+      if (!(($p_entry['external']&0x00000010)==0x00000010))\r
       {\r
 \r
         // ----- Look for not compressed file\r
     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting file in string (with path) '".$p_entry['filename']."', size '$v_header[size]'");\r
 \r
     // ----- Do the extraction (if not a folder)\r
-    if (!($p_entry['external']==0x41FF0010))\r
+    if (!(($p_entry['external']&0x00000010)==0x00000010))\r
     {\r
       // ----- Look for not compressed file\r
       if ($p_entry['compressed_size'] == $p_entry['size'])\r
     }\r
 \r
     // ----- Extract the values\r
-    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Header : '".$v_binary_data."'");\r
-    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Header (Hex) : '".bin2hex($v_binary_data)."'");\r
+    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Header : '".$v_binary_data."'");\r
+    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Header (Hex) : '".bin2hex($v_binary_data)."'");\r
     $p_header = unpack('vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $v_binary_data);\r
 \r
     // ----- Get filename\r
-    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "File name length : ".$p_header['filename_len']);\r
+    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "File name length : ".$p_header['filename_len']);\r
     if ($p_header['filename_len'] != 0)\r
       $p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']);\r
     else\r
       $p_header['filename'] = '';\r
-    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Filename : \''.$p_header['filename'].'\'');\r
+    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Filename : \''.$p_header['filename'].'\'');\r
 \r
     // ----- Get extra\r
-    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extra length : ".$p_header['extra_len']);\r
+    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Extra length : ".$p_header['extra_len']);\r
     if ($p_header['extra_len'] != 0)\r
       $p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']);\r
     else\r
       $p_header['extra'] = '';\r
-    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Extra : \''.$p_header['extra'].'\'');\r
+    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Extra : \''.$p_header['extra'].'\'');\r
 \r
     // ----- Get comment\r
-    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Comment length : ".$p_header['comment_len']);\r
+    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Comment length : ".$p_header['comment_len']);\r
     if ($p_header['comment_len'] != 0)\r
       $p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']);\r
     else\r
       $p_header['comment'] = '';\r
-    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Comment : \''.$p_header['comment'].'\'');\r
+    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Comment : \''.$p_header['comment'].'\'');\r
 \r
     // ----- Extract properties\r
-    //$p_header['size'] = $v_data['size'];\r
-    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Size : \''.$p_header['size'].'\'');\r
-    //$p_header['compressed_size'] = $v_data['compressed_size'];\r
-    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Compressed Size : \''.$p_header['compressed_size'].'\'');\r
-    //$p_header['crc'] = $v_data['crc'];\r
-    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'CRC : \''.$p_header['crc'].'\'');\r
-    //$p_header['flag'] = $v_data['flag'];\r
-    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Flag : \''.$p_header['flag'].'\'');\r
-    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Offset : \''.$p_header['offset'].'\'');\r
+    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Version : \''.($p_header['version']/10).'.'.($p_header['version']%10).'\'');\r
+    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Version need to extract : \''.($p_header['version_extracted']/10).'.'.($p_header['version_extracted']%10).'\'');\r
+    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Size : \''.$p_header['size'].'\'');\r
+    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Compressed Size : \''.$p_header['compressed_size'].'\'');\r
+    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'CRC : \''.$p_header['crc'].'\'');\r
+    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Flag : \''.$p_header['flag'].'\'');\r
+    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Offset : \''.$p_header['offset'].'\'');\r
 \r
     // ----- Recuperate date in UNIX format\r
     if ($p_header['mdate'] && $p_header['mtime'])\r
       // ----- Get UNIX date format\r
       $p_header['mtime'] = mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);\r
 \r
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Date : \''.date("d/m/y H:i:s", $p_header['mtime']).'\'');\r
+      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Date : \''.date("d/m/y H:i:s", $p_header['mtime']).'\'');\r
     }\r
     else\r
     {\r
       $p_header['mtime'] = time();\r
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Date is actual : \''.date("d/m/y H:i:s", $p_header['mtime']).'\'');\r
+      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Date is actual : \''.date("d/m/y H:i:s", $p_header['mtime']).'\'');\r
     }\r
 \r
     // ----- Set the stored filename\r
     $p_header['status'] = 'ok';\r
 \r
     // ----- Look if it is a directory\r
-    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "external (Hex) : '".sprintf("Ox%04X", $p_header['external'])."' (".($p_header['external']==0x41FF0010?'is a folder':'is a file').')');\r
+    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Internal (Hex) : '".sprintf("Ox%04X", $p_header['internal'])."'");\r
+    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "External (Hex) : '".sprintf("Ox%04X", $p_header['external'])."' (".(($p_header['external']&0x00000010)==0x00000010?'is a folder':'is a file').')');\r
     if (substr($p_header['filename'], -1) == '/')\r
     {\r
       $p_header['external'] = 0x41FF0010;\r
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Force folder external : \''.$p_header['external'].'\'');\r
+      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Force folder external : \''.$p_header['external'].'\'');\r
     }\r
 \r
-\r
-    // TBC\r
-    //for(reset($p_header); $key = key($p_header); next($p_header)) {\r
-    // //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "header[$key] = ".$p_header[$key]);\r
-    //}\r
+    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Header of filename : \''.$p_header['filename'].'\'');\r
 \r
     // ----- Return\r
     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);\r
   // --------------------------------------------------------------------------------\r
 \r
   // --------------------------------------------------------------------------------\r
-  // Function : privDeleteByIndex()\r
+  // Function : privDeleteByRule()\r
   // Description :\r
   // Parameters :\r
   // Return Values :\r
   // --------------------------------------------------------------------------------\r
-  function privDeleteByIndex($p_index, &$p_result_list)\r
+  function privDeleteByRule(&$p_result_list, &$p_options)\r
   {\r
-    //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privDeleteByIndex", "index='$p_index'");\r
+    //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privDeleteByRule", "");\r
     $v_result=1;\r
     $v_list_detail = array();\r
 \r
     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in file : ".ftell($this->zip_fd)."'");\r
 \r
     // ----- Scan all the files\r
-    // ----- Manipulate the index list\r
-    $p_index = strtr($p_index, ' ', '');\r
-    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Reduced index : '$p_index'");\r
-    $v_index_list = explode(",", $p_index);\r
-    // TBC : Here I should sort the index. However a simple sort is not enought.\r
-    // look for the use of usort()\r
-    //sort($v_index_list);\r
-\r
     // ----- Start at beginning of Central Dir\r
     $v_pos_entry = $v_central_dir['offset'];\r
-    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position before rewind : ".ftell($this->zip_fd)."'");\r
+    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position before rewind : ".ftell($this->zip_fd)."'");\r
     @rewind($this->zip_fd);\r
-    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position after rewind : ".ftell($this->zip_fd)."'");\r
+    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after rewind : ".ftell($this->zip_fd)."'");\r
     if (@fseek($this->zip_fd, $v_pos_entry))\r
     {\r
       // ----- Close the zip file\r
       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());\r
       return PclZip::errorCode();\r
     }\r
-    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position after fseek : ".ftell($this->zip_fd)."'");\r
+    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after fseek : ".ftell($this->zip_fd)."'");\r
 \r
     // ----- Read each entry\r
     $v_header_list = array();\r
-    for ($i=0, $j_start=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)\r
+    $j_start = 0;\r
+    for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)\r
     {\r
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Read next file header entry : $i'");\r
+      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Read next file header entry (index '$i')");\r
 \r
       // ----- Read the file header\r
       $v_header_list[$v_nb_extracted] = array();\r
         return $v_result;\r
       }\r
 \r
+      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename (index '$i') : '".$v_header_list[$v_nb_extracted]['stored_filename']."'");\r
+\r
       // ----- Store the index\r
       $v_header_list[$v_nb_extracted]['index'] = $i;\r
 \r
-      // ----- Look if the index is in the list\r
-      for ($j=$j_start, $v_found = false; ($j<sizeof($v_index_list)) && (!$v_found); $j++)\r
-      {\r
-        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Look if index '$i' is in '".$v_index_list[$j]."'");\r
-\r
-        // ----- Extract range\r
-        $v_item_list = explode("-", $v_index_list[$j]);\r
-        $v_size_item_list = sizeof($v_item_list);\r
-        if ($v_size_item_list == 1)\r
-        {\r
-          if ($i==$v_item_list[0])\r
-          {\r
-            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Found as a single index");\r
-            $v_found = true;\r
+      // ----- Look for the specific extract rules\r
+      $v_found = false;\r
+\r
+      // ----- Look for extract by name rule\r
+      if (   (isset($p_options[PCLZIP_OPT_BY_NAME]))\r
+          && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {\r
+          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByName'");\r
+\r
+          // ----- Look if the filename is in the list\r
+          for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_found); $j++) {\r
+              //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Compare with file '".$p_options[PCLZIP_OPT_BY_NAME][$j]."'");\r
+\r
+              // ----- Look for a directory\r
+              if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {\r
+                  //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The searched item is a directory");\r
+\r
+                  // ----- Look if the directory is in the filename path\r
+                  if (   (strlen($v_header_list[$v_nb_extracted]['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))\r
+                      && (substr($v_header_list[$v_nb_extracted]['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {\r
+                      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The directory is in the file path");\r
+                      $v_found = true;\r
+                  }\r
+                  elseif (   (($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010) /* Indicates a folder */\r
+                          && ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) {\r
+                      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The entry is the searched directory");\r
+                      $v_found = true;\r
+                  }\r
+              }\r
+              // ----- Look for a filename\r
+              elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {\r
+                  //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The file is the right one.");\r
+                  $v_found = true;\r
+              }\r
           }\r
-          if ($i>=$v_item_list[0])\r
-          {\r
-            $j_start = $j+1;\r
+      }\r
+\r
+      // ----- Look for extract by ereg rule\r
+      else if (   (isset($p_options[PCLZIP_OPT_BY_EREG]))\r
+               && ($p_options[PCLZIP_OPT_BY_EREG] != "")) {\r
+          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract by ereg '".$p_options[PCLZIP_OPT_BY_EREG]."'");\r
+\r
+          if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {\r
+              //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename match the regular expression");\r
+              $v_found = true;\r
           }\r
-        }\r
-        else if ($v_size_item_list == 2)\r
-        {\r
-          if (($i>=$v_item_list[0]) && ($i<=$v_item_list[1]))\r
-          {\r
-            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Found as part of an index range");\r
-            $v_found = true;\r
+      }\r
+\r
+      // ----- Look for extract by preg rule\r
+      else if (   (isset($p_options[PCLZIP_OPT_BY_PREG]))\r
+               && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {\r
+          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByEreg'");\r
+\r
+          if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {\r
+              //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename match the regular expression");\r
+              $v_found = true;\r
           }\r
-          if ($i>=$v_item_list[1])\r
-          {\r
-            $j_start = $j+1;\r
+      }\r
+\r
+      // ----- Look for extract by index rule\r
+      else if (   (isset($p_options[PCLZIP_OPT_BY_INDEX]))\r
+               && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {\r
+          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByIndex'");\r
+\r
+          // ----- Look if the index is in the list\r
+          for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_found); $j++) {\r
+              //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Look if index '$i' is in [".$p_options[PCLZIP_OPT_BY_INDEX][$j]['start'].",".$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']."]");\r
+\r
+              if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {\r
+                  //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Found as part of an index range");\r
+                  $v_found = true;\r
+              }\r
+              if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {\r
+                  //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Do not look this index range for next loop");\r
+                  $j_start = $j+1;\r
+              }\r
+\r
+              if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {\r
+                  //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Index range is greater than index, stop loop");\r
+                  break;\r
+              }\r
           }\r
-        }\r
-        if ($v_item_list[0]>$i)\r
-        {\r
-          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Range is greater than index, stop loop");\r
-          break;\r
-        }\r
       }\r
 \r
       // ----- Look for deletion\r
       if ($v_found)\r
       {\r
-        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$v_header['filename']."', index '$i' need to be deleted");\r
+        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$v_header_list[$v_nb_extracted]['stored_filename']."', index '$i' need to be deleted");\r
         unset($v_header_list[$v_nb_extracted]);\r
       }\r
       else\r
       {\r
-        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$v_header['filename']."', index '$i' will not be deleted");\r
+        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$v_header_list[$v_nb_extracted]['stored_filename']."', index '$i' will not be deleted");\r
         $v_nb_extracted++;\r
       }\r
     }\r
 \r
-    // ----- Creates a temporay file\r
-    $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';\r
+    // ----- Look if something need to be deleted\r
+    if ($v_nb_extracted > 0) {\r
 \r
-    // ----- Creates a temporary zip archive\r
-    $v_temp_zip = new PclZip($v_zip_temp_name);\r
+        // ----- Creates a temporay file\r
+        $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';\r
 \r
-    // ----- Open the temporary zip file in write mode\r
-    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary write mode");\r
-    if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1)\r
-    {\r
-      $this->privCloseFd();\r
+        // ----- Creates a temporary zip archive\r
+        $v_temp_zip = new PclZip($v_zip_temp_name);\r
 \r
-      // ----- Return\r
-      //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);\r
-      return $v_result;\r
-    }\r
+        // ----- Open the temporary zip file in write mode\r
+        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary write mode");\r
+        if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1) {\r
+            $this->privCloseFd();\r
 \r
-    // ----- Look which file need to be kept\r
-    for ($i=0; $i<sizeof($v_header_list); $i++)\r
-    {\r
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Keep entry : $i'");\r
+            // ----- Return\r
+            //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);\r
+            return $v_result;\r
+        }\r
 \r
-      // ----- Calculate the position of the header\r
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Offset='". $v_header_list[$i]['offset']."'");\r
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position before rewind : ".ftell($this->zip_fd)."'");\r
-      @rewind($this->zip_fd);\r
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after rewind : ".ftell($this->zip_fd)."'");\r
-      if (@fseek($this->zip_fd,  $v_header_list[$i]['offset']))\r
-      {\r
-        // ----- Close the zip file\r
-        $this->privCloseFd();\r
-        $v_temp_zip->privCloseFd();\r
-        @unlink($v_zip_temp_name);\r
+        // ----- Look which file need to be kept\r
+        for ($i=0; $i<sizeof($v_header_list); $i++) {\r
+            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Keep entry index '$i' : '".$v_header_list[$i]['filename']."'");\r
+\r
+            // ----- Calculate the position of the header\r
+            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Offset='". $v_header_list[$i]['offset']."'");\r
+            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position before rewind : ".ftell($this->zip_fd)."'");\r
+            @rewind($this->zip_fd);\r
+            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after rewind : ".ftell($this->zip_fd)."'");\r
+            if (@fseek($this->zip_fd,  $v_header_list[$i]['offset'])) {\r
+                // ----- Close the zip file\r
+                $this->privCloseFd();\r
+                $v_temp_zip->privCloseFd();\r
+                @unlink($v_zip_temp_name);\r
+\r
+                // ----- Error log\r
+                PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');\r
+\r
+                // ----- Return\r
+                //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());\r
+                return PclZip::errorCode();\r
+            }\r
+            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after fseek : ".ftell($this->zip_fd)."'");\r
+\r
+            // ----- Read the file header\r
+            if (($v_result = $this->privReadFileHeader($v_header_list[$i])) != 1) {\r
+                // ----- Close the zip file\r
+                $this->privCloseFd();\r
+                $v_temp_zip->privCloseFd();\r
+                @unlink($v_zip_temp_name);\r
+\r
+                // ----- Return\r
+                //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);\r
+                return $v_result;\r
+            }\r
 \r
-        // ----- Error log\r
-        PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');\r
+            // ----- Write the file header\r
+            if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1) {\r
+                // ----- Close the zip file\r
+                $this->privCloseFd();\r
+                $v_temp_zip->privCloseFd();\r
+                @unlink($v_zip_temp_name);\r
 \r
-        // ----- Return\r
-        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());\r
-        return PclZip::errorCode();\r
-      }\r
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after fseek : ".ftell($this->zip_fd)."'");\r
+                // ----- Return\r
+                //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);\r
+                return $v_result;\r
+            }\r
+            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Offset for this file is '".$v_header_list[$i]['offset']."'");\r
+\r
+            // ----- Read/write the data block\r
+            if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1) {\r
+                // ----- Close the zip file\r
+                $this->privCloseFd();\r
+                $v_temp_zip->privCloseFd();\r
+                @unlink($v_zip_temp_name);\r
+\r
+                // ----- Return\r
+                //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);\r
+                return $v_result;\r
+            }\r
+        }\r
 \r
-      // ----- Read the file header\r
-      if (($v_result = $this->privReadFileHeader($v_header_list[$i])) != 1)\r
-      {\r
-        // ----- Close the zip file\r
-        $this->privCloseFd();\r
-        $v_temp_zip->privCloseFd();\r
-        @unlink($v_zip_temp_name);\r
+        // ----- Store the offset of the central dir\r
+        $v_offset = @ftell($v_temp_zip->zip_fd);\r
+        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "New offset of central dir : $v_offset");\r
+\r
+        // ----- Re-Create the Central Dir files header\r
+        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Creates the new central directory");\r
+        for ($i=0; $i<sizeof($v_header_list); $i++) {\r
+            // ----- Create the file header\r
+            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Offset of file : ".$v_header_list[$i]['offset']);\r
+            if (($v_result = $v_temp_zip->privWriteCentralFileHeader($v_header_list[$i])) != 1) {\r
+                $v_temp_zip->privCloseFd();\r
+                $this->privCloseFd();\r
+                @unlink($v_zip_temp_name);\r
+\r
+                // ----- Return\r
+                //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);\r
+                return $v_result;\r
+            }\r
 \r
-        // ----- Return\r
-        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);\r
-        return $v_result;\r
-      }\r
+            // ----- Transform the header to a 'usable' info\r
+            $v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);\r
+        }\r
 \r
-      // ----- Write the file header\r
-      if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1)\r
-      {\r
-        // ----- Close the zip file\r
-        $this->privCloseFd();\r
-        $v_temp_zip->privCloseFd();\r
-        @unlink($v_zip_temp_name);\r
+        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Creates the central directory footer");\r
 \r
-        // ----- Return\r
-        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);\r
-        return $v_result;\r
-      }\r
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Offset for this file is '".$v_header_list[$i]['offset']."'");\r
+        // ----- Zip file comment\r
+        $v_comment = '';\r
 \r
-      // ----- Read/write the data block\r
-      if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1)\r
-      {\r
-        // ----- Close the zip file\r
-        $this->privCloseFd();\r
-        $v_temp_zip->privCloseFd();\r
-        @unlink($v_zip_temp_name);\r
+        // ----- Calculate the size of the central header\r
+        $v_size = @ftell($v_temp_zip->zip_fd)-$v_offset;\r
 \r
-        // ----- Return\r
-        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);\r
-        return $v_result;\r
-      }\r
-    }\r
+        // ----- Create the central dir footer\r
+        if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1) {\r
+            // ----- Reset the file list\r
+            unset($v_header_list);\r
+            $v_temp_zip->privCloseFd();\r
+            $this->privCloseFd();\r
+            @unlink($v_zip_temp_name);\r
 \r
-    // ----- Store the offset of the central dir\r
-    $v_offset = @ftell($v_temp_zip->zip_fd);\r
-    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "New offset of central dir : $v_offset");\r
+            // ----- Return\r
+            //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);\r
+            return $v_result;\r
+        }\r
 \r
-    // ----- Re-Create the Central Dir files header\r
-    for ($i=0; $i<sizeof($v_header_list); $i++)\r
-    {\r
-      // ----- Create the file header\r
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Offset of file : ".$v_header_list[$i]['offset']);\r
-      if (($v_result = $v_temp_zip->privWriteCentralFileHeader($v_header_list[$i])) != 1)\r
-      {\r
+        // ----- Close\r
         $v_temp_zip->privCloseFd();\r
         $this->privCloseFd();\r
-        @unlink($v_zip_temp_name);\r
 \r
-        // ----- Return\r
-        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);\r
-        return $v_result;\r
-      }\r
+        // ----- Delete the zip file\r
+        // TBC : I should test the result ...\r
+        @unlink($this->zipname);\r
 \r
-      // ----- Transform the header to a 'usable' info\r
-      $v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);\r
-    }\r
-\r
-    // ----- Zip file comment\r
-    $v_comment = '';\r
-\r
-    // ----- Calculate the size of the central header\r
-    $v_size = @ftell($v_temp_zip->zip_fd)-$v_offset;\r
-\r
-    // ----- Create the central dir footer\r
-    if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1)\r
-    {\r
-      // ----- Reset the file list\r
-      unset($v_header_list);\r
-      $v_temp_zip->privCloseFd();\r
-      $this->privCloseFd();\r
-      @unlink($v_zip_temp_name);\r
-\r
-      // ----- Return\r
-      //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);\r
-      return $v_result;\r
+        // ----- Rename the temporary file\r
+        // TBC : I should test the result ...\r
+        //@rename($v_zip_temp_name, $this->zipname);\r
+        PclZipUtilRename($v_zip_temp_name, $this->zipname);\r
+    \r
+        // ----- Destroy the temporary archive\r
+        unset($v_temp_zip);\r
     }\r
 \r
-    // ----- Close\r
-    $v_temp_zip->privCloseFd();\r
-    $this->privCloseFd();\r
-\r
-    // ----- Delete the zip file\r
-    // TBC : I should test the result ...\r
-    @unlink($this->zipname);\r
-\r
-    // ----- Rename the temporary file\r
-    // TBC : I should test the result ...\r
-    //@rename($v_zip_temp_name, $this->zipname);\r
-    PclZipUtilRename($v_zip_temp_name, $this->zipname);\r
-\r
     // ----- Return\r
     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);\r
     return $v_result;\r
   }\r
   // --------------------------------------------------------------------------------\r
 \r
-\r
   // --------------------------------------------------------------------------------\r
   // Function : privDirCheck()\r
   // Description :\r
     if ($v_result) {\r
       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Look for tie break");\r
       // ----- Skip all the empty items\r
-      while (($v_list_path[$j] == '') && ($j < $v_list_path_size)) $j++;\r
-      while (($v_list_dir[$i] == '') && ($i < $v_list_dir_size)) $i++;\r
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Looking on dir($i)='".$v_list_dir[$i]."' and path($j)='".$v_list_path[$j]."'");\r
+      while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++;\r
+      while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++;\r
+      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Looking on dir($i)='".($i < $v_list_dir_size?$v_list_dir[$i]:'')."' and path($j)='".($j < $v_list_path_size?$v_list_path[$j]:'')."'");\r
 \r
       if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) {\r
         // ----- There are exactly the same\r
       case PCLZIP_OPT_SET_CHMOD :\r
         $v_result = 'PCLZIP_OPT_SET_CHMOD';\r
       break;\r
+      case PCLZIP_OPT_BY_NAME :\r
+        $v_result = 'PCLZIP_OPT_BY_NAME';\r
+      break;\r
+      case PCLZIP_OPT_BY_INDEX :\r
+        $v_result = 'PCLZIP_OPT_BY_INDEX';\r
+      break;\r
+      case PCLZIP_OPT_BY_EREG :\r
+        $v_result = 'PCLZIP_OPT_BY_EREG';\r
+      break;\r
+      case PCLZIP_OPT_BY_PREG :\r
+        $v_result = 'PCLZIP_OPT_BY_PREG';\r
+      break;\r
 \r
 \r
       case PCLZIP_CB_PRE_EXTRACT :\r
   // --------------------------------------------------------------------------------\r
   function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter=true)\r
   {\r
-    if (OS_WINDOWS) {\r
+    if (stristr(php_uname(), 'windows')) {\r
       // ----- Look for potential disk letter\r
       if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false)) {\r
           $p_path = substr($p_path, $v_position+1);\r
index e53dfaf7bd85c7a5ef0e4c78680b8d4f62917a8a..4574840d87f6ac5919a6a10b75fab1a52efcbfc0 100644 (file)
@@ -1,5 +1,5 @@
 // --------------------------------------------------------------------------------\r
-// PclZip 2.0-rc1 - readme.txt\r
+// PclZip 2.0-rc2 - readme.txt\r
 // --------------------------------------------------------------------------------\r
 // License GNU/GPL - january 2003\r
 // Vincent Blavet - vincent@phpconcept.net\r
 2 - What's new\r
 ==============\r
 \r
-  Version 2.0-rc1 :\r
+  Version 2.0-rc2 :\r
     ***** Warning : Some new features may break the backward compatibility for your scripts.\r
                     Please carefully read the readme file.\r
+    - Add the ability to delete by Index, name and regular expression. This feature is \r
+      performed by the method delete(), which uses the optional parameters\r
+      PCLZIP_OPT_BY_INDEX, PCLZIP_OPT_BY_NAME, PCLZIP_OPT_BY_EREG or PCLZIP_OPT_BY_PREG.\r
+    - Add the ability to extract by regular expression. To extract by regexp you must use the method\r
+      extract(), with the option PCLZIP_OPT_BY_EREG or PCLZIP_OPT_BY_PREG \r
+      (depending if you want to use ereg() or preg_match() syntax) followed by the \r
+      regular expression pattern.\r
+    - Add the ability to extract by index, directly with the extract() method. This is a\r
+      code improvment of the extractByIndex() method.\r
+    - Add the ability to extract by name. To extract by name you must use the method\r
+      extract(), with the option PCLZIP_OPT_BY_NAME followed by the filename to\r
+      extract or an array of filenames to extract. To extract all a folder, use the folder\r
+      name rather than the filename with a '/' at the end.\r
     - Add the ability to add files without compression. This is done with a new attribute\r
       which is PCLZIP_OPT_NO_COMPRESSION.\r
     - Add the attribute PCLZIP_OPT_EXTRACT_AS_STRING, which allow to extract a file directly\r
       path is the same\r
       as a zipped dir. The dir is not zipped (['status'] = filtered), only its content.\r
     - Add better support for windows paths (thanks for help from manus@manusfreedom.com).\r
+    - Corrected bug : When the archive file already exists with size=0, the add() method\r
+      fails. Corrected in 2.0.\r
+    - Remove the use of OS_WINDOWS constant. Use php_uname() function rather.\r
+    - Control the order of index ranges in extract by index feature.\r
+    - Change the internal management of folders (better handling of internal flag).\r
 \r
 \r
   Version 1.3 :\r