From d579d0d8e576f391dea18e361d581d3413e19794 Mon Sep 17 00:00:00 2001
From: Carles Fernandez <carles.fernandez@gmail.com>
Date: Sun, 15 Jul 2012 00:47:20 +0000
Subject: [PATCH] Gives and informative message and exits the program when the
 source file is not found, instead of abort and core dumping

git-svn-id: https://svn.code.sf.net/p/gnss-sdr/code/trunk@210 64b25241-fba3-4117-9849-534c7e92360d
---
 .../adapters/file_signal_source.cc            | 392 ++++++++++--------
 1 file changed, 208 insertions(+), 184 deletions(-)

diff --git a/src/algorithms/signal_source/adapters/file_signal_source.cc b/src/algorithms/signal_source/adapters/file_signal_source.cc
index b2c7ba433..d61c54de9 100644
--- a/src/algorithms/signal_source/adapters/file_signal_source.cc
+++ b/src/algorithms/signal_source/adapters/file_signal_source.cc
@@ -7,7 +7,7 @@
  *
  * -------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2011  (see AUTHORS file for a list of contributors)
+ * Copyright (C) 2010-2012  (see AUTHORS file for a list of contributors)
  *
  * GNSS-SDR is a software defined Global Navigation
  *          Satellite Systems receiver
@@ -37,6 +37,7 @@
 #include <iostream>
 #include <fstream>
 #include <iomanip>
+#include <exception>
 #include <gflags/gflags.h>
 #include <glog/log_severity.h>
 #include <glog/logging.h>
@@ -45,109 +46,132 @@
 using google::LogMessage;
 
 DEFINE_string(signal_source, "-",
-        "If defined, path to the file containing the signal samples (overrides the configuration file)");
+    "If defined, path to the file containing the signal samples (overrides the configuration file)");
 
 
 FileSignalSource::FileSignalSource(ConfigurationInterface* configuration,
-        std::string role, unsigned int in_streams, unsigned int out_streams,
-        gr_msg_queue_sptr queue) :
-        role_(role), in_streams_(in_streams), out_streams_(out_streams), queue_(queue)
+    std::string role, unsigned int in_streams, unsigned int out_streams,
+    gr_msg_queue_sptr queue) :
+    role_(role), in_streams_(in_streams), out_streams_(out_streams), queue_(queue)
 {
 
-    std::string default_filename = "../data/sc2_d16.dat";
-    std::string default_item_type = "short";
-    std::string default_dump_filename = "../data/sc2_d16.dat";
+  std::string default_filename = "../data/sc2_d16.dat";
+  std::string default_item_type = "short";
+  std::string default_dump_filename = "../data/sc2_d16.dat";
 
-    samples_ = configuration->property(role + ".samples", 0);
-    sampling_frequency_ = configuration->property(role + ".sampling_frequency", 0);
-    filename_ = configuration->property(role + ".filename", default_filename);
+  samples_ = configuration->property(role + ".samples", 0);
+  sampling_frequency_ = configuration->property(role + ".sampling_frequency", 0);
+  filename_ = configuration->property(role + ".filename", default_filename);
 
-    // override value with commandline flag, if present
-    if (FLAGS_signal_source.compare("-") != 0) filename_= FLAGS_signal_source;
+  // override value with commandline flag, if present
+  if (FLAGS_signal_source.compare("-") != 0) filename_= FLAGS_signal_source;
 
-    item_type_ = configuration->property(role + ".item_type", default_item_type);
-    repeat_ = configuration->property(role + ".repeat", false);
-    dump_ = configuration->property(role + ".dump", false);
-    dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename);
-    enable_throttle_control_ = configuration->property(role + ".enable_throttle_control", false);
+  item_type_ = configuration->property(role + ".item_type", default_item_type);
+  repeat_ = configuration->property(role + ".repeat", false);
+  dump_ = configuration->property(role + ".dump", false);
+  dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename);
+  enable_throttle_control_ = configuration->property(role + ".enable_throttle_control", false);
 
