*** empty log message ***
authorhachti <hachti>
Mon, 15 Jan 2007 04:31:52 +0000 (04:31 +0000)
committerhachti <hachti>
Mon, 15 Jan 2007 04:31:52 +0000 (04:31 +0000)
pc-tools/ldc2/src/configuration_manager.cpp
pc-tools/ldc2/src/configuration_manager.hh
pc-tools/ldc2/src/hw_constants.hh
pc-tools/ldc2/src/main.cpp
pc-tools/ldc2/src/tape_block.cpp
pc-tools/ldc2/src/tape_block.hh

index 418410508fa72074f42968ebf32c85fa3d78a851..3194ec3eec3e029740acffe8ee5b1cc8d9ad4e9f 100644 (file)
@@ -144,8 +144,15 @@ vector<string> configuration_manager::read_args(int argc, char ** args){
        if (argstring.compare(0,switch_name.length(),switch_name,0,switch_name.length())==0){
          string value=analyse_string(argstring);
          bool result=analyse_bool(value);
-         *(option_switches[switch_no].status)=result;
+         if(option_switches[switch_no].allow_cmdline==true){
+           *(option_switches[switch_no].status)=result;
+         }else{
+           messages.insert(messages.end(),"Switch \"--"
+                           +option_switches[switch_no].longname
+                           +"\" is not allowed on the command line!");
+         }
          found=true;
+         break;
        }
       }
 
@@ -154,9 +161,16 @@ vector<string> configuration_manager::read_args(int argc, char ** args){
        string value_name=option_values[value_no].longname;
        if (argstring.compare(0,value_name.length(),value_name,0,value_name.length())==0){
          string value=analyse_string(argstring);
-         *(option_values[value_no].status)=1;
-         *(option_values[value_no].target)=value;
+         if(option_values[value_no].allow_cmdline==true){
+           *(option_values[value_no].status)=1;
+           *(option_values[value_no].target)=value;
+         }else{
+           messages.insert(messages.end(),"Option value \"--"
+                           +option_values[value_no].longname
+                           +"\" is not allowed on the command line!");
+         }
          found=true;
+         break;
        }
       }
       if (! found) {
@@ -176,9 +190,16 @@ vector<string> configuration_manager::read_args(int argc, char ** args){
        for (unsigned int switch_no=0;switch_no<option_switches.size();switch_no++){
          string short_name=option_switches[switch_no].shortname;
          if (short_name.compare(0,short_name.length(),argstring,pos,short_name.length())==0){
-           *(option_switches[switch_no].status)=1;
+           if(option_switches[switch_no].allow_cmdline==true){
+             *(option_switches[switch_no].status)=1;
+           }else{
+             messages.insert(messages.end(),"Switch \"-"
+                             +option_switches[switch_no].shortname
+                             +"\" is not allowed on the command line!");
+           }
            short_found=true;
            pos+=short_name.length()-1;
+           break;
          }
        }
        
@@ -199,10 +220,17 @@ vector<string> configuration_manager::read_args(int argc, char ** args){
                  short_found=true;
                }
              } else {
-               *(option_values[value_no].status)=1;
-               *(option_values[value_no].target)=argstring.substr(pos+1);
+               if(option_values[value_no].allow_cmdline==true){
+                 *(option_values[value_no].status)=1;
+                 *(option_values[value_no].target)=argstring.substr(pos+1);
+               }else{
+                 messages.insert(messages.end(),"Option value \"-"
+                                 +option_values[value_no].shortname
+                                 +"\" is not allowed on the command line!");
+               }
                pos=argstring.length(); // Do not analyse other characters.
                short_found=true;
+               break;
              }
            }
          }
@@ -241,13 +269,31 @@ string configuration_manager::analyse_string(const string & line){
 }
 
 /*!
- *\brief Extract a boolean value out of a string.
+ *\brief Extract a boolean value out of a string, defaulting to true
+ *
+ * Used for commandline switches
  */
 bool configuration_manager::analyse_bool(const string & data){
-  if ((data=="false")||(data=="0")||(data=="no")) return false;
-  return true;
+  if ((data.find("false",0)!=string::npos)||
+      (data.find("0",0)!=string::npos)||
+      (data.find("no",0)!=string::npos)) return false;
+  else return true;
+}
+
+
+/*!
+ *\brief Extract a boolean value out of a string, defaulting to false
+ *
+ * Used for configuration file switches
+ */
+bool configuration_manager::analyse_bool_false(const string & data){
+  if ((data.find("true",0)!=string::npos)||
+      (data.find("1",0)!=string::npos)||
+      (data.find("yes",0)!=string::npos)) return true;
+  else return false;
 }
 
+
 /*!
  *brief Read in and parse a configuration file.
  *\arg file String containing the filename
@@ -258,35 +304,79 @@ vector<string> configuration_manager::read_file(string filename){
   vector<string>result;
   FILE * fp=fopen(filename.c_str(),"r");
   if (! fp) {
-    result.insert(result.end(),"Error!");
-    result.insert(result.end(),"Could not open file:"+filename);
-    return result;
-  }
-
-  char buffer[1000];
-  while(fgets(buffer,1000,fp)){
-    if (strlen (buffer)){
-      char*l2=buffer+strspn(buffer," \t");
-      if (l2[0]!='#'){
-       string line=l2;
-       unsigned int pos=line.find("=");
-       if (pos==0){
-         result.insert(result.end(),"Error!");
-         result.insert(result.end(),"In File:"+filename);
-         result.insert(result.end(),"Line beginning with '='!");
-         return result;
-       }
-       
-      } // if not #
-      
-    } // if (strlen())
-  } // while(...)
-
+    result.insert(result.end(),"Could not open file: "+filename);
+  } else {
+    char buffer[1000];
+    while(fgets(buffer,1000,fp)){
+      if (buffer[strlen(buffer)-1]=='\n')// Cut trailing newline
+       buffer[strlen(buffer)-1]=0; 
+      if (strlen (buffer)){
+       char*l2=buffer+strspn(buffer," \t");
+       if (l2[0]!='#'){
+         string argstring=l2;
+         unsigned int pos=argstring.find("=");
+         if (pos==0){
+           result.insert(result.end(),"In File "+filename+": Line beginning with '='!");
+         }
+         
+         bool found=false;
+         
+         // Look for long switches.
+         for (unsigned int switch_no=0;switch_no<option_switches.size();switch_no++){
+           string switch_name=option_switches[switch_no].longname;
+           if (argstring.compare(0,switch_name.length(),switch_name,0,switch_name.length())==0){
+             string value=analyse_string(argstring);
+             //result.insert(result.end(),"argstring:\""+argstring+"\"");
+             bool res=analyse_bool_false(value);
+             if(option_switches[switch_no].allow_conffile==true){
+               *(option_switches[switch_no].status)=res;
+             }else{
+               result.insert(result.end(),"In File "+filename+": Switch \""
+                             +option_switches[switch_no].longname
+                             +"\" is not allowed in config files!");
+             }
+             found=true;
+             break;
+           }
+         }
+         
+         // Look for long values.
+         for (unsigned int value_no=0;value_no<option_values.size();value_no++){
+           string value_name=option_values[value_no].longname;
+           if (argstring.compare(0,value_name.length(),value_name,0,value_name.length())==0){
+             string value=analyse_string(argstring);
+             *(option_values[value_no].status)=1;
+             
+             if(option_values[value_no].allow_conffile==true){
+               *(option_values[value_no].status)=1;
+               *(option_values[value_no].target)=value;              
+             }else{
+               result.insert(result.end(),"In File "+filename+": Option value \""
+                             +option_values[value_no].longname
+                             +"\" is not allowed in config files!");
+             }
+             found=true;
+             break;
+           }
+         }
+         if (! found) {
+         result.insert(result.end(),"In File "+filename+": Unknown option: "+argstring+"!");
+         }
+         
+       } // if not #
+      } // if (strlen())
+    } // while(...)
+    fclose (fp);
+  } // fp==0 else branch
   
-  fclose (fp);
+  if (!result.empty()){
+    result.insert(result.begin(),"Error!");
+    result.insert(result.begin(),"");
+  }
   return result;
 }
 
+
 /*!
  *\brief Generate help.
  *\arg target Reference to a vector<string> to which lots of helpful
@@ -381,7 +471,7 @@ void configuration_manager::get_help(vector<string> & target){
       opt_value_t akt_val=option_values[val];
       string rline=akt_val.description;
       string lline=" -"+akt_val.shortname+akt_val.placeholder+", --"+
-       akt_val.longname+akt_val.placeholder;
+       akt_val.longname+"="+akt_val.placeholder;
       left.insert(left.end(),lline);
       right.insert(right.end(),rline);
     }
@@ -488,7 +578,6 @@ configuration_manager::opt_switch_t::opt_switch_t(const string & shortname,
   this->placeholder=placeholder;
   this->allow_conffile=allow_conffile;
   this->allow_cmdline=allow_cmdline;
-  if (status) *status=0;
 }
 
 
@@ -500,5 +589,4 @@ configuration_manager::cmd_arg_t::cmd_arg_t(const string & placeholder,
   this->description=description;
   this->status=status;
   this->target=target;
-  if (this->status) *(this->status)=0;
 }
index 60a215d05725523ae350b870b1d5827b1813d01f..e2f056f4b9be2daf656bcb9b6a1f9c4e1c116450 100644 (file)
@@ -128,6 +128,7 @@ protected: // members
 protected: // methods
   string analyse_string(const string & line);
   bool analyse_bool(const string & data);
+  bool analyse_bool_false(const string & data);
 }; // class configuration_manager
 
 
index 2ec1c87312f52bf844a3be07586e3c36c5187149..4be1bc0e54dcfef870aa8c7aef4022f2dd449daa 100644 (file)
@@ -7,9 +7,11 @@
 #define MINIMUM_DATA_BLOCK_WORDSIZE 1
 
 /* Block end delimiters */
-#define EOB_LENGTH 1
+#define EOB_LENGTH 2
 #define BLOCK_END_DELIMITER_1 0223 
-#define BLOCK_END_DELIMITER_2 0223
+//#define BLOCK_END_DELIMITER_2 0223 // ==0x93
+#define BLOCK_END_DELIMITER_2 0xFF
+
 
 /* End of Tape sequence
  * If EOT_LENGTH is set to 2, EOT_1 becomes insignificant and so on
index 282ce9a6eff410624f1cea52da3158d074dc864e..068ca6e22439e3649ca89c65f6da2fd322ba07e8 100644 (file)
 #include <fcntl.h>
 
 #include "tape_block.hh"
+#include "data_block_0.hh"
+
 #include "configuration_manager.hh"
 
 using namespace std;
 
+static int in_fd, out_fd;
+
+
 int dump_vector(vector<string> arguments){
   int res=0;
   for (vector<string>::iterator iter=arguments.begin();iter<arguments.end();iter++){
-    printf("%s\n",(*iter).c_str());
+    char buffer[2000];
+    snprintf(buffer,2000,"%s\n",(*iter).c_str());
+    write (out_fd,buffer,strlen(buffer));
     res=1;
   }
   return res;
 }
 
 
+/*!
+ *\brief The main routine.
+ *
+ * Here we do the configuration management and process the data.
+ *
+ */
 int main(int argc, char ** args){
-  
   /* Configuration data */
   string config_file;
   string infile, outfile;
-  int infile_set, outfile_set, config_file_set;
+  int infile_set=0, outfile_set=0, config_file_set=0;
   
   int 
-    do_help,
-    output_info,
-    output_called,
-    output_exported,
-    output_unsatisfied,
-    split_objects,
-    split_objects_numbered,
-    ignore_block_errors,
-    ignore_checksum_errors,
-    pause_on_checksum_error,
-    ignore_unknown_block_errors,
-    ignore_object_integrity_errors;
+    do_help=0,
+    output_info=0,
+    output_called=0,
+    output_exported=0,
+    output_unsatisfied=0,
+    split_objects=0,
+    split_objects_numbered=0,
+    ignore_block_errors=0,
+    ignore_checksum_errors=0,
+    pause_on_checksum_error=0,
+    ignore_unknown_block_errors=0,
+    ignore_object_integrity_errors=0,
+    list_contents=1,
+    verbose=0;
   
-  int in_fd, out_fd;
-
   in_fd=0;  /* stdin   {O _ \ */
   out_fd=1; /* stdout  {O ^ / */
 
@@ -55,68 +68,71 @@ int main(int argc, char ** args){
   /* Here come the configuration switches */
   ar.add_option_switch("h","help",
                       "Output this help text and exit.",
-                      &do_help,true,false);
+                      &do_help,false,true);
 
   ar.add_option_switch("a","output_info",
                       "Print tape data information (default)",
-                      &output_info);
+                      &output_info,true,true);
 
   ar.add_option_switch("c","output_called",
                       "Print all called symbols from the object(s).",
-                      &output_called);
+                      &output_called,true,true);
 
   ar.add_option_switch("e","output_exported",
                       "Print all exported symbols from the object(s).",
-                      &output_exported);
+                      &output_exported,true,true);
 
   ar.add_option_switch("u","output_unsatisfied",
                       "List all unsatisfied symbols.",
-                      &output_unsatisfied);
-
-  ar.add_option_switch("s","split_objects",
-                      "Split input data into distinct object files.",
-                      &split_objects);
+                      &output_unsatisfied,true,true);
 
   ar.add_option_switch("S","split_objects_numbered",
                       "Split input data into distinct numbered files",
-                      &split_objects_numbered);
+                      &split_objects_numbered,true,true);
 
+  ar.add_option_switch("s","split_objects",
+                      "Split input data into distinct object files.",
+                      &split_objects,true,true);
+  
   ar.add_option_switch("b","ignore_block_errors",
                       "Ignore block integrity errors. This will output broken blocks,too",
-                      &ignore_block_errors);
+                      &ignore_block_errors,true,true);
 
   ar.add_option_switch("k","ignore_checksum_errors",
                       "Ignore block checksum errors. Errors will be converted to warnings.",
-                      &ignore_checksum_errors);
+                      &ignore_checksum_errors,true,true);
 
   ar.add_option_switch("p","pause_on_checksum_error",
                       "Wait for user input on checksum error.",
-                      &pause_on_checksum_error);
+                      &pause_on_checksum_error,true,true);
   
   ar.add_option_switch("n","ignore_unknown_block_errors",
                       "Ignore errors caused by unknown block types. Errors will be converted to warnings.",
-                      &ignore_unknown_block_errors);
+                      &ignore_unknown_block_errors,true,true);
 
   ar.add_option_switch("g","ignore_object_integrity_errors",
                       "Ignore errors caused by objects without proper end block. \
 Errors will be converted to warnings.",
-                      &ignore_object_integrity_errors);
+                      &ignore_object_integrity_errors,true,true);
+
+  ar.add_option_switch("v","verbose",
+                      "Be a bit more verbose.",
+                      &verbose,true,true);
   
-  ar.add_option_value("i","input_file",
+  ar.add_option_value("i","in_file",
                      "specify input file",
                  &infile_set,&infile,
-                 "<input-file>");
+                     "<input-file>",true,false);
                      
-  ar.add_option_value("o","output_file",
+  ar.add_option_value("o","out_file",
                      "Specify output file.",
                      &outfile_set,&outfile,
-                     "<output_file>");
-                     
-
+                     "<output_file>",true,true);
+  
   ar.add_argument("File from where data is read",
                  &infile_set,&infile,
                  "<input-file>");
-
+  
   ar.add_argument("File to where output is redirected",
                  &outfile_set,&outfile,
                  "<output-file>");
@@ -124,71 +140,215 @@ Errors will be converted to warnings.",
   ar.add_option_value("F","config_file",
                      "Use the specified configuration file.", 
                      &config_file_set,&config_file,
-                     "<file-name>");
+                     "<file-name>",false,true);
+
   
+  // If there's a config file mentioned in the environment, take it!
+  char * env_ldc_config=getenv("LDC_CONFIG");
+  if(env_ldc_config){
+    fprintf(stderr,"Using config file:\"%s\"\n",env_ldc_config);
+    if(dump_vector(ar.read_file(env_ldc_config))){
+      dump_vector(ar.get_help());
+      exit(1);
+    }
+  }
+
   // Process command line first time
