66use MongoDB \BSON \ObjectId ;
77use MongoDB \BSON \UTCDateTime ;
88use MongoDB \Exception \InvalidArgumentException ;
9+ use MongoDB \Exception \RuntimeException ;
910
1011/**
1112 * WritableStream abstracts the process of writing a GridFS file.
@@ -16,8 +17,7 @@ class WritableStream
1617{
1718 private static $ defaultChunkSizeBytes = 261120 ;
1819
19- private $ buffer ;
20- private $ bufferLength = 0 ;
20+ private $ buffer = '' ;
2121 private $ chunkOffset = 0 ;
2222 private $ chunkSize ;
2323 private $ collectionWrapper ;
@@ -76,7 +76,6 @@ public function __construct(CollectionWrapper $collectionWrapper, $filename, arr
7676
7777 $ this ->chunkSize = $ options ['chunkSizeBytes ' ];
7878 $ this ->collectionWrapper = $ collectionWrapper ;
79- $ this ->buffer = fopen ('php://memory ' , 'w+b ' );
8079 $ this ->ctx = hash_init ('md5 ' );
8180
8281 $ this ->file = [
@@ -113,14 +112,10 @@ public function close()
113112 return ;
114113 }
115114
116- rewind ($ this ->buffer );
117- $ cached = stream_get_contents ($ this ->buffer );
118-
119- if (strlen ($ cached ) > 0 ) {
120- $ this ->insertChunk ($ cached );
115+ if (strlen ($ this ->buffer ) > 0 ) {
116+ $ this ->insertChunkFromBuffer ();
121117 }
122118
123- fclose ($ this ->buffer );
124119 $ this ->fileCollectionInsert ();
125120 $ this ->isClosed = true ;
126121 }
@@ -151,36 +146,31 @@ public function getSize()
151146 * Inserts binary data into GridFS via chunks.
152147 *
153148 * Data will be buffered internally until chunkSizeBytes are accumulated, at
154- * which point a chunk's worth of data will be inserted and the buffer
155- * reset.
149+ * which point a chunk document will be inserted and the buffer reset.
156150 *
157- * @param string $toWrite Binary data to write
151+ * @param string $data Binary data to write
158152 * @return integer
159153 */
160- public function insertChunks ( $ toWrite )
154+ public function writeBytes ( $ data )
161155 {
162156 if ($ this ->isClosed ) {
163157 // TODO: Should this be an error condition? e.g. BadMethodCallException
164158 return ;
165159 }
166160
167- $ readBytes = 0 ;
161+ $ bytesRead = 0 ;
168162
169- while ($ readBytes != strlen ($ toWrite )) {
170- $ addToBuffer = substr ($ toWrite , $ readBytes , $ this ->chunkSize - $ this ->bufferLength );
171- fwrite ($ this ->buffer , $ addToBuffer );
172- $ readBytes += strlen ($ addToBuffer );
173- $ this ->bufferLength += strlen ($ addToBuffer );
163+ while ($ bytesRead != strlen ($ data )) {
164+ $ initialBufferLength = strlen ($ this ->buffer );
165+ $ this ->buffer .= substr ($ data , $ bytesRead , $ this ->chunkSize - $ initialBufferLength );
166+ $ bytesRead += strlen ($ this ->buffer ) - $ initialBufferLength ;
174167
175- if ($ this ->bufferLength == $ this ->chunkSize ) {
176- rewind ($ this ->buffer );
177- $ this ->insertChunk (stream_get_contents ($ this ->buffer ));
178- ftruncate ($ this ->buffer , 0 );
179- $ this ->bufferLength = 0 ;
168+ if (strlen ($ this ->buffer ) == $ this ->chunkSize ) {
169+ $ this ->insertChunkFromBuffer ();
180170 }
181171 }
182172
183- return $ readBytes ;
173+ return $ bytesRead ;
184174 }
185175
186176 private function abort ()
@@ -206,22 +196,29 @@ private function fileCollectionInsert()
206196 return $ this ->file ['_id ' ];
207197 }
208198
209- private function insertChunk ( $ data )
199+ private function insertChunkFromBuffer ( )
210200 {
211201 if ($ this ->isClosed ) {
212202 // TODO: Should this be an error condition? e.g. BadMethodCallException
213203 return ;
214204 }
215205
216- $ toUpload = [
206+ if (strlen ($ this ->buffer ) == 0 ) {
207+ return ;
208+ }
209+
210+ $ data = $ this ->buffer ;
211+ $ this ->buffer = '' ;
212+
213+ $ chunk = [
217214 'files_id ' => $ this ->file ['_id ' ],
218215 'n ' => $ this ->chunkOffset ,
219216 'data ' => new Binary ($ data , Binary::TYPE_GENERIC ),
220217 ];
221218
222219 hash_update ($ this ->ctx , $ data );
223220
224- $ this ->collectionWrapper ->insertChunk ($ toUpload );
221+ $ this ->collectionWrapper ->insertChunk ($ chunk );
225222 $ this ->length += strlen ($ data );
226223 $ this ->chunkOffset ++;
227224 }
0 commit comments