File Coverage

blib/lib/Metadata/SOIF.pm
Criterion Covered Total %
statement 76 99 76.7
branch 24 42 57.1
condition 3 10 30.0
subroutine 11 14 78.5
pod 9 10 90.0
total 123 175 70.2


line stmt bran cond sub pod time code
1             # Hey emacs, this is -*-perl-*- !
2             #
3             # $Id: SOIF.pm,v 1.10 2001/01/09 12:04:12 cmdjb Exp $
4             #
5             # Metadata::SOIF - Harvest Structured Objects Interchange Format class
6             #
7             # Copyright (C) 1997-2001 Dave Beckett - http://purl.org/net/dajobe/
8             # All rights reserved.
9             #
10             # This module is free software; you can redistribute it and/or modify
11             # it under the same terms as Perl itself.
12             #
13              
14             package Metadata::SOIF;
15              
16             require 5.004;
17              
18 1     1   15344 use strict;
  1         2  
  1         47  
19 1     1   6 use vars qw(@ISA $VERSION $Debug %Default_Options);
  1         2  
  1         84  
20              
21 1     1   7 use Carp;
  1         3  
  1         76  
22              
23 1     1   828 use Metadata::Base;
  1         2  
  1         1410  
24              
25             @ISA = qw( Metadata::Base );
26             $VERSION = sprintf("%d.%02d", ('$Revision: 1.10 $ ' =~ /\$Revision:\s+(\d+)\.(\d+)/));
27              
28             %Default_Options=(
29             TEMPLATE_TYPE => 'FILE',
30             URL => '',
31             SPLIT => '0',
32             DEBUG => '0',
33             );
34              
35              
36             # Class debugging
37             $Debug = 0;
38              
39             sub debug {
40 0     0 1 0 my $self=shift;
41             # Object debug - have an object reference
42 0 0       0 if (ref ($self)) {
43 0         0 my $old=$self->{DEBUG};
44 0 0       0 $self->{DEBUG}=@_ ? shift : 1;
45 0         0 $self->SUPER::debug($self->{DEBUG});
46 0         0 return $old;
47             }
48              
49             # Class debug (self is debug level)
50 0 0       0 return $Debug if !defined $self; # Careful, could be debug(0)
51              
52 0         0 my $old=$Debug;
53 0         0 $Default_Options{DEBUG}=$Debug=$self;
54 0         0 Metadata::Base::debug($Debug);
55 0         0 $old;
56             }
57              
58 0     0 0 0 sub whowasi { (caller(1))[3] }
59              
60              
61             # Constructor
62             sub new {
63 5     5 1 2506 my $proto =shift;
64 5   33     29 my $class = ref($proto) || $proto;
65 5         11 my $options= { @_ };
66 5         11 $options->{ORDERED}=1;
67 5         18 for (keys %Default_Options) {
68 20 50       67 $options->{$_}=$Default_Options{$_} unless defined $options->{$_};
69             }
70              
71 5         99 my $self = $class->SUPER::new($options);
72 5         9 bless $self, $class;
73 5         12 return $self;
74             }
75              
76              
77             # Clone
78             sub clone ($) {
79 0     0 1 0 my $self=shift;
80              
81 0         0 my $copy = $self->SUPER::clone;
82              
83 0         0 $copy->{TEMPLATE_TYPE}= $self->{TEMPLATE_TYPE};
84 0         0 $copy->{URL}= $self->{URL};
85              
86 0         0 $copy;
87             }
88              
89              
90             sub template_type ($;$) {
91 4     4 1 10 my $self=shift;
92 4 100       13 return $self->{TEMPLATE_TYPE} if !@_;
93              
94 3         4 my $old=$self->{TEMPLATE_TYPE};
95 3         6 $self->{TEMPLATE_TYPE}=shift;
96 3         6 $old;
97             }
98              
99              
100             sub url ($;$) {
101 7     7 1 15 my $self=shift;
102 7 100       19 return $self->{URL} if !@_;
103              
104 4         7 my $old=$self->{URL};
105 4         6 $self->{URL}=shift;
106 4         13 $old;
107             }
108              
109              
110             sub read ($$;$) {
111 2     2 1 268 my $self = shift;
112 2         4 my $fh=shift;
113              
114 2         11 $self->clear;
115              
116 2 50       25 return undef if eof($fh);
117              
118 2         3 my $seen_url=0;
119 2 50 0     7 $self->url(shift) and $seen_url=1 if @_;
120              
121 2         2 my $count=0;
122 2         12 while(<$fh>) {
123 9 50       22 warn "@{[&whowasi]}: Read line: '$_'\n" if $self->{DEBUG};
  0         0  
124 9 100       108 if (/^\}/) {
    100          
    50          
125 2         3 last;
126             } elsif (my($template_type,$url)=/^\@\s*(\S+)\s*\{\s*(\S+)\s*$/o) {
127 2 50       6 warn "@{[&whowasi]}: Read Template Type '$template_type' URL '$url'\n" if $self->{DEBUG};
  0         0  
128 2         7 $self->template_type($template_type);
129 2 50 50     7 $self->url($url) and $seen_url=1 unless $seen_url;
130             } elsif (my($element,$rest_length,$value)=/^\s*([^{]+)\{(\d+)\}:\t(.*)$/so) {
131 5         7 my $value_length=length($value)-1; # -1 off for for NL, removed below
132 5 50       11 $value_length=0 if $value_length<0; # however handle 0 length value
133 5         9 $rest_length-= $value_length;
134 5 100       9 if ($rest_length>0) {
135 1         2 $value_length++; # Append after newline
136 1         14 my $read_length=read($fh,$value,$rest_length, $value_length);
137 1 50       5 croak "Cannot read $rest_length bytes (read $read_length) - $!\n"
138             if $read_length != $rest_length;
139             }
140 5         9 chomp $value; # extra newline removed here
141             # Split values on newlines into sub-values, maybe
142 5         6 my(@v);
143 5 50 33     17 if ($self->{SPLIT} && ((@v)=split(/\n/, $value)) > 1) {
144 0         0 $self->set($element, \@v);
145             } else {
146 5         16 $self->set($element, $value);
147             }
148 5         97 $count++;
149             } else {
150 0         0 warn "@{[&whowasi]}:$.: Do not understand line '$_'\n";
  0         0  
151             }
152             }
153            
154 2 50       7 warn "@{[&whowasi]}: Read $count elements\n" if $self->{DEBUG};
  0         0  
155 2         5 return 1;
156             }
157              
158              
159             sub format ($;$) {
160 2     2 1 208 my $self=shift;
161 2 100       9 $self->url(shift) if @_;
162              
163 2         5 my $url=$self->url;
164 2         6 my $string="\@$self->{TEMPLATE_TYPE} {";
165 2 50       9 $string.= $url ? " $url\n" : "\n";
166 2         11 for my $element ($self->order) {
167 3         9 my $value=join("\n",grep (defined $_, $self->get($element) ));
168 3         13 $string.="$element\{".length($value)."\}:\t".$value."\n";
169             }
170 2         520 return $string."}\n";
171             }
172              
173              
174             # Pack Template Type and URL too
175             sub pack ($) {
176 1     1 1 8 my $self=shift;
177 1         8 my $string=$self->SUPER::pack;
178              
179             # Use the knowledge that Metadata::Base uses 'thing\0' for fields
180 1         5 return join("\001", $self->{TEMPLATE_TYPE}, $self->{URL}, $string);
181             }
182              
183              
184             sub unpack ($$) {
185 1     1 1 6 my $self=shift;
186 1         5 my($tt,$url,$string)=split(/\001/, shift);
187 1         8 $self->SUPER::unpack($string);
188 1         2 $self->{TEMPLATE_TYPE}=$tt;
189 1         3 $self->{URL}=$url;
190             }
191              
192              
193             1;
194             __END__