-  if((dump_vector(ar.read_args(argc,args))||do_help)){
+  if(dump_vector(ar.read_args(argc,args))){
     dump_vector(ar.get_help());
-    exit(1);
+    exit(7);
   }
   
+  if (do_help) {
+    dump_vector(ar.get_help());
+    exit(0);
+  }
+
   // If user has a config file, use it.
   if (config_file_set){
+    fprintf(stderr,"Using config file:\"%s\"\n",config_file.c_str());
     if(dump_vector(ar.read_file(config_file))){
       dump_vector(ar.get_help());
-      exit(1);
+      exit(7);
     }
+
     // Process command line a second time to override values from config file.
     if(dump_vector(ar.read_args(argc,args))||do_help){
       dump_vector(ar.get_help());
-      exit(1);
+      exit(7);
     }
   }
  
-
-
-  
   if (infile_set==1){
-    printf("Opening file for input:%s\n",infile.c_str());
+    fprintf(stderr,"Opening file for input:%s\n",infile.c_str());
     in_fd=open(infile.c_str(),O_RDONLY);
     if (in_fd<0){
-      printf("Error: could not open file:%s\n",infile.c_str());
-      exit (3);
+      fprintf(stderr,"Error: could not open file \"%s\" for reading!\n",infile.c_str());
+      exit (1);
     }
   }
   
+  if (outfile_set==1){
+    fprintf(stderr,"Opening file for output:%s\n",outfile.c_str());
+    out_fd=open(outfile.c_str(),O_WRONLY|O_TRUNC);
+    if (out_fd<0){
+      fprintf(stderr,"Error: could not open file \"%s\" for writing!\n",outfile.c_str());
+      exit (1);
+    }
+  }
   
-  
-  
+  // The configuration implications according to /cfg007/
+  if (in_fd==0) pause_on_checksum_error=0;
+  if (pause_on_checksum_error==1) ignore_checksum_errors=1;
+  if (output_info||output_called||output_exported||output_unsatisfied)
+    list_contents=0;
+
+  // Now we go to read the data!
+
   vector<tape_block*> tape;
-  
+  vector<vector<tape_block *> > objects;
+  vector<tape_block *> current_object;  
   
   tape_block * block=0;
-  while(1){
+  bool read_ahead=true;
+  int read_pointer=0;
+  int block_start=0;
+  int block_end=0;
+  int blocks_read=0;
+  bool in_object=false;
+  int errors=0;
+  int warnings=0;
+  int errcode=0;
+
+  while(read_ahead){
     block=tape_block::gen_from_fd(in_fd);
-    if (block->get_state()==tape_block::TBS_OK){
+
+    block_start=read_pointer+block->get_discarded_bytes();
+    block_end=block_start+block->get_raw_size()-1;
+    read_pointer=block_end+1;
+    //printf("Discarded:%2x, Raw Size:%2x\n",block->get_discarded_bytes(),block->get_raw_size());
+    switch(block->get_state()){ // switchy
+    case tape_block::TBS_EOF_LEGAL: 
+      delete block;
+      if (!in_object){
+       fprintf(stderr,"File successfully read.\n");
+      } else {
+       if (ignore_object_integrity_errors){
+         fprintf(stderr,"Warning: Object integrity check failed!\n");
+         warnings++;
+       } else {
+         fprintf(stderr,"Error: Object integrity check failed!\n");
+         errors++;
+         errcode=6;
+       }
+      }
+      read_ahead=false;
+      break;
+    case tape_block::TBS_EOF_ILLEGAL:
+      delete block;
+      if (ignore_block_errors){
+       fprintf(stderr,"Warning: Block integrity check failed!\n");
+       warnings++;
+      } else {
+       fprintf(stderr,"Error: Block integrity check failed!\n");
+       errors++;
+       errcode=3;
+      }
+      read_ahead=false;
+      break;
+    case tape_block::TBS_CHECKSUM:
+      delete block;
+      if (ignore_checksum_errors){
+       fprintf(stderr,"Warning: Block checksum wrong!\n");
+       warnings++;
+      } else {
+       fprintf(stderr,"Error: Block checksum wrong!\n");
+       errors++;
+       read_ahead=false;
+       errcode=4;
+      }
+      break;
+    case tape_block::TBS_DEFAULT:
+      delete block;
+      fprintf(stderr,"TBS_DEFAULT encountered ->> SEVERE INTERNAL ERROR!\n");
+      errors++;
+      errcode=100;
+      read_ahead=false;
+      break;
+    case tape_block::TBS_IOERR:
+      delete block;
+      if (in_fd){
+       fprintf(stderr,"Error: Could not read from \"%s\"!\n",infile.c_str());
+      } else {
+       fprintf(stderr,"Error: Could not read from stdin!\n");
+      }
+      errors++;
+      read_ahead=false;
+      errcode=2;
+    case tape_block::TBS_OK:
       tape.insert(tape.end(),block);
-      dump_vector(block->get_description());
-    }
-    else break;
-  }
+      blocks_read++;
+      
+      if (verbose){
+       char buffer[200];
+       snprintf(buffer,200,"Block No. %3i: Start(hex):%5x End(hex):%5x Size(hex):%3x\n",
+                blocks_read-1,
+                block_start,
+                block_end,
+                block->get_raw_size());
+       write (out_fd,buffer,strlen(buffer));
+      }
+
+      if(list_contents)
+       dump_vector(block->get_description());
+      
+      if (block->get_type()==0x10){ // Unknown data block!
+       if (ignore_unknown_block_errors){
+         fprintf(stderr,"Warning: Unknown block type!\n");
+         warnings++;
+       }else {
+         fprintf(stderr,"Error: Unknown block type!\n");
+         errors++;
+         errcode=5;
+         read_ahead=false;
+       }
+      }
+      
+      current_object.insert(current_object.end(),block);
+      
+      if ((block->get_type()==data_block::TBT_EOT)
+         ||((block->get_type()==0)&&(block->get_subtype()==3))
+         ||((block->get_type()==4)||(block->get_type()==3))
+         ||((block->get_type()==0)&&(block->get_subtype()==014))){
+       in_object=false;
+       objects.insert(objects.end(),current_object);
+       current_object.clear();
+      } else {
+       in_object=true;
+      }
+      
+      break;
+    } // switch
+  } // generate loop
+  close(in_fd);
 
-  switch(block->get_state()){
-  case tape_block::TBS_EOF_LEGAL: printf("File successfully read.\n");
-    break;
-  case tape_block::TBS_EOF_ILLEGAL: printf("EOF while in block!\n");
-    break;
-  case tape_block::TBS_CHECKSUM:
-    printf("Checksum error!\n");
-    break;
-  case tape_block::TBS_DEFAULT:
-    printf("TBS_DEFAULT encountered ->> SEVERY INTERNAL ERROR!\n");
-    exit(88);
-  case tape_block::TBS_IOERR:
-    printf("I/O Error... Why?\n");
-    exit (43);
+  // Now we have our blocks, tell the user about that!
+  char buffer[200];
+  sprintf(buffer,"Bytes read:%i Blocks read:%i\nErrors:%i Warnings:%i\n",
+         read_pointer,blocks_read,errors,warnings);
+  if(output_info){
+    write (out_fd,buffer,strlen(buffer));
+  } else {
+    fprintf(stderr,buffer);
+  }
+  
+  if (errors>0){
+    fprintf(stderr,"Errors make me sick. Goodbye!\n");
+    exit(errcode);
   }
 
   return 0;
 } // main()
 
index a7ae129509c0b617ef31c832745a526f4b93c9d7..ecc02376a8681590bd9f20b3d2eacd631edbba00 100644 (file)
@@ -59,7 +59,7 @@ tape_block::tape_block(tape_block & org){
 void tape_block::operator=(tape_block &org){
   block_type=org.block_type;
   init_state=org.init_state;
-  data_read=org.data_read; 
+  discarded_bytes=org.discarded_bytes;
   raw_data=0;  
   raw_size=org.raw_size;  
   word_data=0;
@@ -137,6 +137,16 @@ int tape_block::get_raw_size(){
   return raw_size;
 }
 
+/***************************************************************/
+/*!
+ *\brief Get amount of bytes discarded before beginning
+ *       of block sensed.
+ *\return Length of unusable tape before block start delimiter. 
+ */
+int tape_block::get_discarded_bytes(){
+  return discarded_bytes;
+}
+
 /***************************************************************/
 /*!
  *\brief Access internal raw data buffer
@@ -335,12 +345,16 @@ tape_block::tape_block (int  fd,
 
   block_type= TBT_DISCARD;
   init_state= TBS_DEFAULT;
-  data_read = 0;
+  discarded_bytes=0;
   raw_data  = 0;
   raw_size  = 0;
   word_data = 0;
   word_size = 0;
-  
+  poolsize  = 1024;
+
+  // Get initial portion of memory
+  raw_data=(unsigned char*)malloc(poolsize);
+
   if (input_start) input_start (start_stop_arg);
 
   /* Look for block start in input stream */
@@ -356,7 +370,7 @@ tape_block::tape_block (int  fd,
       init_state=TBS_IOERR;
       return;
     }
-    data_read++;
+    discarded_bytes++;
     
     /* Look for end ot tape sequence */
     switch(eot_needed){
@@ -372,6 +386,7 @@ tape_block::tape_block (int  fd,
       if (buffer==EOT_SEQ_3){
        raw_data=(unsigned char*)malloc(3);
        raw_size=3;
+       discarded_bytes-=3;
        raw_data[0]=EOT_SEQ_1;
        raw_data[1]=EOT_SEQ_2;
        raw_data[2]=EOT_SEQ_3;
@@ -383,7 +398,8 @@ tape_block::tape_block (int  fd,
       break;
     }
   } while (buffer != (unsigned char) BLOCK_START_DELIMITER);
-  
+  discarded_bytes--; // Dont want to declare the start delimiter discarded!
+  raw_size=1;        // But we want to account it here!
 
   /* Now input the block data */
   block_complete = 0;
@@ -400,12 +416,16 @@ tape_block::tape_block (int  fd,
       init_state=TBS_IOERR;
       return;
     }
-    data_read++;                  // We have consumed a byte
     
     /* sort in the new byte */
     raw_size++;
-    raw_data=(unsigned char*)realloc(raw_data,raw_size);
-    raw_data[raw_size-1]=buffer;
+    // Need more memory??
+    if (raw_size==poolsize){
+      poolsize+=1024;
+      raw_data=(unsigned char*)realloc(raw_data,poolsize);
+    }
+
+    raw_data[raw_size-2]=buffer;
 
     /* Look for end ot block sequence */
     switch(eob_needed){
@@ -416,7 +436,6 @@ tape_block::tape_block (int  fd,
     case 1:
       if (buffer==BLOCK_END_DELIMITER_2){
        raw_size-=EOB_LENGTH; // Don't want the delimiter(s) in the data!
-       raw_data=(unsigned char*)realloc(raw_data,raw_size);
        block_complete=1;
       }
       else eob_needed=EOB_LENGTH;
@@ -436,7 +455,8 @@ tape_block::tape_block (int  fd,
     init_state=TBS_CHECKSUM;
     return;
   }
-  
+  raw_size+=EOB_LENGTH; // Now we want it...
+
   block_type=TBT_DATA;    
   init_state=TBS_OK;
 }
index d2ca3df4c0e90a65bf62845e65bff59b9341c17b..c1084e9e5c4bdb17c6825ffda63c4fe7875854c3 100644 (file)
@@ -48,6 +48,7 @@ public: // methods
   virtual int get_subtype();
   virtual vector<string> get_description();
   int get_raw_size();
+  int get_discarded_bytes();
   unsigned char * get_raw_data();
   
   static tape_block * gen_from_fd(int  fd,
@@ -73,11 +74,12 @@ private:   // methods
 protected: // members
   int block_type;             //!< Type of this block.
   tb_state_t init_state;      //!< Initialisation state.
-  int data_read;              //!< Total data consumption during intialisation.
+  int discarded_bytes;        //!< Amount of bytes discarded before beginning.
   unsigned char * raw_data;   //!< Raw block data in bytes.
   int raw_size;               //!< Size of the raw data.
   unsigned short * word_data; //!< Data organized in machine words.
   int word_size;              //!< Size of the blocks in machine words.
+  int poolsize;               //!< Amount of data malloc'ed 
 }; // class tape_block