HardwareCanSourceCanfile.cpp
Go to the documentation of this file.
1 // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*-
2 
3 // -- BEGIN LICENSE BLOCK ----------------------------------------------
4 // This file is part of FZIs ic_workspace.
5 //
6 // This program is free software licensed under the LGPL
7 // (GNU LESSER GENERAL PUBLIC LICENSE Version 3).
8 // You can find a copy of this license in LICENSE folder in the top
9 // directory of the source code.
10 //
11 // © Copyright 2016 FZI Forschungszentrum Informatik, Karlsruhe, Germany
12 //
13 // -- END LICENSE BLOCK ------------------------------------------------
14 
15 //----------------------------------------------------------------------
24 //----------------------------------------------------------------------
26 
27 #include <icl_core_config/Config.h>
28 #include <icl_sourcesink/SimpleURI.h>
29 #include <icl_sourcesink/Position.h>
30 
32 
33 namespace icl_hardware {
34 namespace can {
35 
37  const std::string& name)
38  : HardwareCanSource(uri, name,
39  icl_sourcesink::PositionResolverBase::Ptr(
40  new icl_sourcesink::KeyframePositionResolver(
41  icl_sourcesink::FileResolutionHelper::Ptr(
42  new CanFileResolutionHelper(icl_sourcesink::SimpleURI(uri).path())),
43  1000))),
44  m_buffer(),
45  m_resolver_x(
46  boost::dynamic_pointer_cast<icl_sourcesink::KeyframePositionResolver>(
47  m_resolver)),
48  m_resolution_helper(
49  dynamic_cast<CanFileResolutionHelper *>(
50  m_resolver_x->resolutionHelper()->clone())),
51  m_sequence_number(0)
52 {
53  prepareFile();
54 }
55 
57 {
59  {
61  "Failed to open URI '" << uri() << "'." << endl);
62  m_is_good = false;
63  return;
64  }
65 
66  // Check for a resolver index cache.
68  "Checking for resolver index cache." << endl);
69  std::string resolver_index_filename =
70  icl_sourcesink::SimpleURI(uri()).path()
71  + icl_sourcesink::PositionResolverBase::INDEX_FILE_SUFFIX;
73  "Checking for resolver index cache at '" << resolver_index_filename << "'..." << endl);
74  if (m_resolver->load(resolver_index_filename))
75  {
77  "Successfully loaded resolver index cache from '" << resolver_index_filename << "'." << endl);
78  }
79  else
80  {
81  // Build the resolver index.
83  "No resolver index cache found, building index." << endl);
84  uint64_t filesize = m_resolution_helper->size();
85  std::size_t count = 0;
86  for (; m_resolution_helper->good(); m_resolution_helper->advance())
87  {
88  icl_sourcesink::Position pos = m_resolution_helper->current();
89  uint64_t filepos = m_resolution_helper->tellg();
90  m_resolver_x->addEntry(pos.timestamp, pos.dsin, filepos);
91  if (++count % 1000 == 0)
92  {
93  std::cerr << "Building resolver index: "
94  << int(double(filepos)*100.0/double(filesize)) << "% \r"
95  << std::flush;
96  }
97  }
98  std::cerr << "Resolver index completed. " << std::endl;
99 
100  // Store resolver index cache.
102  "Storing resolver index cache at '" << resolver_index_filename << "'." << endl);
103  if (!m_resolver->save(resolver_index_filename))
104  {
106  "Failed to store resolver index cache at '" << resolver_index_filename << "'." << endl);
107  }
108  }
109 
110  // Reset file to first element position and make fragmentable.
111  m_resolver->makeFragmentable();
112  m_is_good = seek(icl_sourcesink::Index(0));
113 
114  // Done.
116  "Resolver index complete, total number of elements: " << m_resolver->registerSize() << endl);
117 }
118 
119 bool HardwareCanSourceCanfile::seekImpl(const icl_sourcesink::InternalIndex internal_index)
120 {
121  // InternalIndex == RegisterIndex.
122  icl_sourcesink::Position pos(m_resolver_x->mapIndex<icl_sourcesink::Index>(internal_index));
123  boost::optional<uint64_t> seek_pos = m_resolver_x->resolveExtra(pos, icl_sourcesink::RT_EXACT);
124  if (seek_pos)
125  {
126  if (!m_resolution_helper->seekg(*seek_pos))
127  {
129  "Failed to seek to position " << seek_pos
130  << " even though the resolver had a valid entry for that position!" << endl);
131  m_buffer.reset();
132  m_is_good = false;
133  return false;
134  }
135  m_buffer = m_resolution_helper->currentMessage();
136  m_buffer->header().sequence_number = m_sequence_number++;
137  return true;
138  }
139  else
140  {
142  "Failed to resolve internal index " << internal_index.value
143  << ", probably end of file" << endl);
144  m_buffer.reset();
145  return false;
146  }
147 }
148 
150 {
151  if (m_resolver->advance())
152  {
153  if (!m_resolution_helper->advance())
154  {
156  "Resolution helper failed to advance. This should not happen!" << endl);
157  return false;
158  }
159  else
160  {
161  m_buffer = m_resolution_helper->currentMessage();
162  m_buffer->header().sequence_number = m_sequence_number++;
163  return true;
164  }
165  }
166  else
167  {
169  "Failed to advance, probably end of file" << endl);
170  m_buffer.reset();
171  m_is_good = false;
172  return false;
173  }
174 }
175 
176 }
177 }
#define LOGGING_INFO_C(streamname, classname, arg)
virtual bool advance()
Implementation of DataSourceBase::advance().
icl_sourcesink::DataSource< tCanMessage > HardwareCanSource
Base type for all sources providing tCanMessage data.
HardwareCanSourceCanfile(const std::string &uri, const std::string &name="HardwareCanSourceCanfile")
std::size_t m_sequence_number
Ever-increasing sequence number.
#define LOGGING_WARNING_C(streamname, classname, arg)
unsigned __int64 uint64_t
#define LOGGING_DEBUG_C(streamname, classname, arg)
ThreadStream & endl(ThreadStream &stream)
CanMessageStamped::Ptr m_buffer
Buffers the current data element.
icl_sourcesink::KeyframePositionResolver::Ptr m_resolver_x
CanFileResolutionHelper::Ptr m_resolution_helper
Our own resolution helper.
virtual bool seekImpl(const icl_sourcesink::InternalIndex internal_index)
Implementation of DataSourceBase::seekImpl().
boost::shared_ptr< HardwareCanSourceCanfile > Ptr
Shared pointer shorthand.
#define LOGGING_ERROR_C(streamname, classname, arg)


fzi_icl_can
Author(s):
autogenerated on Mon Jun 10 2019 13:17:02