-    if (item_type_.compare("gr_complex") == 0)
+  if (item_type_.compare("gr_complex") == 0)
+    {
+      item_size_ = sizeof(gr_complex);
+    }
+  else if (item_type_.compare("float") == 0)
+    {
+      item_size_ = sizeof(float);
+    }
+  else if (item_type_.compare("short") == 0)
+    {
+      item_size_ = sizeof(short);
+    }
+  else
+    {
+      LOG_AT_LEVEL(WARNING) << item_type_
+          << " unrecognized item type. Using short.";
+      item_size_ = sizeof(short);
+    }
+  try
+  {
+      file_source_ = gr_make_file_source(item_size_, filename_.c_str(), repeat_);
+  }
+  catch (const std::exception &e)
+  {
+      std::cerr
+      << "The receiver was configured to work with a file signal source "
+      << std::endl
+      << "but the specified file is unreachable by GNSS-SDR."
+      << std::endl
+      << "Please modify the configuration at "
+      << "conf/gnss-sdr.conf (the default configuration file)"
+      << std::endl
+      << "and point SignalSource.filename to a valid file,"
+      << std::endl
+      << "or specify your own receiver and source with the flag"
+      << std::endl
+      <<"gnss-sdr --config_file=my_GNSS_SDR_configuration"
+      << std::endl;
+      LOG_AT_LEVEL(INFO) << "file_signal_source: Unable to open the samples file "
+          << filename_.c_str() << ", exiting the program.";
+      exit(1);
+  }
+
+  DLOG(INFO) << "file_source(" << file_source_->unique_id() << ")";
+
+  if (samples_ == 0)
+    {
+      /*!
+       * BUG workaround: The GNURadio file source does not stop the receiver after reaching the End of File.
+       * A possible solution is to compute the file length in samples using file size, excluding the last 100 milliseconds, and enable always the
+       * valve block
+       */
+      std::ifstream file (filename_.c_str(), std::ios::in | std::ios::binary | std::ios::ate);
+      std::ifstream::pos_type size;
+      if (file.is_open())
         {
-            item_size_ = sizeof(gr_complex);
+          size = file.tellg();
         }
-    else if (item_type_.compare("float") == 0)
+      else
         {
-            item_size_ = sizeof(float);
+          std::cout << "file_signal_source: Unable to open the samples file " << filename_.c_str() << std::endl;
+          LOG_AT_LEVEL(ERROR) << "file_signal_source: Unable to open the samples file " << filename_.c_str();
         }
-    else if (item_type_.compare("short") == 0)
+      std::cout << std::setprecision(16);
+      std::cout <<"Processing file " << filename_ << ", which contains " << (double)size << " [bytes]" << std::endl;
+      if (size > 0)
         {
-            item_size_ = sizeof(short);
-        }
-    else
-        {
-            LOG_AT_LEVEL(WARNING) << item_type_
-                    << " unrecognized item type. Using short.";
-            item_size_ = sizeof(short);
-        }
+          samples_ = floor((double)size / (double)item_size()) - ceil(0.1 * (double)sampling_frequency_); //process all the samples available in the file excluding the last 100 ms
 
-    file_source_ = gr_make_file_source(item_size_, filename_.c_str(), repeat_);
-    DLOG(INFO) << "file_source(" << file_source_->unique_id() << ")";
-
-    if (samples_ == 0)
-        {
-            /*!
-             * BUG workaround: The GNURadio file source does not stop the receiver after reaching the End of File.
-             * A possible solution is to compute the file length in samples using file size, excluding the last 100 milliseconds, and enable always the
-             * valve block
-             */
-            std::ifstream file (filename_.c_str(), std::ios::in | std::ios::binary | std::ios::ate);
-            std::ifstream::pos_type size;
-            if (file.is_open())
-                {
-                    size = file.tellg();
-                }
-            else
-                {
-                    std::cout << "file_signal_source: Unable to open the samples file " << filename_.c_str() << std::endl;
-                    LOG_AT_LEVEL(ERROR) << "file_signal_source: Unable to open the samples file " << filename_.c_str();
-                }
-            std::cout << std::setprecision(16);
-            std::cout <<"Processing file " << filename_ << ", which contains " << (double)size << " [bytes]" << std::endl;
-            if (size > 0)
-                {
-                    samples_ = floor((double)size / (double)item_size()) - ceil(0.1 * (double)sampling_frequency_); //process all the samples available in the file excluding the last 100 ms
-
-                }
-        }
-    double signal_duration_s;
-    signal_duration_s = (double)samples_ * ( 1 /(double)sampling_frequency_);
-    DLOG(INFO) << "Total samples to be processed= "<< samples_ << " GNSS signal duration= " << signal_duration_s << " [s]";
-    std::cout << "GNSS signal recorded time to be processed: " << signal_duration_s << " [s]" << std::endl;
-    // if samples != 0 then enable a flow valve to stop the process after n samples
-    if (samples_ != 0)
-        {
-            valve_ = gnss_sdr_make_valve(item_size_, samples_, queue_);
-            DLOG(INFO) << "valve(" << valve_->unique_id() << ")";
         }
+    }
+  double signal_duration_s;
+  signal_duration_s = (double)samples_ * ( 1 /(double)sampling_frequency_);
+  DLOG(INFO) << "Total samples to be processed= "<< samples_ << " GNSS signal duration= " << signal_duration_s << " [s]";
+  std::cout << "GNSS signal recorded time to be processed: " << signal_duration_s << " [s]" << std::endl;
+  // if samples != 0 then enable a flow valve to stop the process after n samples
+  if (samples_ != 0)
+    {
+      valve_ = gnss_sdr_make_valve(item_size_, samples_, queue_);
+      DLOG(INFO) << "valve(" << valve_->unique_id() << ")";
+    }
 
