File Coverage

blib/lib/Data/Nested/Multifile.pm
Criterion Covered Total %
statement 366 541 67.6
branch 121 202 59.9
condition 11 21 52.3
subroutine 35 40 87.5
pod 26 26 100.0
total 559 830 67.3


line stmt bran cond sub pod time code
1             package Data::Nested::Multifile;
2             # Copyright (c) 2007-2010 Sullivan Beck. All rights reserved.
3             # This program is free software; you can redistribute it and/or modify it
4             # under the same terms as Perl itself.
5              
6             ###############################################################################
7             # GLOBAL VARIABLES
8             ###############################################################################
9              
10             ###############################################################################
11             # TODO
12             ###############################################################################
13              
14             ###############################################################################
15              
16             require 5.000;
17 28     28   29826 use strict;
  28         63  
  28         1214  
18 28     28   153 use warnings;
  28         45  
  28         902  
19 28     28   24556 use YAML::Syck;
  28         75137  
  28         2307  
20 28     28   39852 use Data::Nested;
  28         104  
  28         1212  
21 28     28   32937 use Data::Nested::Multiele;
  28         113  
  28         2410  
22 28     28   186 use Storable qw(dclone);
  28         58  
  28         2030  
23              
24 28     28   162 use vars qw($VERSION);
  28         59  
  28         166809  
25             $VERSION = "3.12";
26              
27             ###############################################################################
28             # BASE METHODS
29             ###############################################################################
30             #
31             # $NDS always refers to a Data::Nested object
32             # $NME always refers to a Data::Nested::Multiele object
33             # $nds always refers to an actual NDS
34             # $ele always refers to an element name/index
35             # $self always refers to a Data::Nested::Multiele object
36              
37             sub new {
38 28     28 1 113322 my(@args) = @_;
39              
40             # Get the Data::Nested object (if any).
41              
42 28         107 my $class = "Data::Nested::Multifile";
43 28         74 my $NDS = undef;
44              
45 28 50 33     666 if (@args && ref($args[0]) eq $class) {
    50 33        
46             # $obj = $self->new;
47              
48 0         0 my $self = shift(@args);
49 0         0 $NDS = $self->nds();
50              
51             } elsif (@args && $args[0] eq $class) {
52             # $obj = new Data::Nested::Multifile [NDS];
53              
54 28         78 shift(@args);
55 28 50 33     285 if (@args && ref($args[0]) eq "Data::Nested") {
56 0         0 $NDS = shift(@args);
57             } else {
58 28         286 $NDS = new Data::Nested;
59             }
60              
61             } else {
62 0         0 warn "ERROR: [new] first argument must be a $class class/object\n";
63 0         0 return undef;
64             }
65              
66             # Get the label/file args (if any)
67              
68 28         91 my @file = @args;
69              
70 28         313 my $self = {
71             "nds" => $NDS, # Data::Nested object
72             "file" => undef, # LABEL => Data::Nested::Multiele
73             "labels" => [], # The order the labels are read in
74             "list" => "", # 1 if data is a list
75             "err" => "",
76             "errmsg" => "",
77             "elesx" => undef, # Existing elements
78             "elesn" => undef, # Non-empty elements
79             "eles" => {}, # [ LABEL, FILE_ELE ]
80             # Which file an element is in, and
81             # the element in that file (this
82             # differs for lists)
83             };
84 28         112 bless $self, $class;
85              
86 28 50       130 if (@file) {
87 0         0 $self->file(@file);
88 0 0       0 if ($self->err()) {
89 0         0 return undef;
90             }
91             }
92              
93 28         124 return $self;
94             }
95              
96             sub version {
97 0     0 1 0 my($self) = @_;
98              
99 0         0 return $VERSION;
100             }
101              
102             sub nds {
103 28     28 1 82 my($self) = @_;
104              
105 28         111 return $$self{"nds"};
106             }
107              
108             sub err {
109 166     166 1 426 my($self) = @_;
110              
111 166         510 return $$self{"err"};
112             }
113              
114             sub errmsg {
115 0     0 1 0 my($self) = @_;
116              
117 0         0 return $$self{"errmsg"};
118             }
119              
120             sub nme {
121 0     0 1 0 my($self,$label) = @_;
122              
123 0 0       0 return $$self{"file"}{$label} if (exists $$self{"file"}{$label});
124 0         0 return undef;
125             }
126              
127             ###############################################################################
128             # FILE METHODS
129             ###############################################################################
130              
131             sub file {
132 28     28 1 1514 my($self,@args) = @_;
133 28         211 $$self{"err"} = "";
134 28         85 $$self{"errmsg"} = "";
135              
136 28 50       145 if (defined $$self{"elesx"}) {
137 0         0 $$self{"err"} = "nmffil07";
138 0         0 $$self{"errmsg"} = "An attempt to read in a file after element operations " .
139             "have been done";
140 0         0 return;
141             }
142              
143 28 50       191 $$self{"file"} = {} if (! defined $$self{"file"});
144              
145 28 50 33     326 if ($#args == 0 ||
146             $#args % 2 == 0) {
147 0         0 $$self{"err"} = "nmffil01";
148 0         0 $$self{"errmsg"} = "An even number of arguments required to specify " .
149             "files";
150 0         0 return;
151             }
152              
153 28         183 my $NDS = $self->nds();
154              
155 28         152 while (@args) {
156 56         145 my $label = shift(@args);
157 56         388 my $file = shift(@args);
158              
159             # Check the label
160              
161 56 100       213 if (exists $$self{"file"}{$label}) {
162 2         6 $$self{"err"} = "nmffil02";
163 2         9 $$self{"errmsg"} = "An attempt to reuse a file label already in " .
164             "use: $label";
165 2         7 return;
166             }
167              
168             # Create a Data::Nested::Multiele object for the file
169              
170 54         566 my $obj = new Data::Nested::Multiele($NDS,$file);
171              
172 54 50       190 if (! defined $obj) {
173 0         0 $$self{"err"} = "nmffil03";
174 0         0 $$self{"errmsg"} = "An error occurred reading the data file: $file";
175 0         0 return;
176             }
177              
178             # Check to see that all files contain either lists or hashes
179              
180 54 100       340 if ($$self{"list"} eq "") {
    50          
181 28         84 $$self{"list"} = $$obj{"list"};
182             } elsif ($$self{"list"} != $$obj{"list"}) {
183 0         0 $$self{"err"} = "nmffil04";
184 0         0 $$self{"errmsg"} = "All files must contain the same type of data: " .
185             "$file";
186 0         0 return;
187             }
188              
189             # Save the label
190              
191 54         182 $$self{"file"}{$label} = $obj;
192 54         97 push(@{ $$self{"labels"} },$label);
  54         157  
193              
194 54         196 my $err = _eles_label($self,$label);
195 54 50       2296 return if ($err);
196             }
197             }
198              
199             ###############################################################################
200             # ELEMENT EXISTANCE METHODS
201             ###############################################################################
202              
203             # Get the elements that are in a given label (that is being read in).
204             #
205             sub _eles_label {
206 180     180   293 my($self,$label) = @_;
207              
208 180         405 my $NME = $$self{"file"}{$label};
209              
210 180         645 my @elesx = $NME->eles(1);
211 180 50       552 if ($NME->err()) {
212 0         0 $$self{"err"} = $NME->err();
213 0         0 $$self{"errmsg"} = $NME->errmsg() . ": $label";
214 0         0 return 1;
215             }
216              
217 180         259 my $i0;
218 180 100       505 if ($$self{"list"}) {
219 43         51 my @tmp = CORE::keys %{ $$self{"eles"} };
  43         133  
220 43 100       125 if (@tmp) {
221 21         72 @tmp = sort { $a <=> $b } @tmp;
  28         59  
222 21         53 $i0 = pop(@tmp) + 1;
223             } else {
224 22         43 $i0 = 0;
225             }
226             }
227              
228 180         352 foreach my $ele (@elesx) {
229 658         790 my $e = $ele;
230 658 100       1405 $e = $ele + $i0 if ($$self{"list"});
231              
232 658 50       1519 if (exists $$self{"eles"}{$e}) {
233 0         0 my $other = $$self{"eles"}{$e}[0];
234 0         0 $$self{"err"} = "nmffil05";
235 0         0 $$self{"errmsg"} = "A data element is duplicated in 2 files: " .
236             "$ele [$other, $label]";
237 0         0 return 1;
238             }
239              
240 658 100       1098 if ($$self{"list"}) {
241 106         438 $$self{"eles"}{$e} = [$label,$ele];
242             } else {
243 552         1939 $$self{"eles"}{$e} = [ $label,$ele ];
244             }
245             }
246             }
247              
248             # If $op is:
249             # "" Get all the elements from all the labels.
250             # exists Get all elements that exist
251             # nonempty Get all nonempty elements
252             #
253             sub _eles {
254 89     89   175 my($self,$op) = @_;
255 89 100       209 $op = "" if (! $op);
256              
257 89 50       269 if ($op eq "exists") {
    100          
258 0 0       0 return if (defined $$self{"elesx"});
259 0         0 my @tmp = CORE::keys %{ $$self{"eles"} };
  0         0  
260 0 0       0 if ($$self{"list"}) {
261 0         0 $$self{"elesx"} = [ sort { $a <=> $b } @tmp ];
  0         0  
262             } else {
263 0         0 $$self{"elesx"} = [ sort @tmp ];
264             }
265              
266             } elsif ($op eq "nonempty") {
267              
268 26 100       54 if ($$self{"list"}) {
269 11         14 my @tmp;
270 11         14 my $n = 0;
271 11         15 foreach my $label (@{ $$self{"labels"} }) {
  11         25  
272 22         46 my $NME = $$self{"file"}{$label};
273 22         59 my @tmp2 = $NME->eles();
274 22         36 push(@tmp,map { $_+$n } @tmp2);
  45         100  
275 22         64 @tmp2 = $NME->eles(1);
276 22         60 $n += $#tmp2 + 1;
277             }
278 11         202 $$self{"elesn"} = [ @tmp ];
279              
280             } else {
281 15         20 my @tmp;
282 15         16 foreach my $label (@{ $$self{"labels"} }) {
  15         32  
283 30         109 my $NME = $$self{"file"}{$label};
284 30         86 push(@tmp,$NME->eles());
285             }
286 15         75 $$self{"elesn"} = [ sort @tmp ];
287             }
288              
289             } else {
290 63         97 $$self{"elesx"} = undef;
291 63         89 $$self{"elesn"} = undef;
292 63         114 $$self{"eles"} = {};
293 63         277 foreach my $label (@{ $$self{"labels"} }) {
  63         145  
294 126         242 my $err = _eles_label($self,$label);
295 126 50       468 return if ($err);
296             }
297             }
298             }
299              
300             sub eles {
301 26     26 1 5241 my($self,$exists) = @_;
302 26         49 $$self{"err"} = "";
303 26         42 $$self{"errmsg"} = "";
304              
305 26 50       166 if (! defined $$self{"file"}) {
306 0         0 $$self{"err"} = "nmffil08";
307 0         0 $$self{"errmsg"} = "No file set.";
308             }
309              
310 26 50       57 if ($exists) {
311 0         0 _eles($self,"exists");
312 0         0 return @{ $$self{"elesx"} };
  0         0  
313             } else {
314 26         65 _eles($self,"nonempty");
315 26         38 return @{ $$self{"elesn"} };
  26         127  
316             }
317             }
318              
319             sub ele {
320 127     127 1 2046 my($self,$ele,$exists) = @_;
321 127         217 $$self{"err"} = "";
322 127         175 $$self{"errmsg"} = "";
323              
324 127 50       304 if (! defined $$self{"file"}) {
325 0         0 $$self{"err"} = "nmffil08";
326 0         0 $$self{"errmsg"} = "No file set.";
327             }
328              
329 127 100       341 return 0 if (! exists $$self{"eles"}{$ele});
330 125 100       272 return 1 if ($exists);
331              
332 111         133 my($label,$fele) = @{ $$self{"eles"}{$ele} };
  111         284  
333 111         213 my $NME = $$self{"file"}{$label};
334              
335 111         355 my $ret = $NME->ele($fele,$exists);
336 111 50       383 if ($NME->err()) {
337 0         0 $$self{"err"} = $NME->err();
338 0         0 $$self{"errmsg"} = $NME->errmsg() . ": $label";
339 0         0 return undef;
340             }
341              
342 111         339 return $ret;
343             }
344              
345             sub ele_file {
346 11     11 1 30 my($self,$ele) = @_;
347              
348 11 50       27 if (! defined $$self{"file"}) {
349 0         0 $$self{"err"} = "nmffil08";
350 0         0 $$self{"errmsg"} = "No file set.";
351             }
352              
353 11 50       23 if (! $self->ele($ele)) {
354 0         0 $$self{"err"} = "nmfele01";
355 0         0 $$self{"errmsg"} = "The specified element does not exist: $ele";
356 0         0 return "";
357             }
358              
359 11         30 return $$self{"eles"}{$ele}[0];
360             }
361              
362             sub _ele_nme {
363 90     90   263 my($self,$ele) = @_;
364              
365 90 50       206 if (! $self->ele($ele)) {
366 0         0 $$self{"err"} = "nmfele01";
367 0         0 $$self{"errmsg"} = "The specified element does not exist: $ele";
368 0         0 return "";
369             }
370              
371 90         220 my $label = $$self{"eles"}{$ele}[0];
372 90         162 my $fele = $$self{"eles"}{$ele}[1];
373 90         329 return ($$self{"file"}{$label},$fele);
374             }
375              
376             ###############################################################################
377             # DEFAULT METHODS
378             ###############################################################################
379              
380             sub default_element {
381 48     48 1 2320 my($self,@args) = @_;
382 48         92 $$self{"err"} = "";
383 48         73 $$self{"errmsg"} = "";
384              
385 48 50       234 if (! defined $$self{"file"}) {
386 0         0 $$self{"err"} = "nmffil08";
387 0         0 $$self{"errmsg"} = "No file set.";
388             }
389              
390             # Any element which works with the data will have set "elesx", so if
391             # it is set, the operation fails.
392              
393 48 50       112 if (defined $$self{"elesx"}) {
394 0         0 $$self{"err"} = "nmedef09";
395 0         0 $$self{"errmsg"} = "Defaults must be set immediately after the filef " .
396             "are read in.";
397 0         0 return;
398             }
399              
400             # Get the Multiele object containing the default.
401              
402 48         61 my $label;
403 48 100       104 if ($$self{"list"}) {
404             #
405             # Lists = (LABEL [RULESET] [PATH,VAL,...])
406             #
407 6         10 $label = shift(@args);
408 6 50       19 if (! exists $$self{"file"}{$label}) {
409 0         0 $$self{"err"} = "nmffil06";
410 0         0 $$self{"errmsg"} = "An invalid file label was used: $label";
411 0         0 return undef;
412             }
413              
414             } else {
415             #
416             # Hashes = (ELE [RULESET] [PATH,VAL,...])
417             #
418 42         54 my $ele = $args[0];
419 42 50       111 if (! exists $$self{"eles"}{$ele}) {
420 0         0 $$self{"err"} = "nmfele01";
421 0         0 $$self{"errmsg"} = "Attempt to access an undefined element: $ele";
422 0         0 return undef;
423             }
424 42         103 $label = $$self{"eles"}{$ele}[0];
425             }
426              
427 48         91 my $NME = $$self{"file"}{$label};
428              
429             # Handle the default.
430              
431 48         160 $NME->default_element(@args);
432 48 50       129 if ($NME->err()) {
433 0         0 $$self{"err"} = $NME->err();
434 0         0 $$self{"errmsg"} = $NME->errmsg() . ": $label";
435 0         0 return undef;
436             }
437              
438 48         190 _eles($self);
439             }
440              
441             sub is_default_value {
442 14     14 1 2465 my($self,$ele,$path) = @_;
443 14         27 $$self{"err"} = "";
444 14         22 $$self{"errmsg"} = "";
445              
446 14 50       36 if (! defined $$self{"file"}) {
447 0         0 $$self{"err"} = "nmffil08";
448 0         0 $$self{"errmsg"} = "No file set.";
449             }
450              
451 14 50       36 if (! $self->ele($ele,1)) {
452 0         0 $$self{"err"} = "nmfele01";
453 0         0 $$self{"errmsg"} = "The specified element does not exist: $ele";
454 0         0 return;
455             }
456              
457 14 50       36 if (! $self->path_valid($path)) {
458 0         0 $$self{"err"} = "nmeacc03";
459 0         0 $$self{"errmsg"} = "Attempt to access data with an invalid path: $path";
460 0         0 return undef;
461             }
462              
463 14         21 my($label,$fele) = @{ $$self{"eles"}{$ele} };
  14         34  
464 14         27 my $NME = $$self{"file"}{$label};
465              
466 14         51 my $ret = $NME->is_default_value($fele,$path);
467 14 50       40 if ($NME->err()) {
468 0         0 $$self{"err"} = $NME->err();
469 0         0 $$self{"errmsg"} = $NME->errmsg() . ": $label";
470 0         0 return undef;
471             }
472              
473 14         55 return $ret;
474             }
475              
476             ###############################################################################
477             # WHICH METHOD
478             ###############################################################################
479              
480             sub which {
481 68     68 1 19138 my($self,@cond) = @_;
482              
483 68 50       209 if (! defined $$self{"file"}) {
484 0         0 $$self{"err"} = "nmffil08";
485 0         0 $$self{"errmsg"} = "No file set.";
486             }
487              
488 68 100       181 if ($$self{"list"}) {
489 34         86 return _which_list($self,@cond);
490             } else {
491 34         83 return _which_hash($self,@cond);
492             }
493             }
494              
495             sub _which_list {
496 34     34   77 my($self,@cond) = @_;
497              
498 34         54 my @ele = ();
499 34         46 my $n = 0;
500 34         36 foreach my $label (@{ $$self{"labels"} }) {
  34         78  
501 68         146 my $NME = $$self{"file"}{$label};
502              
503 68         229 my @tmp = $NME->which(@cond);
504 68 50       183 if ($NME->err()) {
505 0         0 $$self{"err"} = $NME->err();
506 0         0 $$self{"errmsg"} = $NME->errmsg() . ": $label";
507 0         0 return ();
508             }
509              
510 68         115 push @ele, map { $_ + $n } @tmp;
  102         202  
511              
512 68         222 @tmp = $NME->eles(1);
513 68         215 $n += $#tmp + 1;
514             }
515              
516 34         197 return @ele;
517             }
518              
519             sub _which_hash {
520 34     34   83 my($self,@cond) = @_;
521              
522 34         51 my @ele = ();
523 34         44 while (my($label,$NME) = each %{ $$self{"file"} }) {
  102         388  
524 68         214 my @tmp = $NME->which(@cond);
525 68 50       190 if ($NME->err()) {
526 0         0 $$self{"err"} = $NME->err();
527 0         0 $$self{"errmsg"} = $NME->errmsg() . ": $label";
528 0         0 return ();
529             }
530 68         199 push(@ele,@tmp);
531             }
532 34         95 @ele = sort @ele;
533 34         230 return @ele;
534             }
535              
536             ###############################################################################
537             # PATH_VALID METHOD
538             ###############################################################################
539              
540             sub path_valid {
541 16     16 1 572 my($self,$path) = @_;
542 16         27 my $NDS = $$self{"nds"};
543              
544 16         52 return $NDS->get_structure($path,"valid");
545             }
546              
547             ###############################################################################
548             # VALUE, KEYS, VALUES METHODS
549             ###############################################################################
550              
551             sub value {
552 35     35 1 4010 my($self,$ele,$path,@args) = @_;
553 35         65 $$self{"err"} = "";
554 35         55 $$self{"errmsg"} = "";
555              
556 35 50       90 if (! defined $$self{"file"}) {
557 0         0 $$self{"err"} = "nmffil08";
558 0         0 $$self{"errmsg"} = "No file set.";
559             }
560              
561 35         36 my $NME;
562 35         75 ($NME,$ele) = _ele_nme($self,$ele);
563 35 50       87 return undef if ($self->err());
564              
565 35         151 my $val = $NME->value($ele,$path,@args);
566 35 100       97 if ($NME->err()) {
567 2         8 $$self{"err"} = $NME->err();
568 2         23 $$self{"errmsg"} = $NME->errmsg();
569 2         7 return undef;
570             }
571              
572 33         101 return $val;
573             }
574              
575             sub keys {
576 23     23 1 4515 my($self,$ele,$path,@args) = @_;
577 23         52 $$self{"err"} = "";
578 23         39 $$self{"errmsg"} = "";
579              
580 23 50       81 if (! defined $$self{"file"}) {
581 0         0 $$self{"err"} = "nmffil08";
582 0         0 $$self{"errmsg"} = "No file set.";
583             }
584              
585 23         29 my $NME;
586 23         55 ($NME,$ele) = _ele_nme($self,$ele);
587 23 50       66 return undef if ($self->err());
588              
589 23         89 my @val = $NME->keys($ele,$path,@args);
590 23 100       82 if ($NME->err()) {
591 1         12 $$self{"err"} = $NME->err();
592 1         6 $$self{"errmsg"} = $NME->errmsg();
593 1         5 return undef;
594             }
595              
596 22         95 return @val;
597             }
598              
599             sub values {
600 23     23 1 3365 my($self,$ele,$path,@args) = @_;
601 23         44 $$self{"err"} = "";
602 23         35 $$self{"errmsg"} = "";
603              
604 23 50       57 if (! defined $$self{"file"}) {
605 0         0 $$self{"err"} = "nmffil08";
606 0         0 $$self{"errmsg"} = "No file set.";
607             }
608              
609 23         24 my $NME;
610 23         44 ($NME,$ele) = _ele_nme($self,$ele);
611 23 50       70 return undef if ($self->err());
612              
613 23         93 my @val = $NME->values($ele,$path,@args);
614 23 100       69 if ($NME->err()) {
615 1         3 $$self{"err"} = $NME->err();
616 1         6 $$self{"errmsg"} = $NME->errmsg();
617 1         4 return undef;
618             }
619              
620 22         101 return @val;
621             }
622              
623             ###############################################################################
624             # PATH_VALUES METHOD
625             ###############################################################################
626              
627             sub path_values {
628 4     4 1 6389 my($self,@args) = @_;
629 4         10 $$self{"err"} = "";
630 4         10 $$self{"errmsg"} = "";
631              
632 4 50       13 if (! defined $$self{"file"}) {
633 0         0 $$self{"err"} = "nmffil08";
634 0         0 $$self{"errmsg"} = "No file set.";
635             }
636              
637 4         8 my @ret;
638              
639 4         6 my $prev = 0;
640 4         7 foreach my $label (@{ $$self{"labels"} }) {
  4         18  
641 8         21 my $NME = $$self{"file"}{$label};
642              
643 8         64 my @tmp = $NME->path_values(@args);
644 8 50       28 if ($NME->err()) {
645 0         0 $$self{"err"} = $NME->err();
646 0         0 $$self{"errmsg"} = $NME->errmsg() . ": $label";
647 0         0 return ();
648             }
649              
650 8 100       22 if ($$self{"list"}) {
651 4         11 while (@tmp) {
652 3         4 my $e = shift(@tmp);
653 3         5 my $v = shift(@tmp);
654 3         12 push(@ret,$e+$prev,$v);
655             }
656 4         15 my @ele = $NME->eles(1);
657 4         14 $prev += $#ele + 1;
658             } else {
659 4         14 push(@ret,@tmp);
660             }
661             }
662              
663 4         82 return @ret;
664             }
665              
666             ###############################################################################
667             # PATH_IN_USE METHOD
668             ###############################################################################
669              
670             sub path_in_use {
671 2     2 1 647 my($self,@args) = @_;
672 2         6 $$self{"err"} = "";
673 2         4 $$self{"errmsg"} = "";
674              
675 2 50       9 if (! defined $$self{"file"}) {
676 0         0 $$self{"err"} = "nmffil08";
677 0         0 $$self{"errmsg"} = "No file set.";
678             }
679              
680 2         3 my @ret;
681              
682 2         4 my $prev = 0;
683 2         4 foreach my $label (@{ $$self{"labels"} }) {
  2         6  
684 3         71 my $NME = $$self{"file"}{$label};
685              
686 3         12 my $flag = $NME->path_in_use(@args);
687 3 50       11 if ($NME->err()) {
688 0         0 $$self{"err"} = $NME->err();
689 0         0 $$self{"errmsg"} = $NME->errmsg() . ": $label";
690 0         0 return undef;
691             }
692              
693 3 100       20 return 1 if ($flag);
694             }
695              
696 1         9 return 0;
697             }
698              
699             ###############################################################################
700             # DELETE_ELE METHOD
701             ###############################################################################
702              
703             sub delete_ele {
704 2     2 1 15 my($self,$ele) = @_;
705 2         5 $$self{"err"} = "";
706 2         6 $$self{"errmsg"} = "";
707              
708 2 50       10 if (! defined $$self{"file"}) {
709 0         0 $$self{"err"} = "nmffil08";
710 0         0 $$self{"errmsg"} = "No file set.";
711             }
712              
713 2         3 my $NME;
714 2         11 ($NME,$ele) = _ele_nme($self,$ele);
715 2 50       9 return undef if ($self->err());
716              
717 2         13 $NME->delete_ele($ele);
718 2 50       9 if ($NME->err()) {
719 0         0 $$self{"err"} = $NME->err();
720 0         0 $$self{"errmsg"} = $NME->errmsg();
721 0         0 return undef;
722             }
723              
724 2         7 _eles($self);
725 2         6 return;
726             }
727              
728             ###############################################################################
729             # RENAME_ELE METHOD
730             ###############################################################################
731              
732             sub rename_ele {
733 1     1 1 8 my($self,$ele,$newele) = @_;
734 1         3 $$self{"err"} = "";
735 1         3 $$self{"errmsg"} = "";
736              
737 1 50       5 if (! defined $$self{"file"}) {
738 0         0 $$self{"err"} = "nmffil08";
739 0         0 $$self{"errmsg"} = "No file set.";
740             }
741              
742 1         161 my $NME;
743 1         6 ($NME,$ele) = _ele_nme($self,$ele);
744 1 50       5 return undef if ($self->err());
745              
746 1         6 $NME->rename_ele($ele,$newele);
747 1 50       4 if ($NME->err()) {
748 0         0 $$self{"err"} = $NME->err();
749 0         0 $$self{"errmsg"} = $NME->errmsg();
750 0         0 return undef;
751             }
752              
753 1         4 _eles($self);
754 1         2 return;
755             }
756              
757             ###############################################################################
758             # ADD_ELE METHOD
759             ###############################################################################
760              
761             sub add_ele {
762 13     13 1 124 my($self,@args) = @_;
763              
764 13 50       93 if (! defined $$self{"file"}) {
765 0         0 $$self{"err"} = "nmffil08";
766 0         0 $$self{"errmsg"} = "No file set.";
767             }
768              
769 13 100       27 if ($$self{"list"}) {
770 6         18 return _add_ele_list($self,@args);
771             } else {
772 7         21 return _add_ele_hash($self,@args);
773             }
774             }
775              
776             sub _add_ele_list {
777 6     6   13 my($self,@args) = @_;
778              
779             # Parse arguments
780              
781 6         7 my($label,$ele,$nds,$new);
782 6         7 $ele = "";
783              
784 6 50       29 if ($#args == 0) {
    100          
    50          
785             # $nds
786 0         0 ($nds) = @args;
787              
788             } elsif ($#args == 1) {
789             # $nds,$new
790             # $ele,$nds
791             # $label,$nds
792              
793 3 100       13 if (exists $$self{"file"}{$args[0]}) {
    50          
794 2         4 ($label,$nds) = @args;
795             } elsif (ref($args[0])) {
796 1         3 ($nds,$new) = @args;
797             } else {
798 0         0 ($ele,$nds) = @args;
799             }
800              
801             } elsif ($#args == 2) {
802             # $ele,$nds,$new
803             # $label,$nds,$new
804 3 100       9 if (exists $$self{"file"}{$args[0]}) {
805 1         3 ($label,$nds,$new) = @args;
806             } else {
807 2         5 ($ele,$nds,$new) = @args;
808             }
809              
810             } else {
811 0         0 die "ERROR: add_ele: unknown arguments: @args\n";
812             }
813              
814             # Check each argument
815              
816 6 50 66     27 if ($label && ! exists $$self{"file"}{$label}) {
817 0         0 $$self{"err"} = "nmffil06";
818 0         0 $$self{"errmsg"} = "An invalid file label was used: $label";
819 0         0 return undef;
820             }
821              
822 6 100 100     25 if ($ele ne "" && ! exists $$self{"eles"}{$ele}) {
823 1         3 $$self{"err"} = "nmfele01";
824 1         4 $$self{"errmsg"} = "Attempt to access an undefined element: $ele";
825 1         5 return undef;
826             }
827              
828             # Add the element
829              
830 5         9 my $NME;
831             my @a;
832 5 100       14 if ($label) {
    100          
833             # Push onto list of the given file
834 3         6 @a = ($nds);
835              
836             } elsif ($ele ne "") {
837             # Insert into the list at $ele
838              
839 1         2 my($fele);
840 1         1 ($label,$fele) = @{ $$self{"eles"}{$ele} };
  1         3  
841 1         3 @a = ($fele,$nds);
842              
843             } else {
844             # Push onto the last file.
845 1         2 $label = $$self{"labels"}[ $#{ $$self{"labels"} } ];
  1         2  
846 1         3 @a = ($nds);
847             }
848              
849 5         11 $NME = $$self{"file"}{$label};
850 5         21 $NME->add_ele(@a);
851              
852 5 50       14 if ($NME->err()) {
853 0         0 $$self{"err"} = $NME->err();
854 0         0 $$self{"errmsg"} = $NME->errmsg();
855 0         0 return undef;
856             }
857              
858 5         12 _eles($self);
859 5         19 return;
860             }
861              
862             sub _add_ele_hash {
863 7     7   16 my($self,@args) = @_;
864              
865             # Parse arguments
866              
867 7         9 my($label,$ele,$nds,$new);
868 7 100       80 if (exists $$self{"file"}{$args[0]}) {
869 4         9 ($label,$ele,$nds,$new) = @args;
870             } else {
871 3         7 ($ele,$nds,$new) = @args;
872 3         5 $label = $$self{"labels"}[ $#{ $$self{"labels"} } ];
  3         7  
873             }
874              
875             # Check each argument
876              
877 7 100       19 if (ref($ele)) {
878 1         3 $$self{"err"} = "nmfele04";
879 1         2 $$self{"errmsg"} = "When adding an element, a name must be given.";
880 1         4 return undef;
881             }
882              
883 6 50       21 if (! exists $$self{"file"}{$label}) {
884 0         0 $$self{"err"} = "nmffil06";
885 0         0 $$self{"errmsg"} = "An invalid file label was used: $label";
886 0         0 return undef;
887             }
888              
889 6 50       14 if ($ele eq "") {
890 0         0 $$self{"err"} = "nmfele03";
891 0         0 $$self{"errmsg"} = "When accessing a hash element, a name must be given.";
892 0         0 return undef;
893             }
894              
895 6 100       17 if (exists $$self{"eles"}{$ele}) {
896 1         3 $$self{"err"} = "nmfele02";
897 1         3 $$self{"errmsg"} = "Attempt to overwrite an existing element: $ele";
898 1         4 return undef;
899             }
900              
901             # Add the element
902              
903 5         10 my $NME = $$self{"file"}{$label};
904 5         22 $NME->add_ele($ele,$nds);
905              
906 5 50       16 if ($NME->err()) {
907 0         0 $$self{"err"} = $NME->err();
908 0         0 $$self{"errmsg"} = $NME->errmsg();
909 0         0 return undef;
910             }
911              
912 5         11 _eles($self);
913 5         20 return;
914             }
915              
916             ###############################################################################
917             # COPY_ELE METHOD
918             ###############################################################################
919              
920             sub copy_ele {
921 4     4 1 29 my($self,$ele,@args) = @_;
922              
923 4 50       34 if (! defined $$self{"file"}) {
924 0         0 $$self{"err"} = "nmffil08";
925 0         0 $$self{"errmsg"} = "No file set.";
926             }
927              
928             # Check to make sure $ele is valid (it need only exist)
929              
930 4 50       14 if (! $self->ele($ele)) {
931 0         0 $$self{"err"} = "nmfele01";
932 0         0 $$self{"errmsg"} = "The specified element does not exist: $ele";
933 0         0 return "";
934             }
935              
936             # Get the structure there.
937              
938 4         13 my $file = $self->ele_file($ele);
939 4         13 my $NME = (_ele_nme($self,$ele))[0];
940 4         14 my $nds = dclone($NME->_ele_nds($ele,1));
941              
942 4 100 66     23 if (! @args || ! exists $$self{"file"}{$args[0]}) {
943             # The first argument is not a label, so prepend the label of the
944             # original element.
945 2         47 unshift(@args,$file);
946             }
947              
948 4         14 add_ele($self,@args,$nds);
949             }
950              
951             ###############################################################################
952             # UPDATE_ELE METHOD
953             ###############################################################################
954              
955             sub update_ele {
956 2     2 1 26 my($self,$ele,@args) = @_;
957 2         5 $$self{"err"} = "";
958 2         6 $$self{"errmsg"} = "";
959              
960 2 50       8 if (! defined $$self{"file"}) {
961 0         0 $$self{"err"} = "nmffil08";
962 0         0 $$self{"errmsg"} = "No file set.";
963             }
964              
965 2         3 my $NME;
966 2         5 ($NME,$ele) = _ele_nme($self,$ele);
967 2 50       8 return undef if ($self->err());
968              
969 2         11 $NME->update_ele($ele,@args);
970 2 50       8 if ($NME->err()) {
971 0         0 $$self{"err"} = $NME->err();
972 0         0 $$self{"errmsg"} = $NME->errmsg();
973 0         0 return undef;
974             }
975              
976 2         7 _eles($self);
977 2         6 return;
978             }
979              
980             ###############################################################################
981             # DUMP METHOD
982             ###############################################################################
983              
984             sub dump {
985 0     0 1   my($self,$ele,@args) = @_;
986 0           $$self{"err"} = "";
987 0           $$self{"errmsg"} = "";
988              
989 0 0         if (! defined $$self{"file"}) {
990 0           $$self{"err"} = "nmffil08";
991 0           $$self{"errmsg"} = "No file set.";
992             }
993              
994 0           my $NME;
995 0           ($NME,$ele) = _ele_nme($self,$ele);
996 0 0         return undef if ($self->err());
997              
998 0           my $ret = $NME->dump($ele,@args);
999 0 0         if ($NME->err()) {
1000 0           $$self{"err"} = $NME->err();
1001 0           $$self{"errmsg"} = $NME->errmsg();
1002 0           return undef;
1003             }
1004 0           return $ret;
1005             }
1006              
1007             ###############################################################################
1008             # SAVE METHOD
1009             ###############################################################################
1010              
1011             sub save {
1012 0     0 1   my($self,$nobackup) = @_;
1013              
1014 0 0         if (! defined $$self{"file"}) {
1015 0           $$self{"err"} = "nmffil08";
1016 0           $$self{"errmsg"} = "No file set.";
1017             }
1018              
1019 0           while (my($label,$NME) = each %{ $$self{"file"} }) {
  0            
1020 0           $NME->save($nobackup);
1021 0 0         if ($NME->err()) {
1022 0           $$self{"err"} = $NME->err();
1023 0           $$self{"errmsg"} = $NME->errmsg() . ": $label";
1024 0           return undef;
1025             }
1026             }
1027 0           return;
1028             }
1029              
1030             1;
1031             # Local Variables:
1032             # mode: cperl
1033             # indent-tabs-mode: nil
1034             # cperl-indent-level: 3
1035             # cperl-continued-statement-offset: 2
1036             # cperl-continued-brace-offset: 0
1037             # cperl-brace-offset: 0
1038             # cperl-brace-imaginary-offset: 0
1039             # cperl-label-offset: -2
1040             # End: