Created
January 23, 2013 22:35
-
-
Save sanmadjack/4615030 to your computer and use it in GitHub Desktop.
Perl class script for loading/writing Blue Martini DNA file
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl | |
###################################################################### | |
###################################################################### | |
## | |
## Name: dna.pm | |
## | |
## Prpose: Object for the reading and writing of DNA files | |
## | |
## Author: Matthew Barbour | |
## | |
## Date: 05/23/2012 | |
## | |
###################################################################### | |
###################################################################### | |
package common::dna; | |
use strict; | |
use Data::Dumper; | |
sub new { | |
my $class = shift; | |
my $self = { | |
_fileName => shift, | |
}; | |
print "File name is $self->{_fileName}\n"; | |
open (DNAFILE, $self->{_fileName}); | |
my @lines = ; | |
close (DNAFILE); | |
my $properties; | |
if($lines[0] =~ m/^DNA {/i) { | |
$properties = loadProperties(\@lines); | |
} else { | |
print "NOT A DNA FILE, DOESN'T BEGIN WITH \"DNA {\"\n"; | |
die; | |
} | |
$self->{_properties} = \@$properties; | |
#print "Properties are:\n"; | |
#print Dumper($properties); | |
bless $self, $class; | |
return $self; | |
} | |
sub changeValue { | |
} | |
# Writes the data to a DNA-formatted file | |
# Usage: writeFile("File\Name.txt") | |
sub writeFile { | |
my( $self, $filename ) = @_; | |
print "test $filename\n"; | |
my $output = $self->toString(); | |
open (DNAFILE, ">$filename"); | |
# print DNAFILE Dumper($self); | |
print DNAFILE $output; | |
close DNAFILE; | |
} | |
# Converts the object to a DNA-formatted string | |
# Usage: $object->toString() | |
sub toString { | |
my( $self ) = @_; | |
my $data = $self->{_properties}; | |
my $string = "DNA {\n"; | |
my $i = 0; | |
foreach(@$data) { | |
my $entry = $_; | |
$i++; | |
$string .= convertElementToString($entry,1,$i<@$data); } $string .= "}"; return $string; } # Converts a particular DNA element (and sub-elements) to a string # Usage: convertElementToString(array_entry, number_representing_indent, boolean_wether_this_is_the_last_element) sub convertElementToString { my ($entry, $recursion_level, $last_element) = @_; my $type = $entry->{_type}; | |
my $string = ""; | |
my $indent = ""; | |
my $standard_indent = " "; | |
for(my $i = 0;$i<$recursion_level;$i++) { | |
$indent .= $standard_indent; | |
} | |
if( $type eq "Blank" ) { | |
return "\n"; | |
} elsif( $type eq "Comment" ) { | |
return "\n".$indent."//$entry->{_value}"; | |
} elsif( $type eq "DNA" ) { | |
$string .= "\n".$indent."\"$entry->{_name}\" DNA {\n"; | |
my $data = $entry->{_value}; | |
my $i = 0; | |
foreach(@$data) { | |
$i++; | |
$string .= convertElementToString($_, $recursion_level + 1,$i<@$data); } $string .= $indent."}"; } elsif( $type =~ /([^"]+)Array/ ) { my $data = $entry->{_value}; | |
$string .= $indent."\"$entry->{_name}\" $entry->{_type} [\n"; | |
my $i = 0; | |
my $j = 0; | |
my $value_line = $indent.$standard_indent; | |
foreach(@$data) { | |
$value_line .= "\"$_\""; | |
$i++; | |
$j++; | |
if($i<@$data) { $value_line .= ","; } if($i>=@$data||length($_)>7||$j%5==0) { | |
$string .= $value_line."\n"; | |
$value_line = $indent.$standard_indent; | |
$j = 0; | |
} | |
} | |
$string .= $indent."]"; | |
} else { | |
$string .= $indent."\"$entry->{_name}\" $entry->{_type} \"$entry->{_value}\""; | |
} | |
if($last_element) { | |
$string .= ","; | |
} | |
return $string."\n"; | |
} | |
# This parses the DNA file and loads the data into an object array | |
# Should NOT be called form the outside | |
# Usage: loadProperties(@array_of_dna_file_lines) | |
sub loadProperties { | |
my ($lines) = @_; | |
my @output = (); | |
while(@$lines > 0) { | |
shift(@$lines); | |
my $line = @$lines[0]; | |
my $new = {}; | |
# The basic entry data format is as follows: | |
# _type = The type of the entry (DNA, DataTypeArray, DataType, Comment, Blank) | |
# _value = The value of the entry, or the sub-entries of the entry | |
# _name = The name of the entry (not used for comments) | |
if ($line =~ /^\s*$/) { | |
$new->{_type} = "Blank"; | |
next; | |
} elsif ($line =~ /^\s*\/\/(.*)/) { | |
$new->{_type} = "Comment"; | |
$new->{_value} = $1; | |
} elsif($line =~ /"((\\"|[^"])+)"\s+DNA/) { | |
# Handles DNA entries, places all the sub-entries into an array in _value | |
$new->{_name} = $1; | |
$new->{_type} = "DNA"; | |
$new->{_value} = loadProperties($lines); | |
} elsif($line =~ /"((\\"|[^"])+)"\s+([^"]+)Array/) { | |
# This section handles all the array types | |
my $name = $1; | |
my $type = $3; | |
## Parse any values on the starting line | |
my $values; | |
if ($line =~ /\[(([\s,]*"((\\"|[^"])+)")+[, ]*)/) { | |
my $value = $1; | |
$value =~ s/^\s*(.*?)\s*$/$1/; | |
$values = $value; | |
} | |
## Then we parse subsequent lines for array values | |
while ($line !~ /\]/) { | |
shift(@$lines); | |
$line = @$lines[0]; | |
if($line =~ /\[?(([\s,]*"((\\"|[^"])+)")+[, ]*)/) { | |
my $value = $1; | |
$value =~ s/^\s*(.*?)\s*$/$1/; | |
$values = "$values $value"; | |
} | |
} | |
$new->{_name} = $name; | |
$new->{_type} = $type."Array"; | |
# Then here we break them down into individual array entries | |
my @value_array = (); | |
while ($values =~ /"((\\"|[^"])+)"[,\s]*/g) { | |
push(@value_array,$1); | |
} | |
$new->{_value} = \@value_array; | |
} elsif($line =~ /"((\\"|[^"])+)"\s+([^\s]+)\s+"((\\"|[^"])+)"/) { | |
# This finds all the non-array data types | |
$new->{_name} = $1; | |
$new->{_type} = $3; | |
$new->{_value} = $4; | |
} elsif ($line =~ /},?/) { | |
# This is if a line is a closing brace, | |
# it signifies that we need to stop processing the array and allow the higher-up | |
# code to continue, regardless of wether there is more file to process | |
last; | |
} elsif ($line =~ /{/) { | |
# This is if a line is just an opening brace | |
next; | |
} else { | |
print "Line not understOOd: $line\n"; | |
die; | |
} | |
push(@output, $new); | |
} | |
return \@output; | |
} | |
1; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment