<commit_before>
# $Id$

# /** AUTHOR 
#    <NAME>  (<EMAIL>)
#    Astronomical Data Center <http://adc.gsfc.nasa.gov>
#    NASA/Goddard Space Flight Center
# */

# NOTE: There appears to be some chaff still in this class. Clean it up!!

# /** COPYRIGHT
#    FormattedXMLDataIOStyle.pm Copyright (C) 2000 <NAME>,
#    ADC/GSFC-NASA, Code 631, Greenbelt MD, 20771
#@ 
#    This program is free software; it is licensed under the same terms
#    as Perl itself is. Please refer to the file LICENSE which is contained
#    in the distribution that this file came in.
#@ 
#   This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
# */


# /** DESCRIPTION
# This class indicates how records are to be read in for formatted 
# (untagged) text format.
# */

# /** SEE ALSO
# XDF::XMLDataIOStyle
# */

package XDF::FormattedXMLDataIOStyle;

use XDF::BaseObject;
use Carp;

use strict;
use integer;

use vars qw ($AUTOLOAD %field @ISA);

# inherits from XDF::XMLDataIOStyle
@ISA = ("XDF::XMLDataIOStyle");

# CLASS DATA
my @Class_XML_Attributes = qw (
                                 formatCmdList
                              );
my @Class_Attributes = qw (
                             writeAxisOrderList
                          );

# add in class XML attributes
push @Class_Attributes, @Class_XML_Attributes;

# add in super class attributes
push @Class_Attributes, @{&XDF::XMLDataIOStyle::classAttributes};
push @Class_XML_Attributes, @{&XDF::XMLDataIOStyle::getXMLAttributes};

# Initalization
# set up object attributes.
for my $attr ( @Class_Attributes ) { $field{$attr}++; }

# /** classAttributes
#  This method takes no arguments may not be changed. 
#  This method returns a list reference containing the names
#  of the class attributes for XDF::Structure; 
# */
sub classAttributes {
  return \@Class_Attributes;
}

#
# Get/Set Methods
#

# /** getFormatCmdList
#  */
sub getFormatCmdList {
   my ($self) = @_;
   return $self->{FormatCmdList};
}

# /** setFormatCmdList
#  */
sub setFormatCmdList {
   my ($self, $arrayRefValue) = @_;
   # you must do it this way, or when the arrayRef changes it changes us here!
   my @list = @{$arrayRefValue};
   $self->{FormatCmdList} = \@list;
}

sub getFormatCommands {
  my ($self) = @_;
  return $self->getFormatCmdList();
}

sub getFormatCommand {
  my ($self, $index, $expandRepeatCommands) = @_;

  return unless defined $index && $index >= 0;

  my @list;
  if ($expandRepeatCommands) {
    @list = @{$self->getCommands()};
  } else { 
    @list = $self->getFormatCommands();
  }

  return $list[$index];
}

#/** getWriteAxisOrderList 
# This method sets the ordering of the fastest to slowest axis for
# writing out formatted data. The default is to use the parent array
# axisList ordering.
# */
sub getWriteAxisOrderList {
  my ($self) =@_;
  my $list_ref = $self->{WriteAxisOrderList};
  $list_ref = $self->{_parentArray}->getAxisList() unless 
      defined $list_ref || !defined $self->{_parentArray};
  return $list_ref;
}

#/** setWriteAxisOrderList 
# This method sets the ordering of the fastest to slowest axis for
# writing out formatted data. The fastest axis is the last in
# the array.
# */
sub setWriteAxisOrderList {
  my ($self, $arrayRefValue) = @_;
  # you must do it this way, or when the arrayRef changes it changes us here!
  my @list = @{$arrayRefValue};
  $self->{WriteAxisOrderList} = \@list;
}

# /** getCommands
#    This convenience method returns the command list (as
#    an ARRAY Ref). Repeat commands are expanded into their 
#    component parts.  
# */
sub getCommands () {
  my ($self) = @_;

  my @commandList = ();

  foreach my $obj (@{$self->{FormatCmdList}}) {
     if (ref($obj) eq 'XDF::RepeatFormattedIOCmd') {
       my $count = $obj->getCount();
       my @repeatCommandList = @{$obj->getCommands()};
       while ($count-- > 0) {
          push @commandList, @repeatCommandList;
       }
     } else {
        push @commandList, $obj;
     }
   }

   return \@commandList;
}

sub numOfBytes {
  my ($self) = @_;

  my $bytes = 0;

  my @dataFormatList = $self->{_parentArray}->getDataFormatList();

  if (!@dataFormatList or $#dataFormatList < 0) {
    carp "Error: cant determine Formatted ReadStyle byte size w/o defined dataFormat.\n";
    return;
  }

  foreach my $obj (@{$self->getCommands()}) {
    if(ref($obj) eq 'XDF::ReadCellFormattedIOCmd') {
      my $readObj = shift @dataFormatList;
      push (@dataFormatList, $readObj); # its a circular list
      $bytes += $readObj->numOfBytes();
    } elsif (ref($obj) eq 'XDF::SkipCharFormattedIOCmd') {
      $bytes += $obj->numOfBytes();
    } else {
      warn "Unknown format cmd in $self bytes: $obj, ignoring\n";
    }
  }

  return $bytes;
}

# /** getXMLAttributes
#      This method returns the XMLAttributes of this class. 
#  */
sub getXMLAttributes {
  return \@Class_XML_Attributes;
}

#
# Other Public Methods
#

# perhaps we should be adding full-blown objects here, but
# it doesnt seem to be justified. 
sub addFormatCommand {
  my ($self, $obj) = @_;

  return unless defined $obj && ref $obj;

  # push into our array
  push @{$self->{FormatCmdList}}, $obj;

  return $obj;
}

# Is this needed still? -b.t.
sub hasSpecialIntegers {
  my ($self) = @_;
  my @dataFormatList = $self->{_parentArray}->getDataFormatList();

  if (!@dataFormatList) {
    carp "Error: cant look for special type IntegerFields w/o defined dataFormat\n";
  }

  foreach my $dataType (@dataFormatList) {
    if (ref($dataType) eq 'XDF::IntegerField') {
      return 1 if $dataType->getType() ne $dataType->typeDecimal; 
    }
  }

  return 0;
}

sub toXMLFileHandle {
  my ($self, $fileHandle, $junk, $indent) = @_;

  my $niceOutput = $self->Pretty_XDF_Output;

  $indent = "" unless defined $indent;
  my $more_indent = $self->Pretty_XDF_Output_Indentation;

  print $fileHandle "$indent" if $niceOutput;

  # open the read block, print attributes 
  print $fileHandle "<" . $self->SUPER::classXMLNodeName;
  # print out attributes
  $self->_printAttributes($fileHandle, $self->SUPER::classAttributes);
  print $fileHandle ">";
  print $fileHandle "\n" if $niceOutput;

  my @indent;
  my $Untagged_Instruction_Node_Name = $self->untaggedInstructionNodeName();
  my $next_indent = $indent . $more_indent;
  foreach my $axisObj (@{$self->getWriteAxisOrderList()}) {
    my $axisId = $axisObj->getAxisId();
    push @indent, $next_indent;
    print $fileHandle "$next_indent" if $niceOutput;
    print $fileHandle "<$Untagged_Instruction_Node_Name axisIdRef=\"$axisId\">";
    print $fileHandle "\n" if $niceOutput;
    $next_indent .= $more_indent;
  }

  # now dump our format commands here the trusty generic method
  for (@{$self->getFormatCmdList()}) {
     $_->toXMLFileHandle($fileHandle, $junk, $next_indent);
  }

  #close the instructions
  for (reverse @indent) {
    print $fileHandle "$_" if $niceOutput;
    print $fileHandle "</$Untagged_Instruction_Node_Name>";
    print $fileHandle "\n" if $niceOutput;
  }

  # close the read block
  print $fileHandle "$indent" if $niceOutput;
  print $fileHandle "</" . $self->SUPER::classXMLNodeName . ">";
  print $fileHandle "\n" if $niceOutput;

}

