diff --git a/src/sysfiles.c b/src/sysfiles.c index 46427639d0..804fb746ae 100644 --- a/src/sysfiles.c +++ b/src/sysfiles.c @@ -616,6 +616,9 @@ Int SyFopen ( Char namegz [1024]; int flags = 0; + Char* terminator = strrchr(name, '.'); + Int endsgz = terminator && (strcmp(terminator, ".gz") == 0); + /* handle standard files */ if ( strcmp( name, "*stdin*" ) == 0 ) { if ( strcmp( mode, "r" ) != 0 ) @@ -677,8 +680,13 @@ Int SyFopen ( #endif /* try to open the file */ - syBuf[fid].fp = open(name,flags, 0644); - if ( 0 <= syBuf[fid].fp ) { + + + if(endsgz && (syBuf[fid].gzfp = gzopen(name, mode))) { + syBuf[fid].type = gzip_socket; + syBuf[fid].fp = -1; + syBuf[fid].bufno = -1; + } else if ( 0 <= ( syBuf[fid].fp = open(name,flags, 0644))) { syBuf[fid].type = raw_socket; syBuf[fid].echo = syBuf[fid].fp; syBuf[fid].bufno = -1; diff --git a/tst/example-dir/compress/not-compressed.txt.gz b/tst/example-dir/compress/not-compressed.txt.gz new file mode 100644 index 0000000000..18ec507112 --- /dev/null +++ b/tst/example-dir/compress/not-compressed.txt.gz @@ -0,0 +1 @@ +not compressed diff --git a/tst/example-dir/readme.txt b/tst/example-dir/readme.txt index 8b142980eb..0de024d7f4 100644 --- a/tst/example-dir/readme.txt +++ b/tst/example-dir/readme.txt @@ -7,3 +7,5 @@ Explanation dir-test : A directory containing some example files and sub-directories for testing directory enumeration. + +compress : not-compressed.txt - A text file which is not compressed but ends in gz \ No newline at end of file diff --git a/tst/testinstall/compressed.tst b/tst/testinstall/compressed.tst new file mode 100644 index 0000000000..eaf61cc3a6 --- /dev/null +++ b/tst/testinstall/compressed.tst @@ -0,0 +1,169 @@ +#@local dir,fname,isGzippedFile,stream,str +gap> START_TEST("compressed.tst"); +gap> dir := DirectoryTemporary();; +gap> fname := Filename(dir, "test.g.gz");; + +# Let us check when we have written a compressed file by checking the gzip header +gap> isGzippedFile := function(dir, name) +> local out, str,prog; +> str := ""; +> out := OutputTextString(str, true); +> Process(dir, Filename(DirectoriesSystemPrograms(),"cat"), InputTextNone(), out, [name]); +> return str{[1..2]} = "\037\213"; +> end;; +gap> str := "hello\ngoodbye\n";; + +# Write a compressed file +gap> FileString( Filename(dir, "test.g.gz"), str ) = Length(str); +true + +# Check file really is compressed +gap> isGzippedFile(dir, "test.g.gz"); +true + +# Check reading compressed file +gap> StringFile( Filename(dir, "test.g.gz") ) = str; +true + +# Check gz is added transparently +gap> StringFile( Filename(dir, "test.g") ) = str; +true + +# Test reading/seeking +gap> stream := InputTextFile(fname);; +gap> ReadLine(stream); +"hello\n" +gap> ReadLine(stream); +"goodbye\n" +gap> ReadLine(stream); +fail +gap> SeekPositionStream(stream, -1); +fail +gap> SeekPositionStream(stream, 0); +true +gap> ReadLine(stream); +"hello\n" +gap> ReadLine(stream); +"goodbye\n" +gap> ReadLine(stream); +fail +gap> SeekPositionStream(stream, 2); +true +gap> PositionStream(stream); +2 +gap> ReadLine(stream); +"llo\n" +gap> ReadLine(stream); +"goodbye\n" +gap> SeekPositionStream(stream, 0); +true +gap> ReadAll(stream) = str; +true +gap> SeekPositionStream(stream, 0); +true +gap> PositionStream(stream); +0 +gap> ReadAll(stream) = str; +true +gap> CloseStream(stream); + +# Test multiple writes +gap> stream := OutputTextFile( fname, false );; +gap> PrintTo( stream, "1"); +gap> AppendTo( stream, "2"); +gap> PrintTo( stream, "3"); +gap> CloseStream(stream); +gap> stream; +closed-stream +gap> isGzippedFile(dir, "test.g.gz"); +true + +# verify it +gap> stream := InputTextFile( fname );; +gap> ReadAll(stream); +"123" +gap> CloseStream(stream); +gap> stream; +closed-stream + +# partial reads +gap> stream := InputTextFile( fname );; +gap> ReadAll(stream, 2); +"12" +gap> CloseStream(stream); +gap> stream; +closed-stream + +# too long partial read +gap> stream := InputTextFile( fname );; +gap> ReadAll(stream, 5); +"123" +gap> CloseStream(stream); +gap> stream; +closed-stream + +# error partial read +gap> stream := InputTextFile( fname );; +gap> ReadAll(stream, -1); +Error, ReadAll: negative limit is not allowed +gap> CloseStream(stream); +gap> stream; +closed-stream + +# append to initial data +gap> stream := OutputTextFile( fname, true );; +gap> PrintTo( stream, "4"); +gap> CloseStream(stream); + +# verify it +gap> stream := InputTextFile( fname );; +gap> ReadAll(stream); +"1234" +gap> CloseStream(stream); +gap> stream; +closed-stream + +# overwrite initial data +gap> stream := OutputTextFile( fname, false );; +gap> PrintTo( stream, "new content"); +gap> CloseStream(stream); + +# verify it +gap> stream := InputTextFile( fname );; +gap> ReadAll(stream); +"new content" +gap> CloseStream(stream); +gap> stream; +closed-stream + +# ReadAll with length limit +gap> stream := InputTextFile( fname );; +gap> ReadAll(stream, 3); +"new" +gap> CloseStream(stream); + +# test PrintFormattingStatus +gap> stream := OutputTextFile( fname, false );; +gap> PrintFormattingStatus(stream); +true +gap> PrintTo( stream, "a very long line that GAP is going to wrap at 80 chars by default if we don't do anything about it\n"); +gap> CloseStream(stream); +gap> StringFile(fname); +"a very long line that GAP is going to wrap at 80 chars by default if we don't\ + \\\ndo anything about it\n" +gap> stream := OutputTextFile( fname, false );; +gap> SetPrintFormattingStatus(stream, false); +gap> PrintFormattingStatus(stream); +false +gap> PrintTo( stream, "a very long line that GAP is going to wrap at 80 chars by default if we don't do anything about it\n"); +gap> CloseStream(stream); +gap> StringFile(fname); +"a very long line that GAP is going to wrap at 80 chars by default if we don't\ + do anything about it\n" + +# Test even if a file ends in .gz, if it is not compressed it can still be read +gap> stream := InputTextFile(Filename(DirectoriesLibrary("tst"), "example-dir/compress/not-compressed.txt.gz"));; +gap> ReadAll(stream) = "not compressed\n"; +true +gap> CloseStream(stream); +gap> STOP_TEST("compressed.tst"); diff --git a/tst/testinstall/read.tst b/tst/testinstall/read.tst index a9869942cf..2d40c32c9d 100644 --- a/tst/testinstall/read.tst +++ b/tst/testinstall/read.tst @@ -75,10 +75,6 @@ gap> StringFile( Filename(dir, "tmp2")); fail gap> StringFile( Filename(dir, "tmp1")); "Hello, world!" -gap> FileString( Filename(dir, "test.g.gz"), "\037\213\b\b0,\362W\000\ctest.g\0003\3246\264\346\<\000\225\307\236\324\005\000\000\000" ); -32 -gap> StringFile( Filename(dir, "test.g") ) = "1+1;\n" or ARCH_IS_WINDOWS(); # works only when Cygwin installed with gzip -true gap> StringFile( "/" ); Error, in StringFile: Is a directory (21)