Skip to content

Instantly share code, notes, and snippets.

@sanmadjack
Created January 23, 2013 22:35
Show Gist options
  • Save sanmadjack/4615030 to your computer and use it in GitHub Desktop.
Save sanmadjack/4615030 to your computer and use it in GitHub Desktop.
Perl class script for loading/writing Blue Martini DNA file
#!/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