<commit_before>/******************************************************************************\
* File:          lexer.cpp
* Purpose:       Implementation of lexer classes
* Author:        Anton van Wezenbeek
* RCS-ID:        $Id$
*
* Copyright (c) 1998-2009 Anton van Wezenbeek
* All rights are reserved. Reproduction in whole or part is prohibited
* without the written consent of the copyright owner.
\******************************************************************************/

#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
//#include <numeric> // both for accumulate
//#include <functional>
#include <algorithm>
#include <wx/tokenzr.h>
#include <wx/extension/lexer.h>
#include <wx/extension/lexers.h>
#include <wx/extension/stc.h>
#include <wx/extension/util.h> // for wxExAlignText

wxExLexer::wxExLexer(const wxXmlNode* node)
{
  m_CommentBegin.clear();
  m_CommentBegin2.clear();
  m_CommentEnd.clear();
  m_CommentEnd2.clear();
  m_Styles.clear();
  m_Extensions.clear();
  m_Properties.clear();
  m_Keywords.clear();
  m_KeywordsSet.clear();
  m_ScintillaLexer.clear();

  if (node != NULL)
  {
    Set(node);
  }
}

const std::vector<wxExStyle> wxExLexer::AutoMatch(
  const wxString& lexer) const
{
  std::vector<wxExStyle> text;

  auto itlow =
    wxExLexers::Get()->GetMacros().lower_bound(lexer);

  auto itup =
    wxExLexers::Get()->GetMacros().upper_bound(lexer + "ZZZ");

  for (
    auto it = itlow;
    it != itup;
    ++it)
  {
    for (
      auto style =
        wxExLexers::Get()->GetMacrosStyle().begin();
      style != wxExLexers::Get()->GetMacrosStyle().end();
      ++style)
    {
      if (it->first.Contains(style->first))
      {
        text.push_back(wxExStyle(it->second, style->second));
      }
    }
  }

  return text;
}

void wxExLexer::Colourise(wxExSTC* stc) const
{
  for_each (m_Styles.begin(), m_Styles.end(),
    std::bind2nd(std::mem_fun_ref(&wxExStyle::Apply), stc));

  // And finally colour the entire document.
  stc->Colourise(0, stc->GetLength() - 1);

  const int margin_fold_no = stc->GetMarginFoldingNumber();

  if (stc->GetProperty("fold") == "1")
  {
    stc->SetMarginWidth(margin_fold_no,
      wxConfigBase::Get()->ReadLong(_("Folding"), 16));

    stc->SetFoldFlags(
      wxConfigBase::Get()->ReadLong(_("Fold Flags"),
      wxSTC_FOLDFLAG_LINEBEFORE_CONTRACTED | wxSTC_FOLDFLAG_LINEAFTER_CONTRACTED));
  }
  else
  {
    stc->SetMarginWidth(margin_fold_no, 0);
  }
}

const wxString wxExLexer::GetFormattedText(
  const wxString& lines,
  const wxString& header,
  bool fill_out_with_space,
  bool fill_out) const
{
  wxString text = lines, header_to_use = header;
  size_t nCharIndex;

  wxString out;

  // Process text between the carriage return line feeds.
  while ((nCharIndex = text.find("\n")) != wxString::npos)
  {
    out << wxExAlignText(
      text.substr(0, nCharIndex),
      header_to_use,
      fill_out_with_space,
      fill_out,
      *this);

    text = text.substr(nCharIndex + 1);
    header_to_use = wxString(' ', header.size());
  }

  if (!text.empty())
  {
    out << wxExAlignText(
      text,
      header_to_use,
      fill_out_with_space,
      fill_out,
      *this);
  }

  return out;
}

const wxString wxExLexer::GetKeywordsString(int keyword_set) const
{
  if (keyword_set == -1)
  {
    return GetKeywordsStringSet(m_Keywords);
  }
  else
  {
    const auto it =
      m_KeywordsSet.find(keyword_set);

    if (it != m_KeywordsSet.end())
    {
      return GetKeywordsStringSet(it->second);
    }
  }

  return wxEmptyString;
}

const wxString wxExLexer::GetKeywordsStringSet(
  const std::set<wxString>& kset) const
{
  // accumulate would be nice, but does not add a space, could not do it easily.
  // return accumulate(kset.begin(), kset.end(), wxEmptyString);
  wxString keywords;

  for (
    auto it = kset.begin();
    it != kset.end();
    ++it)
  {
    keywords += *it + " ";
  }

  return keywords.Trim(); // remove the ending space
}

bool wxExLexer::IsKeyword(const wxString& word) const
{
  const auto it = m_Keywords.find(word);
  return (it != m_Keywords.end());
}

bool wxExLexer::IsOk() const
{
  // At this moment ok if scintilla lexer has been filled.
  return !m_ScintillaLexer.empty();
}

bool wxExLexer::KeywordStartsWith(const wxString& word) const
{
  const auto it = m_Keywords.lower_bound(word.Lower());
  return
    it != m_Keywords.end() &&
    it->StartsWith(word.Lower());
}

const wxString wxExLexer::MakeComment(
  const wxString& text,
  bool fill_out_with_space,
  bool fill_out) const
{
  wxString out;

  text.find("\n") != wxString::npos ?
    out << GetFormattedText(text, wxEmptyString, fill_out_with_space, fill_out):
    out << wxExAlignText(text, wxEmptyString, fill_out_with_space, fill_out, *this);

  return out;
}

const wxString wxExLexer::MakeComment(
  const wxString& prefix,
  const wxString& text) const
{
  wxString out;

  text.find("\n") != wxString::npos ?
    out << GetFormattedText(text, prefix, true, true):
    out << wxExAlignText(text, prefix, true, true, *this);

  return out;
}

const wxString wxExLexer::MakeSingleLineComment(
  const wxString& text,
  bool fill_out_with_space,
  bool fill_out) const
{
  if (m_CommentBegin.empty() && m_CommentEnd.empty())
  {
    return text;
  }

  // First set the fill_out_character.
  wxUniChar fill_out_character;

  if (fill_out_with_space || m_ScintillaLexer == "hypertext")
  {
    fill_out_character = ' ';
  }
  else
  {
    if (text.empty())
    {
      if (m_CommentBegin == m_CommentEnd)
           fill_out_character = '-';
      else fill_out_character = m_CommentBegin[m_CommentBegin.size() - 1];
    }
    else   fill_out_character = ' ';
  }

  wxString out = m_CommentBegin + fill_out_character + text;

  // Fill out characters.
  if (fill_out)
  {
    // To prevent filling out spaces
    if (fill_out_character != ' ' || !m_CommentEnd.empty())
    {
      const auto fill_chars = UsableCharactersPerLine() - text.size();

      if (fill_chars > 0)
      {
        const wxString fill_out(fill_out_character, fill_chars);
        out += fill_out;
      }
    }
  }

  if (!m_CommentEnd.empty()) out += fill_out_character + m_CommentEnd;

  return out;
}

const std::vector<wxExStyle> wxExLexer::ParseNodeStyles(
  const wxXmlNode* node) const
{
  std::vector<wxExStyle> text;

  wxXmlNode* child = node->GetChildren();

  while (child)
  {
    if (child->GetName() == "style")
    {
      text.push_back(wxExStyle(child));
    }
    else if (child->GetName() == "comment")
    {
      // Ignore comments.
    }
    else
    {
      wxLogError(_("Undefined styles tag: %s on line: %d"),
        child->GetName().c_str(),
        child->GetLineNumber());
    }

    child = child->GetNext();
  }

  return text;
}

void wxExLexer::Set(const wxXmlNode* node)
{
  m_ScintillaLexer = node->GetAttribute("name", "");

#ifdef __WXMSW__
  m_Extensions = node->GetAttribute(
    "extensions",
    "*." + m_ScintillaLexer);
#else
  m_Extensions = node->GetAttribute("extensions", "");
#endif

  if (node->GetAttribute("match", "") != "")
  {
    m_Styles = AutoMatch(node->GetAttribute("match", ""));
  }

  if (m_ScintillaLexer == "hypertext")
  {
    // As our lexers.xml files cannot use xml comments,
    // add them here.
    m_CommentBegin = "<!--";
    m_CommentEnd = "-->";
  }

  wxXmlNode *child = node->GetChildren();

  while (child)
  {
    if (child->GetName() == "styles")
    {
      const std::vector<wxExStyle> v = ParseNodeStyles(child);

      // Do not assign styles to result of ParseNode,
      // as styles might already be filled with result of automatch.
      m_Styles.insert(
        m_Styles.end(),
        v.begin(), v.end());
    }
    else if (child->GetName() == "keywords")
    {
      if (!SetKeywords(child->GetNodeContent().Strip(wxString::both)))
      {
        wxLogError(
          _("Keywords could not be set on line: %d"),
          child->GetLineNumber());
      }
    }
    else if (child->GetName() == "properties")
    {
      m_Properties = wxExLexers::Get()->ParseNodeProperties(child);
    }
    else if (child->GetName() == "comments")
    {
      m_CommentBegin = child->GetAttribute("begin1", "");
      m_CommentEnd = child->GetAttribute("end1", "");
      m_CommentBegin2 = child->GetAttribute("begin2", "");
      m_CommentEnd2 = child->GetAttribute("end2", "");
    }
    else if (child->GetName() == "comment")
    {
      // Ignore comments.
    }
    else
    {
      wxLogError(_("Undefined lexer tag: %s on line: %d"),
        child->GetName().c_str(),
        child->GetLineNumber());
    }

    child = child->GetNext();
  }

  if (!IsOk())
  {
    wxLogError(_("Illegal lexer on line: %d"), node->GetLineNumber());
  }
}

// Adds the specified keywords to the keywords map and the keywords set.
// The text might contain the keyword set after a ':'.
// Returns true if keyword could be added
// and false if specified set is illegal.
// Empties existing keywords.
bool wxExLexer::SetKeywords(const wxString& value)
{
  if (!m_Keywords.empty())
  {
    m_Keywords.clear();
  }

  if (!m_KeywordsSet.empty())
  {
    m_KeywordsSet.clear();
  }

  std::set<wxString> keywords_set;

  wxStringTokenizer tkz(value, "\r\n ");

  int setno = 0;

  while (tkz.HasMoreTokens())
  {
    const wxString line = tkz.GetNextToken();
    wxStringTokenizer fields(line, ":");

    wxString keyword;

    if (fields.CountTokens() > 1)
    {
      keyword = fields.GetNextToken();

      const auto new_setno = atoi(fields.GetNextToken().c_str());

      if (new_setno >= wxSTC_KEYWORDSET_MAX)
      {
        return false;
      }

      if (new_setno != setno)
      {
        if (!keywords_set.empty())
        {
          m_KeywordsSet.insert(make_pair(setno, keywords_set));
          keywords_set.clear();
        }

        setno = new_setno;
      }

      keywords_set.insert(keyword);
    }
    else
    {
      keyword = line;
      keywords_set.insert(line);
    }

    m_Keywords.insert(keyword);
  }

  m_KeywordsSet.insert(make_pair(setno, keywords_set));

  return true;
}

bool wxExLexer::SetScintillaLexer(
  const wxString& lexer,
  wxExSTC* stc,
  bool show_error)
{
  stc->ClearDocumentStyle();

  for_each (m_Properties.begin(), m_Properties.end(),
    std::bind2nd(std::mem_fun_ref(&wxExProperty::ApplyReset), stc));

  (*this) = wxExLexers::Get()->FindByName(lexer);

  stc->SetLexerLanguage(m_ScintillaLexer);

  if (!IsOk())
  {
    (*this) = wxExLexers::Get()->FindByText(stc->GetLine(0));

    stc->SetLexerLanguage(m_ScintillaLexer);
  }

  if (
      IsOk() &&
      // And check whether the GetLexer from scintilla has a good value.
      // Otherwise it is not known, and we better show an error.
      stc->GetLexer() == wxSTC_LEX_NULL &&
      show_error)
  {
    wxLogError(_("Lexer is not known") + ": " + m_ScintillaLexer);
  }

  // Reset keywords, also if no lexer is available.
  for (size_t setno = 0; setno < wxSTC_KEYWORDSET_MAX; setno++)
  {
    stc->SetKeyWords(setno, wxEmptyString);
  }

  // Readme: The Scintilla lexer only recognized lower case words, apparently.
  for (
    auto it = m_KeywordsSet.begin();
    it != m_KeywordsSet.end();
    ++it)
  {
    stc->SetKeyWords(
      it->first,
      GetKeywordsString(it->first).Lower());
  }

  wxExLexers::Get()->GetDefaultStyle().Apply(stc);

  stc->StyleClearAll();

  wxExLexers::Get()->ApplyGlobalStyles(stc);
  wxExLexers::Get()->ApplyIndicators(stc);
  wxExLexers::Get()->ApplyProperties(stc);
  wxExLexers::Get()->ApplyMarkers(stc);

  for_each (m_Properties.begin(), m_Properties.end(),
    std::bind2nd(std::mem_fun_ref(&wxExProperty::Apply), stc));

  Colourise(stc);

  return stc->GetLexer() != wxSTC_LEX_NULL;
}

int wxExLexer::UsableCharactersPerLine() const
{
  // We always use lines with 80 characters. We adjust this here for
  // the space the beginning and end of the comment characters occupy.
  return 80
    - ((m_CommentBegin.size() != 0) ? m_CommentBegin.size() + 1 : 0)
    - ((m_CommentEnd.size() != 0) ? m_CommentEnd.size() + 1 : 0);
}
<commit_msg>fixed errors<commit_after>/******************************************************************************\
* File:          lexer.cpp
* Purpose:       Implementation of lexer classes
* Author:        Anton van Wezenbeek
* RCS-ID:        $Id$
*
* Copyright (c) 1998-2009 Anton van Wezenbeek
* All rights are reserved. Reproduction in whole or part is prohibited
* without the written consent of the copyright owner.
\******************************************************************************/

#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
//#include <numeric> // both for accumulate
//#include <functional>
#include <algorithm>
#include <wx/config.h>
#include <wx/tokenzr.h>
#include <wx/extension/lexer.h>
#include <wx/extension/lexers.h>
#include <wx/extension/stc.h>
#include <wx/extension/util.h> // for wxExAlignText

wxExLexer::wxExLexer(const wxXmlNode* node)
{
  m_CommentBegin.clear();
  m_CommentBegin2.clear();
  m_CommentEnd.clear();
  m_CommentEnd2.clear();
  m_Styles.clear();
  m_Extensions.clear();
  m_Properties.clear();
  m_Keywords.clear();
  m_KeywordsSet.clear();
  m_ScintillaLexer.clear();

  if (node != NULL)
  {
    Set(node);
  }
}

const std::vector<wxExStyle> wxExLexer::AutoMatch(
  const wxString& lexer) const
{
  std::vector<wxExStyle> text;

  auto itlow =
    wxExLexers::Get()->GetMacros().lower_bound(lexer);

  auto itup =
    wxExLexers::Get()->GetMacros().upper_bound(lexer + "ZZZ");

  for (
    auto it = itlow;
    it != itup;
    ++it)
  {
    for (
      auto style =
        wxExLexers::Get()->GetMacrosStyle().begin();
      style != wxExLexers::Get()->GetMacrosStyle().end();
      ++style)
    {
      if (it->first.Contains(style->first))
      {
        text.push_back(wxExStyle(it->second, style->second));
      }
    }
  }

  return text;
}

void wxExLexer::Colourise(wxExSTC* stc) const
{
  for_each (m_Styles.begin(), m_Styles.end(),
    std::bind2nd(std::mem_fun_ref(&wxExStyle::Apply), stc));

  // And finally colour the entire document.
  stc->Colourise(0, stc->GetLength() - 1);

  const int margin_fold_no = stc->GetMarginFoldingNumber();

  if (stc->GetProperty("fold") == "1")
  {
    stc->SetMarginWidth(margin_fold_no,
      wxConfigBase::Get()->ReadLong(_("Folding"), 16));

    stc->SetFoldFlags(
      wxConfigBase::Get()->ReadLong(_("Fold Flags"),
      wxSTC_FOLDFLAG_LINEBEFORE_CONTRACTED | wxSTC_FOLDFLAG_LINEAFTER_CONTRACTED));
  }
  else
  {
    stc->SetMarginWidth(margin_fold_no, 0);
  }
}

const wxString wxExLexer::GetFormattedText(
  const wxString& lines,
  const wxString& header,
  bool fill_out_with_space,
  bool fill_out) const
{
  wxString text = lines, header_to_use = header;
  size_t nCharIndex;

  wxString out;

  // Process text between the carriage return line feeds.
  while ((nCharIndex = text.find("\n")) != wxString::npos)
  {
    out << wxExAlignText(
      text.substr(0, nCharIndex),
      header_to_use,
      fill_out_with_space,
      fill_out,
      *this);

    text = text.substr(nCharIndex + 1);
    header_to_use = wxString(' ', header.size());
  }

  if (!text.empty())
  {
    out << wxExAlignText(
      text,
      header_to_use,
      fill_out_with_space,
      fill_out,
      *this);
  }

  return out;
}

const wxString wxExLexer::GetKeywordsString(int keyword_set) const
{
  if (keyword_set == -1)
  {
    return GetKeywordsStringSet(m_Keywords);
  }
  else
  {
    const auto it =
      m_KeywordsSet.find(keyword_set);

    if (it != m_KeywordsSet.end())
    {
      return GetKeywordsStringSet(it->second);
    }
  }

  return wxEmptyString;
}

const wxString wxExLexer::GetKeywordsStringSet(
  const std::set<wxString>& kset) const
{
  // accumulate would be nice, but does not add a space, could not do it easily.
  // return accumulate(kset.begin(), kset.end(), wxEmptyString);
  wxString keywords;

  for (
    auto it = kset.begin();
    it != kset.end();
    ++it)
  {
    keywords += *it + " ";
  }

  return keywords.Trim(); // remove the ending space
}

bool wxExLexer::IsKeyword(const wxString& word) const
{
  const auto it = m_Keywords.find(word);
  return (it != m_Keywords.end());
}

bool wxExLexer::IsOk() const
{
  // At this moment ok if scintilla lexer has been filled.
  return !m_ScintillaLexer.empty();
}

bool wxExLexer::KeywordStartsWith(const wxString& word) const
{
  const auto it = m_Keywords.lower_bound(word.Lower());
  return
    it != m_Keywords.end() &&
    it->StartsWith(word.Lower());
}

const wxString wxExLexer::MakeComment(
  const wxString& text,
  bool fill_out_with_space,
  bool fill_out) const
{
  wxString out;

  text.find("\n") != wxString::npos ?
    out << GetFormattedText(text, wxEmptyString, fill_out_with_space, fill_out):
    out << wxExAlignText(text, wxEmptyString, fill_out_with_space, fill_out, *this);

  return out;
}

const wxString wxExLexer::MakeComment(
  const wxString& prefix,
  const wxString& text) const
{
  wxString out;

  text.find("\n") != wxString::npos ?
    out << GetFormattedText(text, prefix, true, true):
    out << wxExAlignText(text, prefix, true, true, *this);

  return out;
}

const wxString wxExLexer::MakeSingleLineComment(
  const wxString& text,
  bool fill_out_with_space,
  bool fill_out) const
{
  if (m_CommentBegin.empty() && m_CommentEnd.empty())
  {
    return text;
  }

  // First set the fill_out_character.
  wxUniChar fill_out_character;

  if (fill_out_with_space || m_ScintillaLexer == "hypertext")
  {
    fill_out_character = ' ';
  }
  else
  {
    if (text.empty())
    {
      if (m_CommentBegin == m_CommentEnd)
           fill_out_character = '-';
      else fill_out_character = m_CommentBegin[m_CommentBegin.size() - 1];
    }
    else   fill_out_character = ' ';
  }

  wxString out = m_CommentBegin + fill_out_character + text;

  // Fill out characters.
  if (fill_out)
  {
    // To prevent filling out spaces
    if (fill_out_character != ' ' || !m_CommentEnd.empty())
    {
      const auto fill_chars = UsableCharactersPerLine() - text.size();

      if (fill_chars > 0)
      {
        const wxString fill_out(fill_out_character, fill_chars);
        out += fill_out;
      }
    }
  }

  if (!m_CommentEnd.empty()) out += fill_out_character + m_CommentEnd;

  return out;
}

const std::vector<wxExStyle> wxExLexer::ParseNodeStyles(
  const wxXmlNode* node) const
{
  std::vector<wxExStyle> text;

  wxXmlNode* child = node->GetChildren();

  while (child)
  {
    if (child->GetName() == "style")
    {
      text.push_back(wxExStyle(child));
    }
    else if (child->GetName() == "comment")
    {
      // Ignore comments.
    }
    else
    {
      wxLogError(_("Undefined styles tag: %s on line: %d"),
        child->GetName().c_str(),
        child->GetLineNumber());
    }

    child = child->GetNext();
  }

  return text;
}

void wxExLexer::Set(const wxXmlNode* node)
{
  m_ScintillaLexer = node->GetAttribute("name", "");

#ifdef __WXMSW__
  m_Extensions = node->GetAttribute(
    "extensions",
    "*." + m_ScintillaLexer);
#else
  m_Extensions = node->GetAttribute("extensions", "");
#endif

  if (node->GetAttribute("match", "") != "")
  {
    m_Styles = AutoMatch(node->GetAttribute("match", ""));
  }

  if (m_ScintillaLexer == "hypertext")
  {
    // As our lexers.xml files cannot use xml comments,
    // add them here.
    m_CommentBegin = "<!--";
    m_CommentEnd = "-->";
  }

  wxXmlNode *child = node->GetChildren();

  while (child)
  {
    if (child->GetName() == "styles")
    {
      const std::vector<wxExStyle> v = ParseNodeStyles(child);

      // Do not assign styles to result of ParseNode,
      // as styles might already be filled with result of automatch.
      m_Styles.insert(
        m_Styles.end(),
        v.begin(), v.end());
    }
    else if (child->GetName() == "keywords")
    {
      if (!SetKeywords(child->GetNodeContent().Strip(wxString::both)))
      {
        wxLogError(
          _("Keywords could not be set on line: %d"),
          child->GetLineNumber());
      }
    }
    else if (child->GetName() == "properties")
    {
      m_Properties = wxExLexers::Get()->ParseNodeProperties(child);
    }
    else if (child->GetName() == "comments")
    {
      m_CommentBegin = child->GetAttribute("begin1", "");
      m_CommentEnd = child->GetAttribute("end1", "");
      m_CommentBegin2 = child->GetAttribute("begin2", "");
      m_CommentEnd2 = child->GetAttribute("end2", "");
    }
    else if (child->GetName() == "comment")
    {
      // Ignore comments.
    }
    else
    {
      wxLogError(_("Undefined lexer tag: %s on line: %d"),
        child->GetName().c_str(),
        child->GetLineNumber());
    }

    child = child->GetNext();
  }

  if (!IsOk())
  {
    wxLogError(_("Illegal lexer on line: %d"), node->GetLineNumber());
  }
}

