<commit_before>#include "nse_sequential.h"

// Include <gtest/gtest.h> _after_ "nse_sequential.h.h"
#include "gtest/gtest.h"

using namespace crv;

TEST(NseSequentialTest, SequentialDfsChecker)
{
  SequentialDfsChecker checker;

  // if (a < 7) { skip } ; if (a < 4)  { skip }
  Internal<int> a;
  EXPECT_FALSE(checker.branch(a < 7));
  EXPECT_FALSE(checker.branch(a < 4));
  EXPECT_TRUE(checker.find_next_path());

  EXPECT_FALSE(checker.branch(a < 7));
  EXPECT_TRUE(checker.branch(a < 4));

  // ignored because "a >= 7 and a < 4" is unsat
  EXPECT_FALSE(checker.branch(a < 1));
  EXPECT_FALSE(checker.branch(a < 2));
  EXPECT_FALSE(checker.branch(a < 3));
  EXPECT_TRUE(checker.find_next_path());

  EXPECT_TRUE(checker.branch(a < 7));
  EXPECT_FALSE(checker.branch(a < 4));
  EXPECT_TRUE(checker.find_next_path());

  EXPECT_TRUE(checker.branch(a < 7));
  EXPECT_TRUE(checker.branch(a < 4));
  EXPECT_FALSE(checker.find_next_path());

  checker.reset();

  Internal<int> b;
  checker.add_assertion(b < 7);
  EXPECT_TRUE(checker.branch(b < 7));
  EXPECT_FALSE(checker.branch(b < 4));
  EXPECT_TRUE(checker.find_next_path());

  checker.add_assertion(b < 7);
  EXPECT_TRUE(checker.branch(b < 7));
  EXPECT_TRUE(checker.branch(b < 4));
  EXPECT_FALSE(checker.find_next_path());

  checker.reset();

  Internal<int> c;
  checker.add_assertion(c < 4);
  EXPECT_TRUE(checker.branch(c < 7));
  EXPECT_TRUE(checker.branch(c < 4));
  EXPECT_FALSE(checker.find_next_path());
}

TEST(NseSequentialTest, Backtrack)
{
  BacktrackDfsChecker checker;

  // if (a < 7) { skip } ; if (a < 4)  { skip }
  Internal<int> a;
  EXPECT_FALSE(checker.branch(a < 7));
  EXPECT_FALSE(checker.branch(a < 4));
  EXPECT_TRUE(checker.find_next_path());

  EXPECT_FALSE(checker.branch(a < 7));
  EXPECT_TRUE(checker.branch(a < 4));

  // ignored because "a >= 7 and a < 4" is unsat
  EXPECT_FALSE(checker.branch(a < 1));
  EXPECT_FALSE(checker.branch(a < 2));
  EXPECT_FALSE(checker.branch(a < 3));
  EXPECT_TRUE(checker.find_next_path());

  EXPECT_TRUE(checker.branch(a < 7));
  EXPECT_FALSE(checker.branch(a < 4));
  EXPECT_TRUE(checker.find_next_path());

  EXPECT_TRUE(checker.branch(a < 7));
  EXPECT_TRUE(checker.branch(a < 4));
  EXPECT_FALSE(checker.find_next_path());

  checker.reset();

  // BacktrackDfsChecker may not prune as
  // many paths as SequentialDfsChecker
  Internal<int> b;
  checker.add_assertion(b < 7);
  EXPECT_FALSE(checker.branch(b < 7));
  EXPECT_FALSE(checker.branch(b < 4));
  EXPECT_TRUE(checker.find_next_path());

  checker.add_assertion(b < 7);
  EXPECT_TRUE(checker.branch(b < 7));
  EXPECT_FALSE(checker.branch(b < 4));
  EXPECT_TRUE(checker.find_next_path());

  checker.add_assertion(b < 7);
  EXPECT_TRUE(checker.branch(b < 7));
  EXPECT_TRUE(checker.branch(b < 4));
  EXPECT_FALSE(checker.find_next_path());
}
<commit_msg>Add test case for non-chronological symbolic execution<commit_after>#include "nse_sequential.h"

// Include <gtest/gtest.h> _after_ "nse_sequential.h.h"
#include "gtest/gtest.h"

using namespace crv;

TEST(NseSequentialTest, SequentialDfsChecker)
{
  SequentialDfsChecker checker;

  // if (a < 7) { skip } ; if (a < 4)  { skip }
  Internal<int> a;
  EXPECT_FALSE(checker.branch(a < 7));
  EXPECT_FALSE(checker.branch(a < 4));
  EXPECT_TRUE(checker.find_next_path());

  EXPECT_FALSE(checker.branch(a < 7));
  EXPECT_TRUE(checker.branch(a < 4));

  // ignored because "a >= 7 and a < 4" is unsat
  EXPECT_FALSE(checker.branch(a < 1));
  EXPECT_FALSE(checker.branch(a < 2));
  EXPECT_FALSE(checker.branch(a < 3));
  EXPECT_TRUE(checker.find_next_path());

  EXPECT_TRUE(checker.branch(a < 7));
  EXPECT_FALSE(checker.branch(a < 4));
  EXPECT_TRUE(checker.find_next_path());

  EXPECT_TRUE(checker.branch(a < 7));
  EXPECT_TRUE(checker.branch(a < 4));
  EXPECT_FALSE(checker.find_next_path());

  checker.reset();

  Internal<int> b;
  checker.add_assertion(b < 7);
  EXPECT_TRUE(checker.branch(b < 7));
  EXPECT_FALSE(checker.branch(b < 4));
  EXPECT_TRUE(checker.find_next_path());

  checker.add_assertion(b < 7);
  EXPECT_TRUE(checker.branch(b < 7));
  EXPECT_TRUE(checker.branch(b < 4));
  EXPECT_FALSE(checker.find_next_path());

  checker.reset();

  Internal<int> c;
  checker.add_assertion(c < 4);
  EXPECT_TRUE(checker.branch(c < 7));
  EXPECT_TRUE(checker.branch(c < 4));
  EXPECT_FALSE(checker.find_next_path());
}

TEST(NseSequentialTest, Backtrack)
{
  BacktrackDfsChecker checker;

  // if (a < 7) { skip } ; if (a < 4)  { skip }
  Internal<int> a;
  EXPECT_FALSE(checker.branch(a < 7));
  EXPECT_FALSE(checker.branch(a < 4));
  EXPECT_TRUE(checker.find_next_path());

  EXPECT_FALSE(checker.branch(a < 7));
  EXPECT_TRUE(checker.branch(a < 4));

  // ignored because "a >= 7 and a < 4" is unsat
  EXPECT_FALSE(checker.branch(a < 1));
  EXPECT_FALSE(checker.branch(a < 2));
  EXPECT_FALSE(checker.branch(a < 3));
  EXPECT_TRUE(checker.find_next_path());

  EXPECT_TRUE(checker.branch(a < 7));
  EXPECT_FALSE(checker.branch(a < 4));
  EXPECT_TRUE(checker.find_next_path());

  EXPECT_TRUE(checker.branch(a < 7));
  EXPECT_TRUE(checker.branch(a < 4));
  EXPECT_FALSE(checker.find_next_path());

  checker.reset();

  // BacktrackDfsChecker may not prune as
  // many paths as SequentialDfsChecker
  Internal<int> b;
  checker.add_assertion(b < 7);
  EXPECT_FALSE(checker.branch(b < 7));
  EXPECT_FALSE(checker.branch(b < 4));
  EXPECT_TRUE(checker.find_next_path());

  checker.add_assertion(b < 7);
  EXPECT_TRUE(checker.branch(b < 7));
  EXPECT_FALSE(checker.branch(b < 4));
  EXPECT_TRUE(checker.find_next_path());

  checker.add_assertion(b < 7);
  EXPECT_TRUE(checker.branch(b < 7));
  EXPECT_TRUE(checker.branch(b < 4));
  EXPECT_FALSE(checker.find_next_path());

  checker.reset();

  // assertion at the end
  EXPECT_FALSE(checker.branch(b < 7));
  EXPECT_FALSE(checker.branch(b < 4));
  checker.add_assertion(a < 7);
  checker.add_assertion(b < 7);
  EXPECT_TRUE(checker.find_next_path());

  EXPECT_TRUE(checker.branch(b < 7));
  EXPECT_FALSE(checker.branch(b < 4));
  checker.add_assertion(a < 7);
  checker.add_assertion(b < 7);
  EXPECT_TRUE(checker.find_next_path());

  EXPECT_TRUE(checker.branch(b < 7));
  EXPECT_TRUE(checker.branch(b < 4));
  checker.add_assertion(a < 7);
  checker.add_assertion(b < 7);
  EXPECT_FALSE(checker.find_next_path());
}
<|endoftext|>


<commit_before>#ifndef UNESCAPE_COPY_ROW_HPP
#define UNESCAPE_COPY_ROW_HPP

#include <boost/noncopyable.hpp>
#include <boost/fusion/include/size.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/optional.hpp>
#include <boost/fusion/include/for_each.hpp>

#include "types.hpp"

template <typename S, typename T>
struct unescape_copy_row
  : public boost::noncopyable {
  static const size_t s_num_columns = boost::fusion::result_of::size<T>::value;

  explicit unescape_copy_row(S &source)
  : m_source(source),
    m_reorder(calculate_reorder(m_source.column_names())) {
  }

  ~unescape_copy_row() {
  }

  size_t read(T &row) {
    std::string line;
    size_t num = m_source.read(line);
    if (num > 0) {
      unpack(line, row);
    }
    return num;
  }

private:
  void unpack(std::string &line, T &row) {
    const size_t sz = s_num_columns;
    std::vector<std::pair<char *, size_t> > columns, old_columns;
    {
      char *prev_ptr = &line[0];
      char * const end_ptr = &line[line.size()];
      char *ptr = &line[0];
      for (; ptr != end_ptr; ++ptr) {
        if (*ptr == '\t') {
          *ptr = '\0';
          old_columns.push_back(std::make_pair(prev_ptr, std::distance(prev_ptr, ptr)));
          prev_ptr = ptr + 1;
        }
      }
      old_columns.push_back(std::make_pair(prev_ptr, std::distance(prev_ptr, ptr)));
    }

    columns.reserve(sz);
    for (size_t i = 0; i < sz; ++i) {
      if (i >= m_reorder.size()) {
        throw std::runtime_error("Index exceeds m_reorder.size(), this is a bug.");
      }
      size_t j = m_reorder[i];
      if (j >= old_columns.size()) {
        throw std::runtime_error("Reordered index exceeds old_columns.size(), this is a bug.");
      }
      columns.push_back(old_columns[j]);
    }

    if (columns.size() != sz) {
      throw std::runtime_error((boost::format("Wrong number of columns: expecting %1%, got %2% in line `%3%'.")
                                % sz % columns.size() % line).str());
    }
    try {
      set_values(row, columns);
    } catch (const std::exception &e) {
      throw std::runtime_error((boost::format("%1%: in line `%2%'.") % e.what() % line).str());
    }
  }

  inline void set_values(T &t, std::vector<std::pair<char *, size_t> > &vs) {
    boost::fusion::for_each(t, set_value(vs.begin()));
  }

  struct set_value {
    explicit set_value(std::vector<std::pair<char *, size_t> >::iterator i) : itr(i) {}

    void operator()(bool &b) const {
      std::pair<char *, size_t> str = *itr++;
      switch (str.first[0]) {
      case 't':
        b = true;
        break;
      case 'f':
        b = false;
        break;
      default:
        throw std::runtime_error((boost::format("Unrecognised value for bool: `%1%'") % str.first).str());
      }
    }

    void operator()(int16_t &i) const {
      std::pair<char *, size_t> str = *itr++;
      unescape(str);
      i = int16_t(strtol(str.first, NULL, 10));
    }

    void operator()(int32_t &i) const {
      std::pair<char *, size_t> str = *itr++;
      unescape(str);
      i = int32_t(strtol(str.first, NULL, 10));
    }

    void operator()(int64_t &i) const {
      std::pair<char *, size_t> str = *itr++;
      unescape(str);
      i = int64_t(strtoll(str.first, NULL, 10));
    }

    void operator()(double &d) const {
      std::pair<char *, size_t> str = *itr++;
      unescape(str);
      d = strtod(str.first, NULL);
    }

    void operator()(std::string &v) const {
      std::pair<char *, size_t> str = *itr++;
      v.assign(str.first, str.second);
    }

    void operator()(boost::posix_time::ptime &t) const {
      std::pair<char *, size_t> str = *itr++;
      unescape(str);
      //                    11111111112
      //           12345678901234567890
      // format is 2013-09-11 13:39:52.742365
      if (str.second < 19) {
        throw std::runtime_error((boost::format("Unexpected format for timestamp: `%1%'.")
                                  % str.first).str());
      }
      int year  = ((str.first[0] - '0') * 1000 +
                   (str.first[1] - '0') * 100 +
                   (str.first[2] - '0') * 10 +
                   (str.first[3] - '0'));
      int month = ((str.first[5] - '0') * 10 + (str.first[6] - '0'));
      int day   = ((str.first[8] - '0') * 10 + (str.first[9] - '0'));
      int hour  = ((str.first[11] - '0') * 10 + (str.first[12] - '0'));
      int min   = ((str.first[14] - '0') * 10 + (str.first[15] - '0'));
      int sec   = ((str.first[17] - '0') * 10 + (str.first[19] - '0'));
      t = boost::posix_time::ptime(boost::gregorian::date(year, month, day),
                                   boost::posix_time::time_duration(hour, min, sec));
    }

    template <typename V>
    void operator()(boost::optional<V> &o) const {
      std::pair<char *, size_t> s = *itr;
      if (strncmp(s.first, "\\N", s.second) == 0) {
        o = boost::none;
        ++itr;
      } else {
        V v;
        operator()(v);
        o = v;
      }
    }

    void operator()(user_status_enum &e) const {
      std::pair<char *, size_t> str = *itr++;
      unescape(str);
      if (strncmp(str.first, "pending", str.second) == 0) {
        e = user_status_pending;
      } else if (strncmp(str.first, "active", str.second) == 0) {
        e = user_status_active;
      } else if (strncmp(str.first, "confirmed", str.second) == 0) {
        e = user_status_confirmed;
      } else if (strncmp(str.first, "suspended", str.second) == 0) {
        e = user_status_suspended;
      } else if (strncmp(str.first, "deleted", str.second) == 0) {
        e = user_status_deleted;
      } else {
        throw std::runtime_error((boost::format("Unrecognised value for user_status_enum: `%1%'.") % str.first).str());
      }
    }

    void operator()(format_enum &e) const {
      std::pair<char *, size_t> str = *itr++;
      unescape(str);
      if (strncmp(str.first, "html", str.second) == 0) {
        e = format_html;
      } else if (strncmp(str.first, "markdown", str.second) == 0) {
        e = format_markdown;
      } else if (strncmp(str.first, "text", str.second) == 0) {
        e = format_text;
      } else {
        throw std::runtime_error((boost::format("Unrecognised value for format_enum: `%1%'.") % str.first).str());
      }
    }

    void operator()(nwr_enum &e) const {
      std::pair<char *, size_t> str = *itr++;
      unescape(str);
      if (strncmp(str.first, "Node", str.second) == 0) {
        e = nwr_node;
      } else if (strncmp(str.first, "Way", str.second) == 0) {
        e = nwr_way;
      } else if (strncmp(str.first, "Relation", str.second) == 0) {
        e = nwr_relation;
      } else {
        throw std::runtime_error((boost::format("Unrecognised value for nwr_enum: `%1%'.") % str.first).str());
      }
    }

    inline int hex2digit(char ch) const {
      switch (ch) {
      case '0':
      case '1':
      case '2':
      case '3':
      case '4':
      case '5':
      case '6':
      case '7':
      case '8':
      case '9':
        return int(ch - '0');

      case 'a':
      case 'b':
      case 'c':
      case 'd':
      case 'e':
      case 'f':
        return 10 + int(ch - 'a');

      case 'A':
      case 'B':
      case 'C':
      case 'D':
      case 'E':
      case 'F':
        return 10 + int(ch - 'A');

      default:
        throw std::runtime_error("Invalid hex digit.");
      }
    }

    inline int oct2digit(char ch) const {
      if ((ch >= '0') && (ch <= '7')) {
        return int(ch - '0');
      } else {
        throw std::runtime_error("Invalid octal digit.");
      }
    }

    void unescape(std::pair<char *, size_t> &s) const {
      const size_t end = s.second;
      char *str = s.first;
      size_t j = 0;

      for (size_t i = 0; i < end; ++i) {
        switch (str[i]) {
        case '\\':
          ++i;
          if (i < end) {
            switch (str[i]) {
            case 'b':
              str[j] = '\b';
              break;

            case 'f':
              str[j] = '\f';
              break;

            case 'n':
              str[j] = '\n';
              break;

            case 'r':
              str[j] = '\r';
              break;

            case 't':
              str[j] = '\t';
              break;

            case 'v':
              str[j] = '\v';
              break;

            case 'x':
              i += 2;
              if (i < end) {
              } else {
                str[j] = char(hex2digit(str[i-1]) * 16 + hex2digit(str[i]));
                throw std::runtime_error("Unterminated hex escape sequence.");
              }
              break;

            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
              i += 2;
              if (i < end) {
                str[j] = char(oct2digit(str[i-2]) * 64 + oct2digit(str[i-1]) * 8 + oct2digit(str[i]));
              } else {
                throw std::runtime_error("Unterminated octal escape sequence.");
              }
              break;

            default:
              // an unnecessary escape
              str[j] = str[i];
            }

          } else {
            throw std::runtime_error("Unterminated escape sequence.");
          }
          break;

        default:
          if (i != j) {
            str[j] = str[i];
          }
        }

        ++j;
      }

      str[j] = '\0';
      s.second = j;
    }

    mutable std::vector<std::pair<char *, size_t> >::iterator itr;
  };

  static std::vector<size_t> calculate_reorder(const std::vector<std::string> &names) {
    std::vector<size_t> indexes;
    const std::vector<std::string> &wanted_names = T::column_names();

    const size_t num_columns = wanted_names.size();
    indexes.reserve(num_columns);
    for (size_t i = 0; i < num_columns; ++i) {
      const std::string &wanted_name = wanted_names[i];
      size_t j = i;

      if (wanted_name != "*") {
        std::vector<std::string>::const_iterator itr = std::find(names.begin(), names.end(), wanted_name);
        if (itr == names.end()) {
          std::ostringstream ostr;
          ostr << "Unable to find wanted column name \"" << wanted_name << "\" in available names: ";
          for (std::vector<std::string>::const_iterator jtr = names.begin(); itr != names.end(); ++itr) {
            ostr << "\"" << *jtr << "\", ";
          }
          throw std::runtime_error(ostr.str());
        }
        j = std::distance(names.begin(), itr);
      }

      indexes.push_back(j);
    }

    return indexes;
  }

  S &m_source;
  std::vector<size_t> m_reorder;
};

#endif /* UNESCAPE_COPY_ROW_HPP */
<commit_msg>Fixed bug in reporting of copy header problems.<commit_after>#ifndef UNESCAPE_COPY_ROW_HPP
#define UNESCAPE_COPY_ROW_HPP

#include <boost/noncopyable.hpp>
#include <boost/fusion/include/size.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/optional.hpp>
#include <boost/fusion/include/for_each.hpp>

#include "types.hpp"