#
# Private Methods (note stuff like *Notation methods arent really private or protected. bleh) 
#

# This is called when we cant find any defined method
# exists already. Used to handle general purpose set/get
# methods for our attributes (object fields).
sub AUTOLOAD {
  my ($self,$val) = @_;
  &XDF::GenericObject::AUTOLOAD($self, $val, $AUTOLOAD, \%field );
}

sub _init {
  my ($self) = @_;

  # set defaults
  $self->{FormatCmdList} = []; 

}

sub _regexNotation {
  my ($self) = @_;
  my $notation;

  my @dataFormatList = $self->{_parentArray}->getDataFormatList();

  if (!@dataFormatList or $#dataFormatList < 0) {
    carp "Error: cant read Formatted ReadStyle w/o defined dataFormat\n";
    return;
  }

  foreach my $obj (@{$self->getCommands()}) {
    if(ref($obj) eq 'XDF::ReadCellFormattedIOCmd') {
      my $readObj = shift @dataFormatList;
      push (@dataFormatList, $readObj); # its a circular list
      $notation .= $readObj->_regexNotation();
    } elsif (ref($obj) eq 'XDF::SkipCharFormattedIOCmd') {
      $notation .= $obj->_regexNotation();
    } else {
      warn "Unknown format cmd in $self _regexNotation: $obj, ignoring\n";
    }
  }

  return $notation;

}

# this is only called from dataCube
sub _outputSkipCharArray { 
  my ($self) =@_; 
  my @outArray;

  my @dataFormatList = $self->{_parentArray}->getDataFormatList();
  
  if (!@dataFormatList or $#dataFormatList < 0) {
    carp "Error: cant read Formatted ReadStyle w/o defined dataFormat\n";
    return;
  }
  
  foreach my $obj (@{$self->getCommands()}) {
    if(ref($obj) eq 'XDF::ReadCellFormattedIOCmd') {
      my $readObj = shift @dataFormatList;
      push (@dataFormatList, $readObj); # its a circular list
      push @outArray, undef; # push in a holding spot for the data
    } elsif (ref($obj) eq 'XDF::SkipCharFormattedIOCmd') {
      push @outArray, $obj->getOutput();
    } else {
      warn "Unknown format cmd in $self outputSkipCharArray $obj, ignoring\n";
    }
  }

  return @outArray;
}

sub _templateNotation {
  my ($self, $input) = @_;

  my $notation;
  my $endian = $self->getEndian();
  my $encoding = $self->getEncoding();

  my @dataFormatList = $self->{_parentArray}->getDataFormatList();

  if (!@dataFormatList or $#dataFormatList < 0) {
    carp "Error: cant read Formatted ReadStyle w/o defined dataFormat\n";
    return;
  }

  foreach my $obj (@{$self->getCommands()}) {
    if(ref($obj) eq 'XDF::ReadCellFormattedIOCmd') {
      my $readObj = shift @dataFormatList;
      push (@dataFormatList, $readObj); # its a circular list
      $notation .= $readObj->_templateNotation($endian,$encoding,$input);
    } elsif (ref($obj) eq 'XDF::SkipCharFormattedIOCmd') {
      $notation .= $obj->_templateNotation($endian,$encoding,$input);
    } else { 
      # everything else, which nothing right now, so throw an error
      warn "Got weird formattedIOCmd in $self : $obj , ignoring it.\n";
    }
  }

  return $notation;

}

