big file support
authorGrazvydas Ignotas <notasas@gmail.com>
Fri, 20 Nov 2015 21:47:01 +0000 (23:47 +0200)
committerGrazvydas Ignotas <notasas@gmail.com>
Fri, 20 Nov 2015 21:47:01 +0000 (23:47 +0200)
Needed for > 2GB PND files.
Tested to work with > 4GB file.

Makefile
include/pnd_discovery.h
lib/pnd_desktop.c
lib/pnd_discovery.c
lib/pnd_pndfiles.c

index 39630ba..d080a1f 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -13,6 +13,7 @@ RM = rm
 # environment
 VPATH = lib test apps minimenu
 CFLAG_SO = -fPIC #-fPIC not always needed, but good to have
 # environment
 VPATH = lib test apps minimenu
 CFLAG_SO = -fPIC #-fPIC not always needed, but good to have
+CFLAG_SO += -D_FILE_OFFSET_BITS=64
 CFLAGS = -Wall -I./include -g ${CFLAG_SO} -I${PNDSTUFF}/usr/include/SDL
 CXXFLAGS = -Wall -I./include -g ${CFLAG_SO}
 
 CFLAGS = -Wall -I./include -g ${CFLAG_SO} -I${PNDSTUFF}/usr/include/SDL
 CXXFLAGS = -Wall -I./include -g ${CFLAG_SO}
 
index 2901010..372fadd 100644 (file)
@@ -95,6 +95,8 @@ typedef struct {
   char *associationitem1_filetype;
   char *exec_dashdash_args;
 
   char *associationitem1_filetype;
   char *exec_dashdash_args;
 
+  unsigned long long pnd_icon_pos64;
+
 } pnd_disco_t;
 
 void pnd_disco_destroy ( pnd_disco_t *p ); // a function name that simply could not be avoided
 } pnd_disco_t;
 
 void pnd_disco_destroy ( pnd_disco_t *p ); // a function name that simply could not be avoided
index 4bb8130..5420116 100644 (file)
@@ -413,7 +413,7 @@ unsigned char pnd_emit_icon ( char *targetpath, pnd_disco_t *p ) {
 
   // prelim .. if a pnd file, and no offset found, discovery code didn't locate icon.. so bail.
   if ( ( p -> object_type == pnd_object_type_pnd ) &&
 
   // prelim .. if a pnd file, and no offset found, discovery code didn't locate icon.. so bail.
   if ( ( p -> object_type == pnd_object_type_pnd ) &&
-       ( ! p -> pnd_icon_pos ) )
+       ( ! p -> pnd_icon_pos64 ) )
   {
     return ( 0 ); // discover code didn't find it, so FAIL
   }
   {
     return ( 0 ); // discover code didn't find it, so FAIL
   }
@@ -437,7 +437,7 @@ unsigned char pnd_emit_icon ( char *targetpath, pnd_disco_t *p ) {
     return ( 0 );
   }
 
     return ( 0 );
   }
 
-  unsigned int len;
+  off_t len;
 
   target = fopen ( buffer, "wb" );
 
 
   target = fopen ( buffer, "wb" );
 
@@ -447,15 +447,19 @@ unsigned char pnd_emit_icon ( char *targetpath, pnd_disco_t *p ) {
     return ( 0 );
   }
 
     return ( 0 );
   }
 
