77use GuzzleHttp \Psr7 \Stream ;
88use GuzzleHttp \Psr7 \StreamWrapper ;
99
10+ /**
11+ * Compressed String Class
12+ *
13+ * Allows a user to directly generate a Gzip String in memory
14+ * as its primary use case, though it also allows for you to
15+ * create a stream for existing Gzip files on your computer.
16+ *
17+ */
1018class CompressedString
1119{
20+ /**
21+ * Class constant
22+ *
23+ * Useful to pass into the CompressedStringList::merge() method
24+ * if you don't already have your own delimiter.
25+ *
26+ */
1227 const DEFAULT_DELIMITER = '#|_|# ' ;
28+
29+ /**
30+ * Holds the instance of GzStreamGuzzle
31+ *
32+ * @var GzStreamGuzzle
33+ */
1334 protected $ gzStream = null ;
35+
36+ /**
37+ * Holds a copy of the raw stream resource
38+ *
39+ * @var resource
40+ */
1441 protected $ stream = null ;
42+
43+ /**
44+ * Holds a copy of the GuzzleHttp\Psr7\Stream class.
45+ *
46+ * @var Stream
47+ */
1548 protected $ streamObject = null ;
49+
50+ /**
51+ * Flag remembering whether the class
52+ * was instantiated as read-only or not.
53+ *
54+ * @var bool
55+ */
56+ protected $ readOnly = false ;
57+
58+ /**
59+ * The Gzip Compression Level to use When Writing
60+ *
61+ * Valid values are 0-9
62+ * 0 = No Compression
63+ * 1 = Minimal Compression
64+ * 6 = Default Compression
65+ * 9 = Maximum Compression
66+ *
67+ * @var int
68+ */
1669 protected $ compressionLevel = 6 ;
70+
71+ /**
72+ * put your comment there...
73+ *
74+ * @var mixed
75+ */
1776 protected $ isRealFile = false ;
1877
78+ /**
79+ * CompressedString constructor.
80+ *
81+ * @param bool $readOnly
82+ * @param int $compressionLevel
83+ * @param string $filepath
84+ */
1985 public function __construct ($ readOnly = false , $ compressionLevel = 6 , $ filepath = 'php://memory ' )
2086 {
2187 $ this ->replaceStream ($ readOnly , $ compressionLevel , $ filepath );
2288 }
2389
90+ /**
91+ * Creates the internal stream and GzStreamGuzzle instances.
92+ *
93+ * Used by other methods when needed.
94+ *
95+ * @param bool $readOnly
96+ * @param int $compressionLevel
97+ * @param string $filepath
98+ *
99+ * @return void
100+ */
24101 public function replaceStream ($ readOnly = false , $ compressionLevel = 6 , $ filepath = 'php://memory ' )
25102 {
26103 if (substr ($ filepath , 0 , 6 ) !== 'php:// ' ) {
27104 $ this ->isRealFile = true ;
28105 }
106+
107+ $ this ->filepath = $ filepath ;
29108 $ this ->compressionLevel = $ compressionLevel ;
30- $ this ->stream = fopen ($ filepath , 'r+ ' );
109+ $ this ->stream = fopen ($ this -> filepath , 'r+ ' );
31110 $ this ->streamObject = Psr7 \stream_for ($ this ->stream );
32- $ this ->gzStream = new GzStreamGuzzle ($ this ->streamObject , $ readOnly , $ this ->compressionLevel );
111+ $ this ->readOnly = $ readOnly ;
112+ $ this ->gzStream = new GzStreamGuzzle ($ this ->streamObject , $ this ->readOnly , $ this ->compressionLevel );
33113 }
34114
115+ /**
116+ * Tells you whether or not the current CompressedString instance
117+ * was created for read-only, or whether it is writable.
118+ *
119+ * @return bool
120+ */
121+ public function isReadOnly ()
122+ {
123+ return $ this ->readOnly ;
124+ }
125+
126+ /**
127+ * Tells you the filepath the current CompressedString instance
128+ * was created with.
129+ *
130+ * @return string
131+ */
132+ public function getPath ()
133+ {
134+ return $ this ->filepath ;
135+ }
136+
137+ /**
138+ * Writes to the CompressedString instance.
139+ *
140+ * Takes a regular string and writes it to the
141+ * CompressedString.
142+ *
143+ * Additionally, you can also pass in an array or object
144+ * and it will json_encode it for you automatically.
145+ *
146+ * If you have any special options to pass into json_encode
147+ * in these situations you may use the optional $options
148+ * and $depth parameters.
149+ *
150+ * Returns the current size (in bytes) of the uncompressed data that has
151+ * been written so far.
152+ *
153+ * @param mixed $string
154+ * @param int $options
155+ * @param int $depth
156+ *
157+ * @return int
158+ */
35159 public function write ($ string , $ options = 0 , $ depth = 512 )
36160 {
37161 if (!is_string ($ string )) {
@@ -41,12 +165,53 @@ public function write($string, $options = 0, $depth = 512)
41165 return $ this ->getGzStream ()->write ($ string );
42166 }
43167
168+ /**
169+ * Reads from the stream and returns the read data
170+ * as a string.
171+ *
172+ * Depending on the state and type of instance you
173+ * have created, reading may result in uncompressed
174+ * or compressed output being returned.
175+ *
176+ * Therefore, depending on what you need, you may
177+ * want to use the getCompressedReadOnlyStream()
178+ * or getDecompressedReadOnlyStream() methods
179+ * instead.
180+ *
181+ * @param int $length
182+ *
183+ * @return string
184+ */
44185 public function read ($ length = 65536 )
45186 {
46187 $ ret = $ this ->getGzStream ()->read ($ length );
47188 return $ ret ;
48189 }
49190
191+ /**
192+ * Prepends an uncompressed string to the beginning
193+ * of the currently compressed string.
194+ *
195+ * This method is somewhat wasteful because it requires
196+ * creating a read-only copy of the current stream,
197+ * creating a new stream, writing the new prepended string,
198+ * and then decompress and write the old string onto the end
199+ * of the new string.
200+ *
201+ * It's here because it's necessary to do this sometimes, but
202+ * just keep in mind it may increase the execution time somewhat
203+ * for your script if used heavily.
204+ *
205+ * It optionally allows you to provide a new compression level to
206+ * use for the new compressed string.
207+ *
208+ * @todo Look into ways to improve this method in the future.
209+ *
210+ * @param mixed $string
211+ * @param int $compressionLevel
212+ *
213+ * @return void
214+ */
50215 public function prepend ($ string , $ compressionLevel = 6 )
51216 {
52217 $ this ->prepareForRead ();
@@ -61,62 +226,163 @@ public function prepend($string, $compressionLevel = 6)
61226 }
62227 }
63228
229+ /**
230+ * Returns the compressed size (in bytes)
231+ * of the current string.
232+ *
233+ * Since this method calls getCompressedContents()
234+ * you won't be able to write anymore to the string
235+ * if you call this method.
236+ *
237+ * @todo Look into ways to improve this method in the future.
238+ *
239+ * @return int
240+ */
64241 public function getCompressedSize ()
65242 {
66243 return strlen ($ this ->getCompressedContents ());
67244 }
68245
246+ /**
247+ * Returns the decompressed string
248+ *
249+ * Since this method calls getCompressedContents()
250+ * you won't be able to write anymore to the string
251+ * if you call this method.
252+ *
253+ * Also, since it calls gzdecode() it may also return
254+ * false if there are any issues with the compressed string.
255+ *
256+ * @todo Look into ways to improve this method in the future.
257+ *
258+ * @return string
259+ */
69260 public function getDecompressedContents ()
70261 {
71262 return gzdecode ($ this ->getCompressedContents ());
72263 }
73264
265+ /**
266+ * Writes the decompressed string to a file
267+ * with optional exclusive file locking.
268+ *
269+ * @param string $filename
270+ * @param bool $lock
271+ *
272+ * @return int
273+ */
74274 public function writeDecompressedContents ($ filename , $ lock = false )
75275 {
76276 return file_put_contents ($ filename , $ this ->getDecompressedContents (), $ lock ? LOCK_EX : 0 );
77277 }
78278
279+ /**
280+ * Returns the compressed contents as a string
281+ *
282+ * @return string
283+ */
79284 public function getCompressedContents ()
80285 {
81286 $ this ->prepareForRead ();
82287 return stream_get_contents ($ this ->getStream ());
83288 }
84289
290+ /**
291+ * Writes the compressed string to a file
292+ * with optional exclusive file locking.
293+ *
294+ * @param string $filename
295+ * @param bool $lock
296+ *
297+ * @return int
298+ */
85299 public function writeCompressedContents ($ filename , $ lock = false )
86300 {
87301 return file_put_contents ($ filename , $ this ->getCompressedContents (), $ lock ? LOCK_EX : 0 );
88302 }
89303
304+ /**
305+ * Returns the internal GzStreamGuzzle instance.
306+ *
307+ * @return GzStreamGuzzle
308+ */
90309 public function getGzStream ()
91310 {
92311 return $ this ->gzStream ;
93312 }
94313
314+ /**
315+ * Prepares the CompressedString stream for reading
316+ *
317+ * @return void
318+ */
95319 public function prepareForRead ()
96320 {
97321 $ this ->getGzStream ()->writeFooterEarly ();
98322 $ this ->rewind ();
99323 }
100324
325+ /**
326+ * Rewinds the CompressedString stream
327+ *
328+ * @return void
329+ */
101330 public function rewind ()
102331 {
103332 rewind ($ this ->stream );
104333 }
105334
335+ /**
336+ * Returns the internal stream resource
337+ *
338+ * @return resource
339+ */
106340 public function getStream ()
107341 {
108342 return $ this ->stream ;
109343 }
110344
345+ /**
346+ * Returns the internal GuzzleHttp\Psr7\Stream Object.
347+ *
348+ * @return Stream
349+ */
111350 public function getStreamObject ()
112351 {
113352 return $ this ->streamObject ;
114353 }
115354
116- public function getReadOnlyStream ()
355+ /**
356+ * Returns a read-only stream that can be used
357+ * for reading the compressed contents back out
358+ * as a stream.
359+ *
360+ * @return GzStreamGuzzle
361+ */
362+ public function getCompressedReadOnlyStream ()
363+ {
364+ if ($ this ->isRealFile && $ this ->isReadOnly ()) {
365+ $ writable = new CompressedString (false , $ this ->compressionLevel , $ this ->filepath );
366+ return $ writable ->getGzStream ();
367+ } elseif ($ this ->isRealFile ) {
368+ return $ this ->getGzStream ();
369+ }
370+
371+ // More specifically for the in-memory streams:
372+ $ this ->prepareForRead ();
373+ return $ this ->getGzStream ();
374+ }
375+
376+ /**
377+ * put your comment there...
378+ *
379+ */
380+ public function getDecompressedReadOnlyStream ()
117381 {
118- if ($ this ->isRealFile ) {
382+ if ($ this ->isRealFile && $ this -> isReadOnly () ) {
119383 return $ this ->getGzStream ();
384+ } elseif ($ this ->isRealFile ) {
385+ return $ this ->getGzStream ()->readOnlyStream ();
120386 }
121387
122388 // More specifically for the in-memory streams:
0 commit comments