// Adds the specified keywords to the keywords map and the keywords set.
// The text might contain the keyword set after a ':'.
// Returns true if keyword could be added
// and false if specified set is illegal.
// Empties existing keywords.
bool wxExLexer::SetKeywords(const wxString& value)
{
  if (!m_Keywords.empty())
  {
    m_Keywords.clear();
  }

  if (!m_KeywordsSet.empty())
  {
    m_KeywordsSet.clear();
  }

  std::set<wxString> keywords_set;

  wxStringTokenizer tkz(value, "\r\n ");

  int setno = 0;

  while (tkz.HasMoreTokens())
  {
    const wxString line = tkz.GetNextToken();
    wxStringTokenizer fields(line, ":");

    wxString keyword;

    if (fields.CountTokens() > 1)
    {
      keyword = fields.GetNextToken();

      const auto new_setno = atoi(fields.GetNextToken().c_str());

      if (new_setno >= wxSTC_KEYWORDSET_MAX)
      {
        return false;
      }

      if (new_setno != setno)
      {
        if (!keywords_set.empty())
        {
          m_KeywordsSet.insert(make_pair(setno, keywords_set));
          keywords_set.clear();
        }

        setno = new_setno;
      }

      keywords_set.insert(keyword);
    }
    else
    {
      keyword = line;
      keywords_set.insert(line);
    }

    m_Keywords.insert(keyword);
  }

  m_KeywordsSet.insert(make_pair(setno, keywords_set));

  return true;
}

bool wxExLexer::SetScintillaLexer(
  const wxString& lexer,
  wxExSTC* stc,
  bool show_error)
{
  stc->ClearDocumentStyle();

  for_each (m_Properties.begin(), m_Properties.end(),
    std::bind2nd(std::mem_fun_ref(&wxExProperty::ApplyReset), stc));

  (*this) = wxExLexers::Get()->FindByName(lexer);

  stc->SetLexerLanguage(m_ScintillaLexer);

  if (!IsOk())
  {
    (*this) = wxExLexers::Get()->FindByText(stc->GetLine(0));

    stc->SetLexerLanguage(m_ScintillaLexer);
  }

  if (
      IsOk() &&
      // And check whether the GetLexer from scintilla has a good value.
      // Otherwise it is not known, and we better show an error.
      ((wxStyledTextCtrl *)stc)->GetLexer() == wxSTC_LEX_NULL &&
      show_error)
  {
    wxLogError(_("Lexer is not known") + ": " + m_ScintillaLexer);
  }

  // Reset keywords, also if no lexer is available.
  for (size_t setno = 0; setno < wxSTC_KEYWORDSET_MAX; setno++)
  {
    stc->SetKeyWords(setno, wxEmptyString);
  }

  // Readme: The Scintilla lexer only recognized lower case words, apparently.
  for (
    auto it = m_KeywordsSet.begin();
    it != m_KeywordsSet.end();
    ++it)
  {
    stc->SetKeyWords(
      it->first,
      GetKeywordsString(it->first).Lower());
  }

  wxExLexers::Get()->GetDefaultStyle().Apply(stc);

  stc->StyleClearAll();

  wxExLexers::Get()->ApplyGlobalStyles(stc);
  wxExLexers::Get()->ApplyIndicators(stc);
  wxExLexers::Get()->ApplyProperties(stc);
  wxExLexers::Get()->ApplyMarkers(stc);

  for_each (m_Properties.begin(), m_Properties.end(),
    std::bind2nd(std::mem_fun_ref(&wxExProperty::Apply), stc));

  Colourise(stc);

  return ((wxStyledTextCtrl *)stc)->GetLexer() != wxSTC_LEX_NULL;
}

int wxExLexer::UsableCharactersPerLine() const
{
  // We always use lines with 80 characters. We adjust this here for
  // the space the beginning and end of the comment characters occupy.
  return 80
    - ((m_CommentBegin.size() != 0) ? m_CommentBegin.size() + 1 : 0)
    - ((m_CommentEnd.size() != 0) ? m_CommentEnd.size() + 1 : 0);
}
<|endoftext|>


<commit_before>/*
 * @file network-health-task.cpp
 *
 * @author C. Smith
 */

#include "network-health-task.hpp"

#include <Esp.h>
#include <ESP8266WiFi.h>
#include <time.h>

#include "root-ca.hpp"
#include "wifi-information.hpp"
#include "mqtt-broker-information.hpp"

namespace app
{

uint32_t NetworkHealthTask::clientIdCount = 0;

NetworkHealthTask::NetworkHealthTask(const uint32_t timeInterval)
  : Task(timeInterval), m_wifiClient(RootCaCertificate),
    m_logger(Serial), m_mqttNetwork(m_wifiClient, m_system),
    m_mqttClient(std::make_shared<MqttClient>(m_mqttOptions, m_logger,
          m_system, m_mqttNetwork, m_sendBuffer, m_recvBuffer, m_msgHandlers))
{
  m_mqttOptions.commandTimeoutMs = 10 * 1000;
  m_mqttClientId = String(ESP.getChipId()) + String(clientIdCount++);
}

NetworkHealthTask::~NetworkHealthTask()
{
  clientIdCount--;
}

bool NetworkHealthTask::OnStart()
{
  WiFi.persistent(false);
  WiFi.mode(WIFI_OFF);
  WiFi.mode(WIFI_STA);
  while(WiFi.status() != WL_CONNECTED)
  {
    connectWifi();
  }

  Serial.print("Configure time..");
  /* Need to synchronize time so TLS can verify certificates */
  /* First parameter is offset from GMT, second is daylight savings (ignored,
   * and then servers (up to three, minimum two).
   */
  configTime(-(4*3600), 1, "pool.ntp.org", "time.nist.gov");

  /* Wait until we have the current time */
  time_t now = time(nullptr);
  while (now < 1000)
  {
    delay(500);
    Serial.print(".");
    now = time(nullptr);
  }
  Serial.println(" Done");
  struct tm timeinfo;
  gmtime_r(&now, &timeinfo);
  Serial.print("Current time: ");
  Serial.println(asctime(&timeinfo));

  connectNetwork();

  if(m_wifiClient.connected())
  {
    connectMqtt();
  }

  return true;
}

void NetworkHealthTask::OnStop()
{
}

void NetworkHealthTask::OnUpdate(uint32_t deltaTime)
{
  if(WiFi.status() != WL_CONNECTED)
  {
    Serial.println("WiFi disconnected. Reconnect.");
    connectWifi();
  }
  if(!m_wifiClient.connected())
  {
    Serial.println("Client disconnected. Reconnect.");
    connectNetwork();
  }
  if(!m_mqttClient->isConnected())
  {
    Serial.println("MQTT disconnected. Reconnect.");
    connectMqtt();
  }
}

void NetworkHealthTask::connectWifi()
{
  for(auto info : g_wifiNetworks)
  {
    uint32_t count = 0;
    const uint32_t failureCount = 10;

    WiFi.begin(info.ssid.c_str(), info.password.c_str());

    Serial.print("Connecting to ");
    Serial.println(info.ssid);

    while(WiFi.status() != WL_CONNECTED &&
          count++ < failureCount)
    {
      delay(500);
    }

    if(WiFi.status() == WL_CONNECTED)
    {
      Serial.println("Connected");
      return;
    }
    else
    {
      Serial.println("Failed to connect, try next network");
    }
  }

}

void NetworkHealthTask::connectNetwork()
{
  const char * host = g_brokerInformation.hostname.c_str();
  const int port = g_brokerInformation.port;

  Serial.print("Connecting to ");
  Serial.println(host);

  if(!m_wifiClient.connect(host, port))
  {
    Serial.println("Connection failed");
  }
  else
  {
    Serial.println("Connection succeeded");
  }
}

void NetworkHealthTask::connectMqtt()
{
  MqttClient::ConnectResult connectionResult;
  MqttClient::Error::type result;
  MQTTPacket_connectData options = MQTTPacket_connectData_initializer;

  options.MQTTVersion = 4;
  options.clientID.cstring = const_cast<char*>(m_mqttClientId.c_str());
  options.cleansession = true;
  options.keepAliveInterval = 65; // seconds
  options.username.cstring = const_cast<char*>(g_brokerInformation.username.c_str());
  options.password.cstring = const_cast<char*>(g_brokerInformation.password.c_str());

  Serial.println("Connecting to MQTT Broker");

  result = m_mqttClient->connect(options, connectionResult);

  if(result != MqttClient::Error::SUCCESS)
  {
    Serial.print("Error connecting to broker: ");
    Serial.println(result);
  }
  else
  {
    Serial.println("Connection succeeded");
  }
}

}
<commit_msg>Fix to construction of MqttClient<commit_after>/*
 * @file network-health-task.cpp
 *
 * @author C. Smith
 */

#include "network-health-task.hpp"

#include <Esp.h>
#include <ESP8266WiFi.h>
#include <time.h>

#include "root-ca.hpp"
#include "wifi-information.hpp"
#include "mqtt-broker-information.hpp"

namespace app
{

uint32_t NetworkHealthTask::clientIdCount = 0;

NetworkHealthTask::NetworkHealthTask(const uint32_t timeInterval)
  : Task(timeInterval), m_wifiClient(RootCaCertificate),
    m_logger(Serial), m_mqttNetwork(m_wifiClient, m_system),
    m_mqttClient(std::make_shared<MqttClient>(MqttClient::Options(), m_logger,
          m_system, m_mqttNetwork, m_sendBuffer, m_recvBuffer, m_msgHandlers))
{
  m_mqttClientId = String(ESP.getChipId()) + String(clientIdCount++);
}

NetworkHealthTask::~NetworkHealthTask()
{
  clientIdCount--;
}

bool NetworkHealthTask::OnStart()
{
  WiFi.persistent(false);
  WiFi.mode(WIFI_OFF);
  WiFi.mode(WIFI_STA);
  while(WiFi.status() != WL_CONNECTED)
  {
    connectWifi();
  }

  Serial.print("Configure time..");
  /* Need to synchronize time so TLS can verify certificates */
  /* First parameter is offset from GMT, second is daylight savings (ignored,
   * and then servers (up to three, minimum two).
   */
  configTime(-(4*3600), 1, "pool.ntp.org", "time.nist.gov");

  /* Wait until we have the current time */
  time_t now = time(nullptr);
  while (now < 1000)
  {
    delay(500);
    Serial.print(".");
    now = time(nullptr);
  }
  Serial.println(" Done");
  struct tm timeinfo;
  gmtime_r(&now, &timeinfo);
  Serial.print("Current time: ");
  Serial.println(asctime(&timeinfo));

  connectNetwork();

  if(m_wifiClient.connected())
  {
    connectMqtt();
  }

  return true;
}

void NetworkHealthTask::OnStop()
{
}

void NetworkHealthTask::OnUpdate(uint32_t deltaTime)
{
  if(WiFi.status() != WL_CONNECTED)
  {
    Serial.println("WiFi disconnected. Reconnect.");
    connectWifi();
  }
  if(!m_wifiClient.connected())
  {
    Serial.println("Client disconnected. Reconnect.");
    connectNetwork();
  }
  if(!m_mqttClient->isConnected())
  {
    Serial.println("MQTT disconnected. Reconnect.");
    connectMqtt();
  }
}

void NetworkHealthTask::connectWifi()
{
  for(auto info : g_wifiNetworks)
  {
    uint32_t count = 0;
    const uint32_t failureCount = 10;

    WiFi.begin(info.ssid.c_str(), info.password.c_str());

    Serial.print("Connecting to ");
    Serial.println(info.ssid);

    while(WiFi.status() != WL_CONNECTED &&
          count++ < failureCount)
    {
      delay(500);
    }

    if(WiFi.status() == WL_CONNECTED)
    {
      Serial.println("Connected");
      return;
    }
    else
    {
      Serial.println("Failed to connect, try next network");
    }
  }

}

void NetworkHealthTask::connectNetwork()
{
  const char * host = g_brokerInformation.hostname.c_str();
  const int port = g_brokerInformation.port;

  Serial.print("Connecting to ");
  Serial.println(host);

  if(!m_wifiClient.connect(host, port))
  {
    Serial.println("Connection failed");
  }
  else
  {
    Serial.println("Connection succeeded");
  }
}

void NetworkHealthTask::connectMqtt()
{
  MqttClient::ConnectResult connectionResult;
  MqttClient::Error::type result;
  MQTTPacket_connectData options = MQTTPacket_connectData_initializer;

  options.MQTTVersion = 4;
  options.clientID.cstring = const_cast<char*>(m_mqttClientId.c_str());
  options.cleansession = true;
  options.keepAliveInterval = 65; // seconds
  options.username.cstring = const_cast<char*>(g_brokerInformation.username.c_str());
  options.password.cstring = const_cast<char*>(g_brokerInformation.password.c_str());

  Serial.println("Connecting to MQTT Broker");

  result = m_mqttClient->connect(options, connectionResult);

  if(result != MqttClient::Error::SUCCESS)
  {
    Serial.print("Error connecting to broker: ");
    Serial.println(result);
    delay(500);
  }
  else
  {
    Serial.println("Connection succeeded");
  }
}

}
<|endoftext|>