-    if (dump_)
-        {
-            sink_ = gr_make_file_sink(item_size_, dump_filename_.c_str());
-            DLOG(INFO) << "file_sink(" << sink_->unique_id() << ")";
-        }
+  if (dump_)
+    {
+      sink_ = gr_make_file_sink(item_size_, dump_filename_.c_str());
+      DLOG(INFO) << "file_sink(" << sink_->unique_id() << ")";
+    }
 
-    if (enable_throttle_control_)
-        {
-            throttle_ = gr_make_throttle(item_size_, sampling_frequency_);
-        }
-    DLOG(INFO) << "File source filename " << filename_;
-    DLOG(INFO) << "Samples " << samples_;
-    DLOG(INFO) << "Sampling frequency " << sampling_frequency_;
-    DLOG(INFO) << "Item type " << item_type_;
-    DLOG(INFO) << "Item size " << item_size_;
-    DLOG(INFO) << "Repeat " << repeat_;
-    DLOG(INFO) << "Dump " << dump_;
-    DLOG(INFO) << "Dump filename " << dump_filename_;
+  if (enable_throttle_control_)
+    {
+      throttle_ = gr_make_throttle(item_size_, sampling_frequency_);
+    }
+  DLOG(INFO) << "File source filename " << filename_;
+  DLOG(INFO) << "Samples " << samples_;
+  DLOG(INFO) << "Sampling frequency " << sampling_frequency_;
+  DLOG(INFO) << "Item type " << item_type_;
+  DLOG(INFO) << "Item size " << item_size_;
+  DLOG(INFO) << "Repeat " << repeat_;
+  DLOG(INFO) << "Dump " << dump_;
+  DLOG(INFO) << "Dump filename " << dump_filename_;
 }
 
 
@@ -161,52 +185,52 @@ FileSignalSource::~FileSignalSource()
 
 void FileSignalSource::connect(gr_top_block_sptr top_block)
 {
-    if (samples_ != 0)
+  if (samples_ != 0)
+    {
+      if (enable_throttle_control_ == true)
         {
-            if (enable_throttle_control_ == true)
-                {
-                    top_block->connect(file_source_, 0, throttle_, 0);
-                    DLOG(INFO) << "connected file source to throttle";
-                    top_block->connect(throttle_, 0, valve_, 0);
-                    DLOG(INFO) << "connected throttle to valve";
-                    if (dump_)
-                        {
-                            top_block->connect(valve_, 0, sink_, 0);
-                            DLOG(INFO) << "connected valve to file sink";
-                        }
-                }
-            else
-                {
-                    top_block->connect(file_source_, 0, valve_, 0);
-                    DLOG(INFO) << "connected file source to valve";
-                    if (dump_)
-                        {
-                            top_block->connect(valve_, 0, sink_, 0);
-                            DLOG(INFO) << "connected valve to file sink";
-                        }
-                }
+          top_block->connect(file_source_, 0, throttle_, 0);
+          DLOG(INFO) << "connected file source to throttle";
+          top_block->connect(throttle_, 0, valve_, 0);
+          DLOG(INFO) << "connected throttle to valve";
+          if (dump_)
+            {
+              top_block->connect(valve_, 0, sink_, 0);
+              DLOG(INFO) << "connected valve to file sink";
+            }
         }
-    else
+      else
         {
-            if (enable_throttle_control_ == true)
-                {
-                    top_block->connect(file_source_, 0, throttle_, 0);
-                    DLOG(INFO) << "connected file source to throttle";
-                    if (dump_)
-                        {
-                            top_block->connect(file_source_, 0, sink_, 0);
-                            DLOG(INFO) << "connected file source to sink";
-                        }
-                }
-            else
-                {
-                    if (dump_)
-                        {
-                            top_block->connect(file_source_, 0, sink_, 0);
-                            DLOG(INFO) << "connected file source to sink";
-                        }
-                }
+          top_block->connect(file_source_, 0, valve_, 0);
+          DLOG(INFO) << "connected file source to valve";
+          if (dump_)
+            {
+              top_block->connect(valve_, 0, sink_, 0);
+              DLOG(INFO) << "connected valve to file sink";
+            }
         }
+    }
+  else
+    {
+      if (enable_throttle_control_ == true)
+        {
+          top_block->connect(file_source_, 0, throttle_, 0);
+          DLOG(INFO) << "connected file source to throttle";
+          if (dump_)
+            {
+              top_block->connect(file_source_, 0, sink_, 0);
+              DLOG(INFO) << "connected file source to sink";
+            }
+        }
+      else
+        {
+          if (dump_)
+            {
+              top_block->connect(file_source_, 0, sink_, 0);
+              DLOG(INFO) << "connected file source to sink";
+            }
+        }
+    }
 }
 
 