template <typename S, typename T>
struct unescape_copy_row
  : public boost::noncopyable {
  static const size_t s_num_columns = boost::fusion::result_of::size<T>::value;

  explicit unescape_copy_row(S &source)
  : m_source(source),
    m_reorder(calculate_reorder(m_source.column_names())) {
  }

  ~unescape_copy_row() {
  }

  size_t read(T &row) {
    std::string line;
    size_t num = m_source.read(line);
    if (num > 0) {
      unpack(line, row);
    }
    return num;
  }

private:
  void unpack(std::string &line, T &row) {
    const size_t sz = s_num_columns;
    std::vector<std::pair<char *, size_t> > columns, old_columns;
    {
      char *prev_ptr = &line[0];
      char * const end_ptr = &line[line.size()];
      char *ptr = &line[0];
      for (; ptr != end_ptr; ++ptr) {
        if (*ptr == '\t') {
          *ptr = '\0';
          old_columns.push_back(std::make_pair(prev_ptr, std::distance(prev_ptr, ptr)));
          prev_ptr = ptr + 1;
        }
      }
      old_columns.push_back(std::make_pair(prev_ptr, std::distance(prev_ptr, ptr)));
    }

    columns.reserve(sz);
    for (size_t i = 0; i < sz; ++i) {
      if (i >= m_reorder.size()) {
        throw std::runtime_error("Index exceeds m_reorder.size(), this is a bug.");
      }
      size_t j = m_reorder[i];
      if (j >= old_columns.size()) {
        throw std::runtime_error("Reordered index exceeds old_columns.size(), this is a bug.");
      }
      columns.push_back(old_columns[j]);
    }

    if (columns.size() != sz) {
      throw std::runtime_error((boost::format("Wrong number of columns: expecting %1%, got %2% in line `%3%'.")
                                % sz % columns.size() % line).str());
    }
    try {
      set_values(row, columns);
    } catch (const std::exception &e) {
      throw std::runtime_error((boost::format("%1%: in line `%2%'.") % e.what() % line).str());
    }
  }

  inline void set_values(T &t, std::vector<std::pair<char *, size_t> > &vs) {
    boost::fusion::for_each(t, set_value(vs.begin()));
  }

  struct set_value {
    explicit set_value(std::vector<std::pair<char *, size_t> >::iterator i) : itr(i) {}

    void operator()(bool &b) const {
      std::pair<char *, size_t> str = *itr++;
      switch (str.first[0]) {
      case 't':
        b = true;
        break;
      case 'f':
        b = false;
        break;
      default:
        throw std::runtime_error((boost::format("Unrecognised value for bool: `%1%'") % str.first).str());
      }
    }

    void operator()(int16_t &i) const {
      std::pair<char *, size_t> str = *itr++;
      unescape(str);
      i = int16_t(strtol(str.first, NULL, 10));
    }

    void operator()(int32_t &i) const {
      std::pair<char *, size_t> str = *itr++;
      unescape(str);
      i = int32_t(strtol(str.first, NULL, 10));
    }

    void operator()(int64_t &i) const {
      std::pair<char *, size_t> str = *itr++;
      unescape(str);
      i = int64_t(strtoll(str.first, NULL, 10));
    }

    void operator()(double &d) const {
      std::pair<char *, size_t> str = *itr++;
      unescape(str);
      d = strtod(str.first, NULL);
    }

    void operator()(std::string &v) const {
      std::pair<char *, size_t> str = *itr++;
      v.assign(str.first, str.second);
    }

    void operator()(boost::posix_time::ptime &t) const {
      std::pair<char *, size_t> str = *itr++;
      unescape(str);
      //                    11111111112
      //           12345678901234567890
      // format is 2013-09-11 13:39:52.742365
      if (str.second < 19) {
        throw std::runtime_error((boost::format("Unexpected format for timestamp: `%1%'.")
                                  % str.first).str());
      }
      int year  = ((str.first[0] - '0') * 1000 +
                   (str.first[1] - '0') * 100 +
                   (str.first[2] - '0') * 10 +
                   (str.first[3] - '0'));
      int month = ((str.first[5] - '0') * 10 + (str.first[6] - '0'));
      int day   = ((str.first[8] - '0') * 10 + (str.first[9] - '0'));
      int hour  = ((str.first[11] - '0') * 10 + (str.first[12] - '0'));
      int min   = ((str.first[14] - '0') * 10 + (str.first[15] - '0'));
      int sec   = ((str.first[17] - '0') * 10 + (str.first[19] - '0'));
      t = boost::posix_time::ptime(boost::gregorian::date(year, month, day),
                                   boost::posix_time::time_duration(hour, min, sec));
    }

    template <typename V>
    void operator()(boost::optional<V> &o) const {
      std::pair<char *, size_t> s = *itr;
      if (strncmp(s.first, "\\N", s.second) == 0) {
        o = boost::none;
        ++itr;
      } else {
        V v;
        operator()(v);
        o = v;
      }
    }

    void operator()(user_status_enum &e) const {
      std::pair<char *, size_t> str = *itr++;
      unescape(str);
      if (strncmp(str.first, "pending", str.second) == 0) {
        e = user_status_pending;
      } else if (strncmp(str.first, "active", str.second) == 0) {
        e = user_status_active;
      } else if (strncmp(str.first, "confirmed", str.second) == 0) {
        e = user_status_confirmed;
      } else if (strncmp(str.first, "suspended", str.second) == 0) {
        e = user_status_suspended;
      } else if (strncmp(str.first, "deleted", str.second) == 0) {
        e = user_status_deleted;
      } else {
        throw std::runtime_error((boost::format("Unrecognised value for user_status_enum: `%1%'.") % str.first).str());
      }
    }

    void operator()(format_enum &e) const {
      std::pair<char *, size_t> str = *itr++;
      unescape(str);
      if (strncmp(str.first, "html", str.second) == 0) {
        e = format_html;
      } else if (strncmp(str.first, "markdown", str.second) == 0) {
        e = format_markdown;
      } else if (strncmp(str.first, "text", str.second) == 0) {
        e = format_text;
      } else {
        throw std::runtime_error((boost::format("Unrecognised value for format_enum: `%1%'.") % str.first).str());
      }
    }

    void operator()(nwr_enum &e) const {
      std::pair<char *, size_t> str = *itr++;
      unescape(str);
      if (strncmp(str.first, "Node", str.second) == 0) {
        e = nwr_node;
      } else if (strncmp(str.first, "Way", str.second) == 0) {
        e = nwr_way;
      } else if (strncmp(str.first, "Relation", str.second) == 0) {
        e = nwr_relation;
      } else {
        throw std::runtime_error((boost::format("Unrecognised value for nwr_enum: `%1%'.") % str.first).str());
      }
    }

    inline int hex2digit(char ch) const {
      switch (ch) {
      case '0':
      case '1':
      case '2':
      case '3':
      case '4':
      case '5':
      case '6':
      case '7':
      case '8':
      case '9':
        return int(ch - '0');

      case 'a':
      case 'b':
      case 'c':
      case 'd':
      case 'e':
      case 'f':
        return 10 + int(ch - 'a');

      case 'A':
      case 'B':
      case 'C':
      case 'D':
      case 'E':
      case 'F':
        return 10 + int(ch - 'A');

      default:
        throw std::runtime_error("Invalid hex digit.");
      }
    }

    inline int oct2digit(char ch) const {
      if ((ch >= '0') && (ch <= '7')) {
        return int(ch - '0');
      } else {
        throw std::runtime_error("Invalid octal digit.");
      }
    }

    void unescape(std::pair<char *, size_t> &s) const {
      const size_t end = s.second;
      char *str = s.first;
      size_t j = 0;

      for (size_t i = 0; i < end; ++i) {
        switch (str[i]) {
        case '\\':
          ++i;
          if (i < end) {
            switch (str[i]) {
            case 'b':
              str[j] = '\b';
              break;

            case 'f':
              str[j] = '\f';
              break;

            case 'n':
              str[j] = '\n';
              break;

            case 'r':
              str[j] = '\r';
              break;

            case 't':
              str[j] = '\t';
              break;

            case 'v':
              str[j] = '\v';
              break;

            case 'x':
              i += 2;
              if (i < end) {
              } else {
                str[j] = char(hex2digit(str[i-1]) * 16 + hex2digit(str[i]));
                throw std::runtime_error("Unterminated hex escape sequence.");
              }
              break;

            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
              i += 2;
              if (i < end) {
                str[j] = char(oct2digit(str[i-2]) * 64 + oct2digit(str[i-1]) * 8 + oct2digit(str[i]));
              } else {
                throw std::runtime_error("Unterminated octal escape sequence.");
              }
              break;

            default:
              // an unnecessary escape
              str[j] = str[i];
            }

          } else {
            throw std::runtime_error("Unterminated escape sequence.");
          }
          break;

        default:
          if (i != j) {
            str[j] = str[i];
          }
        }

        ++j;
      }

      str[j] = '\0';
      s.second = j;
    }

    mutable std::vector<std::pair<char *, size_t> >::iterator itr;
  };

  static std::vector<size_t> calculate_reorder(const std::vector<std::string> &names) {
    std::vector<size_t> indexes;
    const std::vector<std::string> &wanted_names = T::column_names();

    const size_t num_columns = wanted_names.size();
    indexes.reserve(num_columns);
    for (size_t i = 0; i < num_columns; ++i) {
      const std::string &wanted_name = wanted_names[i];
      size_t j = i;

      if (wanted_name != "*") {
        std::vector<std::string>::const_iterator itr = std::find(names.begin(), names.end(), wanted_name);
        if (itr == names.end()) {
          std::ostringstream ostr;
          ostr << "Unable to find wanted column name \"" << wanted_name << "\" in available names: ";
          for (std::vector<std::string>::const_iterator jtr = names.begin(); jtr != names.end(); ++jtr) {
            ostr << "\"" << *jtr << "\", ";
          }
          throw std::runtime_error(ostr.str());
        }
        j = std::distance(names.begin(), itr);
      }

      indexes.push_back(j);
    }

    return indexes;
  }

  S &m_source;
  std::vector<size_t> m_reorder;
};

#endif /* UNESCAPE_COPY_ROW_HPP */
<|endoftext|>


<commit_before>#undef DEBUG
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cmath>

//needed for select
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

//needed for poll
//#include <poll.h>

//for connection to server
#include "../sockets/SocketW.h"
bool ready4data = false;//set to true when streaming starts
bool inited = false;
bool stopparsing = false;
timeval lastrec;

#include "parsechunks.cpp" //chunkstream parsing
#include "handshake.cpp" //handshaking
#include "../util/flv_sock.cpp" //FLV parsing with SocketW

int main(){
  unsigned int ts;
  unsigned int fts = 0;
  unsigned int ftst;
  SWUnixSocket ss;

  fd_set pollset;
  struct timeval timeout;
  //0 timeout - return immediately after select call
  timeout.tv_sec = 1; timeout.tv_usec = 0;

  //pollfd cinfd[1];
  //cinfd[0].fd = fileno(stdin);
  //cinfd[0].events = POLLIN;

  //first timestamp set
  firsttime = getNowMS();

  #ifdef DEBUG
  fprintf(stderr, "Doing handshake...\n");
  #endif
  if (doHandshake()){
    #ifdef DEBUG
    fprintf(stderr, "Handshake succcess!\n");
    #endif
  }else{
    #ifdef DEBUG
    fprintf(stderr, "Handshake fail!\n");
    #endif
    return 0;
  }
  #ifdef DEBUG
  fprintf(stderr, "Starting processing...\n");
  #endif
  while (std::cin.good() && std::cout.good()){
    FD_ZERO(&pollset);//clear the polling set
    FD_SET(fileno(stdin), &pollset);//add stdin to polling set
    select(1, &pollset, 0, 0, &timeout);
    //only parse input from stdin if available or not yet init'ed
    if ((!ready4data || (snd_cnt - snd_window_at >= snd_window_size)) && FD_ISSET(0, &pollset)){parseChunk();fflush(stdout);}
    if (ready4data){
      if (!inited){
        //we are ready, connect the socket!
        if (!ss.connect(streamname.c_str())){
          #ifdef DEBUG
          fprintf(stderr, "Could not connect to server!\n");
          #endif
          return 0;
        }
        FLV_Readheader(ss);//read the header, we don't want it
        #ifdef DEBUG
        fprintf(stderr, "Header read, starting to send video data...\n");
        #endif
        inited = true;
      }
      //only send data if previous data has been ACK'ed...
      if (snd_cnt - snd_window_at < snd_window_size){
        if (FLV_GetPacket(ss)){//able to read a full packet?
          ts = FLVbuffer[7] * 256*256*256;
          ts += FLVbuffer[4] * 256*256;
          ts += FLVbuffer[5] * 256;
          ts += FLVbuffer[6];
          if (ts != 0){
            if (fts == 0){fts = ts;ftst = getNowMS();}
            ts -= fts;
            FLVbuffer[7] = ts / (256*256*256);
            FLVbuffer[4] = ts / (256*256);
            FLVbuffer[5] = ts / 256;
            FLVbuffer[6] = ts % 256;
            ts += ftst;
          }else{
            ftst = getNowMS();
            FLVbuffer[7] = ftst / (256*256*256);
            FLVbuffer[4] = ftst / (256*256);
            FLVbuffer[5] = ftst / 256;
            FLVbuffer[6] = ftst % 256;
          }
          SendMedia((unsigned char)FLVbuffer[0], (unsigned char *)FLVbuffer+11, FLV_len-15, ts);
          FLV_Dump();//dump packet and get ready for next
        }
        if ((SWBerr != SWBaseSocket::ok) && (SWBerr != SWBaseSocket::notReady)){
          #ifdef DEBUG
          fprintf(stderr, "No more data! :-(  (%s)\n", SWBerr.get_error().c_str());
          #endif
          return 0;//no more input possible! Fail immediately.
        }
      }
    }
    //send ACK if we received a whole window
    if (rec_cnt - rec_window_at > rec_window_size){
      rec_window_at = rec_cnt;
      SendCTL(3, rec_cnt);//send ack (msg 3)
    }
  }
  #ifdef DEBUG
  fprintf(stderr, "User disconnected.\n");
  #endif
  return 0;
}//main
<commit_msg>Select poging nummer 2<commit_after>#undef DEBUG
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cmath>

//needed for select
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

//needed for poll
//#include <poll.h>

//for connection to server
#include "../sockets/SocketW.h"
bool ready4data = false;//set to true when streaming starts
bool inited = false;
bool stopparsing = false;
timeval lastrec;

#include "parsechunks.cpp" //chunkstream parsing
#include "handshake.cpp" //handshaking
#include "../util/flv_sock.cpp" //FLV parsing with SocketW