<commit_before>/*
* ipop-project
* Copyright 2016, University of Florida
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "webrtc/base/nethelpers.h"
#include "control_listener.h"
#include "tincan_exception.h"
namespace tincan
{
using namespace rtc;
ControlListener::ControlListener(unique_ptr<ControlDispatch> control_dispatch):
  ctrl_dispatch_(move(control_dispatch)),
  packet_options_(DSCP_DEFAULT)
{
  ctrl_dispatch_->SetDispatchToListenerInf(this);
}

ControlListener::~ControlListener()
{}

void
ControlListener::ReadPacketHandler(
  AsyncPacketSocket *,
  const char * data,
  size_t len,
  const SocketAddress &,
  const PacketTime &)
{
  try {
    TincanControl ctrl(data, len);
    LOG(LS_INFO) << "Received CONTROL: " << ctrl.StyledString();
    (*ctrl_dispatch_)(ctrl);
  }
  catch(exception & e) {
    LOG(LS_WARNING) << "A control failed to execute." << endl
      << string(data, len) << endl
      << e.what();
  }
}
//
//IpopControllerLink interface implementation
void
ControlListener::Deliver(
  TincanControl & ctrl_resp)
{
  std::string msg = ctrl_resp.StyledString();
  LOG(LS_INFO) << "Sending CONTROL: " << msg;
  lock_guard<mutex> lg(skt_mutex_);
  snd_socket_->SendTo(msg.c_str(), msg.length(), *ctrl_addr_, packet_options_);
}
void
ControlListener::Deliver(
  unique_ptr<TincanControl> ctrl_resp)
{
  Deliver(*ctrl_resp.get());
}
//
//DispatchtoListener interface implementation
void
ControlListener::CreateIpopControllerLink(
  unique_ptr<SocketAddress> controller_addr)
{
  lock_guard<mutex> lg(skt_mutex_);
  ctrl_addr_ = move(controller_addr);
  SocketFactory* sf = Thread::Current()->socketserver();
  snd_socket_ = make_unique<AsyncUDPSocket>(
    sf->CreateAsyncSocket(ctrl_addr_->family(), SOCK_DGRAM));
}

void
ControlListener::Run(Thread* thread) {
  BasicPacketSocketFactory packet_factory;
  if (rtc::HasIPv6Enabled()) {
  rcv_socket_.reset(packet_factory.CreateUdpSocket(
    SocketAddress(tp.kLocalHost6, tp.kUdpPort), 0, 0));
    LOG(LS_INFO) << "Tincan listening on " << tp.kLocalHost6 << " UDP port " << tp.kUdpPort;
  }
  else
    rcv_socket_.reset(packet_factory.CreateUdpSocket(
      SocketAddress(tp.kLocalHost, tp.kUdpPort), 0, 0));
  if (!rcv_socket_)
    throw TCEXCEPT("Failed to create control listener socket");
  rcv_socket_->SignalReadPacket.connect(this,
    &ControlListener::ReadPacketHandler);
  thread->ProcessMessages(-1); //run until stopped
}
}  // namespace tincan
<commit_msg>Use IPv4 for Controller to Tincan comm<commit_after>/*
* ipop-project
* Copyright 2016, University of Florida
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "webrtc/base/nethelpers.h"
#include "control_listener.h"
#include "tincan_exception.h"
namespace tincan
{
using namespace rtc;
ControlListener::ControlListener(unique_ptr<ControlDispatch> control_dispatch):
  ctrl_dispatch_(move(control_dispatch)),
  packet_options_(DSCP_DEFAULT)
{
  ctrl_dispatch_->SetDispatchToListenerInf(this);
}

ControlListener::~ControlListener()
{}

void
ControlListener::ReadPacketHandler(
  AsyncPacketSocket *,
  const char * data,
  size_t len,
  const SocketAddress &,
  const PacketTime &)
{
  try {
    TincanControl ctrl(data, len);
    LOG(LS_INFO) << "Received CONTROL: " << ctrl.StyledString();
    (*ctrl_dispatch_)(ctrl);
  }
  catch(exception & e) {
    LOG(LS_WARNING) << "A control failed to execute." << endl
      << string(data, len) << endl
      << e.what();
  }
}
//
//IpopControllerLink interface implementation
void
ControlListener::Deliver(
  TincanControl & ctrl_resp)
{
  std::string msg = ctrl_resp.StyledString();
  LOG(LS_INFO) << "Sending CONTROL: " << msg;
  lock_guard<mutex> lg(skt_mutex_);
  snd_socket_->SendTo(msg.c_str(), msg.length(), *ctrl_addr_, packet_options_);
}
void
ControlListener::Deliver(
  unique_ptr<TincanControl> ctrl_resp)
{
  Deliver(*ctrl_resp.get());
}
//
//DispatchtoListener interface implementation
void
ControlListener::CreateIpopControllerLink(
  unique_ptr<SocketAddress> controller_addr)
{
  lock_guard<mutex> lg(skt_mutex_);
  ctrl_addr_ = move(controller_addr);
  SocketFactory* sf = Thread::Current()->socketserver();
  snd_socket_ = make_unique<AsyncUDPSocket>(
    sf->CreateAsyncSocket(ctrl_addr_->family(), SOCK_DGRAM));
}

void
ControlListener::Run(
  Thread* thread)
{
  BasicPacketSocketFactory packet_factory;
  rcv_socket_.reset(packet_factory.CreateUdpSocket(
    SocketAddress(tp.kLocalHost, tp.kUdpPort), 0, 0));
  if (!rcv_socket_)
    throw TCEXCEPT("Failed to create control listener socket");
  LOG(LS_INFO) << "Tincan listening on " << tp.kLocalHost << " UDP port " << tp.kUdpPort;
  rcv_socket_->SignalReadPacket.connect(this,
    &ControlListener::ReadPacketHandler);
  thread->ProcessMessages(-1); //run until stopped
}
}  // namespace tincan
<|endoftext|>


<commit_before>/*=========================================================================

Library:   IntersonArray

Copyright Kitware Inc. 28 Corporate Drive,
Clifton Park, NY, 12065, USA.

All rights reserved.

Licensed under the Apache License, Version 2.0 ( the "License" );
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

=========================================================================*/
#include <Windows.h> // Sleep

#include "itkImageFileWriter.h"

#include "IntersonArrayCxxImagingContainer.h"
#include "IntersonArrayCxxControlsHWControls.h"

#include "AcquireIntersonArrayRFCLP.h"

typedef IntersonArrayCxx::Imaging::Container ContainerType;

const unsigned int Dimension = 3;
typedef ContainerType::RFImagePixelType    PixelType;
typedef itk::Image< PixelType, Dimension > ImageType;

struct CallbackClientData
{
  ImageType *        Image;
  itk::SizeValueType FrameIndex;
};

void __stdcall pasteIntoImage( PixelType * buffer, void * clientData )
{
  CallbackClientData * callbackClientData =
    static_cast< CallbackClientData * >( clientData );
  ImageType * image =
    callbackClientData->Image;

  const ImageType::RegionType & largestRegion =
    image->GetLargestPossibleRegion();
  const ImageType::SizeType imageSize = largestRegion.GetSize();
  const itk::SizeValueType imageFrames = largestRegion.GetSize()[2];
  if( callbackClientData->FrameIndex >= imageFrames )
    {
    return;
    }

  const int framePixels = imageSize[0] * imageSize[1];
  std::cout << "frame pixels RF = " << framePixels << std::endl;

  PixelType * imageBuffer = image->GetPixelContainer()->GetBufferPointer();
  imageBuffer += framePixels * callbackClientData->FrameIndex;
  std::memcpy( imageBuffer, buffer, framePixels * sizeof( PixelType ) );

  std::cout << "Acquired frame RF: " << callbackClientData->FrameIndex
    << std::endl;
  ++(callbackClientData->FrameIndex);
}

int main( int argc, char * argv[] )
{
  PARSE_ARGS;

  typedef IntersonArrayCxx::Controls::HWControls HWControlsType;
  IntersonArrayCxx::Controls::HWControls hwControls;

  int ret = EXIT_SUCCESS;

  int steering = 0;
  typedef HWControlsType::FoundProbesType FoundProbesType;
  FoundProbesType foundProbes;
  hwControls.FindAllProbes( foundProbes );
  if( foundProbes.empty() )
    {
    std::cerr << "Could not find the probe." << std::endl;
    return EXIT_FAILURE;
    }
  hwControls.FindMyProbe( 0 );
  const unsigned int probeId = hwControls.GetProbeID();
  if( probeId == 0 )
    {
    std::cerr << "Could not find the probe." << std::endl;
    return EXIT_FAILURE;
    }

  HWControlsType::FrequenciesType frequencies;
  hwControls.GetFrequency( frequencies );
  if( !hwControls.SetFrequencyAndFocus( frequencyIndex, focusIndex,
      steering ) )
    {
    std::cerr << "Could not set the frequency and focus." << std::endl;
    return EXIT_FAILURE;
    }

  if( !hwControls.SendHighVoltage( highVoltage, highVoltage ) )
    {
    std::cerr << "Could not set the high voltage." << std::endl;
    return EXIT_FAILURE;
    }
  if( !hwControls.EnableHighVoltage() )
    {
    std::cerr << "Could not enable high voltage." << std::endl;
    return EXIT_FAILURE;
    }

  hwControls.DisableHardButton();

  ContainerType container;
  container.SetHWControls(&hwControls);

  const int height_lines = hwControls.GetLinesPerArray();
  std::cout << "Lines per array: " << height_lines << std::endl;
  const int width_samples = ContainerType::MAX_RFSAMPLES;
  std::cout << "Max RF samples: " << width_samples << std::endl;
  const itk::SizeValueType framesToCollect = frames;

  const double ns = ContainerType::MAX_RFSAMPLES; // number of samples
  const double fs = 30000; // [kHz]=[samples/ms] - sampling frequency
  const double depth = sos * ( ns - 1 ) / ( 2 * fs );
  const double depthCfm = depth/2;
  std::cout << "Depth: " << depth << "mm" << std::endl;
  std::cout << std::endl;

  container.SetRFData( true );

  container.IdleInitScanConverter( depth, width_samples, height_lines, probeId,
      steering, depthCfm, false, false, 0, false );
  container.HardInitScanConverter( depth, width_samples, height_lines, steering,
      depthCfm );

  ImageType::Pointer image = ImageType::New();
  typedef ImageType::RegionType RegionType;
  RegionType imageRegion;
  ImageType::IndexType imageIndex;
  imageIndex.Fill( 0 );
  imageRegion.SetIndex( imageIndex );
  ImageType::SizeType imageSize;
  imageSize[0] = width_samples;
  imageSize[1] = height_lines;
  imageSize[2] = framesToCollect;
  imageRegion.SetSize( imageSize );
  image->SetRegions( imageRegion );
  ImageType::SpacingType imageSpacing;
  imageSpacing[ 0 ] = sos / ( 2 * fs );
  imageSpacing[ 1 ] = 38.0 / ( height_lines - 1 );
  imageSpacing[ 2 ] = 1;
  image->SetSpacing( imageSpacing );
  ImageType::DirectionType direction;
  direction.SetIdentity();
  ImageType::DirectionType::InternalMatrixType & vnlDirection = direction.GetVnlMatrix();
  vnlDirection.put(0, 0,  0.0);
  vnlDirection.put(0, 1, -1.0);
  vnlDirection.put(1, 0,  1.0);
  vnlDirection.put(1, 1,  0.0);
  image->SetDirection( direction );
  image->Allocate();

  CallbackClientData clientData;
  clientData.Image = image.GetPointer();
  clientData.FrameIndex = 0;

  container.SetNewRFImageCallback( &pasteIntoImage, &clientData );

  std::cout << "StartRFReadScan" << std::endl;
  container.StartRFReadScan();
  Sleep( 100 ); // "time to start"
  std::cout << "StartRFmode" << std::endl;
  if( !hwControls.StartRFmode() )
    {
    std::cerr << "Could not start RF collection." << std::endl;
    return EXIT_FAILURE;
    }

  int c = 0;
  while( clientData.FrameIndex < framesToCollect && c < 10000 )
    {
    std::cout << "Frames to collect: " << clientData.FrameIndex << " of " << framesToCollect << std::endl;
    std::cout << clientData.FrameIndex << " of " << framesToCollect
      << std::endl;
    Sleep( 100 );
    ++c;
    }

  std::cout << "StopAcquisition" << std::endl;
  hwControls.StopAcquisition();
  container.StopReadScan();
  Sleep( 100 ); // "time to stop"

  typedef itk::ImageFileWriter< ImageType > WriterType;
  WriterType::Pointer writer = WriterType::New();
  writer->SetFileName( outputImage );
  writer->SetInput( image );

  try
    {
    writer->Update();
    }
  catch( itk::ExceptionObject & error )
    {
    std::cerr << "Error: " << error << std::endl;
    return EXIT_FAILURE;
    }

  return ret;
}
<commit_msg>BUG: Remove debug code<commit_after>/*=========================================================================

Library:   IntersonArray

Copyright Kitware Inc. 28 Corporate Drive,
Clifton Park, NY, 12065, USA.

All rights reserved.

Licensed under the Apache License, Version 2.0 ( the "License" );
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

=========================================================================*/
#include <Windows.h> // Sleep