-  fseek ( pnd, 0, SEEK_END );
-  len = ftell ( pnd );
-  //fseek ( pnd, 0, SEEK_SET );
+  fseeko ( pnd, 0, SEEK_END );
+  len = ftello ( pnd );
 
 
-  fseek ( pnd, p -> pnd_icon_pos, SEEK_SET );
+  fseeko ( pnd, p -> pnd_icon_pos64, SEEK_SET );
 
 
-  len -= p -> pnd_icon_pos;
+  len -= p -> pnd_icon_pos64;
 
 
-  pnd_log ( PND_LOG_DEFAULT, "    Emit icon, length: %u\n", len );
+  if ( len <= 0 ) {
+    fclose ( pnd );
+    return ( 0 );
+  }
+
+  pnd_log ( PND_LOG_DEFAULT, "    Emit icon, length: %u\n", (int)len );
 
   while ( len ) {
 
 
   while ( len ) {
 
@@ -718,7 +722,7 @@ unsigned char *pnd_emit_icon_to_buffer ( pnd_disco_t *p, unsigned int *r_buflen
 
   // prelim .. if a pnd file, and no offset found, discovery code didn't locate icon.. so bail.
   if ( ( p -> object_type == pnd_object_type_pnd ) &&
 
   // prelim .. if a pnd file, and no offset found, discovery code didn't locate icon.. so bail.
   if ( ( p -> object_type == pnd_object_type_pnd ) &&
-       ( ! p -> pnd_icon_pos ) )
+       ( ! p -> pnd_icon_pos64 ) )
   {
     return ( NULL ); // discover code didn't find it, so FAIL
   }
   {
     return ( NULL ); // discover code didn't find it, so FAIL
   }
@@ -739,15 +743,19 @@ unsigned char *pnd_emit_icon_to_buffer ( pnd_disco_t *p, unsigned int *r_buflen
   }
 
   // determine length of file, then adjust by icon position to find begin of icon
   }
 
   // determine length of file, then adjust by icon position to find begin of icon
-  unsigned int len;
+  off_t len;
 
 
-  fseek ( pnd, 0, SEEK_END );
-  len = ftell ( pnd );
-  //fseek ( pnd, 0, SEEK_SET );
+  fseeko ( pnd, 0, SEEK_END );
+  len = ftello ( pnd );
 
 
-  fseek ( pnd, p -> pnd_icon_pos, SEEK_SET );
+  fseeko ( pnd, p -> pnd_icon_pos64, SEEK_SET );
 
 
-  len -= p -> pnd_icon_pos;
+  len -= p -> pnd_icon_pos64;
+
+  if ( len <= 0 ) {
+    fclose ( pnd );
+    return ( NULL );
+  }
 
   // create target buffer
   target = malloc ( len );
 
   // create target buffer
   target = malloc ( len );
@@ -1010,7 +1018,7 @@ pnd_disco_t *pnd_parse_dotdesktop ( char *ddpath, unsigned int flags ) {
       return ( NULL );
     } else {
       char hack [ 100 ];
       return ( NULL );
     } else {
       char hack [ 100 ];
-      snprintf ( hack, 100, "inode-%lu", statbuf.st_ino );
+      snprintf ( hack, 100, "inode-%lu", (long)statbuf.st_ino );
       p -> unique_id = strdup ( hack );
     }
   }
       p -> unique_id = strdup ( hack );
     }
   }
