wire up checksum to create_close/file_info/create_class commands
[MogileFS-Server.git] / lib / MogileFS / Checksum.pm
blobda016f28e501227b0e1a4a2afbb4b0466ae33d14
1 package MogileFS::Checksum;
2 use strict;
3 use warnings;
4 use overload '""' => \&as_string;
6 my %TYPE = (
7 "MD5" => { type => 1, bytelen => 128 / 8 },
8 "SHA-1" => { type => 2, bytelen => 160 / 8 },
9 "SHA-224" => { type => 3, bytelen => 224 / 8 },
10 "SHA-256" => { type => 4, bytelen => 256 / 8 },
11 "SHA-384" => { type => 5, bytelen => 384 / 8 },
12 "SHA-512" => { type => 6, bytelen => 512 / 8 },
15 our %NAME2TYPE = map { $_ => $TYPE{$_}->{type} } keys(%TYPE);
16 our %TYPE2NAME = map { $NAME2TYPE{$_} => $_ } keys(%NAME2TYPE);
18 sub new {
19 my ($class, $row) = @_;
20 my $self = bless {
21 fidid => $row->{fid},
22 checksum => $row->{checksum},
23 checksumtype => $row->{checksumtype}
24 }, $class;
26 return $self;
29 # $string = "MD5:d41d8cd98f00b204e9800998ecf8427e"
30 sub from_string {
31 my ($class, $fidid, $string) = @_;
32 $string =~ /\A([\w-]+):([a-fA-F0-9]{32,128})\z/ or
33 die "invalid checksum string";
34 my $checksumname = $1;
35 my $hexdigest = $2;
36 my $ref = $TYPE{$checksumname} or
37 die "invalid checksum name ($checksumname) from $string";
38 my $checksum = pack("H*", $hexdigest);
39 my $len = length($checksum);
40 $len == $ref->{bytelen} or
41 die "invalid checksum length=$len (expected $ref->{bytelen})";
43 bless {
44 fidid => $fidid,
45 checksum => $checksum,
46 checksumtype => $NAME2TYPE{$checksumname},
47 }, $class;
50 sub checksumname {
51 my $self = shift;
52 my $type = $self->{checksumtype};
53 my $name = $TYPE2NAME{$type} or die "checksumtype=$type unknown";
55 return $name;
58 sub save {
59 my $self = shift;
60 my $sto = Mgd::get_store();
62 $sto->set_checksum($self->{fidid}, $self->{checksumtype}, $self->{checksum});
65 sub maybe_save {
66 my ($self, $dmid, $classid) = @_;
67 my $class = eval { Mgd::class_factory()->get_by_id($dmid, $classid) };
69 # $class may be undef as it could've been deleted between
70 # create_open and create_close, we've never verified this before...
71 if ($class && $self->{checksumtype} eq $class->{checksumtype}) {
72 $self->save;
76 sub hexdigest {
77 my $self = shift;
79 unpack("H*", $self->{checksum});
82 sub as_string {
83 my $self = shift;
84 my $name = $self->checksumname;
85 my $hexdigest = $self->hexdigest;
87 "Checksum[f=$self->{fidid};$name=$hexdigest]"
90 sub info {
91 my $self = shift;
93 $self->checksumname . ':' . $self->hexdigest;