#include "itkImageFileWriter.h"

#include "IntersonArrayCxxImagingContainer.h"
#include "IntersonArrayCxxControlsHWControls.h"

#include "AcquireIntersonArrayRFCLP.h"

typedef IntersonArrayCxx::Imaging::Container ContainerType;

const unsigned int Dimension = 3;
typedef ContainerType::RFImagePixelType    PixelType;
typedef itk::Image< PixelType, Dimension > ImageType;

struct CallbackClientData
{
  ImageType *        Image;
  itk::SizeValueType FrameIndex;
};

void __stdcall pasteIntoImage( PixelType * buffer, void * clientData )
{
  CallbackClientData * callbackClientData =
    static_cast< CallbackClientData * >( clientData );
  ImageType * image =
    callbackClientData->Image;

  const ImageType::RegionType & largestRegion =
    image->GetLargestPossibleRegion();
  const ImageType::SizeType imageSize = largestRegion.GetSize();
  const itk::SizeValueType imageFrames = largestRegion.GetSize()[2];
  if( callbackClientData->FrameIndex >= imageFrames )
    {
    return;
    }

  const int framePixels = imageSize[0] * imageSize[1];

  PixelType * imageBuffer = image->GetPixelContainer()->GetBufferPointer();
  imageBuffer += framePixels * callbackClientData->FrameIndex;
  std::memcpy( imageBuffer, buffer, framePixels * sizeof( PixelType ) );

  std::cout << "Acquired frame RF: " << callbackClientData->FrameIndex
    << std::endl;
  ++(callbackClientData->FrameIndex);
}

int main( int argc, char * argv[] )
{
  PARSE_ARGS;

  typedef IntersonArrayCxx::Controls::HWControls HWControlsType;
  IntersonArrayCxx::Controls::HWControls hwControls;

  int ret = EXIT_SUCCESS;

  int steering = 0;
  typedef HWControlsType::FoundProbesType FoundProbesType;
  FoundProbesType foundProbes;
  hwControls.FindAllProbes( foundProbes );
  if( foundProbes.empty() )
    {
    std::cerr << "Could not find the probe." << std::endl;
    return EXIT_FAILURE;
    }
  hwControls.FindMyProbe( 0 );
  const unsigned int probeId = hwControls.GetProbeID();
  if( probeId == 0 )
    {
    std::cerr << "Could not find the probe." << std::endl;
    return EXIT_FAILURE;
    }

  HWControlsType::FrequenciesType frequencies;
  hwControls.GetFrequency( frequencies );
  if( !hwControls.SetFrequencyAndFocus( frequencyIndex, focusIndex,
      steering ) )
    {
    std::cerr << "Could not set the frequency and focus." << std::endl;
    return EXIT_FAILURE;
    }

  if( !hwControls.SendHighVoltage( highVoltage, highVoltage ) )
    {
    std::cerr << "Could not set the high voltage." << std::endl;
    return EXIT_FAILURE;
    }
  if( !hwControls.EnableHighVoltage() )
    {
    std::cerr << "Could not enable high voltage." << std::endl;
    return EXIT_FAILURE;
    }

  hwControls.DisableHardButton();

  ContainerType container;
  container.SetHWControls(&hwControls);

  const int height_lines = hwControls.GetLinesPerArray();
  std::cout << "Lines per array: " << height_lines << std::endl;
  const int width_samples = ContainerType::MAX_RFSAMPLES;
  std::cout << "Max RF samples: " << width_samples << std::endl;
  const itk::SizeValueType framesToCollect = frames;

  const double ns = ContainerType::MAX_RFSAMPLES; // number of samples
  const double fs = 30000; // [kHz]=[samples/ms] - sampling frequency
  const double depth = sos * ( ns - 1 ) / ( 2 * fs );
  const double depthCfm = depth/2;
  std::cout << "Depth: " << depth << "mm" << std::endl;
  std::cout << std::endl;

  container.SetRFData( true );

  container.IdleInitScanConverter( depth, width_samples, height_lines, probeId,
      steering, depthCfm, false, false, 0, false );
  container.HardInitScanConverter( depth, width_samples, height_lines, steering,
      depthCfm );

  ImageType::Pointer image = ImageType::New();
  typedef ImageType::RegionType RegionType;
  RegionType imageRegion;
  ImageType::IndexType imageIndex;
  imageIndex.Fill( 0 );
  imageRegion.SetIndex( imageIndex );
  ImageType::SizeType imageSize;
  imageSize[0] = width_samples;
  imageSize[1] = height_lines;
  imageSize[2] = framesToCollect;
  imageRegion.SetSize( imageSize );
  image->SetRegions( imageRegion );
  ImageType::SpacingType imageSpacing;
  imageSpacing[ 0 ] = sos / ( 2 * fs );
  imageSpacing[ 1 ] = 38.0 / ( height_lines - 1 );
  imageSpacing[ 2 ] = 1;
  image->SetSpacing( imageSpacing );
  ImageType::DirectionType direction;
  direction.SetIdentity();
  ImageType::DirectionType::InternalMatrixType & vnlDirection = direction.GetVnlMatrix();
  vnlDirection.put(0, 0,  0.0);
  vnlDirection.put(0, 1, -1.0);
  vnlDirection.put(1, 0,  1.0);
  vnlDirection.put(1, 1,  0.0);
  image->SetDirection( direction );
  image->Allocate();

  CallbackClientData clientData;
  clientData.Image = image.GetPointer();
  clientData.FrameIndex = 0;

  container.SetNewRFImageCallback( &pasteIntoImage, &clientData );

  std::cout << "StartRFReadScan" << std::endl;
  container.StartRFReadScan();
  Sleep( 100 ); // "time to start"
  std::cout << "StartRFmode" << std::endl;
  if( !hwControls.StartRFmode() )
    {
    std::cerr << "Could not start RF collection." << std::endl;
    return EXIT_FAILURE;
    }

  int c = 0;
  while( clientData.FrameIndex < framesToCollect && c < 10000 )
    {
    std::cout << "Frames to collect: " << clientData.FrameIndex << " of " << framesToCollect << std::endl;
    std::cout << clientData.FrameIndex << " of " << framesToCollect
      << std::endl;
    Sleep( 100 );
    ++c;
    }

  hwControls.StopAcquisition();
  container.StopReadScan();
  Sleep( 100 ); // "time to stop"

  typedef itk::ImageFileWriter< ImageType > WriterType;
  WriterType::Pointer writer = WriterType::New();
  writer->SetFileName( outputImage );
  writer->SetInput( image );

  try
    {
    writer->Update();
    }
  catch( itk::ExceptionObject & error )
    {
    std::cerr << "Error: " << error << std::endl;
    return EXIT_FAILURE;
    }

  return ret;
}
<|endoftext|>


<commit_before>/*
 * File: Spinlock.hpp
 * Part of commonpp.
 *
 * Distributed under the 2-clause BSD licence (See LICENCE.TXT file at the
 * project root).
 *
 * Copyright (c) 2015 Thomas Sanchez.  All rights reserved.
 *
 */
#pragma once

#include <thread>
#include <iostream>

#define SPINLOCK_USE_ATOMIC 1
#define SPINLOCK_USE_TBB 2

#ifndef SPINLOCK_BACKEND
# define SPINLOCK_BACKEND SPINLOCK_USE_TBB
#endif

#if SPINLOCK_BACKEND == SPINLOCK_USE_ATOMIC
# if defined (__clang__) && (defined (__i386__) || defined (__x86_64__))
#  include <xmmintrin.h>
# endif

# include <atomic>
#elif SPINLOCK_BACKEND == SPINLOCK_USE_TBB
# include <tbb/spin_mutex.h>
#endif

namespace commonpp
{
namespace thread
{

#if SPINLOCK_BACKEND == SPINLOCK_USE_ATOMIC
namespace detail
{
enum LockState
{
    Unlocked = 0,
    Locked = 1,
};

using LockType = std::atomic<LockState>;
struct _spinlock
{
    mutable LockType state;

    void lock() const
    {
        while (state.exchange(Locked, std::memory_order_acquire) == Locked)
        {
#if defined(__i386__) || defined(__x86_64__)
# ifdef __clang__
            _mm_pause();
# else
            __builtin_ia32_pause();
# endif
#endif
        }
    }

    void unlock() const
    {
        state.store(Unlocked, std::memory_order_release);
    }
};
} // namespace detail
#elif SPINLOCK_BACKEND == SPINLOCK_USE_TBB
namespace detail
{
    using _spinlock = tbb::spin_mutex;
} // namespace detail
#endif

struct Spinlock : private detail::_spinlock
{
    using detail::_spinlock::lock;
    using detail::_spinlock::unlock;
};
} // namespace thread
} // namespace commonpp
<commit_msg>Add try_lock to spinlock<commit_after>/*
 * File: Spinlock.hpp
 * Part of commonpp.
 *
 * Distributed under the 2-clause BSD licence (See LICENCE.TXT file at the
 * project root).
 *
 * Copyright (c) 2015 Thomas Sanchez.  All rights reserved.
 *
 */
#pragma once

#include <thread>
#include <iostream>

#define SPINLOCK_USE_ATOMIC 1
#define SPINLOCK_USE_TBB 2

#ifndef SPINLOCK_BACKEND
# define SPINLOCK_BACKEND SPINLOCK_USE_TBB
#endif

#if SPINLOCK_BACKEND == SPINLOCK_USE_ATOMIC
# if defined (__clang__) && (defined (__i386__) || defined (__x86_64__))
#  include <xmmintrin.h>
# endif

# include <atomic>
#elif SPINLOCK_BACKEND == SPINLOCK_USE_TBB
# include <tbb/spin_mutex.h>
#endif

