HardwareCanSourceCanfile.cpp
Go to the documentation of this file.
00001 // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*-
00002 
00003 // -- BEGIN LICENSE BLOCK ----------------------------------------------
00004 // This file is part of FZIs ic_workspace.
00005 //
00006 // This program is free software licensed under the LGPL
00007 // (GNU LESSER GENERAL PUBLIC LICENSE Version 3).
00008 // You can find a copy of this license in LICENSE folder in the top
00009 // directory of the source code.
00010 //
00011 // © Copyright 2016 FZI Forschungszentrum Informatik, Karlsruhe, Germany
00012 //
00013 // -- END LICENSE BLOCK ------------------------------------------------
00014 
00015 //----------------------------------------------------------------------
00024 //----------------------------------------------------------------------
00025 #include "HardwareCanSourceCanfile.h"
00026 
00027 #include <icl_core_config/Config.h>
00028 #include <icl_sourcesink/SimpleURI.h>
00029 #include <icl_sourcesink/Position.h>
00030 
00031 #include "icl_hardware_can/Logging.h"
00032 
00033 namespace icl_hardware {
00034 namespace can {
00035 
00036 HardwareCanSourceCanfile::HardwareCanSourceCanfile(const std::string& uri,
00037                                                    const std::string& name)
00038   : HardwareCanSource(uri, name,
00039                       icl_sourcesink::PositionResolverBase::Ptr(
00040                         new icl_sourcesink::KeyframePositionResolver(
00041                           icl_sourcesink::FileResolutionHelper::Ptr(
00042                             new CanFileResolutionHelper(icl_sourcesink::SimpleURI(uri).path())),
00043                           1000))),
00044     m_buffer(),
00045     m_resolver_x(
00046       boost::dynamic_pointer_cast<icl_sourcesink::KeyframePositionResolver>(
00047         m_resolver)),
00048     m_resolution_helper(
00049       dynamic_cast<CanFileResolutionHelper *>(
00050         m_resolver_x->resolutionHelper()->clone())),
00051     m_sequence_number(0)
00052 {
00053   prepareFile();
00054 }
00055 
00056 void HardwareCanSourceCanfile::prepareFile()
00057 {
00058   if (!m_resolution_helper)
00059   {
00060     LOGGING_ERROR_C(CAN, HardwareCanSourceCanfile,
00061                     "Failed to open URI '" << uri() << "'." << endl);
00062     m_is_good = false;
00063     return;
00064   }
00065 
00066   // Check for a resolver index cache.
00067   LOGGING_DEBUG_C(CAN, HardwareCanSourceCanfile,
00068                   "Checking for resolver index cache." << endl);
00069   std::string resolver_index_filename =
00070     icl_sourcesink::SimpleURI(uri()).path()
00071     + icl_sourcesink::PositionResolverBase::INDEX_FILE_SUFFIX;
00072   LOGGING_DEBUG_C(CAN, HardwareCanSourceCanfile,
00073                   "Checking for resolver index cache at '" << resolver_index_filename << "'..." << endl);
00074   if (m_resolver->load(resolver_index_filename))
00075   {
00076     LOGGING_INFO_C(CAN, HardwareCanSourceCanfile,
00077                    "Successfully loaded resolver index cache from '" << resolver_index_filename << "'." << endl);
00078   }
00079   else
00080   {
00081     // Build the resolver index.
00082     LOGGING_DEBUG_C(CAN, HardwareCanSourceCanfile,
00083                     "No resolver index cache found, building index." << endl);
00084     uint64_t filesize = m_resolution_helper->size();
00085     std::size_t count = 0;
00086     for (; m_resolution_helper->good(); m_resolution_helper->advance())
00087     {
00088       icl_sourcesink::Position pos = m_resolution_helper->current();
00089       uint64_t filepos = m_resolution_helper->tellg();
00090       m_resolver_x->addEntry(pos.timestamp, pos.dsin, filepos);
00091       if (++count % 1000 == 0)
00092       {
00093         std::cerr << "Building resolver index: "
00094                   << int(double(filepos)*100.0/double(filesize)) << "%  \r"
00095                   << std::flush;
00096       }
00097     }
00098     std::cerr << "Resolver index completed.         " << std::endl;
00099 
00100     // Store resolver index cache.
00101     LOGGING_DEBUG_C(CAN, HardwareCanSourceCanfile,
00102                     "Storing resolver index cache at '" << resolver_index_filename << "'." << endl);
00103     if (!m_resolver->save(resolver_index_filename))
00104     {
00105       LOGGING_WARNING_C(CAN, HardwareCanSourceCanfile,
00106                         "Failed to store resolver index cache at '" << resolver_index_filename << "'." << endl);
00107     }
00108   }
00109 
00110   // Reset file to first element position and make fragmentable.
00111   m_resolver->makeFragmentable();
00112   m_is_good = seek(icl_sourcesink::Index(0));
00113 
00114   // Done.
00115   LOGGING_DEBUG_C(CAN, HardwareCanSourceCanfile,
00116                   "Resolver index complete, total number of elements: " << m_resolver->registerSize() << endl);
00117 }
00118 
00119 bool HardwareCanSourceCanfile::seekImpl(const icl_sourcesink::InternalIndex internal_index)
00120 {
00121   // InternalIndex == RegisterIndex.
00122   icl_sourcesink::Position pos(m_resolver_x->mapIndex<icl_sourcesink::Index>(internal_index));
00123   boost::optional<uint64_t> seek_pos = m_resolver_x->resolveExtra(pos, icl_sourcesink::RT_EXACT);
00124   if (seek_pos)
00125   {
00126     if (!m_resolution_helper->seekg(*seek_pos))
00127     {
00128       LOGGING_ERROR_C(CAN, HardwareCanSourceCanfile,
00129                       "Failed to seek to position " << seek_pos
00130                       << " even though the resolver had a valid entry for that position!" << endl);
00131       m_buffer.reset();
00132       m_is_good = false;
00133       return false;
00134     }
00135     m_buffer = m_resolution_helper->currentMessage();
00136     m_buffer->header().sequence_number = m_sequence_number++;
00137     return true;
00138   }
00139   else
00140   {
00141     LOGGING_WARNING_C(CAN, HardwareCanSourceCanfile,
00142                       "Failed to resolve internal index " << internal_index.value
00143                       << ", probably end of file" << endl);
00144     m_buffer.reset();
00145     return false;
00146   }
00147 }
00148 
00149 bool HardwareCanSourceCanfile::advance()
00150 {
00151   if (m_resolver->advance())
00152   {
00153     if (!m_resolution_helper->advance())
00154     {
00155       LOGGING_ERROR_C(CAN, HardwareCanSourceCanfile,
00156                       "Resolution helper failed to advance. This should not happen!" << endl);
00157       return false;
00158     }
00159     else
00160     {
00161       m_buffer = m_resolution_helper->currentMessage();
00162       m_buffer->header().sequence_number = m_sequence_number++;
00163       return true;
00164     }
00165   }
00166   else
00167   {
00168     LOGGING_WARNING_C(CAN, HardwareCanSourceCanfile,
00169                       "Failed to advance, probably end of file" << endl);
00170     m_buffer.reset();
00171     m_is_good = false;
00172     return false;
00173   }
00174 }
00175 
00176 }
00177 }


fzi_icl_can
Author(s):
autogenerated on Thu Jun 6 2019 20:26:01