index 76f2868..1e465ff 100644 (file)
@@ -75,7 +75,7 @@ static int pnd_disco_callback ( const char *fpath, const struct stat *sb,
   pnd_pxml_handle pxmlh = 0;
   pnd_pxml_handle *pxmlapps = NULL;
   pnd_pxml_handle *pxmlappiter;
   pnd_pxml_handle pxmlh = 0;
   pnd_pxml_handle *pxmlapps = NULL;
   pnd_pxml_handle *pxmlappiter;
-  unsigned int pxml_close_pos = 0;
+  off_t pxml_close_pos = 0;
   unsigned char logit = pnd_log_do_buried_logging();
 
   if ( logit ) {
   unsigned char logit = pnd_log_do_buried_logging();
 
   if ( logit ) {
@@ -154,7 +154,7 @@ static int pnd_disco_callback ( const char *fpath, const struct stat *sb,
       pngbuffer [ 4 ] = 13;       pngbuffer [ 5 ] = 10;       pngbuffer [ 6 ] = 26;      pngbuffer [ 7 ] = 10;
 
       unsigned char padtests = 20;
       pngbuffer [ 4 ] = 13;       pngbuffer [ 5 ] = 10;       pngbuffer [ 6 ] = 26;      pngbuffer [ 7 ] = 10;
 
       unsigned char padtests = 20;
-      unsigned int padstart = ftell ( f );
+      off_t padstart = ftello ( f );
 
       // seek back 10 (should be back into the /PXML> part) to catch any appending-icon-no-line-endings funny business
       fseek ( f, -10, SEEK_CUR );
 
       // seek back 10 (should be back into the /PXML> part) to catch any appending-icon-no-line-endings funny business
       fseek ( f, -10, SEEK_CUR );
@@ -163,7 +163,7 @@ static int pnd_disco_callback ( const char *fpath, const struct stat *sb,
 
        if ( fread ( pngbuffer + 8, 8, 1, f ) == 1 ) {
          if ( memcmp ( pngbuffer, pngbuffer + 8, 8 ) == 0 ) {
 
        if ( fread ( pngbuffer + 8, 8, 1, f ) == 1 ) {
          if ( memcmp ( pngbuffer, pngbuffer + 8, 8 ) == 0 ) {
-           pxml_close_pos = ftell ( f ) - 8;
+           pxml_close_pos = ftello ( f ) - 8;
            break;
          } // if
          fseek ( f, -7, SEEK_CUR ); // seek back 7 (so we're 1 further than we started, since PNG header is 8b)
            break;
          } // if
          fseek ( f, -7, SEEK_CUR ); // seek back 7 (so we're 1 further than we started, since PNG header is 8b)
@@ -174,7 +174,7 @@ static int pnd_disco_callback ( const char *fpath, const struct stat *sb,
 
       if ( ! padtests ) {
        // no icon found, so back to where we started looking
 
       if ( ! padtests ) {
        // no icon found, so back to where we started looking
-       fseek ( f, padstart, SEEK_SET );
+       fseeko ( f, padstart, SEEK_SET );
       }
 
     } // icon
       }
 
     } // icon
@@ -234,7 +234,12 @@ static int pnd_disco_callback ( const char *fpath, const struct stat *sb,
       p -> subapp_number = ((pnd_pxml_t*) pxmlh) -> subapp_number;
 
       // png icon path
       p -> subapp_number = ((pnd_pxml_t*) pxmlh) -> subapp_number;
 
       // png icon path
+      p -> pnd_icon_pos64 = pxml_close_pos;
       p -> pnd_icon_pos = pxml_close_pos;
       p -> pnd_icon_pos = pxml_close_pos;
+      if ( (off_t) p -> pnd_icon_pos != pxml_close_pos ) {
+        // pnd_icon_pos is an int and the offset doesn't fit, bad luck...
+        p -> pnd_icon_pos = 0;
+      }
 
       // type
       p -> object_type = valid;
 
       // type
       p -> object_type = valid;
index 3200442..bdef6a6 100644 (file)
@@ -17,8 +17,8 @@
 unsigned char pnd_pnd_seek_pxml ( FILE *f ) {
   char *b;                // buffer
   char *match;            // match within buffer
 unsigned char pnd_pnd_seek_pxml ( FILE *f ) {
   char *b;                // buffer
   char *match;            // match within buffer
-  unsigned int len;       // length of file (not suporting 'big files' 2GB..)
-  unsigned int pos;       // current tape head
+  off_t len;              // length of file (supporting 'big files' 2GB+)
+  off_t pos;              // current tape head
   unsigned int readable;  // amount to read (for small files/chunks)
 
   b = malloc ( PND_PXML_WINDOW_SIZE + 1 );
   unsigned int readable;  // amount to read (for small files/chunks)
 
   b = malloc ( PND_PXML_WINDOW_SIZE + 1 );
@@ -30,9 +30,9 @@ unsigned char pnd_pnd_seek_pxml ( FILE *f ) {
   memset ( b, '\0', PND_PXML_WINDOW_SIZE + 1 );
 
   // determine length of file
   memset ( b, '\0', PND_PXML_WINDOW_SIZE + 1 );
 
   // determine length of file
-  fseek ( f, 0, SEEK_END );
-  len = ftell ( f );
-  fseek ( f, 0, SEEK_SET );
+  fseeko ( f, 0, SEEK_END );
+  len = ftello ( f );
+  fseeko ( f, 0, SEEK_SET );
 
   /* ready to scan through the file, backwards
    */
 
   /* ready to scan through the file, backwards
    */
@@ -51,7 +51,7 @@ unsigned char pnd_pnd_seek_pxml ( FILE *f ) {
     //printf ( "find pxml; pos %u readable %u\n", pos, readable );
 
     // seek into this blocks position
     //printf ( "find pxml; pos %u readable %u\n", pos, readable );
 
     // seek into this blocks position
-    fseek ( f, pos, SEEK_SET );
+    fseeko ( f, pos, SEEK_SET );
 
     // read
     fread ( b, 1, readable, f );
 
     // read
     fread ( b, 1, readable, f );
@@ -60,7 +60,7 @@ unsigned char pnd_pnd_seek_pxml ( FILE *f ) {
     // strings within an arbitrary buffer. Thats needs to be done. This is the worst
     // performing brute force strategy here.
     if ( ( match = pnd_match_binbuf ( b, readable, PXML_TAGHEAD ) ) ) {
     // strings within an arbitrary buffer. Thats needs to be done. This is the worst
     // performing brute force strategy here.
     if ( ( match = pnd_match_binbuf ( b, readable, PXML_TAGHEAD ) ) ) {
-      fseek ( f, pos + ( match - b ), SEEK_SET );
+      fseeko ( f, pos + ( match - b ), SEEK_SET );
       //printf ( "  match found at %u\n", pos + ( match - b ) );
       free ( b );
       return ( 1 );
       //printf ( "  match found at %u\n", pos + ( match - b ) );
       free ( b );
       return ( 1 );