namespace commonpp
{
namespace thread
{

#if SPINLOCK_BACKEND == SPINLOCK_USE_ATOMIC
namespace detail
{
enum LockState
{
    Unlocked = 0,
    Locked = 1,
};

using LockType = std::atomic<LockState>;
struct _spinlock
{
    mutable LockType state;

    bool try_lock() const
    {
        return state.exchange(Locked, std::memory_order_acquire) != Locked;
    }

    void lock() const
    {
        while (!try_lock)
        {
#if defined(__i386__) || defined(__x86_64__)
# ifdef __clang__
            _mm_pause();
# else
            __builtin_ia32_pause();
# endif
#endif
        }
    }

    void unlock() const
    {
        state.store(Unlocked, std::memory_order_release);
    }
};
} // namespace detail
#elif SPINLOCK_BACKEND == SPINLOCK_USE_TBB
namespace detail
{
    using _spinlock = tbb::spin_mutex;
} // namespace detail
#endif

struct Spinlock : private detail::_spinlock
{
    using detail::_spinlock::lock;
    using detail::_spinlock::try_lock;
    using detail::_spinlock::unlock;
};
} // namespace thread
} // namespace commonpp
<|endoftext|>


<commit_before><commit_msg>Reorder `Universe` member variables and clean up initialization code.<commit_after><|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkDirectory.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkDirectory.h"
#include "vtkStringArray.h"

#include "vtkDebugLeaks.h"

#include <sys/stat.h>
#include <vtksys/SystemTools.hxx>

//----------------------------------------------------------------------------
vtkDirectory* vtkDirectory::New()
{
#ifdef VTK_DEBUG_LEAKS
  vtkDebugLeaks::ConstructClass("vtkDirectory");
#endif
  return new vtkDirectory;
}

vtkDirectory::vtkDirectory()
  : Path(0)
{
  this->Files = vtkStringArray::New();
}

void vtkDirectory::CleanUpFilesAndPath()
{
  this->Files->Reset();
  delete [] this->Path;
  this->Path = 0;
}

vtkDirectory::~vtkDirectory()
{
  this->CleanUpFilesAndPath();
  this->Files->Delete();
  this->Files = 0;
}

void vtkDirectory::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
  os << indent << "Files:  (" << this->Files << ")\n";
  if(!this->Path)
    {
    os << indent << "Directory not open\n";
    return;
    }

  os << indent << "Directory for: " <<  this->Path << "\n";
  os << indent << "Contains the following files:\n";
  indent = indent.GetNextIndent();
  for(int i = 0; i < this->Files->GetNumberOfValues(); i++)
    {
    os << indent << this->Files->GetValue(i) << "\n";
    }
}

// First microsoft and borland compilers

#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__MINGW32__)
#include "vtkWindows.h"
#include <io.h>
#include <ctype.h>
#include <direct.h>
#include <fcntl.h>
#include <stdio.h>
#include <cstdlib>
#include <string.h>
#include <sys/types.h>

int vtkDirectory::Open(const char* name)
{
  // clean up from any previous open
  this->CleanUpFilesAndPath();

  char* buf=0;
  int n = static_cast<int>(strlen(name));
  if (name[n - 1] == '/')
    {
    buf = new char[n + 1 + 1];
    sprintf(buf, "%s*", name);
    }
  else
    {
    buf = new char[n + 2 + 1];
    sprintf(buf, "%s/*", name);
    }
  struct _finddata_t data;      // data of current file

  // First count the number of files in the directory
  intptr_t srchHandle;

  srchHandle = _findfirst(buf, &data);

  if (srchHandle == -1)
    {
    _findclose(srchHandle);
    delete[] buf;
    return 0;
    }

  delete [] buf;

  // Loop through names
  do
    {
    this->Files->InsertNextValue(data.name);
    }
  while (_findnext(srchHandle, &data) != -1);

  this->Path = strcpy(new char[strlen(name)+1], name);

  return _findclose(srchHandle) != -1;
}

const char* vtkDirectory::GetCurrentWorkingDirectory(char* buf,
                                                     unsigned int len)
{
  return _getcwd(buf, len);
}

#else

// Now the POSIX style directory access

#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>

/* There is a problem with the Portland compiler, large file
support and glibc/Linux system headers:
             http://www.pgroup.com/userforum/viewtopic.php?
             p=1992&sid=f16167f51964f1a68fe5041b8eb213b6
*/
#if defined(__PGI) && defined(__USE_FILE_OFFSET64)
# define dirent dirent64
#endif

int vtkDirectory::Open(const char* name)
{
  // clean up from any previous open
  this->CleanUpFilesAndPath();

  DIR* dir = opendir(name);

  if (!dir)
    {
    return 0;
    }

  dirent* d =0;

  for (d = readdir(dir); d; d = readdir(dir))
    {
    this->Files->InsertNextValue(d->d_name);
    }
  this->Path = strcpy(new char[strlen(name)+1], name);

  closedir(dir);

  return 1;
}

const char* vtkDirectory::GetCurrentWorkingDirectory(char* buf,
                                                     unsigned int len)
{
  return getcwd(buf, len);
}

#endif

//----------------------------------------------------------------------------
int vtkDirectory::MakeDirectory(const char* dir)
{
  return vtksys::SystemTools::MakeDirectory(dir);
}

const char* vtkDirectory::GetFile(vtkIdType index)
{
  if(index >= this->Files->GetNumberOfValues() || index < 0)
    {
    vtkErrorMacro( << "Bad index for GetFile on vtkDirectory\n");
    return 0;
    }

  return this->Files->GetValue(index).c_str();
}

vtkIdType vtkDirectory::GetNumberOfFiles()
{
  return this->Files->GetNumberOfValues();
}

//----------------------------------------------------------------------------
int vtkDirectory::FileIsDirectory(const char *name)
{
  // The vtksys::SystemTools::FileIsDirectory()
  // does not equal the following code (it probably should),
  // and it will broke KWWidgets. Reverse back to 1.30
  // return vtksys::SystemTools::FileIsDirectory(name);

  if (name == 0)
    {
    return 0;
    }

  int absolutePath = 0;
#if defined(_WIN32)
  if (name[0] == '/' || name[0] == '\\')
    {
    absolutePath = 1;
    }
  else
    {
    for (int i = 0; name[i] != '\0'; i++)
      {
      if (name[i] == ':')
        {
        absolutePath = 1;
        break;
        }
      else if (name[i] == '/' || name[i] == '\\')
        {
        break;
        }
      }
    }
#else
  if (name[0] == '/')
    {
    absolutePath = 1;
    }
#endif

  char *fullPath;

  int n = 0;
  if (!absolutePath && this->Path)
    {
    n = static_cast<int>(strlen(this->Path));
    }

  int m = static_cast<int>(strlen(name));

  fullPath = new char[n+m+2];

  if (!absolutePath && this->Path)
    {
    strcpy(fullPath, this->Path);
#if defined(_WIN32)
    if (fullPath[n-1] != '/'
        && fullPath[n-1] != '\\')
      {
#if !defined(__CYGWIN__)
      fullPath[n++] = '\\';
#else
      fullPath[n++] = '/';
#endif
      }
#else
    if (fullPath[n-1] != '/')
      {
      fullPath[n++] = '/';
      }
#endif
    }

  strcpy(&fullPath[n], name);

  int result = 0;
  struct stat fs;
  if(stat(fullPath, &fs) == 0)
    {
#if defined(_WIN32)
    result = ((fs.st_mode & _S_IFDIR) != 0);
#else
    result = S_ISDIR(fs.st_mode);
#endif
    }

  delete [] fullPath;

  return result;
}

int vtkDirectory::DeleteDirectory(const char* dir)
{
  return vtksys::SystemTools::RemoveADirectory(dir);
}

int vtkDirectory::Rename(const char* oldname, const char* newname)
{
  return 0 == rename(oldname, newname);
}
<commit_msg>vtkDirectory: support PGI and glibc dirent type mismatch<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkDirectory.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkDirectory.h"
#include "vtkStringArray.h"

#include "vtkDebugLeaks.h"

#include <sys/stat.h>
#include <vtksys/SystemTools.hxx>

//----------------------------------------------------------------------------
vtkDirectory* vtkDirectory::New()
{
#ifdef VTK_DEBUG_LEAKS
  vtkDebugLeaks::ConstructClass("vtkDirectory");
#endif
  return new vtkDirectory;
}

vtkDirectory::vtkDirectory()
  : Path(0)
{
  this->Files = vtkStringArray::New();
}

void vtkDirectory::CleanUpFilesAndPath()
{
  this->Files->Reset();
  delete [] this->Path;
  this->Path = 0;
}

vtkDirectory::~vtkDirectory()
{
  this->CleanUpFilesAndPath();
  this->Files->Delete();
  this->Files = 0;
}

void vtkDirectory::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
  os << indent << "Files:  (" << this->Files << ")\n";
  if(!this->Path)
    {
    os << indent << "Directory not open\n";
    return;
    }

  os << indent << "Directory for: " <<  this->Path << "\n";
  os << indent << "Contains the following files:\n";
  indent = indent.GetNextIndent();
  for(int i = 0; i < this->Files->GetNumberOfValues(); i++)
    {
    os << indent << this->Files->GetValue(i) << "\n";
    }
}

// First microsoft and borland compilers

#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__MINGW32__)
#include "vtkWindows.h"
#include <io.h>
#include <ctype.h>
#include <direct.h>
#include <fcntl.h>
#include <stdio.h>
#include <cstdlib>
#include <string.h>
#include <sys/types.h>

int vtkDirectory::Open(const char* name)
{
  // clean up from any previous open
  this->CleanUpFilesAndPath();

  char* buf=0;
  int n = static_cast<int>(strlen(name));
  if (name[n - 1] == '/')
    {
    buf = new char[n + 1 + 1];
    sprintf(buf, "%s*", name);
    }
  else
    {
    buf = new char[n + 2 + 1];
    sprintf(buf, "%s/*", name);
    }
  struct _finddata_t data;      // data of current file

  // First count the number of files in the directory
  intptr_t srchHandle;

  srchHandle = _findfirst(buf, &data);

  if (srchHandle == -1)
    {
    _findclose(srchHandle);
    delete[] buf;
    return 0;
    }

  delete [] buf;

  // Loop through names
  do
    {
    this->Files->InsertNextValue(data.name);
    }
  while (_findnext(srchHandle, &data) != -1);

  this->Path = strcpy(new char[strlen(name)+1], name);

  return _findclose(srchHandle) != -1;
}

const char* vtkDirectory::GetCurrentWorkingDirectory(char* buf,
                                                     unsigned int len)
{
  return _getcwd(buf, len);
}

#else

// Now the POSIX style directory access

#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>

// PGI with glibc has trouble with dirent and large file support:
//  http://www.pgroup.com/userforum/viewtopic.php?
//  p=1992&sid=f16167f51964f1a68fe5041b8eb213b6
// Work around the problem by mapping dirent the same way as readdir.
#if defined(__PGI) && defined(__GLIBC__)
# define vtkdirectory_dirent_readdir dirent
# define vtkdirectory_dirent_readdir64 dirent64
# define vtkdirectory_dirent vtkdirectory_dirent_lookup(readdir)
# define vtkdirectory_dirent_lookup(x) vtkdirectory_dirent_lookup_delay(x)
# define vtkdirectory_dirent_lookup_delay(x) vtkdirectory_dirent_##x
#else
# define vtkdirectory_dirent dirent
#endif

int vtkDirectory::Open(const char* name)
{
  // clean up from any previous open
  this->CleanUpFilesAndPath();

  DIR* dir = opendir(name);

  if (!dir)
    {
    return 0;
    }

  vtkdirectory_dirent* d =0;

  for (d = readdir(dir); d; d = readdir(dir))
    {
    this->Files->InsertNextValue(d->d_name);
    }
  this->Path = strcpy(new char[strlen(name)+1], name);

  closedir(dir);

  return 1;
}

const char* vtkDirectory::GetCurrentWorkingDirectory(char* buf,
                                                     unsigned int len)
{
  return getcwd(buf, len);
}

#endif

//----------------------------------------------------------------------------
int vtkDirectory::MakeDirectory(const char* dir)
{
  return vtksys::SystemTools::MakeDirectory(dir);
}

const char* vtkDirectory::GetFile(vtkIdType index)
{
  if(index >= this->Files->GetNumberOfValues() || index < 0)
    {
    vtkErrorMacro( << "Bad index for GetFile on vtkDirectory\n");
    return 0;
    }

  return this->Files->GetValue(index).c_str();
}

vtkIdType vtkDirectory::GetNumberOfFiles()
{
  return this->Files->GetNumberOfValues();
}

//----------------------------------------------------------------------------
int vtkDirectory::FileIsDirectory(const char *name)
{
  // The vtksys::SystemTools::FileIsDirectory()
  // does not equal the following code (it probably should),
  // and it will broke KWWidgets. Reverse back to 1.30
  // return vtksys::SystemTools::FileIsDirectory(name);

  if (name == 0)
    {
    return 0;
    }

  int absolutePath = 0;
#if defined(_WIN32)
  if (name[0] == '/' || name[0] == '\\')
    {
    absolutePath = 1;
    }
  else
    {
    for (int i = 0; name[i] != '\0'; i++)
      {
      if (name[i] == ':')
        {
        absolutePath = 1;
        break;
        }
      else if (name[i] == '/' || name[i] == '\\')
        {
        break;
        }
      }
    }
#else
  if (name[0] == '/')
    {
    absolutePath = 1;
    }
#endif

  char *fullPath;

  int n = 0;
  if (!absolutePath && this->Path)
    {
    n = static_cast<int>(strlen(this->Path));
    }

  int m = static_cast<int>(strlen(name));

  fullPath = new char[n+m+2];

  if (!absolutePath && this->Path)
    {
    strcpy(fullPath, this->Path);
#if defined(_WIN32)
    if (fullPath[n-1] != '/'
        && fullPath[n-1] != '\\')
      {
#if !defined(__CYGWIN__)
      fullPath[n++] = '\\';
#else
      fullPath[n++] = '/';
#endif
      }
#else
    if (fullPath[n-1] != '/')
      {
      fullPath[n++] = '/';
      }
#endif
    }

  strcpy(&fullPath[n], name);

  int result = 0;
  struct stat fs;
  if(stat(fullPath, &fs) == 0)
    {
#if defined(_WIN32)
    result = ((fs.st_mode & _S_IFDIR) != 0);
#else
    result = S_ISDIR(fs.st_mode);
#endif
    }

  delete [] fullPath;

  return result;
}

int vtkDirectory::DeleteDirectory(const char* dir)
{
  return vtksys::SystemTools::RemoveADirectory(dir);
}

int vtkDirectory::Rename(const char* oldname, const char* newname)
{
  return 0 == rename(oldname, newname);
}
<|endoftext|>


<commit_before>/*
 * Author: Norbert Wesp <nwesp@phytec.de>
 * Copyright (c) 2017 Phytec Messtechnik GmbH.
 *
 * based on: RIOT-driver tcs37727 by Johann Fischer <j.fischer@phytec.de>
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#pragma once

#include <string>
#include <mraa/i2c.hpp>
#include <stdint.h>
#include <stdbool.h>

#define TCS37727_NAME "TCS37727"
#define TCS37727_I2C_ADDRESS   0x29
#define TCS37727_DEVICE_ID     0x49
#define TCS37727_DEVICE_ID_REG 0x92

#define TCS37727_ATIME_DEFAULT     200000  /* Default RGBC integration time */
#define TCS37727_AG_THRESHOLD_LOW  200
#define TCS37727_AG_THRESHOLD_HIGH (65535 - TCS37727_AG_THRESHOLD_LOW)

/* TCS37727 Register Map */
#define TCS37727_ENABLE  0x80 /* Enables states and interrupts */
#define TCS37727_ATIME   0x81 /* RGBC time */
#define TCS37727_PTIME   0x82 /* Proximity time */
#define TCS37727_WTIME   0x83 /* Wait time */
#define TCS37727_AILTL   0x04 /* Clear interrupt low threshold low byte */
#define TCS37727_AILTH   0x05 /* Clear interrupt low threshold high byte */
#define TCS37727_AIHTL   0x06 /* Clear interrupt high threshold low byte */
#define TCS37727_AIHTH   0x07 /* Clear interrupt high threshold high byte */
#define TCS37727_PILTL   0x08 /* Proximity inter. low threshold low byte */
#define TCS37727_PILTH   0x09 /* Proximity inter. low threshold high byte */
#define TCS37727_PIHTL   0x0A /* Proximity inter. high threshold low byte */
#define TCS37727_PIHTH   0x0B /* Proximity inter. high threshold high byte */
#define TCS37727_PERS    0x8C /* Interrupt persistence filters */
#define TCS37727_CONFIG  0x8D /* Configuration */
#define TCS37727_PPULSE  0x8E /* Proximity pulse count */
#define TCS37727_CONTROL 0x8F /* Gain control register */
#define TCS37727_STATUS  0x93 /* Device status */
#define TCS37727_CDATA   0x14 /* Clear ADC data low byte */
#define TCS37727_CDATAH  0x15 /* Clear ADC data high byte */
#define TCS37727_RDATA   0x16 /* Red ADC data low byte */
#define TCS37727_RDATAH  0x17 /* Red ADC data high byte */
#define TCS37727_GDATA   0x18 /* Green ADC data low byte */
#define TCS37727_GDATAH  0x19 /* Green ADC data high byte */
#define TCS37727_BDATA   0x1A /* Blue ADC data low byte */
#define TCS37727_BDATAH  0x1B /* Blue ADC data high byte */
#define TCS37727_PDATA   0x1C /* Proximity ADC data low byte */
#define TCS37727_PDATAH  0x1D /* Proximity ADC data high byte */

/* TCS37727 Command Register */
#define TCS37727_BYTE_TRANS 0x80 /* Repeated byte protocol transaction */
#define TCS37727_INC_TRANS  0xA0 /* Auto-increment protocol transaction */
#define TCS37727_SF_PICLR   0xE5 /* Proximity interrupt clear */
#define TCS37727_SF_CICLR   0xE6 /* Clear channel interrupt clear */
#define TCS37727_SF_PCICLR  0xE7 /* Proximity & Clear channel inter. clear */

/* TCS37727 Enable Register */
#define TCS37727_ENABLE_PIEN (1 << 5) /* Proximity interrupt enable */
#define TCS37727_ENABLE_AIEN (1 << 4) /* Clear channel interrupt enable */
#define TCS37727_ENABLE_WEN  (1 << 3) /* Wait enable */
#define TCS37727_ENABLE_PEN  (1 << 2) /* Proximity enable */
#define TCS37727_ENABLE_AEN  (1 << 1) /* RGBC enable, actives 2-channel ADC */
#define TCS37727_ENABLE_PON  (1 << 0) /* Power ON */

/* TCS37727 Control Register */
#define TCS37727_CONTROL_PDRIVE_100  0x00 /* 100 mA LED Drive Strength */
#define TCS37727_CONTROL_PDRIVE_50   0x04 /* 50 mA LED Drive Strength */
#define TCS37727_CONTROL_PDRIVE_25   0x08 /* 25 mA LED Drive Strength */
#define TCS37727_CONTROL_PDRIVE_12   0x0C /* 12.5 mA LED Drive Strength */
#define TCS37727_CONTROL_PDRIVE_MASK 0x0C /* PDRIVE Mask */
#define TCS37727_CONTROL_AGAIN_1     0x00 /* 1 × gain RGBC Gain Value */
#define TCS37727_CONTROL_AGAIN_4     0x01 /* 4 × gain RGBC Gain Value */
#define TCS37727_CONTROL_AGAIN_16    0x02 /* 16 × gain RGBC Gain Value */
#define TCS37727_CONTROL_AGAIN_60    0x03 /* 60 × gain RGBC Gain Value */
#define TCS37727_CONTROL_AGAIN_MASK  0x03 /* AGAIN Mask */

/* TCS37727 ATIME register values */
#define TCS37727_ATIME_MIN 2400   /* 2.4ms integr. time, max count 1024 */
#define TCS37727_ATIME_MAX 614000 /* 614ms integr. time, max count 0xffff */

#define TCS37727_ATIME_TO_REG(val) (256 - (uint8_t)((val) / 2400))
#define TCS37727_ATIME_TO_US(reg)  ((256 - (uint8_t)(reg)) * 2400)

/* Coefficients for Lux and CT Equations (DN40) */
/* Coefficients in integer format, multiplied by 1000 */
#define DGF_IF        310
#define R_COEF_IF     136
#define G_COEF_IF    1000
#define B_COEF_IF    -444
#define CT_COEF_IF   3810
#define CT_OFFSET_IF 1391

namespace upm {

typedef struct {
    uint32_t red;           /**< IR compensated channels red */
    uint32_t green;         /**< IR compensated channels green */
    uint32_t blue;          /**< IR compensated channels blue */
    uint32_t clear;         /**< channels clear */
    uint32_t lux;           /**< Lux */
    uint32_t ct;            /**< Color temperature */
} tcs37727_data_t;

/**
 * @brief TCS37727 Color Light-To-Digital Converter
 * @defgroup tcs37727 libupm-tcs37727
 * @ingroup ams i2c color
 */

/**
 * @library tcs37727
 * @sensor tcs37727
 * @comname TCS37727 Color Light-To-Digital Converter
 * @type color
 * @man ams
 * @web http://ams.com/eng/Products/Light-Sensors
 * @con i2c
 *
 * @brief API for the TCS37727 Color Light-To-Digital Converter
 *
 * Description in web-link above:
 * The TCS3772 device family provides red, green, blue, and clear (RGBC) light
 * sensing and, when coupled with an external IR LED, proximity detection.
 * These devices detect light intensity under a variety of lighting conditions
 * and through a variety of attenuation materials, including dark glass. The
 * proximity detection feature allows a large dynamic range of operation for
 * accurate short distance detection, such as in a cell phone, for detecting
 * when the user positions the phone close to their ear. An internal state
 * machine provides the ability to put the device into a low power state in
 * between proximity and RGBC measurements providing very low average power
 * consumption.
 *
 * @snippet tcs37727.cxx Interesting
 */
class TCS37727 {
    public:
        /**
         *
         * Instantiates an TCS37727 object
         * Settings: Gain 4x, Proximity Detection off
         *
         * @param bus Number of the used bus
         * @param atime_us RGBC integration time
         * @param devAddr Address of the used I2C device
         */
        TCS37727 (int bus, int atime_us=TCS37727_ATIME_DEFAULT,
                               int devAddr=TCS37727_I2C_ADDRESS);

        /**
         * Check device_id of sensor
         *
         * @return  0 on success
         *         -1 on error
         */
        int checkID(void);

        /**
         * Set active mode, this enables periodic RGBC measurements
         *
         * @return  0 on success
         *         -1 on error
         */
        int setActive(void);

        /**
         * Set standby mode, this disables periodic RGBC measurements
         * Also turns off the sensor when proximity measurement is disabled
         *
         * @return  0 on success
         *         -1 on error
         */
        int setStandby(void);

        /**
         *
         */
        uint8_t trimGain(int rawc);

        /**
         * Read out data of regs and call further function
         * Also saves converted values to variables
         *
         * @return  0 on success
         *         -1 on error
         */
        int sampleData(void);

        /**
         * Get the calculated channel red color
         *
         * @param bSampleData Flag to read sensor
         * @return The channel red color on success
         *         999 on error
         */
        uint32_t getChannelRed(int bSampleData = 0);

        /**
         * Get the calculated channel green color
         *
         * @param bSampleData Flag to read sensor
         * @return The channel green color on success
         *         999 on error
         */
        uint32_t getChannelGreen(int bSampleData = 0);