int main(){
  unsigned int ts;
  unsigned int fts = 0;
  unsigned int ftst;
  SWUnixSocket ss;

  fd_set pollset;
  struct timeval timeout;

  //pollfd cinfd[1];
  //cinfd[0].fd = fileno(stdin);
  //cinfd[0].events = POLLIN;

  //first timestamp set
  firsttime = getNowMS();

  #ifdef DEBUG
  fprintf(stderr, "Doing handshake...\n");
  #endif
  if (doHandshake()){
    #ifdef DEBUG
    fprintf(stderr, "Handshake succcess!\n");
    #endif
  }else{
    #ifdef DEBUG
    fprintf(stderr, "Handshake fail!\n");
    #endif
    return 0;
  }
  #ifdef DEBUG
  fprintf(stderr, "Starting processing...\n");
  #endif
  while (std::cin.good() && std::cout.good()){
    FD_ZERO(&pollset);//clear the polling set
    FD_SET(fileno(stdin), &pollset);//add stdin to polling set
    timeout.tv_sec = 1; timeout.tv_usec = 0;
    select(1, &pollset, 0, 0, &timeout);
    //only parse input from stdin if available or not yet init'ed
    if ((!ready4data || (snd_cnt - snd_window_at >= snd_window_size)) && FD_ISSET(0, &pollset)){parseChunk();fflush(stdout);}
    if (ready4data){
      if (!inited){
        //we are ready, connect the socket!
        if (!ss.connect(streamname.c_str())){
          #ifdef DEBUG
          fprintf(stderr, "Could not connect to server!\n");
          #endif
          return 0;
        }
        FLV_Readheader(ss);//read the header, we don't want it
        #ifdef DEBUG
        fprintf(stderr, "Header read, starting to send video data...\n");
        #endif
        inited = true;
      }
      //only send data if previous data has been ACK'ed...
      if (snd_cnt - snd_window_at < snd_window_size){
        if (FLV_GetPacket(ss)){//able to read a full packet?
          ts = FLVbuffer[7] * 256*256*256;
          ts += FLVbuffer[4] * 256*256;
          ts += FLVbuffer[5] * 256;
          ts += FLVbuffer[6];
          if (ts != 0){
            if (fts == 0){fts = ts;ftst = getNowMS();}
            ts -= fts;
            FLVbuffer[7] = ts / (256*256*256);
            FLVbuffer[4] = ts / (256*256);
            FLVbuffer[5] = ts / 256;
            FLVbuffer[6] = ts % 256;
            ts += ftst;
          }else{
            ftst = getNowMS();
            FLVbuffer[7] = ftst / (256*256*256);
            FLVbuffer[4] = ftst / (256*256);
            FLVbuffer[5] = ftst / 256;
            FLVbuffer[6] = ftst % 256;
          }
          SendMedia((unsigned char)FLVbuffer[0], (unsigned char *)FLVbuffer+11, FLV_len-15, ts);
          FLV_Dump();//dump packet and get ready for next
        }
        if ((SWBerr != SWBaseSocket::ok) && (SWBerr != SWBaseSocket::notReady)){
          #ifdef DEBUG
          fprintf(stderr, "No more data! :-(  (%s)\n", SWBerr.get_error().c_str());
          #endif
          return 0;//no more input possible! Fail immediately.
        }
      }
    }
    //send ACK if we received a whole window
    if (rec_cnt - rec_window_at > rec_window_size){
      rec_window_at = rec_cnt;
      SendCTL(3, rec_cnt);//send ack (msg 3)
    }
  }
  #ifdef DEBUG
  fprintf(stderr, "User disconnected.\n");
  #endif
  return 0;
}//main
<|endoftext|>


<commit_before>/*
 * Software License Agreement (BSD License)
 *
 *  Point Cloud Library (PCL) - www.pointclouds.org
 *  Copyright (c) 2010-2011, Willow Garage, Inc.
 *
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 * $Id$
 *
 */

#ifndef PCL_IO_PCD_IO_IMPL_H_
#define PCL_IO_PCD_IO_IMPL_H_

#include <fstream>
#include <fcntl.h>
#include <string>
#include <stdlib.h>

