1package Mojo::ByteStream; 2use Mojo::Base -strict; 3use overload bool => sub {1}, '""' => sub { ${$_[0]} }, fallback => 1; 4 5use Exporter qw(import); 6use Mojo::Collection; 7use Mojo::Util; 8 9our @EXPORT_OK = ('b'); 10 11# Turn most functions from Mojo::Util into methods 12my @UTILS = ( 13 qw(b64_decode b64_encode camelize decamelize gunzip gzip hmac_sha1_sum html_unescape humanize_bytes md5_bytes), 14 qw(md5_sum punycode_decode punycode_encode quote sha1_bytes sha1_sum slugify term_escape trim unindent unquote), 15 qw(url_escape url_unescape xml_escape xor_encode) 16); 17for my $name (@UTILS) { 18 my $sub = Mojo::Util->can($name); 19 Mojo::Util::monkey_patch __PACKAGE__, $name, sub { 20 my $self = shift; 21 $$self = $sub->($$self, @_); 22 return $self; 23 }; 24} 25 26sub b { __PACKAGE__->new(@_) } 27 28sub clone { $_[0]->new(${$_[0]}) } 29 30sub decode { shift->_delegate(\&Mojo::Util::decode, @_) } 31sub encode { shift->_delegate(\&Mojo::Util::encode, @_) } 32 33sub new { 34 my $class = shift; 35 return bless \(my $dummy = join '', @_), ref $class || $class; 36} 37 38sub say { 39 my ($self, $handle) = @_; 40 $handle ||= \*STDOUT; 41 say $handle $$self; 42 return $self; 43} 44 45sub secure_compare { Mojo::Util::secure_compare ${shift()}, shift } 46 47sub size { length ${$_[0]} } 48 49sub split { 50 my ($self, $pat, $lim) = (shift, shift, shift // 0); 51 return Mojo::Collection->new(map { $self->new($_) } split $pat, $$self, $lim); 52} 53 54sub tap { shift->Mojo::Base::tap(@_) } 55 56sub to_string { ${$_[0]} } 57 58sub with_roles { shift->Mojo::Base::with_roles(@_) } 59 60sub _delegate { 61 my ($self, $sub) = (shift, shift); 62 $$self = $sub->(shift || 'UTF-8', $$self); 63 return $self; 64} 65 661; 67 68=encoding utf8 69 70=head1 NAME 71 72Mojo::ByteStream - ByteStream 73 74=head1 SYNOPSIS 75 76 use Mojo::ByteStream; 77 78 # Manipulate bytestream 79 my $stream = Mojo::ByteStream->new('foo_bar_baz'); 80 say $stream->camelize; 81 82 # Chain methods 83 my $stream = Mojo::ByteStream->new('foo bar baz')->quote; 84 $stream = $stream->unquote->encode('UTF-8')->b64_encode(''); 85 say "$stream"; 86 87 # Use the alternative constructor 88 use Mojo::ByteStream qw(b); 89 my $stream = b('foobarbaz')->b64_encode('')->say; 90 91=head1 DESCRIPTION 92 93L<Mojo::ByteStream> is a scalar-based container for bytestreams that provides a more friendly API for many of the 94functions in L<Mojo::Util>. 95 96 # Access scalar directly to manipulate bytestream 97 my $stream = Mojo::ByteStream->new('foo'); 98 $$stream .= 'bar'; 99 100=head1 FUNCTIONS 101 102L<Mojo::ByteStream> implements the following functions, which can be imported individually. 103 104=head2 b 105 106 my $stream = b('test123'); 107 108Construct a new scalar-based L<Mojo::ByteStream> object. 109 110=head1 METHODS 111 112L<Mojo::ByteStream> implements the following methods. 113 114=head2 b64_decode 115 116 $stream = $stream->b64_decode; 117 118Base64 decode bytestream with L<Mojo::Util/"b64_decode">. 119 120=head2 b64_encode 121 122 $stream = $stream->b64_encode; 123 $stream = $stream->b64_encode("\n"); 124 125Base64 encode bytestream with L<Mojo::Util/"b64_encode">. 126 127 # "Zm9vIGJhciBiYXo=" 128 b('foo bar baz')->b64_encode(''); 129 130=head2 camelize 131 132 $stream = $stream->camelize; 133 134Camelize bytestream with L<Mojo::Util/"camelize">. 135 136=head2 clone 137 138 my $stream2 = $stream->clone; 139 140Return a new L<Mojo::ByteStream> object cloned from this bytestream. 141 142=head2 decamelize 143 144 $stream = $stream->decamelize; 145 146Decamelize bytestream with L<Mojo::Util/"decamelize">. 147 148=head2 decode 149 150 $stream = $stream->decode; 151 $stream = $stream->decode('iso-8859-1'); 152 153Decode bytestream with L<Mojo::Util/"decode">, defaults to using C<UTF-8>. 154 155 # "♥" 156 b('%E2%99%A5')->url_unescape->decode; 157 158=head2 encode 159 160 $stream = $stream->encode; 161 $stream = $stream->encode('iso-8859-1'); 162 163Encode bytestream with L<Mojo::Util/"encode">, defaults to using C<UTF-8>. 164 165 # "%E2%99%A5" 166 b('♥')->encode->url_escape; 167 168=head2 gunzip 169 170 $stream = $stream->gunzip; 171 172Uncompress bytestream with L<Mojo::Util/"gunzip">. 173 174=head2 gzip 175 176 stream = $stream->gzip; 177 178Compress bytestream with L<Mojo::Util/"gzip">. 179 180=head2 hmac_sha1_sum 181 182 $stream = $stream->hmac_sha1_sum('passw0rd'); 183 184Generate HMAC-SHA1 checksum for bytestream with L<Mojo::Util/"hmac_sha1_sum">. 185 186 # "7fbdc89263974a89210ea71f171c77d3f8c21471" 187 b('foo bar baz')->hmac_sha1_sum('secr3t'); 188 189=head2 html_unescape 190 191 $stream = $stream->html_unescape; 192 193Unescape all HTML entities in bytestream with L<Mojo::Util/"html_unescape">. 194 195 # "%3Chtml%3E" 196 b('<html>')->html_unescape->url_escape; 197 198=head2 humanize_bytes 199 200 $stream = $stream->humanize_bytes; 201 202Turn number of bytes into a simplified human readable format for bytestream with L<Mojo::Util/"humanize_bytes">. 203 204=head2 md5_bytes 205 206 $stream = $stream->md5_bytes; 207 208Generate binary MD5 checksum for bytestream with L<Mojo::Util/"md5_bytes">. 209 210=head2 md5_sum 211 212 $stream = $stream->md5_sum; 213 214Generate MD5 checksum for bytestream with L<Mojo::Util/"md5_sum">. 215 216=head2 new 217 218 my $stream = Mojo::ByteStream->new('test123'); 219 220Construct a new scalar-based L<Mojo::ByteStream> object. 221 222=head2 punycode_decode 223 224 $stream = $stream->punycode_decode; 225 226Punycode decode bytestream with L<Mojo::Util/"punycode_decode">. 227 228=head2 punycode_encode 229 230 $stream = $stream->punycode_encode; 231 232Punycode encode bytestream with L<Mojo::Util/"punycode_encode">. 233 234=head2 quote 235 236 $stream = $stream->quote; 237 238Quote bytestream with L<Mojo::Util/"quote">. 239 240=head2 say 241 242 $stream = $stream->say; 243 $stream = $stream->say(*STDERR); 244 245Print bytestream to handle and append a newline, defaults to using C<STDOUT>. 246 247=head2 secure_compare 248 249 my $bool = $stream->secure_compare($str); 250 251Compare bytestream with L<Mojo::Util/"secure_compare">. 252 253=head2 sha1_bytes 254 255 $stream = $stream->sha1_bytes; 256 257Generate binary SHA1 checksum for bytestream with L<Mojo::Util/"sha1_bytes">. 258 259=head2 sha1_sum 260 261 $stream = $stream->sha1_sum; 262 263Generate SHA1 checksum for bytestream with L<Mojo::Util/"sha1_sum">. 264 265=head2 size 266 267 my $size = $stream->size; 268 269Size of bytestream. 270 271=head2 slugify 272 273 $stream = $stream->slugify; 274 $stream = $stream->slugify($bool); 275 276Generate URL slug for bytestream with L<Mojo::Util/"slugify">. 277 278=head2 split 279 280 my $collection = $stream->split(','); 281 my $collection = $stream->split(',', -1); 282 283Turn bytestream into L<Mojo::Collection> object containing L<Mojo::ByteStream> objects. 284 285 # "One,Two,Three" 286 b("one,two,three")->split(',')->map('camelize')->join(','); 287 288 # "One,Two,Three,,," 289 b("one,two,three,,,")->split(',', -1)->map('camelize')->join(','); 290 291=head2 tap 292 293 $stream = $stream->tap(sub {...}); 294 295Alias for L<Mojo::Base/"tap">. 296 297=head2 term_escape 298 299 $stream = $stream->term_escape; 300 301Escape POSIX control characters in bytestream with L<Mojo::Util/"term_escape">. 302 303 # Print binary checksum to terminal 304 b('foo')->sha1_bytes->term_escape->say; 305 306=head2 to_string 307 308 my $str = $stream->to_string; 309 310Stringify bytestream. 311 312=head2 trim 313 314 $stream = $stream->trim; 315 316Trim whitespace characters from both ends of bytestream with L<Mojo::Util/"trim">. 317 318=head2 unindent 319 320 $stream = $stream->unindent; 321 322Unindent bytestream with L<Mojo::Util/"unindent">. 323 324=head2 unquote 325 326 $stream = $stream->unquote; 327 328Unquote bytestream with L<Mojo::Util/"unquote">. 329 330=head2 url_escape 331 332 $stream = $stream->url_escape; 333 $stream = $stream->url_escape('^A-Za-z0-9\-._~'); 334 335Percent encode all unsafe characters in bytestream with L<Mojo::Util/"url_escape">. 336 337 # "%E2%98%83" 338 b('☃')->encode->url_escape; 339 340=head2 url_unescape 341 342 $stream = $stream->url_unescape; 343 344Decode percent encoded characters in bytestream with L<Mojo::Util/"url_unescape">. 345 346 # "<html>" 347 b('%3Chtml%3E')->url_unescape->xml_escape; 348 349=head2 with_roles 350 351 my $new_class = Mojo::ByteStream->with_roles('Mojo::ByteStream::Role::One'); 352 my $new_class = Mojo::ByteStream->with_roles('+One', '+Two'); 353 $stream = $stream->with_roles('+One', '+Two'); 354 355Alias for L<Mojo::Base/"with_roles">. 356 357=head2 xml_escape 358 359 $stream = $stream->xml_escape; 360 361Escape only the characters C<&>, C<E<lt>>, C<E<gt>>, C<"> and C<'> in bytestream with L<Mojo::Util/"xml_escape">. 362 363=head2 xor_encode 364 365 $stream = $stream->xor_encode($key); 366 367XOR encode bytestream with L<Mojo::Util/"xor_encode">. 368 369 # "%04%0E%15B%03%1B%10" 370 b('foo bar')->xor_encode('baz')->url_escape; 371 372=head1 OPERATORS 373 374L<Mojo::ByteStream> overloads the following operators. 375 376=head2 bool 377 378 my $bool = !!$bytestream; 379 380Always true. 381 382=head2 stringify 383 384 my $str = "$bytestream"; 385 386Alias for L</"to_string">. 387 388=head1 SEE ALSO 389 390L<Mojolicious>, L<Mojolicious::Guides>, L<https://mojolicious.org>. 391 392=cut 393