From: Grazvydas Ignotas Date: Fri, 20 Nov 2015 21:47:01 +0000 (+0200) Subject: big file support X-Git-Tag: sz_173~3 X-Git-Url: http://git.openpandora.org/cgi-bin/gitweb.cgi?p=pandora-libraries.git;a=commitdiff_plain;h=0b8d2ba30c7c7371fd410931f4310cfd19bd04c2 big file support Needed for > 2GB PND files. Tested to work with > 4GB file. --- diff --git a/Makefile b/Makefile index 39630ba..d080a1f 100644 --- 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 +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} diff --git a/include/pnd_discovery.h b/include/pnd_discovery.h index 2901010..372fadd 100644 --- a/include/pnd_discovery.h +++ b/include/pnd_discovery.h @@ -95,6 +95,8 @@ typedef struct { 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 diff --git a/lib/pnd_desktop.c b/lib/pnd_desktop.c index 4bb8130..5420116 100644 --- a/lib/pnd_desktop.c +++ b/lib/pnd_desktop.c @@ -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 ) && - ( ! p -> pnd_icon_pos ) ) + ( ! p -> pnd_icon_pos64 ) ) { 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 ); } - unsigned int len; + off_t len; target = fopen ( buffer, "wb" ); @@ -447,15 +447,19 @@ unsigned char pnd_emit_icon ( char *targetpath, pnd_disco_t *p ) { 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 ) { @@ -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 ) && - ( ! p -> pnd_icon_pos ) ) + ( ! p -> pnd_icon_pos64 ) ) { 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 - 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 ); @@ -1010,7 +1018,7 @@ pnd_disco_t *pnd_parse_dotdesktop ( char *ddpath, unsigned int flags ) { 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 ); } } diff --git a/lib/pnd_discovery.c b/lib/pnd_discovery.c index 76f2868..1e465ff 100644 --- a/lib/pnd_discovery.c +++ b/lib/pnd_discovery.c @@ -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; - unsigned int pxml_close_pos = 0; + off_t pxml_close_pos = 0; 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; - 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 ); @@ -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 ) { - 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) @@ -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 - fseek ( f, padstart, SEEK_SET ); + fseeko ( f, padstart, SEEK_SET ); } } // 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 -> pnd_icon_pos64 = 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; diff --git a/lib/pnd_pndfiles.c b/lib/pnd_pndfiles.c index 3200442..bdef6a6 100644 --- a/lib/pnd_pndfiles.c +++ b/lib/pnd_pndfiles.c @@ -17,8 +17,8 @@ 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 ); @@ -30,9 +30,9 @@ unsigned char pnd_pnd_seek_pxml ( FILE *f ) { 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 */ @@ -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 - fseek ( f, pos, SEEK_SET ); + fseeko ( f, pos, SEEK_SET ); // 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 ) ) ) { - 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 );