sub _sprintfNotation {
  my ($self) = @_;
  my $notation;

  my @dataFormatList = $self->{_parentArray}->getDataFormatList();

  if (!@dataFormatList or $#dataFormatList < 0) {
    carp "Error: cant read Formatted ReadStyle w/o defined dataFormat\n";
    return;
  }

  foreach my $obj (@{$self->getCommands()}) {
   if(ref($obj) eq 'XDF::ReadCellFormattedIOCmd') {
      my $readObj = shift @dataFormatList;
      push (@dataFormatList, $readObj); # its a circular list
      $notation .= $readObj->_sprintfNotation(); 
    } elsif (ref($obj) eq 'XDF::SkipCharFormattedIOCmd') {
      $notation .= $obj->_sprintfNotation(); 
    } else {
      warn "Got weird formattedIOCmd in $self : $obj , ignoring it.\n";
    }
  }

  return $notation;
}


# Modification History
#
# $Log$
# Revision 1.7  2001/02/15 17:50:31  thomas
# changed getBytes to numOfBytes method as per
# java API.
#
# Revision 1.6  2000/12/15 22:12:00  thomas
# Regenerated perlDoc section in files. -b.t.
#
# Revision 1.5  2000/12/14 22:11:26  thomas
# Big changes to the API. get/set methods, added Href/Entity stuff, deep cloning,
# added Href, Notes, NotesLocationOrder nodes/classes. Ripped out _enlarge_array
# from DataCube (not needed) and fixed problems outputing delimited/formatted
# read nodes. -b.t.
#
# Revision 1.4  2000/12/01 20:03:38  thomas
# Brought Pod docmentation up to date. Bumped up version
# number. -b.t.
#
# Revision 1.3  2000/11/28 19:39:10  thomas
# Fix to formatted  reads. Implemented getCommands
# method. -b.t.
#
# Revision 1.2  2000/10/16 17:37:20  thomas
# Changed over to BaseObject Class from Object Class.
# Added in History Modification section.<commit_msg>getCommands changed to return ARRAY instead of ARRAY ref.<commit_after>
# $Id$

# /** AUTHOR 
#    <NAME>  (<EMAIL>)
#    Astronomical Data Center <http://adc.gsfc.nasa.gov>
#    NASA/Goddard Space Flight Center
# */

# NOTE: There appears to be some chaff still in this class. Clean it up!!

# /** COPYRIGHT
#    FormattedXMLDataIOStyle.pm Copyright (C) 2000 <NAME>,
#    ADC/GSFC-NASA, Code 631, Greenbelt MD, 20771
#@ 
#    This program is free software; it is licensed under the same terms
#    as Perl itself is. Please refer to the file LICENSE which is contained
#    in the distribution that this file came in.
#@ 
#   This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
# */


# /** DESCRIPTION
# This class indicates how records are to be read in for formatted 
# (untagged) text format.
# */

# /** SEE ALSO
# XDF::XMLDataIOStyle
# */

package XDF::FormattedXMLDataIOStyle;

use XDF::BaseObject;
use Carp;

use strict;
use integer;

use vars qw ($AUTOLOAD %field @ISA);

# inherits from XDF::XMLDataIOStyle
@ISA = ("XDF::XMLDataIOStyle");

# CLASS DATA
my @Class_XML_Attributes = qw (
                                 formatCmdList
                              );
my @Class_Attributes = qw (
                             writeAxisOrderList
                          );

# add in class XML attributes
push @Class_Attributes, @Class_XML_Attributes;

# add in super class attributes
push @Class_Attributes, @{&XDF::XMLDataIOStyle::classAttributes};
push @Class_XML_Attributes, @{&XDF::XMLDataIOStyle::getXMLAttributes};

# Initalization
# set up object attributes.
for my $attr ( @Class_Attributes ) { $field{$attr}++; }

# /** classAttributes
#  This method takes no arguments may not be changed. 
#  This method returns a list reference containing the names
#  of the class attributes for XDF::Structure; 
# */
sub classAttributes {
  return \@Class_Attributes;
}

#
# Get/Set Methods
#

# /** getFormatCmdList
#  */
sub getFormatCmdList {
   my ($self) = @_;
   return $self->{FormatCmdList};
}

