Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
M
mongo-php-library
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
sinan
mongo-php-library
Commits
480da55f
Commit
480da55f
authored
Jan 12, 2017
by
Jeremy Mikola
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
PHPLIB-213: Support seeking and partial file retrieval for GridFS streams
parent
90967fca
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
143 additions
and
0 deletions
+143
-0
ReadableStream.php
src/GridFS/ReadableStream.php
+38
-0
StreamWrapper.php
src/GridFS/StreamWrapper.php
+45
-0
WritableStream.php
src/GridFS/WritableStream.php
+15
-0
StreamWrapperFunctionalTest.php
tests/GridFS/StreamWrapperFunctionalTest.php
+45
-0
No files found.
src/GridFS/ReadableStream.php
View file @
480da55f
...
@@ -166,6 +166,44 @@ class ReadableStream
...
@@ -166,6 +166,44 @@ class ReadableStream
return
$data
;
return
$data
;
}
}
/**
* Seeks the chunk and buffer offsets for the next read operation.
*
* @param integer $offset
* @throws InvalidArgumentException if $offset is out of range
*/
public
function
seek
(
$offset
)
{
if
(
$offset
<
0
||
$offset
>
$this
->
file
->
length
)
{
throw
new
InvalidArgumentException
(
sprintf
(
'$offset must be >= 0 and <= %d; given: %d'
,
$length
,
$offset
));
}
/* Compute the offsets for the chunk and buffer (i.e. chunk data) from
* which we will expect to read after seeking. If the chunk offset
* changed, we'll also need to reset the buffer.
*/
$lastChunkOffset
=
$this
->
chunkOffset
;
$this
->
chunkOffset
=
(
integer
)
floor
(
$offset
/
$this
->
chunkSize
);
$this
->
bufferOffset
=
$offset
%
$this
->
chunkSize
;
if
(
$lastChunkOffset
!==
$this
->
chunkOffset
)
{
$this
->
buffer
=
null
;
$this
->
chunksIterator
=
null
;
}
}
/**
* Return the current position of the stream.
*
* This is the offset within the stream where the next byte would be read.
*
* @return integer
*/
public
function
tell
()
{
return
(
$this
->
chunkOffset
*
$this
->
chunkSize
)
+
$this
->
bufferOffset
;
}
/**
/**
* Initialize the buffer to the current chunk's data.
* Initialize the buffer to the current chunk's data.
*
*
...
...
src/GridFS/StreamWrapper.php
View file @
480da55f
...
@@ -136,6 +136,40 @@ class StreamWrapper
...
@@ -136,6 +136,40 @@ class StreamWrapper
}
}
}
}
/**
* Return the current position of the stream.
*
* @see http://php.net/manual/en/streamwrapper.stream-seek.php
* @param integer $offset Stream offset to seek to
* @param integer $whence One of SEEK_SET, SEEK_CUR, or SEEK_END
* @return boolean True if the position was updated and false otherwise
*/
public
function
stream_seek
(
$offset
,
$whence
=
\SEEK_SET
)
{
$size
=
$this
->
stream
->
getSize
();
if
(
$whence
===
\SEEK_CUR
)
{
$offset
+=
$this
->
stream
->
tell
();
}
if
(
$whence
===
\SEEK_END
)
{
$offset
+=
$size
;
}
// WritableStreams are always positioned at the end of the stream
if
(
$this
->
stream
instanceof
WritableStream
)
{
return
$offset
===
$size
;
}
if
(
$offset
<
0
||
$offset
>
$size
)
{
return
false
;
}
$this
->
stream
->
seek
(
$offset
);
return
true
;
}
/**
/**
* Return information about the stream.
* Return information about the stream.
*
*
...
@@ -166,6 +200,17 @@ class StreamWrapper
...
@@ -166,6 +200,17 @@ class StreamWrapper
return
$stat
;
return
$stat
;
}
}
/**
* Return the current position of the stream.
*
* @see http://php.net/manual/en/streamwrapper.stream-tell.php
* @return integer The current position of the stream
*/
public
function
stream_tell
()
{
return
$this
->
stream
->
tell
();
}
/**
/**
* Write bytes to the stream.
* Write bytes to the stream.
*
*
...
...
src/GridFS/WritableStream.php
View file @
480da55f
...
@@ -161,6 +161,21 @@ class WritableStream
...
@@ -161,6 +161,21 @@ class WritableStream
return
$this
->
length
+
strlen
(
$this
->
buffer
);
return
$this
->
length
+
strlen
(
$this
->
buffer
);
}
}
/**
* Return the current position of the stream.
*
* This is the offset within the stream where the next byte would be
* written. Since seeking is not supported and writes are appended, this is
* always the end of the stream.
*
* @see WriteableStream::getSize()
* @return integer
*/
public
function
tell
()
{
return
$this
->
getSize
();
}
/**
/**
* Inserts binary data into GridFS via chunks.
* Inserts binary data into GridFS via chunks.
*
*
...
...
tests/GridFS/StreamWrapperFunctionalTest.php
View file @
480da55f
...
@@ -50,6 +50,32 @@ class StreamWrapperFunctionalTest extends FunctionalTestCase
...
@@ -50,6 +50,32 @@ class StreamWrapperFunctionalTest extends FunctionalTestCase
$this
->
assertSame
(
''
,
fread
(
$stream
,
3
));
$this
->
assertSame
(
''
,
fread
(
$stream
,
3
));
}
}
public
function
testReadableStreamSeek
()
{
$stream
=
$this
->
bucket
->
openDownloadStream
(
'length-10'
);
$this
->
assertSame
(
0
,
fseek
(
$stream
,
2
,
\SEEK_SET
));
$this
->
assertSame
(
'cde'
,
fread
(
$stream
,
3
));
$this
->
assertSame
(
0
,
fseek
(
$stream
,
10
,
\SEEK_SET
));
$this
->
assertSame
(
''
,
fread
(
$stream
,
3
));
$this
->
assertSame
(
-
1
,
fseek
(
$stream
,
-
1
,
\SEEK_SET
));
$this
->
assertSame
(
-
1
,
fseek
(
$stream
,
11
,
\SEEK_SET
));
$this
->
assertSame
(
0
,
fseek
(
$stream
,
-
5
,
\SEEK_CUR
));
$this
->
assertSame
(
'fgh'
,
fread
(
$stream
,
3
));
$this
->
assertSame
(
0
,
fseek
(
$stream
,
1
,
\SEEK_CUR
));
$this
->
assertSame
(
'j'
,
fread
(
$stream
,
3
));
$this
->
assertSame
(
-
1
,
fseek
(
$stream
,
1
,
\SEEK_CUR
));
$this
->
assertSame
(
-
1
,
fseek
(
$stream
,
-
11
,
\SEEK_CUR
));
$this
->
assertSame
(
0
,
fseek
(
$stream
,
0
,
\SEEK_END
));
$this
->
assertSame
(
''
,
fread
(
$stream
,
3
));
$this
->
assertSame
(
0
,
fseek
(
$stream
,
-
8
,
\SEEK_END
));
$this
->
assertSame
(
'cde'
,
fread
(
$stream
,
3
));
$this
->
assertSame
(
-
1
,
fseek
(
$stream
,
-
11
,
\SEEK_END
));
$this
->
assertSame
(
-
1
,
fseek
(
$stream
,
1
,
\SEEK_END
));
}
public
function
testReadableStreamStat
()
public
function
testReadableStreamStat
()
{
{
$stream
=
$this
->
bucket
->
openDownloadStream
(
'length-10'
);
$stream
=
$this
->
bucket
->
openDownloadStream
(
'length-10'
);
...
@@ -102,6 +128,25 @@ class StreamWrapperFunctionalTest extends FunctionalTestCase
...
@@ -102,6 +128,25 @@ class StreamWrapperFunctionalTest extends FunctionalTestCase
$this
->
assertSame
(
''
,
fread
(
$stream
,
8192
));
$this
->
assertSame
(
''
,
fread
(
$stream
,
8192
));
}
}
public
function
testWritableStreamSeek
()
{
$stream
=
$this
->
bucket
->
openUploadStream
(
'filename'
);
$this
->
assertSame
(
6
,
fwrite
(
$stream
,
'foobar'
));
$this
->
assertSame
(
-
1
,
fseek
(
$stream
,
0
,
\SEEK_SET
));
$this
->
assertSame
(
-
1
,
fseek
(
$stream
,
7
,
\SEEK_SET
));
$this
->
assertSame
(
0
,
fseek
(
$stream
,
6
,
\SEEK_SET
));
$this
->
assertSame
(
0
,
fseek
(
$stream
,
0
,
\SEEK_CUR
));
$this
->
assertSame
(
-
1
,
fseek
(
$stream
,
-
1
,
\SEEK_CUR
));
$this
->
assertSame
(
-
1
,
fseek
(
$stream
,
1
,
\SEEK_CUR
));
$this
->
assertSame
(
0
,
fseek
(
$stream
,
0
,
\SEEK_END
));
$this
->
assertSame
(
-
1
,
fseek
(
$stream
,
-
1
,
\SEEK_END
));
$this
->
assertSame
(
-
1
,
fseek
(
$stream
,
1
,
\SEEK_END
));
}
public
function
testWritableStreamStat
()
public
function
testWritableStreamStat
()
{
{
$currentTimestamp
=
time
();
$currentTimestamp
=
time
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment