summaryrefslogtreecommitdiff
path: root/shared/ossp_uuid/perl/uuid.pm
diff options
context:
space:
mode:
Diffstat (limited to 'shared/ossp_uuid/perl/uuid.pm')
-rw-r--r--shared/ossp_uuid/perl/uuid.pm334
1 files changed, 334 insertions, 0 deletions
diff --git a/shared/ossp_uuid/perl/uuid.pm b/shared/ossp_uuid/perl/uuid.pm
new file mode 100644
index 00000000..b3223966
--- /dev/null
+++ b/shared/ossp_uuid/perl/uuid.pm
@@ -0,0 +1,334 @@
+##
+## OSSP uuid - Universally Unique Identifier
+## Copyright (c) 2004-2007 Ralf S. Engelschall <rse@engelschall.com>
+## Copyright (c) 2004-2007 The OSSP Project <http://www.ossp.org/>
+##
+## This file is part of OSSP uuid, a library for the generation
+## of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/
+##
+## Permission to use, copy, modify, and distribute this software for
+## any purpose with or without fee is hereby granted, provided that
+## the above copyright notice and this permission notice appear in all
+## copies.
+##
+## THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+## SUCH DAMAGE.
+##
+## uuid.pm: Perl Binding (Perl part)
+##
+
+##
+## High-Level Perl Module TIE-style API
+## (just a functionality-reduced TIE wrapper around the OO-style API)
+##
+
+package OSSP::uuid::tie;
+
+use 5.008;
+use strict;
+use warnings;
+use Carp;
+
+# inhert from Tie::Scalar
+require Tie::Scalar;
+our @ISA = qw(Tie::Scalar);
+
+# helper function
+sub mode_sanity {
+ my ($mode) = @_;
+ if (not ( defined($mode)
+ and ref($mode) eq 'ARRAY'
+ and ( (@{$mode} == 1 and $mode->[0] =~ m|^v[14]$|)
+ or (@{$mode} == 3 and $mode->[0] =~ m|^v[35]$|)))) {
+ return (undef, "invalid UUID generation mode specification");
+ }
+ if ($mode->[0] =~ m|^v[35]$|) {
+ my $uuid_ns = new OSSP::uuid;
+ $uuid_ns->load($mode->[1])
+ or return (undef, "failed to load UUID $mode->[0] namespace");
+ $mode->[1] = $uuid_ns;
+ }
+ return ($mode, undef);
+}
+
+# constructor
+sub TIESCALAR {
+ my ($class, @args) = @_;
+ my $self = {};
+ bless ($self, $class);
+ $self->{-uuid} = new OSSP::uuid
+ or croak "failed to create OSSP::uuid object";
+ my ($mode, $error) = mode_sanity(defined($args[0]) ? [ @args ] : [ "v1" ]);
+ croak $error if defined($error);
+ $self->{-mode} = $mode;
+ return $self;
+}
+
+# destructor
+sub DESTROY {
+ my ($self) = @_;
+ delete $self->{-uuid};
+ delete $self->{-mode};
+ return;
+}
+
+# fetch value from scalar
+# (applied semantic: export UUID in string format)
+sub FETCH {
+ my ($self) = @_;
+ $self->{-uuid}->make(@{$self->{-mode}})
+ or croak "failed to generate new UUID";
+ my $value = $self->{-uuid}->export("str")
+ or croak "failed to export new UUID";
+ return $value;
+}
+
+# store value into scalar
+# (applied semantic: configure new UUID generation mode)
+sub STORE {
+ my ($self, $value) = @_;
+ my ($mode, $error) = mode_sanity($value);
+ croak $error if defined($error);
+ $self->{-mode} = $mode;
+ return;
+}
+
+##
+## High-Level Perl Module OO-style API
+## (just an OO wrapper around the C-style API)
+##
+
+package OSSP::uuid;
+
+use 5.008;
+use strict;
+use warnings;
+use Carp;
+use XSLoader;
+use Exporter;
+
+# API version
+our $VERSION = do { my @v = ('1.6.2' =~ m/\d+/g); sprintf("%d.".("%02d"x$#v), @v); };
+
+# API inheritance
+our @ISA = qw(Exporter);
+
+# API symbols
+my $symbols = {
+ 'const' => [qw(
+ UUID_VERSION
+ UUID_LEN_BIN
+ UUID_LEN_STR
+ UUID_LEN_SIV
+ UUID_RC_OK
+ UUID_RC_ARG
+ UUID_RC_MEM
+ UUID_RC_SYS
+ UUID_RC_INT
+ UUID_RC_IMP
+ UUID_MAKE_V1
+ UUID_MAKE_V3
+ UUID_MAKE_V4
+ UUID_MAKE_V5
+ UUID_MAKE_MC
+ UUID_FMT_BIN
+ UUID_FMT_STR
+ UUID_FMT_SIV
+ UUID_FMT_TXT
+ )],
+ 'func' => [qw(
+ uuid_create
+ uuid_destroy
+ uuid_load
+ uuid_make
+ uuid_isnil
+ uuid_compare
+ uuid_import
+ uuid_export
+ uuid_error
+ uuid_version
+ )]
+};
+
+# API symbol exportation
+our %EXPORT_TAGS = (
+ 'all' => [ @{$symbols->{'const'}}, @{$symbols->{'func'}} ],
+ 'const' => [ @{$symbols->{'const'}} ],
+ 'func' => [ @{$symbols->{'func'}} ]
+);
+our @EXPORT_OK = @{$EXPORT_TAGS{'all'}};
+our @EXPORT = ();
+
+# constructor
+sub new {
+ my $proto = shift;
+ my $class = ref($proto) || $proto;
+ my $self = {};
+ bless ($self, $class);
+ $self->{-uuid} = undef;
+ $self->{-rc} = $self->UUID_RC_OK;
+ my $rc = uuid_create($self->{-uuid});
+ if ($rc != $self->UUID_RC_OK) {
+ croak(sprintf("OSSP::uuid::new: uuid_create: %s (%d)", uuid_error($rc), $rc));
+ return undef;
+ }
+ return $self;
+}
+
+# destructor
+sub DESTROY ($) {
+ my ($self) = @_;
+ $self->{-rc} = uuid_destroy($self->{-uuid}) if (defined($self->{-uuid}));
+ if ($self->{-rc} != $self->UUID_RC_OK) {
+ carp(sprintf("OSSP::uuid::DESTROY: uuid_destroy: %s (%d)", uuid_error($self->{-rc}), $self->{-rc}));
+ return;
+ }
+ $self->{-uuid} = undef;
+ $self->{-rc} = undef;
+ return;
+}
+
+sub load ($$) {
+ my ($self, $name) = @_;
+ $self->{-rc} = uuid_load($self->{-uuid}, $name);
+ return ($self->{-rc} == $self->UUID_RC_OK);
+}
+
+sub make ($$;@) {
+ my ($self, $mode, @valist) = @_;
+ my $mode_code = 0;
+ foreach my $spec (split(/,/, $mode)) {
+ if ($spec eq 'v1') { $mode_code |= $self->UUID_MAKE_V1; }
+ elsif ($spec eq 'v3') { $mode_code |= $self->UUID_MAKE_V3; }
+ elsif ($spec eq 'v4') { $mode_code |= $self->UUID_MAKE_V4; }
+ elsif ($spec eq 'v5') { $mode_code |= $self->UUID_MAKE_V5; }
+ elsif ($spec eq 'mc') { $mode_code |= $self->UUID_MAKE_MC; }
+ else { croak("invalid mode specification \"$spec\""); }
+ }
+ if (($mode_code & $self->UUID_MAKE_V3) or ($mode_code & $self->UUID_MAKE_V5)) {
+ if (not (ref($valist[0]) and $valist[0]->isa("OSSP::uuid"))) {
+ croak("UUID_MAKE_V3/UUID_MAKE_V5 requires namespace argument to be OSSP::uuid object");
+ }
+ my $ns = $valist[0]->{-uuid};
+ my $name = $valist[1];
+ $self->{-rc} = uuid_make($self->{-uuid}, $mode_code, $ns, $name);
+ }
+ else {
+ $self->{-rc} = uuid_make($self->{-uuid}, $mode_code);
+ }
+ return ($self->{-rc} == $self->UUID_RC_OK);
+}
+
+sub isnil ($) {
+ my ($self) = @_;
+ my $result;
+ $self->{-rc} = uuid_isnil($self->{-uuid}, $result);
+ return ($self->{-rc} == $self->UUID_RC_OK ? $result : undef);
+}
+
+sub compare ($$) {
+ my ($self, $other) = @_;
+ my $result = 0;
+ if (not (ref($other) and $other->isa("OSSP::uuid"))) {
+ croak("argument has to an OSSP::uuid object");
+ }
+ $self->{-rc} = uuid_compare($self->{-uuid}, $other->{-uuid}, $result);
+ return ($self->{-rc} == $self->UUID_RC_OK ? $result : undef);
+}
+
+sub import {
+ # ATTENTION: The OSSP uuid API function "import" conflicts with
+ # the standardized "import" method the Perl world expects from
+ # their modules. In order to keep the Perl binding consist
+ # with the C API, we solve the conflict under run-time by
+ # distinguishing between the two types of "import" calls.
+ if (defined($_[0]) and ref($_[0]) =~ m/^OSSP::uuid/) {
+ # the regular OSSP::uuid "import" method
+ croak("import method expects 3 or 4 arguments") if (@_ < 3 or @_ > 4); # emulate prototype
+ my ($self, $fmt, $data_ptr, $data_len) = @_;
+ if ($fmt eq 'bin') { $fmt = $self->UUID_FMT_BIN; }
+ elsif ($fmt eq 'str') { $fmt = $self->UUID_FMT_STR; }
+ elsif ($fmt eq 'siv') { $fmt = $self->UUID_FMT_SIV; }
+ elsif ($fmt eq 'txt') { $fmt = $self->UUID_FMT_TXT; }
+ else { croak("invalid format \"$fmt\""); }
+ $data_len ||= length($data_ptr); # functional redudant, but Perl dislikes undef value here
+ $self->{-rc} = uuid_import($self->{-uuid}, $fmt, $data_ptr, $data_len);
+ return ($self->{-rc} == $self->UUID_RC_OK);
+ }
+ else {
+ # the special Perl "import" method
+ # (usually inherited from the Exporter)
+ no strict "refs";
+ return OSSP::uuid->export_to_level(1, @_);
+ }
+}
+
+sub export {
+ # ATTENTION: The OSSP uuid API function "export" conflicts with
+ # the standardized "export" method the Perl world expects from
+ # their modules. In order to keep the Perl binding consist
+ # with the C API, we solve the conflict under run-time by
+ # distinguishing between the two types of "export" calls.
+ if (defined($_[0]) and ref($_[0]) =~ m/^OSSP::uuid/) {
+ # the regular OSSP::uuid "export" method
+ croak("export method expects 2 arguments") if (@_ != 2); # emulate prototype
+ my ($self, $fmt) = @_;
+ my $data_ptr;
+ if ($fmt eq 'bin') { $fmt = $self->UUID_FMT_BIN; }
+ elsif ($fmt eq 'str') { $fmt = $self->UUID_FMT_STR; }
+ elsif ($fmt eq 'siv') { $fmt = $self->UUID_FMT_SIV; }
+ elsif ($fmt eq 'txt') { $fmt = $self->UUID_FMT_TXT; }
+ else { croak("invalid format \"$fmt\""); }
+ $self->{-rc} = uuid_export($self->{-uuid}, $fmt, $data_ptr, undef);
+ return ($self->{-rc} == $self->UUID_RC_OK ? $data_ptr : undef);
+ }
+ else {
+ # the special Perl "export" method
+ # (usually inherited from the Exporter)
+ return Exporter::export(@_);
+ }
+}
+
+sub error ($;$) {
+ my ($self, $rc) = @_;
+ $rc = $self->{-rc} if (not defined($rc));
+ return wantarray ? (uuid_error($rc), $rc) : uuid_error($rc);
+}
+
+sub version (;$) {
+ my ($self) = @_;
+ return uuid_version();
+}
+
+##
+## Low-Level Perl XS C-style API
+## (actually just the activation of the XS part)
+##
+
+# auto-loading constants
+sub AUTOLOAD {
+ my $constname;
+ our $AUTOLOAD;
+ ($constname = $AUTOLOAD) =~ s/.*:://;
+ croak "&OSSP::uuid::constant not defined" if ($constname eq 'constant');
+ my ($error, $val) = constant($constname);
+ croak $error if ($error);
+ { no strict 'refs'; *$AUTOLOAD = sub { $val }; }
+ goto &$AUTOLOAD;
+}
+
+# static-loading functions
+XSLoader::load('OSSP::uuid', $VERSION);
+
+1;
+
bgstack15