# /** setFormatCmdList
#  */
sub setFormatCmdList {
   my ($self, $arrayRefValue) = @_;
   # you must do it this way, or when the arrayRef changes it changes us here!
   my @list = @{$arrayRefValue};
   $self->{FormatCmdList} = \@list;
}

sub getFormatCommands {
  my ($self) = @_;
  return $self->getFormatCmdList();
}

sub getFormatCommand {
  my ($self, $index, $expandRepeatCommands) = @_;

  return unless defined $index && $index >= 0;

  my @list;
  if ($expandRepeatCommands) {
    @list = $self->getCommands();
  } else { 
    @list = $self->getFormatCommands();
  }

  return $list[$index];
}

#/** getWriteAxisOrderList 
# This method sets the ordering of the fastest to slowest axis for
# writing out formatted data. The default is to use the parent array
# axisList ordering.
# */
sub getWriteAxisOrderList {
  my ($self) =@_;
  my $list_ref = $self->{WriteAxisOrderList};
  $list_ref = $self->{_parentArray}->getAxisList() unless 
      defined $list_ref || !defined $self->{_parentArray};
  return $list_ref;
}

#/** setWriteAxisOrderList 
# This method sets the ordering of the fastest to slowest axis for
# writing out formatted data. The fastest axis is the last in
# the array.
# */
sub setWriteAxisOrderList {
  my ($self, $arrayRefValue) = @_;
  # you must do it this way, or when the arrayRef changes it changes us here!
  my @list = @{$arrayRefValue};
  $self->{WriteAxisOrderList} = \@list;
}

# /** getCommands
#    This convenience method returns the command list (as
#    an ARRAY Ref). Repeat commands are expanded into their 
#    component parts.  
# */
sub getCommands () {
  my ($self) = @_;

  my @commandList = ();

  foreach my $obj (@{$self->{FormatCmdList}}) {
     if (ref($obj) eq 'XDF::RepeatFormattedIOCmd') {
       my $count = $obj->getCount();
       my @repeatCommandList = $obj->getCommands();
       while ($count-- > 0) {
          push @commandList, @repeatCommandList;
       }
     } else {
        push @commandList, $obj;
     }
   }

   return @commandList;
}

sub numOfBytes {
  my ($self) = @_;

  my $bytes = 0;

  my @dataFormatList = $self->{_parentArray}->getDataFormatList();

  if (!@dataFormatList or $#dataFormatList < 0) {
    carp "Error: cant determine Formatted ReadStyle byte size w/o defined dataFormat.\n";
    return;
  }

  foreach my $obj ($self->getCommands()) {
    if(ref($obj) eq 'XDF::ReadCellFormattedIOCmd') {
      my $readObj = shift @dataFormatList;
      push (@dataFormatList, $readObj); # its a circular list
      $bytes += $readObj->numOfBytes();
    } elsif (ref($obj) eq 'XDF::SkipCharFormattedIOCmd') {
      $bytes += $obj->numOfBytes();
    } else {
      warn "Unknown format cmd in $self bytes: $obj, ignoring\n";
    }
  }

  return $bytes;
}

# /** getXMLAttributes
#      This method returns the XMLAttributes of this class. 
#  */
sub getXMLAttributes {
  return \@Class_XML_Attributes;
}

#
# Other Public Methods
#

# perhaps we should be adding full-blown objects here, but
# it doesnt seem to be justified. 
sub addFormatCommand {
  my ($self, $obj) = @_;

  return unless defined $obj && ref $obj;

  # push into our array
  push @{$self->{FormatCmdList}}, $obj;

  return $obj;
}

# Is this needed still? -b.t.
sub hasSpecialIntegers {
  my ($self) = @_;
  my @dataFormatList = $self->{_parentArray}->getDataFormatList();

  if (!@dataFormatList) {
    carp "Error: cant look for special type IntegerFields w/o defined dataFormat\n";
  }

  foreach my $dataType (@dataFormatList) {
    if (ref($dataType) eq 'XDF::IntegerField') {
      return 1 if $dataType->getType() ne $dataType->typeDecimal; 
    }
  }

  return 0;
}

sub toXMLFileHandle {
  my ($self, $fileHandle, $junk, $indent) = @_;

  my $niceOutput = $self->Pretty_XDF_Output;

  $indent = "" unless defined $indent;
  my $more_indent = $self->Pretty_XDF_Output_Indentation;

  print $fileHandle "$indent" if $niceOutput;

  # open the read block, print attributes 
  print $fileHandle "<" . $self->SUPER::classXMLNodeName;
  # print out attributes
  $self->_printAttributes($fileHandle, $self->SUPER::classAttributes);
  print $fileHandle ">";
  print $fileHandle "\n" if $niceOutput;

  my @indent;
  my $Untagged_Instruction_Node_Name = $self->untaggedInstructionNodeName();
  my $next_indent = $indent . $more_indent;
  foreach my $axisObj (@{$self->getWriteAxisOrderList()}) {
    my $axisId = $axisObj->getAxisId();
    push @indent, $next_indent;
    print $fileHandle "$next_indent" if $niceOutput;
    print $fileHandle "<$Untagged_Instruction_Node_Name axisIdRef=\"$axisId\">";
    print $fileHandle "\n" if $niceOutput;
    $next_indent .= $more_indent;
  }

  # now dump our format commands here the trusty generic method
  for (@{$self->getFormatCmdList()}) {
     $_->toXMLFileHandle($fileHandle, $junk, $next_indent);
  }

  #close the instructions
  for (reverse @indent) {
    print $fileHandle "$_" if $niceOutput;
    print $fileHandle "</$Untagged_Instruction_Node_Name>";
    print $fileHandle "\n" if $niceOutput;
  }

  # close the read block
  print $fileHandle "$indent" if $niceOutput;
  print $fileHandle "</" . $self->SUPER::classXMLNodeName . ">";
  print $fileHandle "\n" if $niceOutput;

}

#
# Private Methods (note stuff like *Notation methods arent really private or protected. bleh) 
#

# This is called when we cant find any defined method
# exists already. Used to handle general purpose set/get
# methods for our attributes (object fields).
sub AUTOLOAD {
  my ($self,$val) = @_;
  &XDF::GenericObject::AUTOLOAD($self, $val, $AUTOLOAD, \%field );
}

sub _init {
  my ($self) = @_;

  # set defaults
  $self->{FormatCmdList} = []; 

}

sub _regexNotation {
  my ($self) = @_;
  my $notation;

  my @dataFormatList = $self->{_parentArray}->getDataFormatList();

  if (!@dataFormatList or $#dataFormatList < 0) {
    carp "Error: cant read Formatted ReadStyle w/o defined dataFormat\n";
    return;
  }

  foreach my $obj ($self->getCommands()) {
    if(ref($obj) eq 'XDF::ReadCellFormattedIOCmd') {
      my $readObj = shift @dataFormatList;
      push (@dataFormatList, $readObj); # its a circular list
      $notation .= $readObj->_regexNotation();
    } elsif (ref($obj) eq 'XDF::SkipCharFormattedIOCmd') {
      $notation .= $obj->_regexNotation();
    } else {
      warn "Unknown format cmd in $self _regexNotation: $obj, ignoring\n";
    }
  }

  return $notation;

}

# this is only called from dataCube
sub _outputSkipCharArray { 
  my ($self) =@_; 
  my @outArray;

  my @dataFormatList = $self->{_parentArray}->getDataFormatList();
  
  if (!@dataFormatList or $#dataFormatList < 0) {
    carp "Error: cant read Formatted ReadStyle w/o defined dataFormat\n";
    return;
  }
  
  foreach my $obj ($self->getCommands()) {
    if(ref($obj) eq 'XDF::ReadCellFormattedIOCmd') {
      my $readObj = shift @dataFormatList;
      push (@dataFormatList, $readObj); # its a circular list
      push @outArray, undef; # push in a holding spot for the data
    } elsif (ref($obj) eq 'XDF::SkipCharFormattedIOCmd') {
      push @outArray, $obj->getOutput();
    } else {
      warn "Unknown format cmd in $self outputSkipCharArray $obj, ignoring\n";
    }
  }

  return @outArray;
}

