Filesys-Virtual-Async-inMemory

 view release on metacpan or  search on metacpan

lib/Filesys/Virtual/Async/inMemory.pm  view on Meta::CPAN


	return;
}

sub lstat {
	my( $self, $path, $callback ) = @_;

	# FIXME unimplemented because of complexity
	$callback->( -ENOSYS() );

	return;
}

sub utime {
	my( $self, $path, $atime, $mtime, $callback ) = @_;

	# FIXME we don't support fh mode because it would require insane amounts of munging the paths
	if ( ref $path ) {
		if ( DEBUG ) {
			warn 'Passing a REF to utime() is not supported!';
		}
		$callback->( -ENOSYS() );
		return;
	}

	# are we readonly?
	if ( $self->readonly ) {
		$callback->( -EROFS() );
		return;
	}

	# FIXME fix relative path/sanitize path?

	# determine if we should be using callback mode
	if ( ref( $self ) ne __PACKAGE__ ) {
		if ( $self->can( '_utime' ) ) {
			$callback->( $self->_utime( $path, $atime, $mtime ) );
		} else {
			$callback->( -ENOSYS() );
		}
		return;
	}

	if ( exists $self->_fs->{ $path } ) {
		# okay, update the time
		if ( ! defined $atime ) { $atime = time() }
		if ( ! defined $mtime ) { $mtime = $atime }
		$self->_fs->{ $path }{'atime'} = $atime;
		$self->_fs->{ $path }{'mtime'} = $mtime;

		# successful update of time!
		$callback->( 0 );
	} else {
		# path does not exist
		$callback->( -ENOENT() );
	}

	return;
}

sub chown {
	my( $self, $path, $uid, $gid, $callback ) = @_;

	# FIXME we don't support fh mode because it would require insane amounts of munging the paths
	if ( ref $path ) {
		if ( DEBUG ) {
			warn 'Passing a REF to chown() is not supported!';
		}
		$callback->( -ENOSYS() );
		return;
	}

	# are we readonly?
	if ( $self->readonly ) {
		$callback->( -EROFS() );
		return;
	}

	# FIXME fix relative path/sanitize path?

	# determine if we should be using callback mode
	if ( ref( $self ) ne __PACKAGE__ ) {
		if ( $self->can( '_chown' ) ) {
			$callback->( $self->_chown( $path, $uid, $gid ) );
		} else {
			$callback->( -ENOSYS() );
		}
		return;
	}

	if ( exists $self->_fs->{ $path } ) {
		# okay, update the ownerships!
		if ( defined $uid and $uid > -1 ) {
			$self->_fs->{ $path }{'uid'} = $uid;
		}
		if ( defined $gid and $gid > -1 ) {
			$self->_fs->{ $path }{'gid'} = $gid;
		}

		# successful update of ownership!
		$callback->( 0 );
	} else {
		# path does not exist
		$callback->( -ENOENT() );
	}

	return;
}

sub truncate {
	my( $self, $path, $offset, $callback ) = @_;

	# FIXME we don't support fh mode because it would require insane amounts of munging the paths
	if ( ref $path ) {
		if ( DEBUG ) {
			warn 'Passing a REF to truncate() is not supported!';
		}
		$callback->( -ENOSYS() );
		return;
	}

	# are we readonly?
	if ( $self->readonly ) {
		$callback->( -EROFS() );
		return;
	}

	# FIXME fix relative path/sanitize path?

	# determine if we should be using callback mode
	if ( ref( $self ) ne __PACKAGE__ ) {
		if ( $self->can( '_truncate' ) ) {
			$callback->( $self->_truncate( $path, $offset ) );
		} else {
			$callback->( -ENOSYS() );
		}
		return;
	}

	if ( exists $self->_fs->{ $path } ) {
		if ( ! S_ISDIR( $self->_fs->{ $path }{'mode'} ) ) {
			# valid file, proceed with the truncate!

			# sanity check, offset cannot be bigger than the length of the file!

lib/Filesys/Virtual/Async/inMemory.pm  view on Meta::CPAN


=head2 Initializing the vfs

This constructor accepts either a hashref or a hash, valid options are:

=head3 filesystem

This sets the "filesystem" that we will have in memory. It needs to be a particular structure!

If this argument is missing, we will create an empty filesystem.

=head3 readonly

This enables readonly mode, which will prohibit any changes to the filesystem.

The default is: false

=head3 cwd

This sets the "current working directory" in the filesystem.

The default is: File::Spec->rootdir()

=head2 METHODS

=head3 readonly

Enables/disables readonly mode. This is also an accessor.

=head2 Special Cases

This module does a good job of covering the entire ::Async API, but there are some areas that needs mentioning.

=head3 root

Unimplemented, No sense in changing the root during run-time...

=head3 stat

Array mode not supported because it would require extra munging on my part to get the paths right.

=head3 link/symlink/lstat

Links are not supported at this time because of the complexity involved.

=head3 readahead/fsync/fdatasync

Always returns success ( 0 ), because they are useless to us

=head2 Subclassing this module

If you want to subclass this module, please read on! The primary reason for subclassing is so you have true "callbacks"
whenever the API is called, instead of providing a static filesystem structure. This module tries to do it's best
to reduce the pain, but you would need to be aware of some things.

The way this module implements subclassing is to call a private method whenever it detects a subclass using this
module as a superclass. Please don't override the ::Async API! What you need to do is define your own _method subs
for the ones you want to override. All other methods that aren't defined will return ENOSYS to the ::Async API.

Available methods to implement: _rmtree, _scandir, _move, _copy, _load, _readdir, _rmdir, _mkdir, _rename, _mknod,
_unlink, _chmod, _truncate, _chown, _utime, _stat, _write, _open.

Again, please look at the source for this module to see how it interacts with the subclass. Some of the methods have
been "simplified" to reduce the pain of managing the data. Be sure to let this module create the object, because
we need the "readonly" attribute to be present in the hash! If "readonly" is set, this module will take over the
logic for certain methods and not call your method if there's a readonly violation ( write(), for example ).

=head2 Debugging

You can enable debug mode which prints out some information ( and especially error messages ) by doing this:

	sub Filesys::Virtual::Async::inMemory::DEBUG () { 1 }
	use Filesys::Virtual::Async::inMemory;

=head2 TODO

=over 4

=item * automatically overriding CORE::* methods

	#poe@magnet

	<buu> Apocalypse: Hey, while you're at it, can you make it so all file access operators in perl operate on virtual directories?
	<Apocalypse> buu: hm you mean overriding readdir(), stat()?
	<buu> Yes.
	<Apocalypse> as of now you would have to explicitly use the filesys::virtual::async::inmemory object and do operations on it -> $fsv->readdir(), $fsv->open(), etc
	<buu> But I don't want to!
	<buu> =]
	<Apocalypse> but that would be a fun side project to try and figure out how to hijack CORE:: stuff
	<buu> Yes!
	<Apocalypse> hmm you could locally scope the hijack, pass a $fsv object to the module init, and have it transparently replace all file operations in the scope with $fsv->method calls
	<Apocalypse> why would you want it? pure laziness? haha
	<buu> Apocalypse: For buubot..
	<Apocalypse> mmm for now you can just use fsv::inmemory until somebody with enough wizardry does the overrides :)
	<Apocalypse> I'll file that away in my TODO and see if I will return to it someday hah
	<buu> Exccelent.

=back

=head1 SEE ALSO

L<Filesys::Virtual::Async>

=head1 SUPPORT

You can find documentation for this module with the perldoc command.

    perldoc Filesys::Virtual::Async::inMemory

=head2 Websites

=over 4

=item * Search CPAN

L<http://search.cpan.org/dist/Filesys-Virtual-Async-inMemory>

=item * AnnoCPAN: Annotated CPAN documentation

L<http://annocpan.org/dist/Filesys-Virtual-Async-inMemory>



( run in 0.577 second using v1.01-cache-2.11-cpan-71847e10f99 )