@@ -216,52 +240,52 @@ void FileSignalSource::connect(gr_top_block_sptr top_block)
 
 void FileSignalSource::disconnect(gr_top_block_sptr top_block)
 {
-    if (samples_ != 0)
+  if (samples_ != 0)
+    {
+      if (enable_throttle_control_ == true)
         {
-            if (enable_throttle_control_ == true)
-                {
-                    top_block->disconnect(file_source_, 0, throttle_, 0);
-                    DLOG(INFO) << "disconnected file source to throttle";
-                    top_block->disconnect(throttle_, 0, valve_, 0);
-                    DLOG(INFO) << "disconnected throttle to valve";
-                    if (dump_)
-                        {
-                            top_block->disconnect(valve_, 0, sink_, 0);
-                            DLOG(INFO) << "disconnected valve to file sink";
-                        }
-                }
-            else
-                {
-                    top_block->disconnect(file_source_, 0, valve_, 0);
-                    DLOG(INFO) << "disconnected file source to valve";
-                    if (dump_)
-                        {
-                            top_block->disconnect(valve_, 0, sink_, 0);
-                            DLOG(INFO) << "disconnected valve to file sink";
-                        }
-                }
+          top_block->disconnect(file_source_, 0, throttle_, 0);
+          DLOG(INFO) << "disconnected file source to throttle";
+          top_block->disconnect(throttle_, 0, valve_, 0);
+          DLOG(INFO) << "disconnected throttle to valve";
+          if (dump_)
+            {
+              top_block->disconnect(valve_, 0, sink_, 0);
+              DLOG(INFO) << "disconnected valve to file sink";
+            }
         }
-    else
+      else
         {
-            if (enable_throttle_control_ == true)
-                {
-                    top_block->disconnect(file_source_, 0, throttle_, 0);
-                    DLOG(INFO) << "disconnected file source to throttle";
-                    if (dump_)
-                        {
-                            top_block->disconnect(file_source_, 0, sink_, 0);
-                            DLOG(INFO) << "disconnected file source to sink";
-                        }
-                }
-            else
-                {
-                    if (dump_)
-                        {
-                            top_block->disconnect(file_source_, 0, sink_, 0);
-                            DLOG(INFO) << "disconnected file source to sink";
-                        }
-                }
+          top_block->disconnect(file_source_, 0, valve_, 0);
+          DLOG(INFO) << "disconnected file source to valve";
+          if (dump_)
+            {
+              top_block->disconnect(valve_, 0, sink_, 0);
+              DLOG(INFO) << "disconnected valve to file sink";
+            }
         }
+    }
+  else
+    {
+      if (enable_throttle_control_ == true)
+        {
+          top_block->disconnect(file_source_, 0, throttle_, 0);
+          DLOG(INFO) << "disconnected file source to throttle";
+          if (dump_)
+            {
+              top_block->disconnect(file_source_, 0, sink_, 0);
+              DLOG(INFO) << "disconnected file source to sink";
+            }
+        }
+      else
+        {
+          if (dump_)
+            {
+              top_block->disconnect(file_source_, 0, sink_, 0);
+              DLOG(INFO) << "disconnected file source to sink";
+            }
+        }
+    }
 }
 
 
@@ -270,9 +294,9 @@ void FileSignalSource::disconnect(gr_top_block_sptr top_block)
 
 gr_basic_block_sptr FileSignalSource::get_left_block()
 {
-    LOG_AT_LEVEL(WARNING)
-                    << "Left block of a signal source should not be retrieved";
-    return gr_block_sptr();
+  LOG_AT_LEVEL(WARNING)
+                        << "Left block of a signal source should not be retrieved";
+  return gr_block_sptr();
 }
 
 
@@ -281,19 +305,19 @@ gr_basic_block_sptr FileSignalSource::get_left_block()
 
 gr_basic_block_sptr FileSignalSource::get_right_block()
 {
-    if (samples_ != 0)
+  if (samples_ != 0)
+    {
+      return valve_;
+    }
+  else
+    {
+      if (enable_throttle_control_ == true)
         {
-            return valve_;
+          return throttle_;
         }
-    else
+      else
         {
-            if (enable_throttle_control_ == true)
-                {
-                    return throttle_;
-                }
-            else
-                {
-                    return file_source_;
-                }
+          return file_source_;
         }
+    }
 }