sub _templateNotation {
  my ($self, $input) = @_;

  my $notation;
  my $endian = $self->getEndian();
  my $encoding = $self->getEncoding();

  my @dataFormatList = $self->{_parentArray}->getDataFormatList();

  if (!@dataFormatList or $#dataFormatList < 0) {
    carp "Error: cant read Formatted ReadStyle w/o defined dataFormat\n";
    return;
  }

  foreach my $obj ($self->getCommands()) {
    if(ref($obj) eq 'XDF::ReadCellFormattedIOCmd') {
      my $readObj = shift @dataFormatList;
      push (@dataFormatList, $readObj); # its a circular list
      $notation .= $readObj->_templateNotation($endian,$encoding,$input);
    } elsif (ref($obj) eq 'XDF::SkipCharFormattedIOCmd') {
      $notation .= $obj->_templateNotation($endian,$encoding,$input);
    } else { 
      # everything else, which nothing right now, so throw an error
      warn "Got weird formattedIOCmd in $self : $obj , ignoring it.\n";
    }
  }

  return $notation;

}

sub _sprintfNotation {
  my ($self) = @_;
  my $notation;

  my @dataFormatList = $self->{_parentArray}->getDataFormatList();

  if (!@dataFormatList or $#dataFormatList < 0) {
    carp "Error: cant read Formatted ReadStyle w/o defined dataFormat\n";
    return;
  }

  foreach my $obj ($self->getCommands()) {
   if(ref($obj) eq 'XDF::ReadCellFormattedIOCmd') {
      my $readObj = shift @dataFormatList;
      push (@dataFormatList, $readObj); # its a circular list
      $notation .= $readObj->_sprintfNotation(); 
    } elsif (ref($obj) eq 'XDF::SkipCharFormattedIOCmd') {
      $notation .= $obj->_sprintfNotation(); 
    } else {
      warn "Got weird formattedIOCmd in $self : $obj , ignoring it.\n";
    }
  }

  return $notation;
}


# Modification History
#
# $Log$
# Revision 1.8  2001/03/07 23:12:00  thomas
# getCommands changed to return ARRAY instead of ARRAY ref.
#
# Revision 1.7  2001/02/15 17:50:31  thomas
# changed getBytes to numOfBytes method as per
# java API.
#
# Revision 1.6  2000/12/15 22:12:00  thomas
# Regenerated perlDoc section in files. -b.t.
#
# Revision 1.5  2000/12/14 22:11:26  thomas
# Big changes to the API. get/set methods, added Href/Entity stuff, deep cloning,
# added Href, Notes, NotesLocationOrder nodes/classes. Ripped out _enlarge_array
# from DataCube (not needed) and fixed problems outputing delimited/formatted
# read nodes. -b.t.
#
# Revision 1.4  2000/12/01 20:03:38  thomas
# Brought Pod docmentation up to date. Bumped up version
# number. -b.t.
#
# Revision 1.3  2000/11/28 19:39:10  thomas
# Fix to formatted  reads. Implemented getCommands
# method. -b.t.
#
# Revision 1.2  2000/10/16 17:37:20  thomas
# Changed over to BaseObject Class from Object Class.
# Added in History Modification section.
{'fraction_non_alphanumeric': 0.13304936106239038, 'fraction_numerical': 0.010523678276121273, 'mean_word_length': 3.4760747663551403, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 135, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2736944', 'n_tokens_mistral': 8092, 'n_tokens_neox': 7857, 'n_words': 2319}