package Mojo::Asset::Memory; use Mojo::Base 'Mojo::Asset'; use Carp 'croak'; use Mojo::Asset::File; use Mojo::File qw(path); has 'auto_upgrade'; has max_memory_size => sub { $ENV{MOJO_MAX_MEMORY_SIZE} || 262144 }; has mtime => sub {$^T}; sub add_chunk { my ($self, $chunk) = @_; croak 'Asset has been upgraded and is now frozen' if $self->{frozen}; if ($self->auto_upgrade && ($self->size + length $chunk) > $self->max_memory_size) { $self->emit(upgrade => my $file = Mojo::Asset::File->new)->{frozen} = 1; return $file->add_chunk($self->slurp . $chunk); } $self->{content} .= $chunk; return $self; } sub contains { my ($self, $str) = @_; my $start = $self->start_range; my $pos = index $self->{content} // '', $str, $start; $pos -= $start if $start && $pos >= 0; my $end = $self->end_range; return $end && ($pos + length $str) >= $end ? -1 : $pos; } sub get_chunk { my ($self, $offset, $max) = @_; $max //= 131072; $offset += $self->start_range; if (my $end = $self->end_range) { $max = $end + 1 - $offset if ($offset + $max) > $end } return substr shift->{content} // '', $offset, $max; } sub move_to { path($_[1])->spew($_[0]{content} // '') and return $_[0] } sub size { length(shift->{content} // '') } sub slurp { shift->{content} // '' } sub to_file { Mojo::Asset::File->new->add_chunk(shift->slurp) } 1; =encoding utf8 =head1 NAME Mojo::Asset::Memory - In-memory storage for HTTP content =head1 SYNOPSIS use Mojo::Asset::Memory; my $mem = Mojo::Asset::Memory->new; $mem->add_chunk('foo bar baz'); say $mem->slurp; =head1 DESCRIPTION L is an in-memory storage backend for HTTP content. =head1 EVENTS L inherits all events from L and can emit the following new ones. =head2 upgrade $mem->on(upgrade => sub ($mem, $file) {...}); Emitted when asset gets upgraded to a L object. $mem->on(upgrade => sub ($mem, $file) { $file->tmpdir('/tmp') }); =head1 ATTRIBUTES L inherits all attributes from L and implements the following new ones. =head2 auto_upgrade my $bool = $mem->auto_upgrade; $mem = $mem->auto_upgrade($bool); Try to detect if content size exceeds L limit and automatically upgrade to a L object. =head2 max_memory_size my $size = $mem->max_memory_size; $mem = $mem->max_memory_size(1024); Maximum size in bytes of data to keep in memory before automatically upgrading to a L object, defaults to the value of the C environment variable or C<262144> (256KiB). =head2 mtime my $mtime = $mem->mtime; $mem = $mem->mtime(1408567500); Modification time of asset, defaults to the value of C<$^T>. =head1 METHODS L inherits all methods from L and implements the following new ones. =head2 add_chunk $mem = $mem->add_chunk('foo bar baz'); my $file = $mem->add_chunk('abc' x 262144); Add chunk of data and upgrade to L object if necessary. =head2 contains my $position = $mem->contains('bar'); Check if asset contains a specific string. =head2 get_chunk my $bytes = $mem->get_chunk($offset); my $bytes = $mem->get_chunk($offset, $max); Get chunk of data starting from a specific position, defaults to a maximum chunk size of C<131072> bytes (128KiB). =head2 move_to $mem = $mem->move_to('/home/sri/foo.txt'); Move asset data into a specific file. =head2 size my $size = $mem->size; Size of asset data in bytes. =head2 slurp my $bytes = $mem->slurp; Read all asset data at once. =head2 to_file my $file = $mem->to_file; Convert asset to L object. =head1 SEE ALSO L, L, L. =cut