Skip to content

Commit

Permalink
Fix bug in PositionStream, add tests for reading files
Browse files Browse the repository at this point in the history
  • Loading branch information
ChrisJefferson authored and fingolfin committed Apr 25, 2018
1 parent 78fda19 commit 31aa775
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 5 deletions.
21 changes: 16 additions & 5 deletions src/streams.c
Original file line number Diff line number Diff line change
Expand Up @@ -1581,18 +1581,29 @@ Obj FuncPOSITION_FILE (
Obj self,
Obj fid )
{
Int ret;

/* check the argument */
while ( ! IS_INTOBJ(fid) ) {
fid = ErrorReturnObj(
"<fid> must be an integer (not a %s)",
(Int)TNAM_OBJ(fid), 0L,
"you can replace <fid> via 'return <fid>;'" );
}

ret = SyFtell( INT_INTOBJ(fid) );
return ret == -1 ? Fail : INTOBJ_INT(ret);

Int ifid = INT_INTOBJ(fid);
Int ret = SyFtell(ifid);

// Return if failed
if (ret == -1) {
return Fail;
}

// Need to account for characters in buffer
if (syBuf[ifid].bufno >= 0) {
UInt bufno = syBuf[ifid].bufno;
ret -= syBuffers[bufno].buflen - syBuffers[bufno].bufstart;
}

return INTOBJ_INT(ret);
}


Expand Down
Empty file.
3 changes: 3 additions & 0 deletions tst/teststandard/files/example.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
here is line 1

here is line 2
Binary file added tst/teststandard/files/examplegz.txt.gz
Binary file not shown.
111 changes: 111 additions & 0 deletions tst/teststandard/files/files.tst
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
gap> START_TEST("files.tst");

# Perform some general tests for reading from streams
# testName : A nice name to print out on failure
# openFunc : A zero-argument function which returns an InputStream
# lines : A list of the lines which should be in the file
# supportsPosition : Does the InputStream support
# PositionStream/SeekPositionStream/RewindStream?
gap> testRead := function(testName, openFunc, lines, supportsPosition)
> local file, i, j, read, line, byte, concatlines;
> # Check we can read many times, to check we close properly
> for i in [1..100] do
> file := openFunc();
> for j in [1..Length(lines)] do
> line := ReadAllLine(file);
> if lines[j] <> line then
> PrintFormatted("Expected {!v}, found {!v}, at line {} in {}\n",
> lines[j], line, j, testName);
> fi;
> # it is valid to get, or not get, end of stream at end of last line
> if IsEndOfStream(file) and j < Length(lines) then
> Print("Unexpected end of stream in ", testName);
> fi;
> if supportsPosition then
> if PositionStream(file) <> Sum(lines{[1..j]},Length) then
> PrintFormatted("At position {}, expected {}, on line {} of {}\n",
> PositionStream(file), Sum(lines{[1..j]},Length), j, testName);
> fi;
> else
> if PositionStream(file) <> fail then
> Print("Unexpected PositionStream success ", testName, "\n");
> fi;
> fi;
> od;
> if ReadAllLine(file) <> fail then
> Print("reading past end of file did not return 'fail' in ",testName, "\n");
> fi;
> if not IsEndOfStream(file) then
> Print("failed to find end of stream in ", testName, "\n");
> fi;
> if supportsPosition then
> if Length(lines) > 2 then
> SeekPositionStream(file, Length(lines[1]));
> if PositionStream(file) <> Length(lines[1]) then
> Print("failed seek position ", testName, "\n");
> fi;
> if ReadAllLine(file) <> lines[2] then
> Print("failed read after seek ", testName, "\n");
> fi;
> fi;
> if not SeekPositionStream(file, 0) or PositionStream(file) <> 0 then
> Print("failed seek to 0 ", testName, "\n");
> fi;
> if not SeekPositionStream(file, Sum(lines, Length)) or
> PositionStream(file) <> Sum(lines, Length) then
> Print("failed seek to end ", testName, "\n");
> fi;
> if ReadAllLine(file) <> fail then
> Print("failed read past end of file ", testName, "\n");
> fi;
> if not RewindStream(file) or PositionStream(file) <> 0 then
> Print("failed rewind stream ", testName, "\n");
> fi;
> else
> if SeekPositionStream(file, 0) <> fail then
> Print("Unexpected SeekPositionStream success ", testName, "\n");
> fi;
> if RewindStream(file) <> fail then
> Print("Unexpected RewindStream success ", testName, "\n");
> fi;
> fi;
> CloseStream(file);
> file := openFunc();
> concatlines := Concatenation(lines);
> for i in [1..Length(concatlines)] do
> byte := ReadByte(file);
> if byte <> IntChar(concatlines[i]) then
> PrintFormatted("Expected {}, found {}, at position {} in {}\n",
> IntChar(concatlines[i]), byte, i, testName);
> fi;
> if i <> Length(concatlines) and IsEndOfStream(file) then
> PrintFormatted("Unexpected end of stream in {}\n", testName);
> fi;
> if supportsPosition and PositionStream(file) <> i then
> PrintFormatted("Expected to be at {}, instead at {}, in {}\n",
> i, PositionStream(i), testName);
> fi;
> od;
> if ReadByte(file) <> fail then
> PrintFormatted("Unexpected extra byte in {}\n", testName);
> fi;
> if not IsEndOfStream(file) then
> PrintFormatted("Exepected end of stream in {}\n", testName);
> fi;
> CloseStream(file);
> od;
> end;;
gap> dir := DirectoriesLibrary("tst/teststandard/files");;
gap> lines := ["here is line 1\n", "\n", "here is line 2\n"];;
gap> testRead("example.txt", {} -> InputTextFile(Filename(dir, "example.txt")),
> lines, true);

# Test automatic gzip detection
gap> testRead("example.txt", {} -> InputTextFile(Filename(dir, "examplegz.txt")),
> lines, false);
gap> testRead("empty.txt", {} -> InputTextFile(Filename(dir, "empty.txt")),
> [], true);
gap> testRead("lines string", {} -> InputTextString(Concatenation(lines)), lines, true);
gap> testRead("empty string", {} -> InputTextString(""), [], true);
gap> testRead("dummy input", {} -> InputTextNone(), [], true);
gap> STOP_TEST("files.tst", 1);

0 comments on commit 31aa775

Please sign in to comment.