#ifdef _WIN32
# include <io.h>
# include <windows.h>
# define pcl_open                    _open
# define pcl_close(fd)               _close(fd)
# define pcl_lseek(fd,offset,origin) _lseek(fd,offset,origin)
#else
# include <sys/mman.h>
# define pcl_open                    open
# define pcl_close(fd)               close(fd)
# define pcl_lseek(fd,offset,origin) lseek(fd,offset,origin)
#endif

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> std::string
pcl::PCDWriter::generateHeaderBinary (const pcl::PointCloud<PointT> &cloud, const int nr_points)
{
  std::ostringstream oss;

  oss << "# .PCD v0.7 - Point Cloud Data file format"
         "\nVERSION 0.7"
         "\nFIELDS";

  std::vector<sensor_msgs::PointField> fields;
  pcl::getFields (cloud, fields);

  std::stringstream field_names, field_types, field_sizes, field_counts;
  for (size_t i = 0; i < fields.size (); ++i)
  {
    if (fields[i].name == "_")
      continue;
    // Add the regular dimension
    field_names << " " << fields[i].name;
    field_sizes << " " << pcl::getFieldSize (fields[i].datatype);
    field_types << " " << pcl::getFieldType (fields[i].datatype);
    int count = abs ((int)fields[i].count);
    if (count == 0) count = 1;  // check for 0 counts (coming from older converter code)
    field_counts << " " << count;
  }
  oss << field_names.str ();
  oss << "\nSIZE" << field_sizes.str ()
      << "\nTYPE" << field_types.str ()
      << "\nCOUNT" << field_counts.str ();
  // If the user passes in a number of points value, use that instead
  if (nr_points != std::numeric_limits<int>::max ())
    oss << "\nWIDTH " << nr_points << "\nHEIGHT " << 1 << "\n";
  else
    oss << "\nWIDTH " << cloud.width << "\nHEIGHT " << cloud.height << "\n";

  oss << "VIEWPOINT " << cloud.sensor_origin_[0] << " " << cloud.sensor_origin_[1] << " " << cloud.sensor_origin_[2] << " " <<
                         cloud.sensor_orientation_.w () << " " <<
                         cloud.sensor_orientation_.x () << " " <<
                         cloud.sensor_orientation_.y () << " " <<
                         cloud.sensor_orientation_.z () << "\n";

  // If the user passes in a number of points value, use that instead
  if (nr_points != std::numeric_limits<int>::max ())
    oss << "POINTS " << nr_points << "\n";
  else
    oss << "POINTS " << cloud.points.size () << "\n";

  return (oss.str ());
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> int
pcl::PCDWriter::writeBinary (const std::string &file_name,
                             const pcl::PointCloud<PointT> &cloud)
{
  if (cloud.points.empty ())
  {
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Input point cloud has no data!");
    return (-1);
  }
  int data_idx = 0;
  std::ostringstream oss;
  oss << generateHeaderBinary<PointT> (cloud) << "DATA binary\n";
  oss.flush ();
  data_idx = oss.tellp ();

#if _WIN32
  HANDLE h_native_file = CreateFile (file_name.c_str (), GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  if(h_native_file == INVALID_HANDLE_VALUE)
  {
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during CreateFile!");
    return (-1);
  }
#else
  int fd = pcl_open (file_name.c_str (), O_RDWR | O_CREAT | O_TRUNC, (mode_t)0600);
  if (fd < 0)
  {
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during open!");
    return (-1);
  }

  std::vector<sensor_msgs::PointField> fields;
  std::vector<int> fields_sizes;
  size_t fsize = 0;
  size_t data_size = 0;
  size_t nri = 0;
  pcl::getFields (cloud, fields);
  // Compute the total size of the fields
  for (size_t i = 0; i < fields.size (); ++i)
  {
    if (fields[i].name == "_")
      continue;

    int fs = fields[i].count * getFieldSize (fields[i].datatype);
    fsize += fs;
    fields_sizes.push_back (fs);
    fields[nri++] = fields[i];
  }
  fields.resize (nri);

  data_size = cloud.points.size () * fsize;

  // Stretch the file size to the size of the data
  int result = pcl_lseek (fd, getpagesize () + data_size - 1, SEEK_SET);
  if (result < 0)
  {
    pcl_close (fd);
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during lseek ()!");
    return (-1);
  }
  // Write a bogus entry so that the new file size comes in effect
  result = ::write (fd, "", 1);
  if (result != 1)
  {
    pcl_close (fd);
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during write ()!");
    return (-1);
  }
#endif
  // Prepare the map
#if _WIN32
  HANDLE fm = CreateFileMapping (h_native_file, NULL, PAGE_READWRITE, 0, data_idx + cloud.data.size (), NULL);
  char *map = static_cast<char*>(MapViewOfFile (fm, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, data_idx + cloud.data.size ()));
  CloseHandle (fm);

#else
  char *map = (char*)mmap (0, data_idx + data_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
  if (map == MAP_FAILED)
  {
    pcl_close (fd);
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during mmap ()!");
    return (-1);
  }
#endif

  // Copy the header
  memcpy (&map[0], oss.str ().c_str (), data_idx);

  // Copy the data
  char *out = &map[0] + data_idx;
  for (size_t i = 0; i < cloud.points.size (); ++i)
  {
    int nrj = 0;
    for (size_t j = 0; j < fields.size (); ++j)
    {
      memcpy (out, (const char*)&cloud.points[i] + fields[j].offset, fields_sizes[nrj]);
      out += fields_sizes[nrj++];
    }
  }

  // Unmap the pages of memory
#if _WIN32
    UnmapViewOfFile (map);
#else
  if (munmap (map, (data_idx + data_size)) == -1)
  {
    pcl_close (fd);
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during munmap ()!");
    return (-1);
  }
#endif
  // Close file
#if _WIN32
  CloseHandle(h_native_file);
#else
  pcl_close (fd);
#endif
  return (0);
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> int
pcl::PCDWriter::writeBinary (const std::string &file_name,
                             const pcl::PointCloud<PointT> &cloud,
                             const std::vector<int> &indices)
{
  if (cloud.points.empty () || indices.empty ())
  {
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Input point cloud has no data or empty indices given!");
    return (-1);
  }
  int data_idx = 0;
  std::ostringstream oss;
  oss << generateHeaderBinary<PointT> (cloud, indices.size ()) << "DATA binary\n";
  oss.flush ();
  data_idx = oss.tellp ();

#if _WIN32
  HANDLE h_native_file = CreateFile (file_name.c_str (), GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  if(h_native_file == INVALID_HANDLE_VALUE)
  {
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during CreateFile!");
    return (-1);
  }
#else
  int fd = pcl_open (file_name.c_str (), O_RDWR | O_CREAT | O_TRUNC, (mode_t)0600);
  if (fd < 0)
  {
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during open!");
    return (-1);
  }

  std::vector<sensor_msgs::PointField> fields;
  std::vector<int> fields_sizes;
  size_t fsize = 0;
  size_t data_size = 0;
  size_t nri = 0;
  pcl::getFields (cloud, fields);
  // Compute the total size of the fields
  for (size_t i = 0; i < fields.size (); ++i)
  {
    if (fields[i].name == "_")
      continue;

    int fs = fields[i].count * getFieldSize (fields[i].datatype);
    fsize += fs;
    fields_sizes.push_back (fs);
    fields[nri++] = fields[i];
  }
  fields.resize (nri);

  data_size = indices.size () * fsize;

  // Stretch the file size to the size of the data
  int result = pcl_lseek (fd, getpagesize () + data_size - 1, SEEK_SET);
  if (result < 0)
  {
    pcl_close (fd);
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during lseek ()!");
    return (-1);
  }
  // Write a bogus entry so that the new file size comes in effect
  result = ::write (fd, "", 1);
  if (result != 1)
  {
    pcl_close (fd);
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during write ()!");
    return (-1);
  }
#endif
  // Prepare the map
#if _WIN32
  HANDLE fm = CreateFileMapping (h_native_file, NULL, PAGE_READWRITE, 0, data_idx + cloud.data.size (), NULL);
  char *map = static_cast<char*>(MapViewOfFile (fm, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, data_idx + cloud.data.size ()));
  CloseHandle (fm);

#else
  char *map = (char*)mmap (0, data_idx + data_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
  if (map == MAP_FAILED)
  {
    pcl_close (fd);
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during mmap ()!");
    return (-1);
  }
#endif

  // Copy the header
  memcpy (&map[0], oss.str ().c_str (), data_idx);

  char *out = &map[0] + data_idx;
  // Copy the data
  for (size_t i = 0; i < indices.size (); ++i)
  {
    int nrj = 0;
    for (size_t j = 0; j < fields.size (); ++j)
    {
      memcpy (out, (const char*)&cloud.points[indices[i]] + fields[j].offset, fields_sizes[nrj]);
      out += fields_sizes[nrj++];
    }
  }

  // Unmap the pages of memory
#if _WIN32
    UnmapViewOfFile (map);
#else
  if (munmap (map, (data_idx + data_size)) == -1)
  {
    pcl_close (fd);
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during munmap ()!");
    return (-1);
  }
#endif
  // Close file
#if _WIN32
  CloseHandle(h_native_file);
#else
  pcl_close (fd);
#endif
  return (0);
}

#endif  //#ifndef PCL_IO_PCD_IO_H_

<commit_msg>fiw the windows path in pcd_io.hpp<commit_after>/*
 * Software License Agreement (BSD License)
 *
 *  Point Cloud Library (PCL) - www.pointclouds.org
 *  Copyright (c) 2010-2011, Willow Garage, Inc.
 *
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 * $Id$
 *
 */

#ifndef PCL_IO_PCD_IO_IMPL_H_
#define PCL_IO_PCD_IO_IMPL_H_

#include <fstream>
#include <fcntl.h>
#include <string>
#include <stdlib.h>

#ifdef _WIN32
# include <io.h>
# include <windows.h>
# define pcl_open                    _open
# define pcl_close(fd)               _close(fd)
# define pcl_lseek(fd,offset,origin) _lseek(fd,offset,origin)
#else
# include <sys/mman.h>
# define pcl_open                    open
# define pcl_close(fd)               close(fd)
# define pcl_lseek(fd,offset,origin) lseek(fd,offset,origin)
#endif

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> std::string
pcl::PCDWriter::generateHeaderBinary (const pcl::PointCloud<PointT> &cloud, const int nr_points)
{
  std::ostringstream oss;

  oss << "# .PCD v0.7 - Point Cloud Data file format"
         "\nVERSION 0.7"
         "\nFIELDS";

  std::vector<sensor_msgs::PointField> fields;
  pcl::getFields (cloud, fields);

  std::stringstream field_names, field_types, field_sizes, field_counts;
  for (size_t i = 0; i < fields.size (); ++i)
  {
    if (fields[i].name == "_")
      continue;
    // Add the regular dimension
    field_names << " " << fields[i].name;
    field_sizes << " " << pcl::getFieldSize (fields[i].datatype);
    field_types << " " << pcl::getFieldType (fields[i].datatype);
    int count = abs ((int)fields[i].count);
    if (count == 0) count = 1;  // check for 0 counts (coming from older converter code)
    field_counts << " " << count;
  }
  oss << field_names.str ();
  oss << "\nSIZE" << field_sizes.str ()
      << "\nTYPE" << field_types.str ()
      << "\nCOUNT" << field_counts.str ();
  // If the user passes in a number of points value, use that instead
  if (nr_points != std::numeric_limits<int>::max ())
    oss << "\nWIDTH " << nr_points << "\nHEIGHT " << 1 << "\n";
  else
    oss << "\nWIDTH " << cloud.width << "\nHEIGHT " << cloud.height << "\n";

  oss << "VIEWPOINT " << cloud.sensor_origin_[0] << " " << cloud.sensor_origin_[1] << " " << cloud.sensor_origin_[2] << " " <<
                         cloud.sensor_orientation_.w () << " " <<
                         cloud.sensor_orientation_.x () << " " <<
                         cloud.sensor_orientation_.y () << " " <<
                         cloud.sensor_orientation_.z () << "\n";

  // If the user passes in a number of points value, use that instead
  if (nr_points != std::numeric_limits<int>::max ())
    oss << "POINTS " << nr_points << "\n";
  else
    oss << "POINTS " << cloud.points.size () << "\n";

  return (oss.str ());
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> int
pcl::PCDWriter::writeBinary (const std::string &file_name,
                             const pcl::PointCloud<PointT> &cloud)
{
  if (cloud.points.empty ())
  {
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Input point cloud has no data!");
    return (-1);
  }
  int data_idx = 0;
  std::ostringstream oss;
  oss << generateHeaderBinary<PointT> (cloud) << "DATA binary\n";
  oss.flush ();
  data_idx = oss.tellp ();

#if _WIN32
  HANDLE h_native_file = CreateFile (file_name.c_str (), GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  if(h_native_file == INVALID_HANDLE_VALUE)
  {
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during CreateFile!");
    return (-1);
  }
#else
  int fd = pcl_open (file_name.c_str (), O_RDWR | O_CREAT | O_TRUNC, (mode_t)0600);
  if (fd < 0)
  {
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during open!");
    return (-1);
  }
#endif

  std::vector<sensor_msgs::PointField> fields;
  std::vector<int> fields_sizes;
  size_t fsize = 0;
  size_t data_size = 0;
  size_t nri = 0;
  pcl::getFields (cloud, fields);
  // Compute the total size of the fields
  for (size_t i = 0; i < fields.size (); ++i)
  {
    if (fields[i].name == "_")
      continue;

    int fs = fields[i].count * getFieldSize (fields[i].datatype);
    fsize += fs;
    fields_sizes.push_back (fs);
    fields[nri++] = fields[i];
  }
  fields.resize (nri);

  data_size = cloud.points.size () * fsize;

  // Prepare the map
#if _WIN32
  HANDLE fm = CreateFileMapping (h_native_file, NULL, PAGE_READWRITE, 0, data_idx + data_size, NULL);
  char *map = static_cast<char*>(MapViewOfFile (fm, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, data_idx + data_size));
  CloseHandle (fm);

#else
  // Stretch the file size to the size of the data
  int result = pcl_lseek (fd, getpagesize () + data_size - 1, SEEK_SET);
  if (result < 0)
  {
    pcl_close (fd);
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during lseek ()!");
    return (-1);
  }
  // Write a bogus entry so that the new file size comes in effect
  result = ::write (fd, "", 1);
  if (result != 1)
  {
    pcl_close (fd);
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during write ()!");
    return (-1);
  }

  char *map = (char*)mmap (0, data_idx + data_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
  if (map == MAP_FAILED)
  {
    pcl_close (fd);
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during mmap ()!");
    return (-1);
  }
#endif

  // Copy the header
  memcpy (&map[0], oss.str ().c_str (), data_idx);

  // Copy the data
  char *out = &map[0] + data_idx;
  for (size_t i = 0; i < cloud.points.size (); ++i)
  {
    int nrj = 0;
    for (size_t j = 0; j < fields.size (); ++j)
    {
      memcpy (out, (const char*)&cloud.points[i] + fields[j].offset, fields_sizes[nrj]);
      out += fields_sizes[nrj++];
    }
  }

  // Unmap the pages of memory
#if _WIN32
    UnmapViewOfFile (map);
#else
  if (munmap (map, (data_idx + data_size)) == -1)
  {
    pcl_close (fd);
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during munmap ()!");
    return (-1);
  }
#endif
  // Close file
#if _WIN32
  CloseHandle(h_native_file);
#else
  pcl_close (fd);
#endif
  return (0);
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> int
pcl::PCDWriter::writeBinary (const std::string &file_name,
                             const pcl::PointCloud<PointT> &cloud,
                             const std::vector<int> &indices)
{
  if (cloud.points.empty () || indices.empty ())
  {
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Input point cloud has no data or empty indices given!");
    return (-1);
  }
  int data_idx = 0;
  std::ostringstream oss;
  oss << generateHeaderBinary<PointT> (cloud, indices.size ()) << "DATA binary\n";
  oss.flush ();
  data_idx = oss.tellp ();

#if _WIN32
  HANDLE h_native_file = CreateFile (file_name.c_str (), GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  if(h_native_file == INVALID_HANDLE_VALUE)
  {
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during CreateFile!");
    return (-1);
  }
#else
  int fd = pcl_open (file_name.c_str (), O_RDWR | O_CREAT | O_TRUNC, (mode_t)0600);
  if (fd < 0)
  {
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during open!");
    return (-1);
  }
#endif

  std::vector<sensor_msgs::PointField> fields;
  std::vector<int> fields_sizes;
  size_t fsize = 0;
  size_t data_size = 0;
  size_t nri = 0;
  pcl::getFields (cloud, fields);
  // Compute the total size of the fields
  for (size_t i = 0; i < fields.size (); ++i)
  {
    if (fields[i].name == "_")
      continue;

    int fs = fields[i].count * getFieldSize (fields[i].datatype);
    fsize += fs;
    fields_sizes.push_back (fs);
    fields[nri++] = fields[i];
  }
  fields.resize (nri);

  data_size = indices.size () * fsize;

  // Prepare the map
#if _WIN32
  HANDLE fm = CreateFileMapping (h_native_file, NULL, PAGE_READWRITE, 0, data_idx + data_size, NULL);
  char *map = static_cast<char*>(MapViewOfFile (fm, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, data_idx + data_size));
  CloseHandle (fm);

#else
  // Stretch the file size to the size of the data
  int result = pcl_lseek (fd, getpagesize () + data_size - 1, SEEK_SET);
  if (result < 0)
  {
    pcl_close (fd);
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during lseek ()!");
    return (-1);
  }
  // Write a bogus entry so that the new file size comes in effect
  result = ::write (fd, "", 1);
  if (result != 1)
  {
    pcl_close (fd);
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during write ()!");
    return (-1);
  }

  char *map = (char*)mmap (0, data_idx + data_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
  if (map == MAP_FAILED)
  {
    pcl_close (fd);
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during mmap ()!");
    return (-1);
  }
#endif

  // Copy the header
  memcpy (&map[0], oss.str ().c_str (), data_idx);

  char *out = &map[0] + data_idx;
  // Copy the data
  for (size_t i = 0; i < indices.size (); ++i)
  {
    int nrj = 0;
    for (size_t j = 0; j < fields.size (); ++j)
    {
      memcpy (out, (const char*)&cloud.points[indices[i]] + fields[j].offset, fields_sizes[nrj]);
      out += fields_sizes[nrj++];
    }
  }

  // Unmap the pages of memory
#if _WIN32
    UnmapViewOfFile (map);
#else
  if (munmap (map, (data_idx + data_size)) == -1)
  {
    pcl_close (fd);
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during munmap ()!");
    return (-1);
  }
#endif
  // Close file
#if _WIN32
  CloseHandle(h_native_file);
#else
  pcl_close (fd);
#endif
  return (0);
}

#endif  //#ifndef PCL_IO_PCD_IO_H_

<|endoftext|>


<commit_before>#pragma once

#include "vfs/platform.hpp"
#include "vfs/file.h"

namespace vfs {

    //----------------------------------------------------------------------------------------------
    using file_view_impl = class win_file_view;
    //----------------------------------------------------------------------------------------------

    //----------------------------------------------------------------------------------------------
    class win_file_view
    {
	protected:
		//------------------------------------------------------------------------------------------
        win_file_view(file_sptr spFile, int64_t viewSize)
            : spFile_(std::move(spFile))
            , name_(spFile_->fileName())
            , fileMappingHandle_(nullptr)
            , pData_(nullptr)
            , pCursor_(nullptr)
            , mappedTotalSize_(viewSize)
        {
			vfs_check(spFile_->isValid());
            map(viewSize, false);
        }

        //------------------------------------------------------------------------------------------
        win_file_view(const path &name, int64_t size, bool openExistent)
            : name_(name)
            , fileMappingHandle_(nullptr)
            , pData_(nullptr)
            , pCursor_(nullptr)
            , mappedTotalSize_(size)
        {
            map(size, openExistent);
        }

		//------------------------------------------------------------------------------------------
        ~win_file_view()
        {
            flush();
            unmap();

            if (fileMappingHandle_ != nullptr)
            {
                CloseHandle(fileMappingHandle_);
            }
        }

		//------------------------------------------------------------------------------------------
        bool map(int64_t viewSize, bool openExistent)
        {
            const auto access = spFile_ ? spFile_->fileAccess() : file_access::read_write;

            if (spFile_)
            {
                if (!spFile_->createMapping(viewSize))
                {
                    return false;
                }

                fileMappingHandle_  = spFile_->nativeFileMappingHandle();
                fileTotalSize_      = spFile_->size();
            }
            else
            {
                if (openExistent)
                {
                    fileMappingHandle_ = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, name_.c_str());
                }
                else
                {
                    fileMappingHandle_ = CreateFileMapping
                    (
                        INVALID_HANDLE_VALUE,
                        nullptr,
                        PAGE_READWRITE,
                        DWORD(viewSize >> 32), DWORD((viewSize << 32) >> 32),
                        name_.c_str()
                    );
                }

                if (fileMappingHandle_ == nullptr)
                {
                    const auto errorCode = GetLastError();
                    vfs_errorf("%sFileMapping(%ws) failed with error: %s", openExistent ? "Open" : "Create", name_.c_str(), get_last_error_as_string(errorCode).c_str());
                    return false;
                }

                fileTotalSize_ = viewSize;
            }

            const auto fileMapAccess = (
                (access == file_access::read_only)
                ? FILE_MAP_READ
                : ((access == file_access::write_only)
                    ? FILE_MAP_WRITE
                    : FILE_MAP_ALL_ACCESS
                )
            );

            pData_ = reinterpret_cast<uint8_t*>(MapViewOfFile(fileMappingHandle_, fileMapAccess, 0, 0, 0));
            pCursor_ = pData_;

            if (pData_ == nullptr)
            {
                const auto errorCode = GetLastError();
                vfs_errorf("MapViewOfFile(%ws) failed with error: %s", name_.c_str(), get_last_error_as_string(errorCode).c_str());
                return false;
            }

            MEMORY_BASIC_INFORMATION memInfo;
            const auto dwInfoBytesCount = VirtualQuery(pData_, &memInfo, sizeof(memInfo));
            if (dwInfoBytesCount != 0)
            {
                mappedTotalSize_ = memInfo.RegionSize;
            }

            return true;
        }

		//------------------------------------------------------------------------------------------
        bool unmap()
        {
            if (pData_ && !UnmapViewOfFile(pData_))
            {
                return false;
            }
            return true;
        }

		//------------------------------------------------------------------------------------------
        bool flush()
        {
            if (!FlushViewOfFile(pData_, 0))
            {
                return false;
            }
            return true;
        }

		//------------------------------------------------------------------------------------------
        int64_t read(uint8_t *dst, int64_t sizeInBytes)
        {
            if (canMoveCursor(sizeInBytes))
            {
                memcpy(dst, pCursor_, sizeInBytes);
                pCursor_ += sizeInBytes;
                return sizeInBytes;
            }
            return 0;
        }

		//------------------------------------------------------------------------------------------
        int64_t write(const uint8_t *src, int64_t sizeInBytes)
        {
            if (canMoveCursor(sizeInBytes))
            {
                memcpy(pCursor_, src, sizeInBytes);
                pCursor_ += sizeInBytes;
                return sizeInBytes;
            }
            return 0;
        }

		//------------------------------------------------------------------------------------------
        bool isValid() const
        {
            return pData_ != nullptr;
        }

		//------------------------------------------------------------------------------------------
        int64_t totalSize() const
        {
            return fileTotalSize_;
        }

		//------------------------------------------------------------------------------------------
        bool canMoveCursor(int64_t offsetInBytes) const
        {
            return isValid() && (pCursor_ - pData_ + offsetInBytes) <= mappedTotalSize_;
        }

		//------------------------------------------------------------------------------------------
        template<typename T = uint8_t>
        T* data()
        {
            return reinterpret_cast<T*>(pData_);
        }

		//------------------------------------------------------------------------------------------
        uint8_t* data()
        {
            return data<>();
        }

		//------------------------------------------------------------------------------------------
        template<typename T = uint8_t>
        T* cursor()
        {
            return reinterpret_cast<T*>(pCursor_);
        }

		//------------------------------------------------------------------------------------------
        bool skip(int64_t offsetInBytes)
        {
            if (canMoveCursor(offsetInBytes))
            {
                pCursor_ += offsetInBytes;
                return true;
            }
            return false;
        }

	private:
		//------------------------------------------------------------------------------------------
        file_sptr   spFile_;
        path        name_;
        HANDLE      fileMappingHandle_;
        uint8_t     *pData_;
        uint8_t     *pCursor_;
        int64_t     fileTotalSize_;
        int64_t     mappedTotalSize_;
    };
    //----------------------------------------------------------------------------------------------

} /*vfs*/
<commit_msg>Removed deleted included file<commit_after>#pragma once

#include "vfs/platform.hpp"

namespace vfs {

    //----------------------------------------------------------------------------------------------
    using file_view_impl = class win_file_view;
    //----------------------------------------------------------------------------------------------

    //----------------------------------------------------------------------------------------------
    class win_file_view
    {
	protected:
		//------------------------------------------------------------------------------------------
        win_file_view(file_sptr spFile, int64_t viewSize)
            : spFile_(std::move(spFile))
            , name_(spFile_->fileName())
            , fileMappingHandle_(nullptr)
            , pData_(nullptr)
            , pCursor_(nullptr)
            , mappedTotalSize_(viewSize)
        {
			vfs_check(spFile_->isValid());
            map(viewSize, false);
        }

        //------------------------------------------------------------------------------------------
        win_file_view(const path &name, int64_t size, bool openExistent)
            : name_(name)
            , fileMappingHandle_(nullptr)
            , pData_(nullptr)
            , pCursor_(nullptr)
            , mappedTotalSize_(size)
        {
            map(size, openExistent);
        }

		//------------------------------------------------------------------------------------------
        ~win_file_view()
        {
            flush();
            unmap();

            if (fileMappingHandle_ != nullptr)
            {
                CloseHandle(fileMappingHandle_);
            }
        }

		//------------------------------------------------------------------------------------------
        bool map(int64_t viewSize, bool openExistent)
        {
            const auto access = spFile_ ? spFile_->fileAccess() : file_access::read_write;

            if (spFile_)
            {
                if (!spFile_->createMapping(viewSize))
                {
                    return false;
                }

                fileMappingHandle_  = spFile_->nativeFileMappingHandle();
                fileTotalSize_      = spFile_->size();
            }
            else
            {
                if (openExistent)
                {
                    fileMappingHandle_ = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, name_.c_str());
                }
                else
                {
                    fileMappingHandle_ = CreateFileMapping
                    (
                        INVALID_HANDLE_VALUE,
                        nullptr,
                        PAGE_READWRITE,
                        DWORD(viewSize >> 32), DWORD((viewSize << 32) >> 32),
                        name_.c_str()
                    );
                }

                if (fileMappingHandle_ == nullptr)
                {
                    const auto errorCode = GetLastError();
                    vfs_errorf("%sFileMapping(%ws) failed with error: %s", openExistent ? "Open" : "Create", name_.c_str(), get_last_error_as_string(errorCode).c_str());
                    return false;
                }

                fileTotalSize_ = viewSize;
            }

            const auto fileMapAccess = (
                (access == file_access::read_only)
                ? FILE_MAP_READ
                : ((access == file_access::write_only)
                    ? FILE_MAP_WRITE
                    : FILE_MAP_ALL_ACCESS
                )
            );

            pData_ = reinterpret_cast<uint8_t*>(MapViewOfFile(fileMappingHandle_, fileMapAccess, 0, 0, 0));
            pCursor_ = pData_;

            if (pData_ == nullptr)
            {
                const auto errorCode = GetLastError();
                vfs_errorf("MapViewOfFile(%ws) failed with error: %s", name_.c_str(), get_last_error_as_string(errorCode).c_str());
                return false;
            }

            MEMORY_BASIC_INFORMATION memInfo;
            const auto dwInfoBytesCount = VirtualQuery(pData_, &memInfo, sizeof(memInfo));
            if (dwInfoBytesCount != 0)
            {
                mappedTotalSize_ = memInfo.RegionSize;
            }

            return true;
        }

		//------------------------------------------------------------------------------------------
        bool unmap()
        {
            if (pData_ && !UnmapViewOfFile(pData_))
            {
                return false;
            }
            return true;
        }

		//------------------------------------------------------------------------------------------
        bool flush()
        {
            if (!FlushViewOfFile(pData_, 0))
            {
                return false;
            }
            return true;
        }

		//------------------------------------------------------------------------------------------
        int64_t read(uint8_t *dst, int64_t sizeInBytes)
        {
            if (canMoveCursor(sizeInBytes))
            {
                memcpy(dst, pCursor_, sizeInBytes);
                pCursor_ += sizeInBytes;
                return sizeInBytes;
            }
            return 0;
        }

		//------------------------------------------------------------------------------------------
        int64_t write(const uint8_t *src, int64_t sizeInBytes)
        {
            if (canMoveCursor(sizeInBytes))
            {
                memcpy(pCursor_, src, sizeInBytes);
                pCursor_ += sizeInBytes;
                return sizeInBytes;
            }
            return 0;
        }

		//------------------------------------------------------------------------------------------
        bool isValid() const
        {
            return pData_ != nullptr;
        }

		//------------------------------------------------------------------------------------------
        int64_t totalSize() const
        {
            return fileTotalSize_;
        }

		//------------------------------------------------------------------------------------------
        bool canMoveCursor(int64_t offsetInBytes) const
        {
            return isValid() && (pCursor_ - pData_ + offsetInBytes) <= mappedTotalSize_;
        }

		//------------------------------------------------------------------------------------------
        template<typename T = uint8_t>
        T* data()
        {
            return reinterpret_cast<T*>(pData_);
        }

		//------------------------------------------------------------------------------------------
        uint8_t* data()
        {
            return data<>();
        }

		//------------------------------------------------------------------------------------------
        template<typename T = uint8_t>
        T* cursor()
        {
            return reinterpret_cast<T*>(pCursor_);
        }

		//------------------------------------------------------------------------------------------
        bool skip(int64_t offsetInBytes)
        {
            if (canMoveCursor(offsetInBytes))
            {
                pCursor_ += offsetInBytes;
                return true;
            }
            return false;
        }

	private:
		//------------------------------------------------------------------------------------------
        file_sptr   spFile_;
        path        name_;
        HANDLE      fileMappingHandle_;
        uint8_t     *pData_;
        uint8_t     *pCursor_;
        int64_t     fileTotalSize_;
        int64_t     mappedTotalSize_;
    };
    //----------------------------------------------------------------------------------------------

} /*vfs*/
<|endoftext|>


<commit_before>#pragma once
//=====================================================================//
/*!	@file
	@brief	RX64M グループ・ポート・マッピング @n
			・ペリフェラル型に従って、ポートの設定をグループ化
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2016, 2017 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include "RX600/port.hpp"
#include "RX64M/mpc.hpp"
#include "RX64M/peripheral.hpp"

namespace device {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  ポート・マッピング・ユーティリティー
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	class port_map {

		static void sub_(peripheral t, bool enable) {
			switch(t) {
			// ※シリアルポートの MPC 設定では、PDR を制御する必要は無いが、
			// 出力ポートのインピーダンス制御の一環として入れてある。
			case peripheral::SCI0:
				{
					uint8_t sel = enable ? 0b001010 : 0;
					PORT2::PDR.B0 = enable; // TXD0
					PORT2::PDR.B1 = 0;  	// RXD0
					MPC::P20PFS.PSEL = sel;
					MPC::P21PFS.PSEL = sel;
					PORT2::PMR.B0 = enable;
					PORT2::PMR.B1 = enable;
				}
				break;
			case peripheral::SCI1:
				{
					uint8_t sel = enable ? 0b001010 : 0;
					PORTF::PDR.B0 = enable; // TXD1
					PORTF::PDR.B2 = 0;  	// RXD1
					MPC::PF0PFS.PSEL = sel;
					MPC::PF2PFS.PSEL = sel;
					PORTF::PMR.B0 = enable;
					PORTF::PMR.B2 = enable;
				}
				break;
			case peripheral::SCI2:
				{
					uint8_t sel = enable ? 0b001010 : 0;
					PORT1::PDR.B3 = enable; // TXD2
					PORT1::PDR.B2 = 0;  	// RXD2
					MPC::P13PFS.PSEL = sel;
					MPC::P12PFS.PSEL = sel;
					PORT1::PMR.B3 = enable;
					PORT1::PMR.B2 = enable;
				}
				break;
			case peripheral::SCI3:
				{
					uint8_t sel = enable ? 0b001010 : 0;
					PORT2::PDR.B3 = enable; // TXD3
					PORT2::PDR.B5 = 0;  	// RXD3
					MPC::P23PFS.PSEL = sel;
					MPC::P25PFS.PSEL = sel;
					PORT2::PMR.B3 = enable;
					PORT2::PMR.B5 = enable;
				}
				break;
			case peripheral::SCI4:
				{
					uint8_t sel = enable ? 0b001010 : 0;
					PORTB::PDR.B1 = enable; // TXD4
					PORTB::PDR.B0 = 0;  	// RXD4
					MPC::PB1PFS.PSEL = sel;
					MPC::PB0PFS.PSEL = sel;
					PORTB::PMR.B1 = enable;
					PORTB::PMR.B0 = enable;
				}
				break;
			case peripheral::SCI5:
				{
					uint8_t sel = enable ? 0b001010 : 0;
					PORTA::PDR.B4 = enable; // TXD5
					PORTA::PDR.B3 = 0;  	// RXD5
					MPC::PA4PFS.PSEL = sel;
					MPC::PA3PFS.PSEL = sel;
					PORTA::PMR.B4 = enable;
					PORTA::PMR.B3 = enable;
				}
				break;
			case peripheral::SCI6:
				{
					uint8_t sel = enable ? 0b001010 : 0;
					PORT0::PDR.B0 = enable; // TXD6
					PORT0::PDR.B1 = 0;  	// RXD6
					MPC::P00PFS.PSEL = sel;
					MPC::P01PFS.PSEL = sel;
					PORT0::PMR.B0 = enable;
					PORT0::PMR.B1 = enable;
				}
				break;
			case peripheral::SCI7:
				{
					uint8_t sel = enable ? 0b001010 : 0;
					PORT9::PDR.B0 = enable; // TXD7
					PORT9::PDR.B2 = 0;  	// RXD7
					MPC::P90PFS.PSEL = sel;
					MPC::P92PFS.PSEL = sel;
					PORT9::PMR.B0 = enable;
					PORT9::PMR.B2 = enable;
				}
				break;

			case peripheral::SCI12:
				{
					uint8_t sel = enable ? 0b001100 : 0;
					PORTE::PDR.B2 = enable; // TXD12
					PORTE::PDR.B1 = 0;  	// RXD12
					MPC::PE2PFS.PSEL = sel;
					MPC::PE1PFS.PSEL = sel;
					PORTE::PMR.B2 = enable;
					PORTE::PMR.B1 = enable;
				}
				break;

			case peripheral::RSPI:
				{
					uint8_t sel = enable ? 0b001101 : 0;
//					PORTC::PCR.B7 = 1;		// pull-up
//					PORTC::PDR.B7 = 0;		// MISOA
//					PORTC::PDR.B6 = 1;		// MOSIA
//					PORTC::PDR.B5 = 1;		// RSPCKA
					MPC::PC7PFS.PSEL = sel;  // MISOA
					MPC::PC6PFS.PSEL = sel;  // MOSIA
					MPC::PC5PFS.PSEL = sel;  // RSPCKA
					PORTC::PMR.B7 = enable;
					PORTC::PMR.B6 = enable;
					PORTC::PMR.B5 = enable;
				}
				break;

			case peripheral::SDHI:
				{
					uint8_t sel = enable ? 0b011010 : 0;
					MPC::P80PFS.PSEL = sel;  // SDHI_WP
					MPC::P81PFS.PSEL = sel;  // SDHI_CD
					PORT8::PMR.B0 = enable;
					PORT8::PMR.B2 = enable;
					MPC::PC2PFS.PSEL = sel;  // SDHI_D3
					MPC::PC3PFS.PSEL = sel;  // SDHI_D0
					MPC::PC4PFS.PSEL = sel;  // SDHI_D1
					PORTC::PMR.B2 = enable;
					PORTC::PMR.B3 = enable;
					PORTC::PMR.B4 = enable;
   					MPC::P75PFS.PSEL = sel;  // SDHI_D2
					MPC::P76PFS.PSEL = sel;  // SDHI_CMD
					MPC::P77PFS.PSEL = sel;  // SDHI_CLK
					PORT7::PMR.B5 = enable;
					PORT7::PMR.B6 = enable;
					PORT7::PMR.B7 = enable;
				}
				break;

			case peripheral::ETHERC0:  // only RMII mode, not use link status interrupt
				{
					uint8_t  mii = enable ? 0b010001 : 0;
					uint8_t rmii = enable ? 0b010010 : 0;
//					MPC::P34PFS.PSEL = mii;   // ET0_LINKSTA
//					PORT3::PMR.B4 = enable;
					MPC::P71PFS.PSEL = mii;   // ET0_MDIO
					MPC::P72PFS.PSEL = mii;   // ET0_MDC
//					MPC::P73PFS.PSEL = mii;   // ET0_WOL
					MPC::P74PFS.PSEL = rmii;  // RMII0_RXD1
					MPC::P75PFS.PSEL = rmii;  // RMII0_RXD0
					MPC::P76PFS.PSEL = rmii;  // REF50CK0
					MPC::P77PFS.PSEL = rmii;  // RMII0_RX_ER
					PORT7::PMR.B1 = enable;
					PORT7::PMR.B2 = enable;
//					PORT7::PMR.B3 = enable;
					PORT7::PMR.B4 = enable;
					PORT7::PMR.B5 = enable;
					PORT7::PMR.B6 = enable;
					PORT7::PMR.B7 = enable;
					MPC::P80PFS.PSEL = rmii;  // RMII0_TXD_EN
					MPC::P81PFS.PSEL = rmii;  // RMII0_TXD0
					MPC::P82PFS.PSEL = rmii;  // RMII0_TXD1
					MPC::P83PFS.PSEL = rmii;  // RMII0_CRS_DV
					PORT8::PMR.B0 = enable;
					PORT8::PMR.B1 = enable;
					PORT8::PMR.B2 = enable;
					PORT8::PMR.B3 = enable;
					MPC::PFENET.PHYMODE0 = 0;  // for RMII mode chanel 0
				}
				break;

			case peripheral::ETHERCA:  // only RMII mode, not use link status interrupt
				{
					uint8_t  mii = enable ? 0b010001 : 0;
					uint8_t rmii = enable ? 0b010010 : 0;
///					MPC::P73PFS.PSEL = mii;   // ET0_WOL  (144LQFP: 77)
					MPC::P72PFS.PSEL = mii;   // ET0_MDC  (144LQFP: 85)
					MPC::P71PFS.PSEL = mii;   // ET0_MDIO (144LQFP: 86)
///					PORT7::PMR.B3 = enable;
					PORT7::PMR.B2 = enable;
					PORT7::PMR.B1 = enable;
					MPC::PB7PFS.PSEL = rmii;  // RMII0_CRS_DV (144LQFP: 78)
					MPC::PB6PFS.PSEL = rmii;  // RMII0_TXD1   (144LQFP: 79)
					MPC::PB5PFS.PSEL = rmii;  // RMII0_TXD0   (144LQFP: 80)
					MPC::PB4PFS.PSEL = rmii;  // RMII0_TXD_EN (144LQFP: 81)
					MPC::PB3PFS.PSEL = rmii;  // RMII0_RX_ER  (144LQFP: 82)
					MPC::PB2PFS.PSEL = rmii;  // REF50CK0     (144LQFP: 83)
					MPC::PB1PFS.PSEL = rmii;  // RMII0_RXD0   (144LQFP: 84)
					MPC::PB0PFS.PSEL = rmii;  // RMII0_RXD1   (144LQFP: 87)
					PORTB::PMR.B7 = enable;
					PORTB::PMR.B6 = enable;
					PORTB::PMR.B5 = enable;
					PORTB::PMR.B4 = enable;
					PORTB::PMR.B3 = enable;
					PORTB::PMR.B2 = enable;
					PORTB::PMR.B1 = enable;
					PORTB::PMR.B0 = enable;
					MPC::PFENET.PHYMODE0 = 0;  // for RMII mode chanel 0
				}
				break;

			default:
//				utils::format("Fail port map: %d\n") % static_cast<int>(t);
				break;
			}
		}

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief  周辺機器に切り替える
			@param[in]	t	周辺機器タイプ
			@param[in]	ena	無効にする場合「false」
		*/
		//-----------------------------------------------------------------//
		static void turn(peripheral t, bool ena = true)
		{
			MPC::PWPR.B0WI = 0;		// PWPR 書き込み許可
			MPC::PWPR.PFSWE = 1;	// PxxPFS 書き込み許可

			sub_(t, ena);

			MPC::PWPR = device::MPC::PWPR.B0WI.b();
		}
	};
}

<commit_msg>fix port NO for SDHI<commit_after>#pragma once
//=====================================================================//
/*!	@file
	@brief	RX64M グループ・ポート・マッピング @n
			・ペリフェラル型に従って、ポートの設定をグループ化
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2016, 2017 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include "RX600/port.hpp"
#include "RX64M/mpc.hpp"
#include "RX64M/peripheral.hpp"

namespace device {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  ポート・マッピング・ユーティリティー
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	class port_map {

		static bool sub_(peripheral t, bool enable) {
			bool ret = true;
			switch(t) {
			// ※シリアルポートの MPC 設定では、PDR を制御する必要は無いが、
			// 出力ポートのインピーダンス制御の一環として入れてある。
			case peripheral::SCI0:
				{
					uint8_t sel = enable ? 0b001010 : 0;
					PORT2::PDR.B0 = enable; // TXD0
					PORT2::PDR.B1 = 0;  	// RXD0
					MPC::P20PFS.PSEL = sel;
					MPC::P21PFS.PSEL = sel;
					PORT2::PMR.B0 = enable;
					PORT2::PMR.B1 = enable;
				}
				break;
			case peripheral::SCI1:
				{
					uint8_t sel = enable ? 0b001010 : 0;
					PORTF::PDR.B0 = enable; // TXD1
					PORTF::PDR.B2 = 0;  	// RXD1
					MPC::PF0PFS.PSEL = sel;
					MPC::PF2PFS.PSEL = sel;
					PORTF::PMR.B0 = enable;
					PORTF::PMR.B2 = enable;
				}
				break;
			case peripheral::SCI2:
				{
					uint8_t sel = enable ? 0b001010 : 0;
					PORT1::PDR.B3 = enable; // TXD2
					PORT1::PDR.B2 = 0;  	// RXD2
					MPC::P13PFS.PSEL = sel;
					MPC::P12PFS.PSEL = sel;
					PORT1::PMR.B3 = enable;
					PORT1::PMR.B2 = enable;
				}
				break;
			case peripheral::SCI3:
				{
					uint8_t sel = enable ? 0b001010 : 0;
					PORT2::PDR.B3 = enable; // TXD3
					PORT2::PDR.B5 = 0;  	// RXD3
					MPC::P23PFS.PSEL = sel;
					MPC::P25PFS.PSEL = sel;
					PORT2::PMR.B3 = enable;
					PORT2::PMR.B5 = enable;
				}
				break;
			case peripheral::SCI4:
				{
					uint8_t sel = enable ? 0b001010 : 0;
					PORTB::PDR.B1 = enable; // TXD4
					PORTB::PDR.B0 = 0;  	// RXD4
					MPC::PB1PFS.PSEL = sel;
					MPC::PB0PFS.PSEL = sel;
					PORTB::PMR.B1 = enable;
					PORTB::PMR.B0 = enable;
				}
				break;
			case peripheral::SCI5:
				{
					uint8_t sel = enable ? 0b001010 : 0;
					PORTA::PDR.B4 = enable; // TXD5
					PORTA::PDR.B3 = 0;  	// RXD5
					MPC::PA4PFS.PSEL = sel;
					MPC::PA3PFS.PSEL = sel;
					PORTA::PMR.B4 = enable;
					PORTA::PMR.B3 = enable;
				}
				break;
			case peripheral::SCI6:
				{
					uint8_t sel = enable ? 0b001010 : 0;
					PORT0::PDR.B0 = enable; // TXD6
					PORT0::PDR.B1 = 0;  	// RXD6
					MPC::P00PFS.PSEL = sel;
					MPC::P01PFS.PSEL = sel;
					PORT0::PMR.B0 = enable;
					PORT0::PMR.B1 = enable;
				}
				break;
			case peripheral::SCI7:
				{
					uint8_t sel = enable ? 0b001010 : 0;
					PORT9::PDR.B0 = enable; // TXD7
					PORT9::PDR.B2 = 0;  	// RXD7
					MPC::P90PFS.PSEL = sel;
					MPC::P92PFS.PSEL = sel;
					PORT9::PMR.B0 = enable;
					PORT9::PMR.B2 = enable;
				}
				break;

			case peripheral::SCI12:
				{
					uint8_t sel = enable ? 0b001100 : 0;
					PORTE::PDR.B2 = enable; // TXD12
					PORTE::PDR.B1 = 0;  	// RXD12
					MPC::PE2PFS.PSEL = sel;
					MPC::PE1PFS.PSEL = sel;
					PORTE::PMR.B2 = enable;
					PORTE::PMR.B1 = enable;
				}
				break;

			case peripheral::RSPI:
				{
					uint8_t sel = enable ? 0b001101 : 0;
//					PORTC::PCR.B7 = 1;		// pull-up
//					PORTC::PDR.B7 = 0;		// MISOA
//					PORTC::PDR.B6 = 1;		// MOSIA
//					PORTC::PDR.B5 = 1;		// RSPCKA
					MPC::PC7PFS.PSEL = sel;  // MISOA
					MPC::PC6PFS.PSEL = sel;  // MOSIA
					MPC::PC5PFS.PSEL = sel;  // RSPCKA
					PORTC::PMR.B7 = enable;
					PORTC::PMR.B6 = enable;
					PORTC::PMR.B5 = enable;
				}
				break;

			case peripheral::SDHI:
				{
					uint8_t sel = enable ? 0b011010 : 0;
					MPC::P80PFS.PSEL = sel;  // SDHI_WP
					MPC::P81PFS.PSEL = sel;  // SDHI_CD
					PORT8::PMR.B0 = enable;
					PORT8::PMR.B1 = enable;
					MPC::PC2PFS.PSEL = sel;  // SDHI_D3
					MPC::PC3PFS.PSEL = sel;  // SDHI_D0
					MPC::PC4PFS.PSEL = sel;  // SDHI_D1
					PORTC::PMR.B2 = enable;
					PORTC::PMR.B3 = enable;
					PORTC::PMR.B4 = enable;
   					MPC::P75PFS.PSEL = sel;  // SDHI_D2
					MPC::P76PFS.PSEL = sel;  // SDHI_CMD
					MPC::P77PFS.PSEL = sel;  // SDHI_CLK
					PORT7::PMR.B5 = enable;
					PORT7::PMR.B6 = enable;
					PORT7::PMR.B7 = enable;
				}
				break;

			case peripheral::ETHERC0:  // only RMII mode, not use link status interrupt
				{
					uint8_t  mii = enable ? 0b010001 : 0;
					uint8_t rmii = enable ? 0b010010 : 0;
//					MPC::P34PFS.PSEL = mii;   // ET0_LINKSTA
//					PORT3::PMR.B4 = enable;
					MPC::P71PFS.PSEL = mii;   // ET0_MDIO
					MPC::P72PFS.PSEL = mii;   // ET0_MDC
//					MPC::P73PFS.PSEL = mii;   // ET0_WOL
					MPC::P74PFS.PSEL = rmii;  // RMII0_RXD1
					MPC::P75PFS.PSEL = rmii;  // RMII0_RXD0
					MPC::P76PFS.PSEL = rmii;  // REF50CK0
					MPC::P77PFS.PSEL = rmii;  // RMII0_RX_ER
					PORT7::PMR.B1 = enable;
					PORT7::PMR.B2 = enable;
//					PORT7::PMR.B3 = enable;
					PORT7::PMR.B4 = enable;
					PORT7::PMR.B5 = enable;
					PORT7::PMR.B6 = enable;
					PORT7::PMR.B7 = enable;
					MPC::P80PFS.PSEL = rmii;  // RMII0_TXD_EN
					MPC::P81PFS.PSEL = rmii;  // RMII0_TXD0
					MPC::P82PFS.PSEL = rmii;  // RMII0_TXD1
					MPC::P83PFS.PSEL = rmii;  // RMII0_CRS_DV
					PORT8::PMR.B0 = enable;
					PORT8::PMR.B1 = enable;
					PORT8::PMR.B2 = enable;
					PORT8::PMR.B3 = enable;
					MPC::PFENET.PHYMODE0 = 0;  // for RMII mode chanel 0
				}
				break;

			case peripheral::ETHERCA:  // only RMII mode, not use link status interrupt
				{
					uint8_t  mii = enable ? 0b010001 : 0;
					uint8_t rmii = enable ? 0b010010 : 0;
///					MPC::P73PFS.PSEL = mii;   // ET0_WOL  (144LQFP: 77)
					MPC::P72PFS.PSEL = mii;   // ET0_MDC  (144LQFP: 85)
					MPC::P71PFS.PSEL = mii;   // ET0_MDIO (144LQFP: 86)
///					PORT7::PMR.B3 = enable;
					PORT7::PMR.B2 = enable;
					PORT7::PMR.B1 = enable;
					MPC::PB7PFS.PSEL = rmii;  // RMII0_CRS_DV (144LQFP: 78)
					MPC::PB6PFS.PSEL = rmii;  // RMII0_TXD1   (144LQFP: 79)
					MPC::PB5PFS.PSEL = rmii;  // RMII0_TXD0   (144LQFP: 80)
					MPC::PB4PFS.PSEL = rmii;  // RMII0_TXD_EN (144LQFP: 81)
					MPC::PB3PFS.PSEL = rmii;  // RMII0_RX_ER  (144LQFP: 82)
					MPC::PB2PFS.PSEL = rmii;  // REF50CK0     (144LQFP: 83)
					MPC::PB1PFS.PSEL = rmii;  // RMII0_RXD0   (144LQFP: 84)
					MPC::PB0PFS.PSEL = rmii;  // RMII0_RXD1   (144LQFP: 87)
					PORTB::PMR.B7 = enable;
					PORTB::PMR.B6 = enable;
					PORTB::PMR.B5 = enable;
					PORTB::PMR.B4 = enable;
					PORTB::PMR.B3 = enable;
					PORTB::PMR.B2 = enable;
					PORTB::PMR.B1 = enable;
					PORTB::PMR.B0 = enable;
					MPC::PFENET.PHYMODE0 = 0;  // for RMII mode chanel 0
				}
				break;

			default:
				ret = false;
				break;
			}
			return ret;
		}

	public:

		//-----------------------------------------------------------------//
		/*!
			@brief  周辺機器に切り替える
			@param[in]	t	周辺機器タイプ
			@param[in]	ena	無効にする場合「false」
		*/
		//-----------------------------------------------------------------//
		static bool turn(peripheral t, bool ena = true) noexcept
		{
			MPC::PWPR.B0WI = 0;		// PWPR 書き込み許可
			MPC::PWPR.PFSWE = 1;	// PxxPFS 書き込み許可

			auto ret = sub_(t, ena);

			MPC::PWPR = device::MPC::PWPR.B0WI.b();

			return ret;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  SDHI クロック端子のソフト制御
			@param[in]	t	周辺機器タイプ
		*/
		//-----------------------------------------------------------------//
		static bool turn_sdhi_clk(peripheral t)
		{
			MPC::PWPR.B0WI = 0;		// PWPR 書き込み許可
			MPC::PWPR.PFSWE = 1;	// PxxPFS 書き込み許可

			bool ret = false;
			if(t == peripheral::SDHI) {
				MPC::P77PFS.PSEL = 0;  // SDHI_CLK
				PORT7::PMR.B7 = 0;
				ret = true;
			}
			MPC::PWPR = device::MPC::PWPR.B0WI.b();

			return ret;
		}
	};
}

<|endoftext|>