        /**
         * Get the calculated channel blue color
         *
         * @param bSampleData Flag to read sensor
         * @return The channel blue color on success
         *         999 on error
         */
        uint32_t getChannelBlue(int bSampleData = 0);

        /**
         * Get the calculated channel clear color
         *
         * @param bSampleData Flag to read sensor
         * @return The channel clear color on success
         *         999 on error
         */
        uint32_t getChannelClear(int bSampleData = 0);

        /**
         * Get the calculated lux value
         *
         * @param bSampleData Flag to read sensor
         * @return The lux value on success
         *         999 on error
         */
        uint32_t getLux(int bSampleData = 0);

        /**
         * Get the calculated color temperature
         *
         * @param bSampleData Flag to read sensor
         * @return The color temperature on success
         *         999 on error
         */
        uint32_t getColorTemperature(int bSampleData = 0);

        /**
         * Get calculated sensor values
         *
         * @param data Calculated sensor values
         * @param bSampleData Flag to read sensor
         * @return  0 on success
         *         -1 on error
         */
        int getData(tcs37727_data_t* data, int bSampleData = 0);

    private:

        std::string m_name;

        int m_controlAddr;
        int m_bus;
        mraa::I2c m_i2ControlCtx;

        int s_atime_us;              /* atime value conveted to microseconds */
        int s_again;                 /* amount of gain */

        tcs37727_data_t s_data[1];
    };

}
<commit_msg>tcs37727: remove utf8 characters<commit_after>/*
 * Author: Norbert Wesp <nwesp@phytec.de>
 * Copyright (c) 2017 Phytec Messtechnik GmbH.
 *
 * based on: RIOT-driver tcs37727 by Johann Fischer <j.fischer@phytec.de>
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#pragma once

#include <string>
#include <mraa/i2c.hpp>
#include <stdint.h>
#include <stdbool.h>

#define TCS37727_NAME "TCS37727"
#define TCS37727_I2C_ADDRESS   0x29
#define TCS37727_DEVICE_ID     0x49
#define TCS37727_DEVICE_ID_REG 0x92

#define TCS37727_ATIME_DEFAULT     200000  /* Default RGBC integration time */
#define TCS37727_AG_THRESHOLD_LOW  200
#define TCS37727_AG_THRESHOLD_HIGH (65535 - TCS37727_AG_THRESHOLD_LOW)

/* TCS37727 Register Map */
#define TCS37727_ENABLE  0x80 /* Enables states and interrupts */
#define TCS37727_ATIME   0x81 /* RGBC time */
#define TCS37727_PTIME   0x82 /* Proximity time */
#define TCS37727_WTIME   0x83 /* Wait time */
#define TCS37727_AILTL   0x04 /* Clear interrupt low threshold low byte */
#define TCS37727_AILTH   0x05 /* Clear interrupt low threshold high byte */
#define TCS37727_AIHTL   0x06 /* Clear interrupt high threshold low byte */
#define TCS37727_AIHTH   0x07 /* Clear interrupt high threshold high byte */
#define TCS37727_PILTL   0x08 /* Proximity inter. low threshold low byte */
#define TCS37727_PILTH   0x09 /* Proximity inter. low threshold high byte */
#define TCS37727_PIHTL   0x0A /* Proximity inter. high threshold low byte */
#define TCS37727_PIHTH   0x0B /* Proximity inter. high threshold high byte */
#define TCS37727_PERS    0x8C /* Interrupt persistence filters */
#define TCS37727_CONFIG  0x8D /* Configuration */
#define TCS37727_PPULSE  0x8E /* Proximity pulse count */
#define TCS37727_CONTROL 0x8F /* Gain control register */
#define TCS37727_STATUS  0x93 /* Device status */
#define TCS37727_CDATA   0x14 /* Clear ADC data low byte */
#define TCS37727_CDATAH  0x15 /* Clear ADC data high byte */
#define TCS37727_RDATA   0x16 /* Red ADC data low byte */
#define TCS37727_RDATAH  0x17 /* Red ADC data high byte */
#define TCS37727_GDATA   0x18 /* Green ADC data low byte */
#define TCS37727_GDATAH  0x19 /* Green ADC data high byte */
#define TCS37727_BDATA   0x1A /* Blue ADC data low byte */
#define TCS37727_BDATAH  0x1B /* Blue ADC data high byte */
#define TCS37727_PDATA   0x1C /* Proximity ADC data low byte */
#define TCS37727_PDATAH  0x1D /* Proximity ADC data high byte */

/* TCS37727 Command Register */
#define TCS37727_BYTE_TRANS 0x80 /* Repeated byte protocol transaction */
#define TCS37727_INC_TRANS  0xA0 /* Auto-increment protocol transaction */
#define TCS37727_SF_PICLR   0xE5 /* Proximity interrupt clear */
#define TCS37727_SF_CICLR   0xE6 /* Clear channel interrupt clear */
#define TCS37727_SF_PCICLR  0xE7 /* Proximity & Clear channel inter. clear */

/* TCS37727 Enable Register */
#define TCS37727_ENABLE_PIEN (1 << 5) /* Proximity interrupt enable */
#define TCS37727_ENABLE_AIEN (1 << 4) /* Clear channel interrupt enable */
#define TCS37727_ENABLE_WEN  (1 << 3) /* Wait enable */
#define TCS37727_ENABLE_PEN  (1 << 2) /* Proximity enable */
#define TCS37727_ENABLE_AEN  (1 << 1) /* RGBC enable, actives 2-channel ADC */
#define TCS37727_ENABLE_PON  (1 << 0) /* Power ON */

/* TCS37727 Control Register */
#define TCS37727_CONTROL_PDRIVE_100  0x00 /* 100 mA LED Drive Strength */
#define TCS37727_CONTROL_PDRIVE_50   0x04 /* 50 mA LED Drive Strength */
#define TCS37727_CONTROL_PDRIVE_25   0x08 /* 25 mA LED Drive Strength */
#define TCS37727_CONTROL_PDRIVE_12   0x0C /* 12.5 mA LED Drive Strength */
#define TCS37727_CONTROL_PDRIVE_MASK 0x0C /* PDRIVE Mask */
#define TCS37727_CONTROL_AGAIN_1     0x00 /* 1 x gain RGBC Gain Value */
#define TCS37727_CONTROL_AGAIN_4     0x01 /* 4 x gain RGBC Gain Value */
#define TCS37727_CONTROL_AGAIN_16    0x02 /* 16 x gain RGBC Gain Value */
#define TCS37727_CONTROL_AGAIN_60    0x03 /* 60 x gain RGBC Gain Value */
#define TCS37727_CONTROL_AGAIN_MASK  0x03 /* AGAIN Mask */

/* TCS37727 ATIME register values */
#define TCS37727_ATIME_MIN 2400   /* 2.4ms integr. time, max count 1024 */
#define TCS37727_ATIME_MAX 614000 /* 614ms integr. time, max count 0xffff */

#define TCS37727_ATIME_TO_REG(val) (256 - (uint8_t)((val) / 2400))
#define TCS37727_ATIME_TO_US(reg)  ((256 - (uint8_t)(reg)) * 2400)

/* Coefficients for Lux and CT Equations (DN40) */
/* Coefficients in integer format, multiplied by 1000 */
#define DGF_IF        310
#define R_COEF_IF     136
#define G_COEF_IF    1000
#define B_COEF_IF    -444
#define CT_COEF_IF   3810
#define CT_OFFSET_IF 1391

namespace upm {

typedef struct {
    uint32_t red;           /**< IR compensated channels red */
    uint32_t green;         /**< IR compensated channels green */
    uint32_t blue;          /**< IR compensated channels blue */
    uint32_t clear;         /**< channels clear */
    uint32_t lux;           /**< Lux */
    uint32_t ct;            /**< Color temperature */
} tcs37727_data_t;

/**
 * @brief TCS37727 Color Light-To-Digital Converter
 * @defgroup tcs37727 libupm-tcs37727
 * @ingroup ams i2c color
 */

/**
 * @library tcs37727
 * @sensor tcs37727
 * @comname TCS37727 Color Light-To-Digital Converter
 * @type color
 * @man ams
 * @web http://ams.com/eng/Products/Light-Sensors
 * @con i2c
 *
 * @brief API for the TCS37727 Color Light-To-Digital Converter
 *
 * Description in web-link above:
 * The TCS3772 device family provides red, green, blue, and clear (RGBC) light
 * sensing and, when coupled with an external IR LED, proximity detection.
 * These devices detect light intensity under a variety of lighting conditions
 * and through a variety of attenuation materials, including dark glass. The
 * proximity detection feature allows a large dynamic range of operation for
 * accurate short distance detection, such as in a cell phone, for detecting
 * when the user positions the phone close to their ear. An internal state
 * machine provides the ability to put the device into a low power state in
 * between proximity and RGBC measurements providing very low average power
 * consumption.
 *
 * @snippet tcs37727.cxx Interesting
 */
class TCS37727 {
    public:
        /**
         *
         * Instantiates an TCS37727 object
         * Settings: Gain 4x, Proximity Detection off
         *
         * @param bus Number of the used bus
         * @param atime_us RGBC integration time
         * @param devAddr Address of the used I2C device
         */
        TCS37727 (int bus, int atime_us=TCS37727_ATIME_DEFAULT,
                               int devAddr=TCS37727_I2C_ADDRESS);

        /**
         * Check device_id of sensor
         *
         * @return  0 on success
         *         -1 on error
         */
        int checkID(void);

        /**
         * Set active mode, this enables periodic RGBC measurements
         *
         * @return  0 on success
         *         -1 on error
         */
        int setActive(void);

        /**
         * Set standby mode, this disables periodic RGBC measurements
         * Also turns off the sensor when proximity measurement is disabled
         *
         * @return  0 on success
         *         -1 on error
         */
        int setStandby(void);

        /**
         *
         */
        uint8_t trimGain(int rawc);

        /**
         * Read out data of regs and call further function
         * Also saves converted values to variables
         *
         * @return  0 on success
         *         -1 on error
         */
        int sampleData(void);

        /**
         * Get the calculated channel red color
         *
         * @param bSampleData Flag to read sensor
         * @return The channel red color on success
         *         999 on error
         */
        uint32_t getChannelRed(int bSampleData = 0);

        /**
         * Get the calculated channel green color
         *
         * @param bSampleData Flag to read sensor
         * @return The channel green color on success
         *         999 on error
         */
        uint32_t getChannelGreen(int bSampleData = 0);

        /**
         * Get the calculated channel blue color
         *
         * @param bSampleData Flag to read sensor
         * @return The channel blue color on success
         *         999 on error
         */
        uint32_t getChannelBlue(int bSampleData = 0);

        /**
         * Get the calculated channel clear color
         *
         * @param bSampleData Flag to read sensor
         * @return The channel clear color on success
         *         999 on error
         */
        uint32_t getChannelClear(int bSampleData = 0);

        /**
         * Get the calculated lux value
         *
         * @param bSampleData Flag to read sensor
         * @return The lux value on success
         *         999 on error
         */
        uint32_t getLux(int bSampleData = 0);

        /**
         * Get the calculated color temperature
         *
         * @param bSampleData Flag to read sensor
         * @return The color temperature on success
         *         999 on error
         */
        uint32_t getColorTemperature(int bSampleData = 0);

        /**
         * Get calculated sensor values
         *
         * @param data Calculated sensor values
         * @param bSampleData Flag to read sensor
         * @return  0 on success
         *         -1 on error
         */
        int getData(tcs37727_data_t* data, int bSampleData = 0);

    private:

        std::string m_name;

        int m_controlAddr;
        int m_bus;
        mraa::I2c m_i2ControlCtx;

        int s_atime_us;              /* atime value conveted to microseconds */
        int s_again;                 /* amount of gain */

        tcs37727_data_t s_data[1];
    };

}
<|endoftext|>