<commit_before>#include "reqresp.hpp"

namespace YaHTTP {

  void Request::build(const std::string &method, const std::string &url, const std::string &params) {
    this->method = method;
    std::transform(this->method.begin(), this->method.end(), this->method.begin(), ::toupper);
    this->url.parse(url);
    this->headers["host"] = this->url.host;
    this->headers["connection"] = "close";
    this->headers["user-agent"] = "yahttp 0.1";
    this->headers["accept"] = "*/*";
    if (params.empty() == false) {
      this->headers["content-type"] = "application/x-www-form-urlencoded; charset=utf-8";
      this->headers["content-length"] = params.size();
      this->body = params;
    } else {
      this->body = "";
    }
  };

  Request::Request() {};
  Request::Request(const Response &resp) {
    method = resp.method;
    url = resp.url;
    cookies = resp.cookies;
  };
  Request::Request(const Request &req) {
    method = req.method;
    url = req.url;
    parameters = req.parameters;
    headers = req.headers;
    cookies = req.cookies;
    body = req.body;
  };
  Request::~Request() {};

  Response::Response() {};
  Response::Response(const Request &req) {
    method = req.method;
    url = req.url;
    cookies = req.cookies;
    status = 200;
  };
  Response::Response(const Response &resp) {
    method = resp.method;
    url = resp.url;
    parameters = resp.parameters;
    headers = resp.headers;
    cookies = resp.cookies;
    body = resp.body;
    status = resp.status;
    statusText = resp.statusText;
  };
  Response::~Response() {};

  void Response::load(std::istream &is) {
    AsyncResponseLoader arl(this);
    while(is.good()) {
      char buf[1024];
      is.read(buf, 1024);
      if (is.gcount()) { // did we actually read anything
        is.clear();
        if (arl.feed(std::string(buf, is.gcount())) == true) return; // completed
      }
    }
    // FIXME: parse cookies
  };

  void Response::write(std::ostream &os) const {
    os << "HTTP/1.1 " << status << " ";
    if (statusText.empty())
      os << Utility::status2text(status);
    else
      os << statusText;
    os << "\r\n";

    // write headers
    strstr_map_t::const_iterator iter = headers.begin();
    while(iter != headers.end()) {
      os << Utility::camelizeHeader(iter->first) << ": " << iter->second << "\r\n";
      iter++;
    }
    os << "\r\n";
    os << body;
  };

  void Request::load(std::istream &is) {
    AsyncRequestLoader arl(this);
    while(is.good()) {
      char buf[1024];
      is.read(buf, 1024);
      if (is.gcount()) { // did we actually read anything
        is.clear();
        if (arl.feed(std::string(buf, is.gcount())) == true) return; // completed
      }
    }
  };

  void Request::write(std::ostream &os) const {
    os << method << " " << url.path << " HTTP/1.1" << "\r\n";
    strstr_map_t::const_iterator iter = headers.begin();
    while(iter != headers.end()) {
      os << Utility::camelizeHeader(iter->first) << ": " << iter->second << "\r\n";
      iter++;
    }
    os << "\r\n";
    if (body.size()>0) {
      os << body;
    }
  };

  std::ostream& operator<<(std::ostream& os, const Response &resp) {
    resp.write(os);
    return os;
  };

  std::istream& operator>>(std::istream& is, Response &resp) {
    resp.load(is);
    return is;
  };

  std::ostream& operator<<(std::ostream& os, const Request &req) {
    req.write(os);
    return os;
  };

  std::istream& operator>>(std::istream& is, Request &req) {
    req.load(is);
    return is;
  };

  bool AsyncRequestLoader::feed(const std::string &somedata) {
    size_t pos;

    buffer.append(somedata);
    while(state < 2) {
      // need to find newline in buffer
      if ((pos = buffer.find("\r\n")) == std::string::npos) return false;
      std::string line(buffer.begin(), buffer.begin()+pos); // exclude CRLF
      buffer.erase(buffer.begin(), buffer.begin()+pos+2); // remove line from buffer including CRLF
      if (state == 0) { // startup line
        std::string ver;
        std::string tmpurl;
        std::istringstream iss(line);
        iss >> request->method >> tmpurl >> ver;
        if (ver != "HTTP/1.1")
          throw ParseError("Not a HTTP 1.1 request");
        // uppercase the request method
        std::transform(request->method.begin(), request->method.end(), request->method.begin(), ::toupper);
        request->url.parse(tmpurl);
        state = 1;
      } else if (state == 1) {
        std::string key,value;
        size_t pos;
        if (line.empty()) {
          chunked = (request->headers.find("transfer-encoding") != request->headers.end() && request->headers["transfer-encoding"] == "chunked");
          // validate certain headers
          if (request->headers.find("host") == request->headers.end())
            throw ParseError("Missing Host header");
          else
            request->url.host = request->headers["host"];
          // parse url

          state = 2;
          break;
        }
        // split headers
        if ((pos = line.find_first_of(": ")) == std::string::npos)
          throw ParseError("Malformed line");
        key = line.substr(0, pos);
        value = line.substr(pos+2);
        std::transform(key.begin(), key.end(), key.begin(), ::tolower);
        request->headers[key] = value;
      }
    }

    if (request->method != "POST")
      return true;

    // do we have content-length?
    if (!chunked) {
      if (request->headers.find("content-length") != request->headers.end()) {
        std::istringstream maxbodyS(request->headers["content-length"]);
        maxbodyS >> maxbody;
      }
      if (maxbody < 1) return true; // guess there isn't anything left.
      if (maxbody > YAHTTP_MAX_REQUEST_SIZE)
        throw ParseError("Request size exceeded");
    }

    if (buffer.size() == 0) return false;

    while(buffer.size() > 0 && bodybuf.str().size() < static_cast<size_t>(maxbody)) {
      char buf[1024] = {0};

      if (chunked) {
        if (chunk_size == 0) {
          // read chunk length
          if ((pos = buffer.find('\n')) == std::string::npos) return false;
          if (pos > 1023)
            throw ParseError("Impossible chunk_size");
          buffer.copy(buf, pos);
          buf[pos]=0; // just in case...
          buffer.erase(buffer.begin(), buffer.begin()+pos+1); // remove line from buffer
          sscanf(buf, "%x", &chunk_size);
          if (!chunk_size) break; // last chunk
        } else {
          if (buffer.size() < static_cast<size_t>(chunk_size+1)) return false; // expect newline
          if (buffer.at(chunk_size) != '\n') return false; // there should be newline.
          buffer.copy(buf, chunk_size);
          buffer.erase(buffer.begin(), buffer.begin()+chunk_size+1);
          bodybuf << buf;
          chunk_size = 0;
          if (buffer.size() == 0) return false; // just in case
        }
      } else {
        bodybuf << buffer;
        buffer = "";
      }
    }

    if (chunk_size!=0) return false; // need more data

    bodybuf.flush();
    request->body = bodybuf.str();
    bodybuf.str("");
    return true;
  };

  bool AsyncResponseLoader::feed(const std::string &somedata) {
    size_t pos;
    buffer.append(somedata);
    while(state < 2) {
      // need to find CRLF in buffer
      if ((pos = buffer.find("\r\n")) == std::string::npos) return false;
      std::string line(buffer.begin(), buffer.begin()+pos); // exclude CRLF
      buffer.erase(buffer.begin(), buffer.begin()+pos+2); // remove line from buffer including CRLF
      if (state == 0) { // startup line
        std::string ver;
        std::istringstream iss(line);
        iss >> ver >> response->status >> response->statusText;
        if (ver != "HTTP/1.1")
          throw ParseError("Not a HTTP response");
        state = 1;
      } else if (state == 1) {
        std::string key,value;
        size_t pos;
        if (line.empty()) {
          chunked = (response->headers.find("transfer-encoding") != response->headers.end() && response->headers["transfer-encoding"] == "chunked");
          state = 2;
          break;
        }
        // split headers
        if ((pos = line.find_first_of(": ")) == std::string::npos)
          throw ParseError("Malformed header line");
        key = line.substr(0, pos);
        value = line.substr(pos+2);
        std::transform(key.begin(), key.end(), key.begin(), ::tolower);
        response->headers[key] = value;
      }
    }

    if (buffer.size() == 0) return false;

    while(buffer.size() > 0) {
      char buf[1024] = {0};

      if (chunked) {
        if (chunk_size == 0) {
          // read chunk length
          if ((pos = buffer.find('\n')) == std::string::npos) return false;
          if (pos > 1023)
            throw ParseError("Impossible chunk_size");
          buffer.copy(buf, pos);
          buf[pos]=0; // just in case...
          buffer.erase(buffer.begin(), buffer.begin()+pos+1); // remove line from buffer
          sscanf(buf, "%x", &chunk_size);
          if (!chunk_size) break; // last chunk
        } else {
          if (buffer.size() < static_cast<size_t>(chunk_size+1)) return false; // expect newline
          if (buffer.at(chunk_size) != '\n') return false; // there should be newline.
          buffer.copy(buf, chunk_size);
          buffer.erase(buffer.begin(), buffer.begin()+chunk_size+1);
          bodybuf << buf;
          chunk_size = 0;
          if (buffer.size() == 0) return false; // just in case
        }
      } else {
        bodybuf << buffer;
        buffer = "";
      }
    }

    if (chunk_size!=0) return false; // need more data

    bodybuf.flush();
    response->body = bodybuf.str();
    bodybuf.str("");
    return true;
  };
};
<commit_msg>allow HTTP 1.0<commit_after>#include "reqresp.hpp"

namespace YaHTTP {

  void Request::build(const std::string &method, const std::string &url, const std::string &params) {
    this->method = method;
    std::transform(this->method.begin(), this->method.end(), this->method.begin(), ::toupper);
    this->url.parse(url);
    this->headers["host"] = this->url.host;
    this->headers["connection"] = "close";
    this->headers["user-agent"] = "yahttp 0.1";
    this->headers["accept"] = "*/*";
    if (params.empty() == false) {
      this->headers["content-type"] = "application/x-www-form-urlencoded; charset=utf-8";
      this->headers["content-length"] = params.size();
      this->body = params;
    } else {
      this->body = "";
    }
  };

  Request::Request() {};
  Request::Request(const Response &resp) {
    method = resp.method;
    url = resp.url;
    cookies = resp.cookies;
  };
  Request::Request(const Request &req) {
    method = req.method;
    url = req.url;
    parameters = req.parameters;
    headers = req.headers;
    cookies = req.cookies;
    body = req.body;
  };
  Request::~Request() {};

  Response::Response() {};
  Response::Response(const Request &req) {
    method = req.method;
    url = req.url;
    cookies = req.cookies;
    status = 200;
  };
  Response::Response(const Response &resp) {
    method = resp.method;
    url = resp.url;
    parameters = resp.parameters;
    headers = resp.headers;
    cookies = resp.cookies;
    body = resp.body;
    status = resp.status;
    statusText = resp.statusText;
  };
  Response::~Response() {};

  void Response::load(std::istream &is) {
    AsyncResponseLoader arl(this);
    while(is.good()) {
      char buf[1024];
      is.read(buf, 1024);
      if (is.gcount()) { // did we actually read anything
        is.clear();
        if (arl.feed(std::string(buf, is.gcount())) == true) return; // completed
      }
    }
    // FIXME: parse cookies
  };

  void Response::write(std::ostream &os) const {
    os << "HTTP/1.1 " << status << " ";
    if (statusText.empty())
      os << Utility::status2text(status);
    else
      os << statusText;
    os << "\r\n";

    // write headers
    strstr_map_t::const_iterator iter = headers.begin();
    while(iter != headers.end()) {
      os << Utility::camelizeHeader(iter->first) << ": " << iter->second << "\r\n";
      iter++;
    }
    os << "\r\n";
    os << body;
  };

  void Request::load(std::istream &is) {
    AsyncRequestLoader arl(this);
    while(is.good()) {
      char buf[1024];
      is.read(buf, 1024);
      if (is.gcount()) { // did we actually read anything
        is.clear();
        if (arl.feed(std::string(buf, is.gcount())) == true) return; // completed
      }
    }
  };

  void Request::write(std::ostream &os) const {
    os << method << " " << url.path << " HTTP/1.1" << "\r\n";
    strstr_map_t::const_iterator iter = headers.begin();
    while(iter != headers.end()) {
      os << Utility::camelizeHeader(iter->first) << ": " << iter->second << "\r\n";
      iter++;
    }
    os << "\r\n";
    if (body.size()>0) {
      os << body;
    }
  };

  std::ostream& operator<<(std::ostream& os, const Response &resp) {
    resp.write(os);
    return os;
  };

  std::istream& operator>>(std::istream& is, Response &resp) {
    resp.load(is);
    return is;
  };

  std::ostream& operator<<(std::ostream& os, const Request &req) {
    req.write(os);
    return os;
  };

  std::istream& operator>>(std::istream& is, Request &req) {
    req.load(is);
    return is;
  };

  bool AsyncRequestLoader::feed(const std::string &somedata) {
    size_t pos;

    buffer.append(somedata);
    while(state < 2) {
      // need to find newline in buffer
      if ((pos = buffer.find("\r\n")) == std::string::npos) return false;
      std::string line(buffer.begin(), buffer.begin()+pos); // exclude CRLF
      buffer.erase(buffer.begin(), buffer.begin()+pos+2); // remove line from buffer including CRLF
      if (state == 0) { // startup line
        std::string ver;
        std::string tmpurl;
        std::istringstream iss(line);
        iss >> request->method >> tmpurl >> ver;
        if (ver.find("HTTP/1.") != 0)
          throw ParseError("Not a HTTP 1.x request");
        // uppercase the request method
        std::transform(request->method.begin(), request->method.end(), request->method.begin(), ::toupper);
        request->url.parse(tmpurl);
        state = 1;
      } else if (state == 1) {
        std::string key,value;
        size_t pos;
        if (line.empty()) {
          chunked = (request->headers.find("transfer-encoding") != request->headers.end() && request->headers["transfer-encoding"] == "chunked");
          // host header is optional
          if (request->headers.find("host") != request->headers.end())
            request->url.host = request->headers["host"];

          state = 2;
          break;
        }
        // split headers
        if ((pos = line.find_first_of(": ")) == std::string::npos)
          throw ParseError("Malformed line");
        key = line.substr(0, pos);
        value = line.substr(pos+2);
        std::transform(key.begin(), key.end(), key.begin(), ::tolower);
        request->headers[key] = value;
      }
    }

    if (request->method != "POST")
      return true;

    // do we have content-length?
    if (!chunked) {
      if (request->headers.find("content-length") != request->headers.end()) {
        std::istringstream maxbodyS(request->headers["content-length"]);
        maxbodyS >> maxbody;
      }
      if (maxbody < 1) return true; // guess there isn't anything left.
      if (maxbody > YAHTTP_MAX_REQUEST_SIZE)
        throw ParseError("Request size exceeded");
    }

    if (buffer.size() == 0) return false;

    while(buffer.size() > 0 && bodybuf.str().size() < static_cast<size_t>(maxbody)) {
      char buf[1024] = {0};

      if (chunked) {
        if (chunk_size == 0) {
          // read chunk length
          if ((pos = buffer.find('\n')) == std::string::npos) return false;
          if (pos > 1023)
            throw ParseError("Impossible chunk_size");
          buffer.copy(buf, pos);
          buf[pos]=0; // just in case...
          buffer.erase(buffer.begin(), buffer.begin()+pos+1); // remove line from buffer
          sscanf(buf, "%x", &chunk_size);
          if (!chunk_size) break; // last chunk
        } else {
          if (buffer.size() < static_cast<size_t>(chunk_size+1)) return false; // expect newline
          if (buffer.at(chunk_size) != '\n') return false; // there should be newline.
          buffer.copy(buf, chunk_size);
          buffer.erase(buffer.begin(), buffer.begin()+chunk_size+1);
          bodybuf << buf;
          chunk_size = 0;
          if (buffer.size() == 0) return false; // just in case
        }
      } else {
        bodybuf << buffer;
        buffer = "";
      }
    }

    if (chunk_size!=0) return false; // need more data

    bodybuf.flush();
    request->body = bodybuf.str();
    bodybuf.str("");
    return true;
  };

  bool AsyncResponseLoader::feed(const std::string &somedata) {
    size_t pos;
    buffer.append(somedata);
    while(state < 2) {
      // need to find CRLF in buffer
      if ((pos = buffer.find("\r\n")) == std::string::npos) return false;
      std::string line(buffer.begin(), buffer.begin()+pos); // exclude CRLF
      buffer.erase(buffer.begin(), buffer.begin()+pos+2); // remove line from buffer including CRLF
      if (state == 0) { // startup line
        std::string ver;
        std::istringstream iss(line);
        iss >> ver >> response->status >> response->statusText;
        if (ver.find("HTTP/1.") != 0)
          throw ParseError("Not a HTTP 1.x response");
        state = 1;
      } else if (state == 1) {
        std::string key,value;
        size_t pos;
        if (line.empty()) {
          chunked = (response->headers.find("transfer-encoding") != response->headers.end() && response->headers["transfer-encoding"] == "chunked");
          state = 2;
          break;
        }
        // split headers
        if ((pos = line.find_first_of(": ")) == std::string::npos)
          throw ParseError("Malformed header line");
        key = line.substr(0, pos);
        value = line.substr(pos+2);
        std::transform(key.begin(), key.end(), key.begin(), ::tolower);
        response->headers[key] = value;
      }
    }

    if (buffer.size() == 0) return false;

    while(buffer.size() > 0) {
      char buf[1024] = {0};

      if (chunked) {
        if (chunk_size == 0) {
          // read chunk length
          if ((pos = buffer.find('\n')) == std::string::npos) return false;
          if (pos > 1023)
            throw ParseError("Impossible chunk_size");
          buffer.copy(buf, pos);
          buf[pos]=0; // just in case...
          buffer.erase(buffer.begin(), buffer.begin()+pos+1); // remove line from buffer
          sscanf(buf, "%x", &chunk_size);
          if (!chunk_size) break; // last chunk
        } else {
          if (buffer.size() < static_cast<size_t>(chunk_size+1)) return false; // expect newline
          if (buffer.at(chunk_size) != '\n') return false; // there should be newline.
          buffer.copy(buf, chunk_size);
          buffer.erase(buffer.begin(), buffer.begin()+chunk_size+1);
          bodybuf << buf;
          chunk_size = 0;
          if (buffer.size() == 0) return false; // just in case
        }
      } else {
        bodybuf << buffer;
        buffer = "";
      }
    }

    if (chunk_size!=0) return false; // need more data

    bodybuf.flush();
    response->body = bodybuf.str();
    bodybuf.str("");
    return true;
  };
};
<|endoftext|>


<commit_before>#include "SimpleITKTestHarness.h"
#include "sitkCastImageFilter.h"
#include "sitkHashImageFilter.h"
#include "sitkSimpleElastix.h"

namespace sitk = itk::simple;

TEST(ParameterMapTest,ParameterMap)
{
    sitk::SimpleElastix::ParameterMapType parameterMap;

    EXPECT_EQ( parameterMap.size(), 0u );
    EXPECT_NO_THROW( parameterMap["key"] = sitk::SimpleElastix::ParameterValueVectorType( 1, "value" ) );
    EXPECT_EQ( parameterMap["key"], sitk::SimpleElastix::ParameterValueVectorType( 1, "value" ) );
    EXPECT_EQ( parameterMap["key"].size(), 1u );
    EXPECT_EQ( parameterMap.size(), 1u );

    EXPECT_NO_THROW( parameterMap["key"] = sitk::SimpleElastix::ParameterValueVectorType( 2, "values" ) );
    EXPECT_EQ( parameterMap["key"], sitk::SimpleElastix::ParameterValueVectorType( 2, "values" ) );
    EXPECT_EQ( parameterMap["key"].size(), 2u );
    EXPECT_EQ( parameterMap.size(), 1u );
}

TEST(ParameteMapTest,ParameterMapVector)
{
    sitk::SimpleElastix::ParameterMapType parameterMap;
    parameterMap["key1"] = sitk::SimpleElastix::ParameterValueVectorType( 1, "value1" );
    parameterMap["key2"] = sitk::SimpleElastix::ParameterValueVectorType( 2, "value2" );
    parameterMap["key3"] = sitk::SimpleElastix::ParameterValueVectorType( 3, "value3" );
    EXPECT_EQ( parameterMap.size(), 3u );

    sitk::SimpleElastix::ParameterMapVectorType parameterMapVector0;
    EXPECT_EQ( parameterMapVector0.size(), 0u );
    parameterMapVector0.push_back( parameterMap );
    EXPECT_EQ( parameterMapVector0.size(), 1u );
    EXPECT_EQ( parameterMapVector0[0].size(), 3u );
    EXPECT_EQ( parameterMapVector0[0]["key3"], sitk::SimpleElastix::ParameterValueVectorType( 3, "value3" ) );

    EXPECT_NO_THROW( parameterMapVector0[0]["key3"] = sitk::SimpleElastix::ParameterValueVectorType( 4, "newValue3" ) );
    EXPECT_EQ( parameterMapVector0[0]["key3"], sitk::SimpleElastix::ParameterValueVectorType( 4, "newValue3" ) );

    sitk::SimpleElastix::ParameterMapVectorType parameterMapVector1 = sitk::SimpleElastix::ParameterMapVectorType( 2, parameterMap );
    EXPECT_EQ( parameterMapVector1.size(), 2u );
}

TEST( ParameterMapTest, ProceduralInterface )
{
    sitk::SimpleElastix::ParameterMapType parameterMap;
    EXPECT_NO_THROW( parameterMap = sitk::GetDefaultParameterMap( "translation" ) );
    EXPECT_NO_THROW( sitk::PrettyPrint( parameterMap ) );

    sitk::SimpleElastix::ParameterMapVectorType parameterMapVector;
    parameterMapVector.push_back( parameterMap );
    parameterMapVector.push_back( parameterMap );
    EXPECT_NO_THROW( sitk::PrettyPrint( parameterMapVector ) );
}

TEST( ParameterMapTest, ReadWrite )
{
    sitk::SimpleElastix::ParameterMapType parameterMap;
    EXPECT_NO_THROW( parameterMap = sitk::GetDefaultParameterMap( "translation" ) );

    sitk::Image fixedImage = sitk::Cast( sitk::ReadImage( dataFinder.GetFile( "Input/BrainProtonDensitySliceBorder20.png" ) ), sitk::sitkFloat32 );
    sitk::Image movingImage = sitk::Cast( sitk::ReadImage( dataFinder.GetFile( "Input/BrainProtonDensitySliceShifted13x17y.png" ) ), sitk::sitkFloat32 );

    sitk::Image resultImage0;
    EXPECT_NO_THROW( resultImage0 = Elastix( fixedImage, movingImage, parameterMap ) );

    sitk::Image resultImage1;
    EXPECT_NO_THROW( sitk::WriteParameterFile( parameterMap, "ParameterMapTestProceduralInterface.txt" ) );
    sitk::SimpleElastix::ParameterMapType parameterMapRead;
    EXPECT_NO_THROW( parameterMapRead = sitk::ReadParameterFile( "ParameterMapTestProceduralInterface.txt" ) );
    EXPECT_NO_THROW( resultImage1 = Elastix( fixedImage, movingImage, parameterMapRead ) );

    EXPECT_EQ( sitk::Hash( resultImage0 ), sitk::Hash( resultImage1 ) );
}
<commit_msg>STYLE: Rename parameter map test I/O file<commit_after>#include "SimpleITKTestHarness.h"
#include "sitkCastImageFilter.h"
#include "sitkHashImageFilter.h"
#include "sitkSimpleElastix.h"

namespace sitk = itk::simple;

TEST(ParameterMapTest,ParameterMap)
{
    sitk::SimpleElastix::ParameterMapType parameterMap;

    EXPECT_EQ( parameterMap.size(), 0u );
    EXPECT_NO_THROW( parameterMap["key"] = sitk::SimpleElastix::ParameterValueVectorType( 1, "value" ) );
    EXPECT_EQ( parameterMap["key"], sitk::SimpleElastix::ParameterValueVectorType( 1, "value" ) );
    EXPECT_EQ( parameterMap["key"].size(), 1u );
    EXPECT_EQ( parameterMap.size(), 1u );

    EXPECT_NO_THROW( parameterMap["key"] = sitk::SimpleElastix::ParameterValueVectorType( 2, "values" ) );
    EXPECT_EQ( parameterMap["key"], sitk::SimpleElastix::ParameterValueVectorType( 2, "values" ) );
    EXPECT_EQ( parameterMap["key"].size(), 2u );
    EXPECT_EQ( parameterMap.size(), 1u );
}

TEST(ParameteMapTest,ParameterMapVector)
{
    sitk::SimpleElastix::ParameterMapType parameterMap;
    parameterMap["key1"] = sitk::SimpleElastix::ParameterValueVectorType( 1, "value1" );
    parameterMap["key2"] = sitk::SimpleElastix::ParameterValueVectorType( 2, "value2" );
    parameterMap["key3"] = sitk::SimpleElastix::ParameterValueVectorType( 3, "value3" );
    EXPECT_EQ( parameterMap.size(), 3u );

    sitk::SimpleElastix::ParameterMapVectorType parameterMapVector0;
    EXPECT_EQ( parameterMapVector0.size(), 0u );
    parameterMapVector0.push_back( parameterMap );
    EXPECT_EQ( parameterMapVector0.size(), 1u );
    EXPECT_EQ( parameterMapVector0[0].size(), 3u );
    EXPECT_EQ( parameterMapVector0[0]["key3"], sitk::SimpleElastix::ParameterValueVectorType( 3, "value3" ) );

    EXPECT_NO_THROW( parameterMapVector0[0]["key3"] = sitk::SimpleElastix::ParameterValueVectorType( 4, "newValue3" ) );
    EXPECT_EQ( parameterMapVector0[0]["key3"], sitk::SimpleElastix::ParameterValueVectorType( 4, "newValue3" ) );

    sitk::SimpleElastix::ParameterMapVectorType parameterMapVector1 = sitk::SimpleElastix::ParameterMapVectorType( 2, parameterMap );
    EXPECT_EQ( parameterMapVector1.size(), 2u );
}

TEST( ParameterMapTest, ProceduralInterface )
{
    sitk::SimpleElastix::ParameterMapType parameterMap;
    EXPECT_NO_THROW( parameterMap = sitk::GetDefaultParameterMap( "translation" ) );
    EXPECT_NO_THROW( sitk::PrettyPrint( parameterMap ) );

    sitk::SimpleElastix::ParameterMapVectorType parameterMapVector;
    parameterMapVector.push_back( parameterMap );
    parameterMapVector.push_back( parameterMap );
    EXPECT_NO_THROW( sitk::PrettyPrint( parameterMapVector ) );
}

TEST( ParameterMapTest, ReadWrite )
{
    sitk::SimpleElastix::ParameterMapType parameterMap;
    EXPECT_NO_THROW( parameterMap = sitk::GetDefaultParameterMap( "translation" ) );

    sitk::Image fixedImage = sitk::Cast( sitk::ReadImage( dataFinder.GetFile( "Input/BrainProtonDensitySliceBorder20.png" ) ), sitk::sitkFloat32 );
    sitk::Image movingImage = sitk::Cast( sitk::ReadImage( dataFinder.GetFile( "Input/BrainProtonDensitySliceShifted13x17y.png" ) ), sitk::sitkFloat32 );

    sitk::Image resultImage0;
    EXPECT_NO_THROW( resultImage0 = Elastix( fixedImage, movingImage, parameterMap ) );

    sitk::Image resultImage1;
    EXPECT_NO_THROW( sitk::WriteParameterFile( parameterMap, "ParameterMapTestReadWrite.txt" ) );
    sitk::SimpleElastix::ParameterMapType parameterMapRead;
    EXPECT_NO_THROW( parameterMapRead = sitk::ReadParameterFile( "ParameterMapTestReadWrite.txt" ) );
    EXPECT_NO_THROW( resultImage1 = Elastix( fixedImage, movingImage, parameterMapRead ) );

    EXPECT_EQ( sitk::Hash( resultImage0 ), sitk::Hash( resultImage1 ) );
}
<|endoftext|>


<commit_before>#include "reqresp.hpp"

namespace YaHTTP {

  void Request::build(const std::string &method, const std::string &url, const std::string &params) {
    this->method = method;
    std::transform(this->method.begin(), this->method.end(), this->method.begin(), ::toupper);
    this->url.parse(url);
    this->headers["host"] = this->url.host;
    this->headers["connection"] = "close";
    this->headers["user-agent"] = "yahttp 0.1";
    this->headers["accept"] = "*/*";
    if (params.empty() == false) {
      this->headers["content-type"] = "application/x-www-form-urlencoded; charset=utf-8";
      this->headers["content-length"] = params.size();
      this->body = params;
    } else {
      this->body = "";
    }
  };

  Request::Request() {};
  Request::Request(const Response &resp) {
    method = resp.method;
    url = resp.url;
    cookies = resp.cookies;
  };
  Request::Request(const Request &req) {
    method = req.method;
    url = req.url;
    parameters = req.parameters;
    headers = req.headers;
    cookies = req.cookies;
    body = req.body;
  };
  Request::~Request() {};

  Response::Response() {};
  Response::Response(const Request &req) {
    headers["connection"] = "close";
    method = req.method;
    url = req.url;
    cookies = req.cookies;
    status = 200;
  };
  Response::Response(const Response &resp) {
    method = resp.method;
    url = resp.url;
    parameters = resp.parameters;
    headers = resp.headers;
    cookies = resp.cookies;
    body = resp.body;
    status = resp.status;
    statusText = resp.statusText;
  };
  Response::~Response() {};

  void Response::load(std::istream &is) {
    AsyncResponseLoader arl(this);
    while(is.good()) {
      char buf[1024];
      is.read(buf, 1024);
      if (is.gcount()) { // did we actually read anything
        is.clear();
        if (arl.feed(std::string(buf, is.gcount())) == true) return; // completed
      }
    }
    // FIXME: parse cookies
  };

  void Response::write(std::ostream &os) const {
    os << "HTTP/1.1 " << status << " ";
    if (statusText.empty())
      os << Utility::status2text(status);
    else
      os << statusText;
    os << "\r\n";

    // write headers
    strstr_map_t::const_iterator iter = headers.begin();
    while(iter != headers.end()) {
      os << Utility::camelizeHeader(iter->first) << ": " << iter->second << "\r\n";
      iter++;
    }
    os << "\r\n";
    os << body;
  };

  void Request::load(std::istream &is) {
    AsyncRequestLoader arl(this);
    while(is.good()) {
      char buf[1024];
      is.read(buf, 1024);
      if (is.gcount()) { // did we actually read anything
        is.clear();
        if (arl.feed(std::string(buf, is.gcount())) == true) return; // completed
      }
    }
  };

  void Request::write(std::ostream &os) const {
    os << method << " " << url.path << " HTTP/1.1" << "\r\n";
    strstr_map_t::const_iterator iter = headers.begin();
    while(iter != headers.end()) {
      os << Utility::camelizeHeader(iter->first) << ": " << iter->second << "\r\n";
      iter++;
    }
    os << "\r\n";
    if (body.size()>0) {
      os << body;
    }
  };

  std::ostream& operator<<(std::ostream& os, const Response &resp) {
    resp.write(os);
    return os;
  };

  std::istream& operator>>(std::istream& is, Response &resp) {
    resp.load(is);
    return is;
  };

  std::ostream& operator<<(std::ostream& os, const Request &req) {
    req.write(os);
    return os;
  };

  std::istream& operator>>(std::istream& is, Request &req) {
    req.load(is);
    return is;
  };

  bool AsyncRequestLoader::feed(const std::string &somedata) {
    size_t pos;

    buffer.append(somedata);
    while(state < 2) {
      // need to find newline in buffer
      if ((pos = buffer.find("\r\n")) == std::string::npos) return false;
      std::string line(buffer.begin(), buffer.begin()+pos); // exclude CRLF
      buffer.erase(buffer.begin(), buffer.begin()+pos+2); // remove line from buffer including CRLF
      if (state == 0) { // startup line
        std::string ver;
        std::string tmpurl;
        std::istringstream iss(line);
        iss >> request->method >> tmpurl >> ver;
        if (ver.find("HTTP/1.") != 0)
          throw ParseError("Not a HTTP 1.x request");
        // uppercase the request method
        std::transform(request->method.begin(), request->method.end(), request->method.begin(), ::toupper);
        request->url.parse(tmpurl);
        request->parameters = Utility::parseUrlParameters(request->url.parameters);
        state = 1;
      } else if (state == 1) {
        std::string key,value;
        size_t pos;
        if (line.empty()) {
          chunked = (request->headers.find("transfer-encoding") != request->headers.end() && request->headers["transfer-encoding"] == "chunked");
          // host header is optional
          if (request->headers.find("host") != request->headers.end())
            request->url.host = request->headers["host"];

          state = 2;
          break;
        }
        // split headers
        if ((pos = line.find_first_of(": ")) == std::string::npos)
          throw ParseError("Malformed line");
        key = line.substr(0, pos);
        value = line.substr(pos+2);
        std::transform(key.begin(), key.end(), key.begin(), ::tolower);
        request->headers[key] = value;
      }
    }

    // do we have content-length?
    if (!chunked) {
      if (request->headers.find("content-length") != request->headers.end()) {
        std::istringstream maxbodyS(request->headers["content-length"]);
        maxbodyS >> maxbody;
      }
      if (maxbody < 1) return true; // guess there isn't anything left.
      if (maxbody > YAHTTP_MAX_REQUEST_SIZE)
        throw ParseError("Request size exceeded");
    }

    if (buffer.size() == 0) return false;

    while(buffer.size() > 0 && bodybuf.str().size() < static_cast<size_t>(maxbody)) {
      char buf[1024] = {0};

      if (chunked) {
        if (chunk_size == 0) {
          // read chunk length
          if ((pos = buffer.find('\n')) == std::string::npos) return false;
          if (pos > 1023)
            throw ParseError("Impossible chunk_size");
          buffer.copy(buf, pos);
          buf[pos]=0; // just in case...
          buffer.erase(buffer.begin(), buffer.begin()+pos+1); // remove line from buffer
          sscanf(buf, "%x", &chunk_size);
          if (!chunk_size) break; // last chunk
        } else {
          if (buffer.size() < static_cast<size_t>(chunk_size+1)) return false; // expect newline
          if (buffer.at(chunk_size) != '\n') return false; // there should be newline.
          buffer.copy(buf, chunk_size);
          buffer.erase(buffer.begin(), buffer.begin()+chunk_size+1);
          bodybuf << buf;
          chunk_size = 0;
          if (buffer.size() == 0) return false; // just in case
        }
      } else {
        bodybuf << buffer;
        buffer = "";
      }
    }

    if (chunk_size!=0) return false; // need more data

    bodybuf.flush();
    request->body = bodybuf.str();
    bodybuf.str("");
    return true;
  };

  bool AsyncResponseLoader::feed(const std::string &somedata) {
    size_t pos;
    buffer.append(somedata);
    while(state < 2) {
      // need to find CRLF in buffer
      if ((pos = buffer.find("\r\n")) == std::string::npos) return false;
      std::string line(buffer.begin(), buffer.begin()+pos); // exclude CRLF
      buffer.erase(buffer.begin(), buffer.begin()+pos+2); // remove line from buffer including CRLF
      if (state == 0) { // startup line
        std::string ver;
        std::istringstream iss(line);
        iss >> ver >> response->status >> response->statusText;
        if (ver.find("HTTP/1.") != 0)
          throw ParseError("Not a HTTP 1.x response");
        state = 1;
      } else if (state == 1) {
        std::string key,value;
        size_t pos;
        if (line.empty()) {
          chunked = (response->headers.find("transfer-encoding") != response->headers.end() && response->headers["transfer-encoding"] == "chunked");
          state = 2;
          break;
        }
        // split headers
        if ((pos = line.find_first_of(": ")) == std::string::npos)
          throw ParseError("Malformed header line");
        key = line.substr(0, pos);
        value = line.substr(pos+2);
        std::transform(key.begin(), key.end(), key.begin(), ::tolower);
        response->headers[key] = value;
      }
    }

    if (buffer.size() == 0) return false;

    while(buffer.size() > 0) {
      char buf[1024] = {0};

      if (chunked) {
        if (chunk_size == 0) {
          // read chunk length
          if ((pos = buffer.find('\n')) == std::string::npos) return false;
          if (pos > 1023)
            throw ParseError("Impossible chunk_size");
          buffer.copy(buf, pos);
          buf[pos]=0; // just in case...
          buffer.erase(buffer.begin(), buffer.begin()+pos+1); // remove line from buffer
          sscanf(buf, "%x", &chunk_size);
          if (!chunk_size) break; // last chunk
        } else {
          if (buffer.size() < static_cast<size_t>(chunk_size+1)) return false; // expect newline
          if (buffer.at(chunk_size) != '\n') return false; // there should be newline.
          buffer.copy(buf, chunk_size);
          buffer.erase(buffer.begin(), buffer.begin()+chunk_size+1);
          bodybuf << buf;
          chunk_size = 0;
          if (buffer.size() == 0) return false; // just in case
        }
      } else {
        bodybuf << buffer;
        buffer = "";
      }
    }

    if (chunk_size!=0) return false; // need more data

    bodybuf.flush();
    response->body = bodybuf.str();
    bodybuf.str("");
    return true;
  };
};
<commit_msg>Now handles newlines correctly<commit_after>#include "reqresp.hpp"

namespace YaHTTP {
  void Request::build(const std::string &method, const std::string &url, const std::string &params) {
    this->method = method;
    std::transform(this->method.begin(), this->method.end(), this->method.begin(), ::toupper);
    this->url.parse(url);
    this->headers["host"] = this->url.host;
    this->headers["connection"] = "close";
    this->headers["user-agent"] = "yahttp 0.1";
    this->headers["accept"] = "*/*";
    if (params.empty() == false) {
      this->headers["content-type"] = "application/x-www-form-urlencoded; charset=utf-8";
      this->headers["content-length"] = params.size();
      this->body = params;
    } else {
      this->body = "";
    }
  };

  Request::Request() {};
  Request::Request(const Response &resp) {
    method = resp.method;
    url = resp.url;
    cookies = resp.cookies;
  };
  Request::Request(const Request &req) {
    method = req.method;
    url = req.url;
    parameters = req.parameters;
    headers = req.headers;
    cookies = req.cookies;
    body = req.body;
  };
  Request::~Request() {};

  Response::Response() {};
  Response::Response(const Request &req) {
    headers["connection"] = "close";
    method = req.method;
    url = req.url;
    cookies = req.cookies;
    status = 200;
  };
  Response::Response(const Response &resp) {
    method = resp.method;
    url = resp.url;
    parameters = resp.parameters;
    headers = resp.headers;
    cookies = resp.cookies;
    body = resp.body;
    status = resp.status;
    statusText = resp.statusText;
  };
  Response::~Response() {};

  void Response::load(std::istream &is) {
    AsyncResponseLoader arl(this);
    while(is.good()) {
      char buf[1024];
      is.read(buf, 1024);
      if (is.gcount()) { // did we actually read anything
        is.clear();
        if (arl.feed(std::string(buf, is.gcount())) == true) return; // completed
      }
    }

  };

  void Response::write(std::ostream &os) const {
    os << "HTTP/1.1 " << status << " ";
    if (statusText.empty())
      os << Utility::status2text(status);
    else
      os << statusText;
    os << "\r\n";

    // write headers
    strstr_map_t::const_iterator iter = headers.begin();
    while(iter != headers.end()) {
      os << Utility::camelizeHeader(iter->first) << ": " << iter->second << "\r\n";
      iter++;
    }
    os << "\r\n";
    os << body;
  };

  void Request::load(std::istream &is) {
    AsyncRequestLoader arl(this);
    while(is.good()) {
      char buf[1024];
      is.read(buf, 1024);
      if (is.gcount()) { // did we actually read anything
        is.clear();
        if (arl.feed(std::string(buf, is.gcount())) == true) return; // completed
      }
    }
  };

  void Request::write(std::ostream &os) const {
    os << method << " " << url.path << " HTTP/1.1" << "\r\n";
    strstr_map_t::const_iterator iter = headers.begin();
    while(iter != headers.end()) {
      os << Utility::camelizeHeader(iter->first) << ": " << iter->second << "\r\n";
      iter++;
    }
    os << "\r\n";
    if (body.size()>0) {
      os << body;
    }
  };

  std::ostream& operator<<(std::ostream& os, const Response &resp) {
    resp.write(os);
    return os;
  };

  std::istream& operator>>(std::istream& is, Response &resp) {
    resp.load(is);
    return is;
  };

  std::ostream& operator<<(std::ostream& os, const Request &req) {
    req.write(os);
    return os;
  };

  std::istream& operator>>(std::istream& is, Request &req) {
    req.load(is);
    return is;
  };

  bool AsyncRequestLoader::feed(const std::string &somedata) {
    size_t pos;

    buffer.append(somedata);
    while(state < 2) {
      int cr=0;
      // need to find CRLF in buffer
      if ((pos = buffer.find_first_of("\n")) == std::string::npos) return false;
      if (buffer[pos-1]=='\r')
        cr=1;
      std::string line(buffer.begin(), buffer.begin()+pos-cr); // exclude CRLF
      buffer.erase(buffer.begin(), buffer.begin()+pos+1+cr); // remove line from buffer including CRLF

      if (state == 0) { // startup line
        std::string ver;
        std::string tmpurl;
        std::istringstream iss(line);
        iss >> request->method >> tmpurl >> ver;
        if (ver.find("HTTP/1.") != 0)
          throw ParseError("Not a HTTP 1.x request");
        // uppercase the request method
        std::transform(request->method.begin(), request->method.end(), request->method.begin(), ::toupper);
        request->url.parse(tmpurl);
        request->parameters = Utility::parseUrlParameters(request->url.parameters);
        state = 1;
      } else if (state == 1) {
        std::string key,value;
        size_t pos;
        if (line.empty()) {
          chunked = (request->headers.find("transfer-encoding") != request->headers.end() && request->headers["transfer-encoding"] == "chunked");
          // host header is optional
          if (request->headers.find("host") != request->headers.end())
            request->url.host = request->headers["host"];

          state = 2;
          break;
        }
        // split headers
        if ((pos = line.find_first_of(": ")) == std::string::npos)
          throw ParseError("Malformed line");
        key = line.substr(0, pos);
        value = line.substr(pos+2);
        std::transform(key.begin(), key.end(), key.begin(), ::tolower);
        request->headers[key] = value;
      }
    }

    // do we have content-length?
    if (!chunked) {
      if (request->headers.find("content-length") != request->headers.end()) {
        std::istringstream maxbodyS(request->headers["content-length"]);
        maxbodyS >> maxbody;
      }
      if (maxbody < 1) return true; // guess there isn't anything left.
      if (maxbody > YAHTTP_MAX_REQUEST_SIZE)
        throw ParseError("Request size exceeded");
    }

    if (buffer.size() == 0) return false;

    while(buffer.size() > 0 && bodybuf.str().size() < static_cast<size_t>(maxbody)) {
      char buf[1024] = {0};

      if (chunked) {
        if (chunk_size == 0) {
          // read chunk length
          if ((pos = buffer.find('\n')) == std::string::npos) return false;
          if (pos > 1023)
            throw ParseError("Impossible chunk_size");
          buffer.copy(buf, pos);
          buf[pos]=0; // just in case...
          buffer.erase(buffer.begin(), buffer.begin()+pos+1); // remove line from buffer
          sscanf(buf, "%x", &chunk_size);
          if (!chunk_size) break; // last chunk
        } else {
          if (buffer.size() < static_cast<size_t>(chunk_size+1)) return false; // expect newline
          if (buffer.at(chunk_size) != '\n') return false; // there should be newline.
          buffer.copy(buf, chunk_size);
          buffer.erase(buffer.begin(), buffer.begin()+chunk_size+1);
          bodybuf << buf;
          chunk_size = 0;
          if (buffer.size() == 0) return false; // just in case
        }
      } else {
        bodybuf << buffer;
        buffer = "";
      }
    }

    if (chunk_size!=0) return false; // need more data

    bodybuf.flush();
    request->body = bodybuf.str();
    bodybuf.str("");
    return true;
  };

  bool AsyncResponseLoader::feed(const std::string &somedata) {
    size_t pos;
    buffer.append(somedata);
    while(state < 2) {
      int cr=0;
      // need to find CRLF in buffer
      if ((pos = buffer.find_first_of("\n")) == std::string::npos) return false;
      if (buffer[pos-1]=='\r')
        cr=1;
      std::string line(buffer.begin(), buffer.begin()+pos-cr); // exclude CRLF
      buffer.erase(buffer.begin(), buffer.begin()+pos+1+cr); // remove line from buffer including CRLF

      if (state == 0) { // startup line
        std::string ver;
        std::istringstream iss(line);
        iss >> ver >> response->status >> response->statusText;
        if (ver.find("HTTP/1.") != 0)
          throw ParseError("Not a HTTP 1.x response");
        state = 1;
      } else if (state == 1) {
        std::string key,value;
        size_t pos;
        if (line.empty()) {
          chunked = (response->headers.find("transfer-encoding") != response->headers.end() && response->headers["transfer-encoding"] == "chunked");
          state = 2;
          break;
        }
        // split headers
        if ((pos = line.find_first_of(": ")) == std::string::npos)
          throw ParseError("Malformed header line");
        key = line.substr(0, pos);
        value = line.substr(pos+2);
        std::transform(key.begin(), key.end(), key.begin(), ::tolower);
        response->headers[key] = value;
      }
    }

    if (buffer.size() == 0) return false;

    while(buffer.size() > 0) {
      char buf[1024] = {0};

      if (chunked) {
        if (chunk_size == 0) {
          // read chunk length
          if ((pos = buffer.find('\n')) == std::string::npos) return false;
          if (pos > 1023)
            throw ParseError("Impossible chunk_size");
          buffer.copy(buf, pos);
          buf[pos]=0; // just in case...
          buffer.erase(buffer.begin(), buffer.begin()+pos+1); // remove line from buffer
          sscanf(buf, "%x", &chunk_size);
          if (!chunk_size) break; // last chunk
        } else {
          if (buffer.size() < static_cast<size_t>(chunk_size+1)) return false; // expect newline
          if (buffer.at(chunk_size) != '\n') return false; // there should be newline.
          buffer.copy(buf, chunk_size);
          buffer.erase(buffer.begin(), buffer.begin()+chunk_size+1);
          bodybuf << buf;
          chunk_size = 0;
          if (buffer.size() == 0) return false; // just in case
        }
      } else {
        bodybuf << buffer;
        buffer = "";
      }
    }

    if (chunk_size!=0) return false; // need more data

    bodybuf.flush();
    response->body = bodybuf.str();
    bodybuf.str("");
    return true;
  };
};
<|endoftext|>


<commit_before>/*
 * Open Chinese Convert
 *
 * Copyright 2010-2014 BYVoid <byvoid@byvoid.com>
 *
 * 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 "CmdLineOutput.hpp"
#include "Config.hpp"
#include "Converter.hpp"

using opencc::Config;
using opencc::Exception;
using opencc::FileNotFound;
using opencc::FileNotWritable;
using opencc::Optional;

void ShowVersion() {
  printf("\n");
  printf("Open Chinese Convert (OpenCC) Command Line Tool\n");
  printf("Version %s\n", VERSION);
  printf("\n");
  printf("Author: %s\n", "Carbo Kuo <byvoid@byvoid.com>");
  printf("Bug Report: %s\n", "http://github.com/BYVoid/OpenCC/issues");
  printf("\n");
}

void ShowUsage() {
  ShowVersion();
  printf("Usage:\n");
  printf(" opencc [Options]\n");
  printf("\n");
  printf("Options:\n");
  printf(" -i [file], --input=[file]   Read original text from [file].\n");
  printf(" -o [file], --output=[file]  Write converted text to [file].\n");
  printf(" -c [file], --config=[file]  Load configuration from [file].\n");
  printf(" -v, --version               Print version and build information.\n");
  printf(" -h, --help                  Print this help.\n");
  printf("\n");
  printf("With no input file, reads stdin and writes to stdout.\n");
  printf("By default configuration is simplified to traditional.\n");
  printf("\n");
}

std::istream& GetInputStream(const Optional<string>& inputFileName) {
  if (inputFileName.IsNull()) {
    return std::cin;
  } else {
    std::ifstream* stream = new std::ifstream(inputFileName.Get());
    if (!stream->is_open()) {
      throw FileNotFound(inputFileName.Get());
    }
    return *stream;
  }
}

std::ostream& GetOutputStream(const Optional<string>& outputFileName) {
  if (outputFileName.IsNull()) {
    return std::cout;
  } else {
    std::ofstream* stream = new std::ofstream(outputFileName.Get());
    if (!stream->is_open()) {
      throw FileNotWritable(outputFileName.Get());
    }
    return *stream;
  }
}

void Convert(const Optional<string>& inputFileName,
             const Optional<string>& outputFileName,
             const string& configFileName) {
  Config config;
  auto converter = config.NewFromFile(configFileName);
  std::istream& inputStream = GetInputStream(inputFileName);
  std::ostream& outputStream = GetOutputStream(outputFileName);
  while (!inputStream.eof()) {
    string line;
    std::getline(inputStream, line);
    string converted = converter->Convert(line);
    outputStream << converted << std::endl;
    outputStream.flush();
  }
}

int main(int argc, const char* argv[]) {
  try {
    TCLAP::CmdLine cmd("Open Chinese Convert (OpenCC) Command Line Tool",
                       ' ',
                       VERSION);
    CmdLineOutput cmdLineOutput;
    cmd.setOutput(&cmdLineOutput);

    TCLAP::ValueArg<string> configArg("c", "config",
                                      "Configuration file",
                                      false /* required */,
                                      "s2t.json" /* default */,
                                      "file" /* type */,
                                      cmd);
    TCLAP::ValueArg<string> outputArg("o", "output",
                                      "Write converted text to",
                                      false /* required */,
                                      "" /* default */,
                                      "file" /* type */,
                                      cmd);
    TCLAP::ValueArg<string> inputArg("i", "input",
                                     "Read original text from",
                                     false /* required */,
                                     "" /* default */,
                                     "file" /* type */,
                                     cmd);
    cmd.parse(argc, argv);
    Optional<string> inputFileName = Optional<string>::Null();
    Optional<string> outputFileName = Optional<string>::Null();
    string configFileName = configArg.getValue();
    if (inputArg.isSet()) {
      inputFileName = Optional<string>(inputArg.getValue());
    }
    if (outputArg.isSet()) {
      outputFileName = Optional<string>(outputArg.getValue());
    }
    Convert(inputFileName, outputFileName, configFileName);
  } catch (TCLAP::ArgException& e) {
    std::cerr << "error: " << e.error()
        << " for arg " << e.argId() << std::endl;
  } catch (Exception& e) {
    std::cerr << e.what() << std::endl;
  }
  return 0;
}
<commit_msg>Stop flushing if "-o" is set in CommandLine<commit_after>/*
 * Open Chinese Convert
 *
 * Copyright 2010-2014 BYVoid <byvoid@byvoid.com>
 *
 * 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 "CmdLineOutput.hpp"
#include "Config.hpp"
#include "Converter.hpp"

using opencc::Config;
using opencc::Exception;
using opencc::FileNotFound;
using opencc::FileNotWritable;
using opencc::Optional;

std::istream& GetInputStream(const Optional<string>& inputFileName) {
  if (inputFileName.IsNull()) {
    return std::cin;
  } else {
    std::ifstream* stream = new std::ifstream(inputFileName.Get());
    if (!stream->is_open()) {
      throw FileNotFound(inputFileName.Get());
    }
    return *stream;
  }
}

std::ostream& GetOutputStream(const Optional<string>& outputFileName) {
  if (outputFileName.IsNull()) {
    return std::cout;
  } else {
    std::ofstream* stream = new std::ofstream(outputFileName.Get());
    if (!stream->is_open()) {
      throw FileNotWritable(outputFileName.Get());
    }
    return *stream;
  }
}

string Read(std::istream& inputStream, bool lineByLine) {
  // TODO block read
  string line;
  std::getline(inputStream, line);
  return line;
}

void Convert(const Optional<string>& inputFileName,
             const Optional<string>& outputFileName,
             const string& configFileName,
             const bool noFlush) {
  Config config;
  auto converter = config.NewFromFile(configFileName);
  std::istream& inputStream = GetInputStream(inputFileName);
  std::ostream& outputStream = GetOutputStream(outputFileName);
  bool lineByLine = inputFileName.IsNull();
  while (!inputStream.eof()) {
    const string& text = Read(inputStream, lineByLine);
    const string& converted = converter->Convert(text);
    outputStream << converted << '\n';
    if (!noFlush) {
      // Flush every line if the output stream is stdout.
      outputStream.flush();
    }
  }
  outputStream.flush();
}

int main(int argc, const char* argv[]) {
  try {
    TCLAP::CmdLine cmd("Open Chinese Convert (OpenCC) Command Line Tool",
                       ' ',
                       VERSION);
    CmdLineOutput cmdLineOutput;
    cmd.setOutput(&cmdLineOutput);

    TCLAP::ValueArg<string> configArg("c", "config",
                                      "Configuration file",
                                      false /* required */,
                                      "s2t.json" /* default */,
                                      "file" /* type */,
                                      cmd);
    TCLAP::ValueArg<string> outputArg("o", "output",
                                      "Write converted text to",
                                      false /* required */,
                                      "" /* default */,
                                      "file" /* type */,
                                      cmd);
    TCLAP::ValueArg<string> inputArg("i", "input",
                                     "Read original text from",
                                     false /* required */,
                                     "" /* default */,
                                     "file" /* type */,
                                     cmd);
    TCLAP::ValueArg<bool> noFlushArg("", "noflush",
                                     "Disable flush for every line",
                                     false /* required */,
                                     false /* default */,
                                     "bool" /* type */,
                                     cmd);
    cmd.parse(argc, argv);
    Optional<string> inputFileName = Optional<string>::Null();
    Optional<string> outputFileName = Optional<string>::Null();
    string configFileName = configArg.getValue();
    bool noFlush = noFlushArg.getValue();
    if (inputArg.isSet()) {
      inputFileName = Optional<string>(inputArg.getValue());
    }
    if (outputArg.isSet()) {
      outputFileName = Optional<string>(outputArg.getValue());
      noFlush = true;
    }
    Convert(inputFileName, outputFileName, configFileName, noFlush);
  } catch (TCLAP::ArgException& e) {
    std::cerr << "error: " << e.error()
        << " for arg " << e.argId() << std::endl;
  } catch (Exception& e) {
    std::cerr << e.what() << std::endl;
  }
  return 0;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: Currency.cxx,v $
 *
 *  $Revision: 1.13 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 22:35:48 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _FORMS_CURRENCY_HXX_
#include "Currency.hxx"
#endif

#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _UNOTOOLS_LOCALEDATAWRAPPER_HXX
#include <unotools/localedatawrapper.hxx>
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif
#ifndef INCLUDED_SVTOOLS_SYSLOCALE_HXX
#include <svtools/syslocale.hxx>
#endif

//.........................................................................
namespace frm
{
//.........................................................................
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::sdb;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::sdbcx;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::form;
using namespace ::com::sun::star::awt;
using namespace ::com::sun::star::io;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::util;

//==================================================================
// OCurrencyControl
//==================================================================
//------------------------------------------------------------------
OCurrencyControl::OCurrencyControl(const Reference<XMultiServiceFactory>& _rxFactory)
    :OBoundControl(_rxFactory, VCL_CONTROL_CURRENCYFIELD)
{
}

//------------------------------------------------------------------
InterfaceRef SAL_CALL OCurrencyControl_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory)
{
    return *(new OCurrencyControl(_rxFactory));
}

//------------------------------------------------------------------------------
Sequence<Type> OCurrencyControl::_getTypes()
{
    return OBoundControl::_getTypes();
}

//------------------------------------------------------------------------------
StringSequence SAL_CALL OCurrencyControl::getSupportedServiceNames() throw()
{
    StringSequence aSupported = OBoundControl::getSupportedServiceNames();
    aSupported.realloc(aSupported.getLength() + 1);

    ::rtl::OUString*pArray = aSupported.getArray();
    pArray[aSupported.getLength()-1] = FRM_SUN_CONTROL_CURRENCYFIELD;
    return aSupported;
}

//==================================================================
// OCurrencyModel
//==================================================================
//------------------------------------------------------------------
InterfaceRef SAL_CALL OCurrencyModel_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory)
{
    return *(new OCurrencyModel(_rxFactory));
}

//------------------------------------------------------------------------------
Sequence<Type> OCurrencyModel::_getTypes()
{
    return OEditBaseModel::_getTypes();
}

//------------------------------------------------------------------
void OCurrencyModel::implConstruct()
{
    if (m_xAggregateSet.is())
    {
        try
        {
            // get the system international informations
            const LocaleDataWrapper& aLocaleInfo = SvtSysLocale().GetLocaleData();

            ::rtl::OUString sCurrencySymbol;
            sal_Bool bPrependCurrencySymbol;
            switch ( aLocaleInfo.getCurrPositiveFormat() )
            {
                case 0: // $1
                    sCurrencySymbol = String(aLocaleInfo.getCurrSymbol());
                    bPrependCurrencySymbol = sal_True;
                    break;
                case 1: // 1$
                    sCurrencySymbol = String(aLocaleInfo.getCurrSymbol());
                    bPrependCurrencySymbol = sal_False;
                    break;
                case 2: // $ 1
                    sCurrencySymbol = ::rtl::OUString(String(aLocaleInfo.getCurrSymbol())) + ::rtl::OUString::createFromAscii(" ");
                    bPrependCurrencySymbol = sal_True;
                    break;
                case 3: // 1 $
                    sCurrencySymbol = ::rtl::OUString::createFromAscii(" ") + ::rtl::OUString(String(aLocaleInfo.getCurrSymbol()));
                    bPrependCurrencySymbol = sal_False;
                    break;
            }
            if (sCurrencySymbol.getLength())
            {
                m_xAggregateSet->setPropertyValue(PROPERTY_CURRENCYSYMBOL, makeAny(sCurrencySymbol));
                m_xAggregateSet->setPropertyValue(PROPERTY_CURRSYM_POSITION, makeAny(bPrependCurrencySymbol));
            }
        }
        catch(Exception&)
        {
            DBG_ERROR( "OCurrencyModel::implConstruct: caught an exception while initializing the aggregate!" );
        }
    }
}

//------------------------------------------------------------------
DBG_NAME( OCurrencyModel )
//------------------------------------------------------------------
OCurrencyModel::OCurrencyModel(const Reference<XMultiServiceFactory>& _rxFactory)
    :OEditBaseModel( _rxFactory, VCL_CONTROLMODEL_CURRENCYFIELD, FRM_SUN_CONTROL_CURRENCYFIELD, sal_False, sal_True )
                                    // use the old control name for compytibility reasons
{
    DBG_CTOR( OCurrencyModel, NULL );

    m_nClassId = FormComponentType::CURRENCYFIELD;
    initValueProperty( PROPERTY_VALUE, PROPERTY_ID_VALUE );

    implConstruct();
}

//------------------------------------------------------------------
OCurrencyModel::OCurrencyModel( const OCurrencyModel* _pOriginal, const Reference<XMultiServiceFactory>& _rxFactory )
    :OEditBaseModel( _pOriginal, _rxFactory )
{
    DBG_CTOR( OCurrencyModel, NULL );
    implConstruct();
}

//------------------------------------------------------------------
OCurrencyModel::~OCurrencyModel()
{
    DBG_DTOR( OCurrencyModel, NULL );
}

// XCloneable
//------------------------------------------------------------------------------
IMPLEMENT_DEFAULT_CLONING( OCurrencyModel )

// XServiceInfo
//------------------------------------------------------------------------------
StringSequence SAL_CALL OCurrencyModel::getSupportedServiceNames() throw()
{
    StringSequence aSupported = OBoundControlModel::getSupportedServiceNames();

    sal_Int32 nOldLen = aSupported.getLength();
    aSupported.realloc( nOldLen + 4 );
    ::rtl::OUString* pStoreTo = aSupported.getArray() + nOldLen;

    *pStoreTo++ = DATA_AWARE_CONTROL_MODEL;
    *pStoreTo++ = VALIDATABLE_CONTROL_MODEL;

    *pStoreTo++ = FRM_SUN_COMPONENT_CURRENCYFIELD;
    *pStoreTo++ = FRM_SUN_COMPONENT_DATABASE_CURRENCYFIELD;

    return aSupported;
}

//------------------------------------------------------------------------------
Reference<XPropertySetInfo> SAL_CALL OCurrencyModel::getPropertySetInfo() throw( RuntimeException )
{
    Reference<XPropertySetInfo>  xInfo( createPropertySetInfo( getInfoHelper() ) );
    return xInfo;
}

//------------------------------------------------------------------------------
void OCurrencyModel::fillProperties(
        Sequence< Property >& _rProps,
        Sequence< Property >& _rAggregateProps ) const
{
    BEGIN_DESCRIBE_PROPERTIES( 2, OEditBaseModel )
        // Value auf transient setzen
//      ModifyPropertyAttributes(_rAggregateProps, PROPERTY_VALUE, PropertyAttribute::TRANSIENT, 0);

        DECL_PROP3(DEFAULT_VALUE,       double,             BOUND, MAYBEDEFAULT, MAYBEVOID);
        DECL_PROP1(TABINDEX,        sal_Int16,              BOUND);
    END_DESCRIBE_PROPERTIES();
}

//------------------------------------------------------------------------------
::cppu::IPropertyArrayHelper& OCurrencyModel::getInfoHelper()
{
    return *const_cast<OCurrencyModel*>(this)->getArrayHelper();
}

//------------------------------------------------------------------------------
::rtl::OUString SAL_CALL OCurrencyModel::getServiceName() throw ( ::com::sun::star::uno::RuntimeException)
{
    return FRM_COMPONENT_CURRENCYFIELD; // old (non-sun) name for compatibility !
}

//------------------------------------------------------------------------------
sal_Bool OCurrencyModel::commitControlValueToDbColumn( bool _bPostReset )
{
    Any aControlValue( m_xAggregateFastSet->getFastPropertyValue( getValuePropertyAggHandle() ) );
    if ( !compare( aControlValue, m_aSaveValue ) )
    {
        if ( aControlValue.getValueType().getTypeClass() == TypeClass_VOID )
            m_xColumnUpdate->updateNull();
        else
        {
            try
            {
                m_xColumnUpdate->updateDouble( getDouble( aControlValue ) );
            }
            catch(Exception&)
            {
                return sal_False;
            }
        }
        m_aSaveValue = aControlValue;
    }
    return sal_True;
}

//------------------------------------------------------------------------------
Any OCurrencyModel::translateDbColumnToControlValue()
{
    m_aSaveValue <<= m_xColumn->getDouble();
    if ( m_xColumn->wasNull() )
        m_aSaveValue.clear();
    return m_aSaveValue;
}

// XReset
//------------------------------------------------------------------------------
Any OCurrencyModel::getDefaultForReset() const
{
    Any aValue;
    if ( m_aDefault.getValueType().getTypeClass() == TypeClass_DOUBLE )
        aValue = m_aDefault;

    return aValue;
}

//.........................................................................
}   // namespace frm
//.........................................................................

<commit_msg>INTEGRATION: CWS warnings01 (1.13.68); FILE MERGED 2006/03/14 15:20:25 fs 1.13.68.1: #i57457# warning-free code<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: Currency.cxx,v $
 *
 *  $Revision: 1.14 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-19 12:46:41 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _FORMS_CURRENCY_HXX_
#include "Currency.hxx"
#endif

#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _UNOTOOLS_LOCALEDATAWRAPPER_HXX
#include <unotools/localedatawrapper.hxx>
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif
#ifndef INCLUDED_SVTOOLS_SYSLOCALE_HXX
#include <svtools/syslocale.hxx>
#endif

//.........................................................................
namespace frm
{
//.........................................................................
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::sdb;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::sdbcx;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::form;
using namespace ::com::sun::star::awt;
using namespace ::com::sun::star::io;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::util;

//==================================================================
// OCurrencyControl
//==================================================================
//------------------------------------------------------------------
OCurrencyControl::OCurrencyControl(const Reference<XMultiServiceFactory>& _rxFactory)
    :OBoundControl(_rxFactory, VCL_CONTROL_CURRENCYFIELD)
{
}

//------------------------------------------------------------------
InterfaceRef SAL_CALL OCurrencyControl_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory)
{
    return *(new OCurrencyControl(_rxFactory));
}

//------------------------------------------------------------------------------
Sequence<Type> OCurrencyControl::_getTypes()
{
    return OBoundControl::_getTypes();
}

//------------------------------------------------------------------------------
StringSequence SAL_CALL OCurrencyControl::getSupportedServiceNames() throw()
{
    StringSequence aSupported = OBoundControl::getSupportedServiceNames();
    aSupported.realloc(aSupported.getLength() + 1);

    ::rtl::OUString*pArray = aSupported.getArray();
    pArray[aSupported.getLength()-1] = FRM_SUN_CONTROL_CURRENCYFIELD;
    return aSupported;
}

//==================================================================
// OCurrencyModel
//==================================================================
//------------------------------------------------------------------
InterfaceRef SAL_CALL OCurrencyModel_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory)
{
    return *(new OCurrencyModel(_rxFactory));
}

//------------------------------------------------------------------------------
Sequence<Type> OCurrencyModel::_getTypes()
{
    return OEditBaseModel::_getTypes();
}

//------------------------------------------------------------------
void OCurrencyModel::implConstruct()
{
    if (m_xAggregateSet.is())
    {
        try
        {
            // get the system international informations
            const LocaleDataWrapper& aLocaleInfo = SvtSysLocale().GetLocaleData();

            ::rtl::OUString sCurrencySymbol;
            sal_Bool bPrependCurrencySymbol;
            switch ( aLocaleInfo.getCurrPositiveFormat() )
            {
                case 0: // $1
                    sCurrencySymbol = String(aLocaleInfo.getCurrSymbol());
                    bPrependCurrencySymbol = sal_True;
                    break;
                case 1: // 1$
                    sCurrencySymbol = String(aLocaleInfo.getCurrSymbol());
                    bPrependCurrencySymbol = sal_False;
                    break;
                case 2: // $ 1
                    sCurrencySymbol = ::rtl::OUString(String(aLocaleInfo.getCurrSymbol())) + ::rtl::OUString::createFromAscii(" ");
                    bPrependCurrencySymbol = sal_True;
                    break;
                case 3: // 1 $
                    sCurrencySymbol = ::rtl::OUString::createFromAscii(" ") + ::rtl::OUString(String(aLocaleInfo.getCurrSymbol()));
                    bPrependCurrencySymbol = sal_False;
                    break;
            }
            if (sCurrencySymbol.getLength())
            {
                m_xAggregateSet->setPropertyValue(PROPERTY_CURRENCYSYMBOL, makeAny(sCurrencySymbol));
                m_xAggregateSet->setPropertyValue(PROPERTY_CURRSYM_POSITION, makeAny(bPrependCurrencySymbol));
            }
        }
        catch(Exception&)
        {
            DBG_ERROR( "OCurrencyModel::implConstruct: caught an exception while initializing the aggregate!" );
        }
    }
}

//------------------------------------------------------------------
DBG_NAME( OCurrencyModel )
//------------------------------------------------------------------
OCurrencyModel::OCurrencyModel(const Reference<XMultiServiceFactory>& _rxFactory)
    :OEditBaseModel( _rxFactory, VCL_CONTROLMODEL_CURRENCYFIELD, FRM_SUN_CONTROL_CURRENCYFIELD, sal_False, sal_True )
                                    // use the old control name for compytibility reasons
{
    DBG_CTOR( OCurrencyModel, NULL );

    m_nClassId = FormComponentType::CURRENCYFIELD;
    initValueProperty( PROPERTY_VALUE, PROPERTY_ID_VALUE );

    implConstruct();
}

//------------------------------------------------------------------
OCurrencyModel::OCurrencyModel( const OCurrencyModel* _pOriginal, const Reference<XMultiServiceFactory>& _rxFactory )
    :OEditBaseModel( _pOriginal, _rxFactory )
{
    DBG_CTOR( OCurrencyModel, NULL );
    implConstruct();
}

//------------------------------------------------------------------
OCurrencyModel::~OCurrencyModel()
{
    DBG_DTOR( OCurrencyModel, NULL );
}

// XCloneable
//------------------------------------------------------------------------------
IMPLEMENT_DEFAULT_CLONING( OCurrencyModel )

// XServiceInfo
//------------------------------------------------------------------------------
StringSequence SAL_CALL OCurrencyModel::getSupportedServiceNames() throw()
{
    StringSequence aSupported = OBoundControlModel::getSupportedServiceNames();

    sal_Int32 nOldLen = aSupported.getLength();
    aSupported.realloc( nOldLen + 4 );
    ::rtl::OUString* pStoreTo = aSupported.getArray() + nOldLen;

    *pStoreTo++ = DATA_AWARE_CONTROL_MODEL;
    *pStoreTo++ = VALIDATABLE_CONTROL_MODEL;

    *pStoreTo++ = FRM_SUN_COMPONENT_CURRENCYFIELD;
    *pStoreTo++ = FRM_SUN_COMPONENT_DATABASE_CURRENCYFIELD;

    return aSupported;
}

//------------------------------------------------------------------------------
Reference<XPropertySetInfo> SAL_CALL OCurrencyModel::getPropertySetInfo() throw( RuntimeException )
{
    Reference<XPropertySetInfo>  xInfo( createPropertySetInfo( getInfoHelper() ) );
    return xInfo;
}

//------------------------------------------------------------------------------
void OCurrencyModel::fillProperties(
        Sequence< Property >& _rProps,
        Sequence< Property >& _rAggregateProps ) const
{
    BEGIN_DESCRIBE_PROPERTIES( 2, OEditBaseModel )
        // Value auf transient setzen
//      ModifyPropertyAttributes(_rAggregateProps, PROPERTY_VALUE, PropertyAttribute::TRANSIENT, 0);

        DECL_PROP3(DEFAULT_VALUE,       double,             BOUND, MAYBEDEFAULT, MAYBEVOID);
        DECL_PROP1(TABINDEX,        sal_Int16,              BOUND);
    END_DESCRIBE_PROPERTIES();
}

//------------------------------------------------------------------------------
::cppu::IPropertyArrayHelper& OCurrencyModel::getInfoHelper()
{
    return *const_cast<OCurrencyModel*>(this)->getArrayHelper();
}

//------------------------------------------------------------------------------
::rtl::OUString SAL_CALL OCurrencyModel::getServiceName() throw ( ::com::sun::star::uno::RuntimeException)
{
    return FRM_COMPONENT_CURRENCYFIELD; // old (non-sun) name for compatibility !
}

//------------------------------------------------------------------------------
sal_Bool OCurrencyModel::commitControlValueToDbColumn( bool /*_bPostReset*/ )
{
    Any aControlValue( m_xAggregateFastSet->getFastPropertyValue( getValuePropertyAggHandle() ) );
    if ( !compare( aControlValue, m_aSaveValue ) )
    {
        if ( aControlValue.getValueType().getTypeClass() == TypeClass_VOID )
            m_xColumnUpdate->updateNull();
        else
        {
            try
            {
                m_xColumnUpdate->updateDouble( getDouble( aControlValue ) );
            }
            catch(Exception&)
            {
                return sal_False;
            }
        }
        m_aSaveValue = aControlValue;
    }
    return sal_True;
}

//------------------------------------------------------------------------------
Any OCurrencyModel::translateDbColumnToControlValue()
{
    m_aSaveValue <<= m_xColumn->getDouble();
    if ( m_xColumn->wasNull() )
        m_aSaveValue.clear();
    return m_aSaveValue;
}

// XReset
//------------------------------------------------------------------------------
Any OCurrencyModel::getDefaultForReset() const
{
    Any aValue;
    if ( m_aDefault.getValueType().getTypeClass() == TypeClass_DOUBLE )
        aValue = m_aDefault;

    return aValue;
}

//.........................................................................
}   // namespace frm
//.........................................................................

<|endoftext|>


<commit_before>/*
 *  yosys -- Yosys Open SYnthesis Suite
 *
 *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
 *
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#include "kernel/yosys.h"
#include "kernel/sigtools.h"

USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN

template<class T> bool includes(const T &lhs, const T &rhs) {
	return std::includes(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
}
#include "passes/pmgen/ice40_dsp_pm.h"

void create_ice40_dsp(ice40_dsp_pm &pm)
{
	auto &st = pm.st_ice40_dsp;

#if 0
	log("\n");
	log("ffA:    %s\n", log_id(st.ffA, "--"));
	log("ffB:    %s\n", log_id(st.ffB, "--"));
	log("mul:    %s\n", log_id(st.mul, "--"));
	log("ffH:    %s\n", log_id(st.ffH, "--"));
	log("addAB:  %s\n", log_id(st.addAB, "--"));
	log("muxAB:  %s\n", log_id(st.muxAB, "--"));
	log("ffO_lo: %s\n", log_id(st.ffO_lo, "--"));
	log("ffO_hi: %s\n", log_id(st.ffO_hi, "--"));
#endif

	log("Checking %s.%s for iCE40 DSP inference.\n", log_id(pm.module), log_id(st.mul));

	if (GetSize(st.sigA) > 16) {
		log("  input A (%s) is too large (%d > 16).\n", log_signal(st.sigA), GetSize(st.sigA));
		return;
	}

	if (GetSize(st.sigB) > 16) {
		log("  input B (%s) is too large (%d > 16).\n", log_signal(st.sigB), GetSize(st.sigB));
		return;
	}

	if (GetSize(st.sigO) > 33) {
		log("  adder/accumulator (%s) is too large (%d > 33).\n", log_signal(st.sigO), GetSize(st.sigO));
		return;
	}

	if (GetSize(st.sigH) > 32) {
		log("  output (%s) is too large (%d > 32).\n", log_signal(st.sigH), GetSize(st.sigH));
		return;
	}

	log("  replacing %s with SB_MAC16 cell.\n", log_id(st.mul->type));

	Cell *cell = pm.module->addCell(NEW_ID, "\\SB_MAC16");
	pm.module->swap_names(cell, st.mul);

	// SB_MAC16 Input Interface
	SigSpec A = st.sigA;
	log_assert(GetSize(A) == 16);

	SigSpec B = st.sigB;
	log_assert(GetSize(B) == 16);

	SigSpec CD = st.sigCD;
	if (CD.empty())
		CD = RTLIL::Const(0, 32);
	else
		log_assert(GetSize(CD) == 32);

	cell->setPort("\\A", A);
	cell->setPort("\\B", B);
	cell->setPort("\\C", CD.extract(16, 16));
	cell->setPort("\\D", CD.extract(0, 16));

	cell->setParam("\\A_REG", st.ffA ? State::S1 : State::S0);
	cell->setParam("\\B_REG", st.ffB ? State::S1 : State::S0);

	cell->setPort("\\AHOLD", State::S0);
	cell->setPort("\\BHOLD", State::S0);
	cell->setPort("\\CHOLD", State::S0);
	cell->setPort("\\DHOLD", State::S0);

	cell->setPort("\\IRSTTOP", State::S0);
	cell->setPort("\\IRSTBOT", State::S0);

	if (st.clock != SigBit())
	{
		cell->setPort("\\CLK", st.clock);
		cell->setPort("\\CE", State::S1);
		cell->setParam("\\NEG_TRIGGER", st.clock_pol ? State::S0 : State::S1);

		log("  clock: %s (%s)", log_signal(st.clock), st.clock_pol ? "posedge" : "negedge");

		if (st.ffA)
			log(" ffA:%s", log_id(st.ffA));

		if (st.ffB)
			log(" ffB:%s", log_id(st.ffB));

		if (st.ffH)
			log(" ffH:%s", log_id(st.ffH));

		if (st.ffO_lo)
			log(" ffO_lo:%s", log_id(st.ffO_lo));
		if (st.ffO_hi)
			log(" ffO_hi:%s", log_id(st.ffO_hi));

		log("\n");
	}
	else
	{
		cell->setPort("\\CLK", State::S0);
		cell->setPort("\\CE", State::S0);
		cell->setParam("\\NEG_TRIGGER", State::S0);
	}

	// SB_MAC16 Cascade Interface

	cell->setPort("\\SIGNEXTIN", State::Sx);
	cell->setPort("\\SIGNEXTOUT", pm.module->addWire(NEW_ID));

	cell->setPort("\\CI", State::Sx);

	cell->setPort("\\ACCUMCI", State::Sx);
	cell->setPort("\\ACCUMCO", pm.module->addWire(NEW_ID));

	// SB_MAC16 Output Interface

	SigSpec O = st.sigO;
	int O_width = GetSize(O);
	if (O_width == 33) {
		log_assert(st.addAB);
		// If we have a signed multiply-add, then perform sign extension
		// TODO: Need to check CD[31:16] is sign extension of CD[15:0]?
		if (st.addAB->getParam("\\A_SIGNED").as_bool() && st.addAB->getParam("\\B_SIGNED").as_bool())
			pm.module->connect(O[-1], O[-2]);
		else
			cell->setPort("\\CO", O[-1]);
		O.remove(O_width-1);
	}
	else
		cell->setPort("\\CO", pm.module->addWire(NEW_ID));
	log_assert(GetSize(O) <= 32);
	if (GetSize(O) < 32)
		O.append(pm.module->addWire(NEW_ID, 32-GetSize(O)));

	cell->setPort("\\O", O);

	bool accum = false;
	if (st.addAB) {
		if (st.addA)
			accum = (st.ffO_lo && st.ffO_hi && st.addAB->getPort("\\B") == st.sigO);
		else if (st.addB)
			accum = (st.ffO_lo && st.ffO_hi && st.addAB->getPort("\\A") == st.sigO);
		else log_abort();
		if (accum)
			log("  accumulator %s (%s)\n", log_id(st.addAB), log_id(st.addAB->type));
		else
			log("  adder %s (%s)\n", log_id(st.addAB), log_id(st.addAB->type));
		cell->setPort("\\ADDSUBTOP", st.addAB->type == "$add" ? State::S0 : State::S1);
		cell->setPort("\\ADDSUBBOT", st.addAB->type == "$add" ? State::S0 : State::S1);
	} else {
		cell->setPort("\\ADDSUBTOP", State::S0);
		cell->setPort("\\ADDSUBBOT", State::S0);
	}

	cell->setPort("\\ORSTTOP", State::S0);
	cell->setPort("\\ORSTBOT", State::S0);

	cell->setPort("\\OHOLDTOP", State::S0);
	cell->setPort("\\OHOLDBOT", State::S0);

	SigSpec acc_reset = State::S0;
	if (st.muxA)
		acc_reset = st.muxA->getPort("\\S");
	if (st.muxB)
		acc_reset = pm.module->Not(NEW_ID, st.muxB->getPort("\\S"));

	cell->setPort("\\OLOADTOP", acc_reset);
	cell->setPort("\\OLOADBOT", acc_reset);

	// SB_MAC16 Remaining Parameters

	cell->setParam("\\C_REG", State::S0);
	cell->setParam("\\D_REG", State::S0);

	cell->setParam("\\TOP_8x8_MULT_REG", st.ffH ? State::S1 : State::S0);
	cell->setParam("\\BOT_8x8_MULT_REG", st.ffH ? State::S1 : State::S0);
	cell->setParam("\\PIPELINE_16x16_MULT_REG1", st.ffH ? State::S1 : State::S0);
	cell->setParam("\\PIPELINE_16x16_MULT_REG2", State::S0);

	cell->setParam("\\TOPOUTPUT_SELECT", Const(st.ffO_hi ? 1 : (st.addAB ? 0 : 3), 2));
	cell->setParam("\\TOPADDSUB_LOWERINPUT", Const(2, 2));
	cell->setParam("\\TOPADDSUB_UPPERINPUT", accum ? State::S0 : State::S1);
	cell->setParam("\\TOPADDSUB_CARRYSELECT", Const(3, 2));

	cell->setParam("\\BOTOUTPUT_SELECT", Const(st.ffO_lo ? 1 : (st.addAB ? 0 : 3), 2));
	cell->setParam("\\BOTADDSUB_LOWERINPUT", Const(2, 2));
	cell->setParam("\\BOTADDSUB_UPPERINPUT", accum ? State::S0 : State::S1);
	cell->setParam("\\BOTADDSUB_CARRYSELECT", Const(0, 2));

	cell->setParam("\\MODE_8x8", State::S0);
	cell->setParam("\\A_SIGNED", st.mul->getParam("\\A_SIGNED").as_bool());
	cell->setParam("\\B_SIGNED", st.mul->getParam("\\B_SIGNED").as_bool());

	pm.autoremove(st.mul);
	pm.autoremove(st.ffH);
	pm.autoremove(st.addAB);
	if (st.ffO_lo) {
			SigSpec O = st.sigO.extract(0,GetSize(st.ffO_lo));
			st.ffO_lo->connections_.at("\\Q").replace(O, pm.module->addWire(NEW_ID, GetSize(O)));
	}
	if (st.ffO_hi) {
			SigSpec O = st.sigO.extract(16,GetSize(st.ffo_hi));
			st.ffO_hi->connections_.at("\\Q").replace(O, pm.module->addWire(NEW_ID, GetSize(O)));
	}
}

struct Ice40DspPass : public Pass {
	Ice40DspPass() : Pass("ice40_dsp", "iCE40: map multipliers") { }
	void help() YS_OVERRIDE
	{
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
		log("\n");
		log("    ice40_dsp [options] [selection]\n");
		log("\n");
		log("Map multipliers and multiply-accumulate blocks to iCE40 DSP resources.\n");
		log("\n");
	}
	void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
	{
		log_header(design, "Executing ICE40_DSP pass (map multipliers).\n");

		size_t argidx;
		for (argidx = 1; argidx < args.size(); argidx++)
		{
			// if (args[argidx] == "-singleton") {
			// 	singleton_mode = true;
			// 	continue;
			// }
			break;
		}
		extra_args(args, argidx, design);

		for (auto module : design->selected_modules())
			ice40_dsp_pm(module, module->selected_cells()).run_ice40_dsp(create_ice40_dsp);
	}
} Ice40DspPass;

PRIVATE_NAMESPACE_END
<commit_msg>Fix compile error<commit_after>/*
 *  yosys -- Yosys Open SYnthesis Suite
 *
 *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
 *
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#include "kernel/yosys.h"
#include "kernel/sigtools.h"

USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN

template<class T> bool includes(const T &lhs, const T &rhs) {
	return std::includes(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
}
#include "passes/pmgen/ice40_dsp_pm.h"

void create_ice40_dsp(ice40_dsp_pm &pm)
{
	auto &st = pm.st_ice40_dsp;

#if 0
	log("\n");
	log("ffA:    %s\n", log_id(st.ffA, "--"));
	log("ffB:    %s\n", log_id(st.ffB, "--"));
	log("mul:    %s\n", log_id(st.mul, "--"));
	log("ffH:    %s\n", log_id(st.ffH, "--"));
	log("addAB:  %s\n", log_id(st.addAB, "--"));
	log("muxAB:  %s\n", log_id(st.muxAB, "--"));
	log("ffO_lo: %s\n", log_id(st.ffO_lo, "--"));
	log("ffO_hi: %s\n", log_id(st.ffO_hi, "--"));
#endif

	log("Checking %s.%s for iCE40 DSP inference.\n", log_id(pm.module), log_id(st.mul));

	if (GetSize(st.sigA) > 16) {
		log("  input A (%s) is too large (%d > 16).\n", log_signal(st.sigA), GetSize(st.sigA));
		return;
	}

	if (GetSize(st.sigB) > 16) {
		log("  input B (%s) is too large (%d > 16).\n", log_signal(st.sigB), GetSize(st.sigB));
		return;
	}

	if (GetSize(st.sigO) > 33) {
		log("  adder/accumulator (%s) is too large (%d > 33).\n", log_signal(st.sigO), GetSize(st.sigO));
		return;
	}

	if (GetSize(st.sigH) > 32) {
		log("  output (%s) is too large (%d > 32).\n", log_signal(st.sigH), GetSize(st.sigH));
		return;
	}

	log("  replacing %s with SB_MAC16 cell.\n", log_id(st.mul->type));

	Cell *cell = pm.module->addCell(NEW_ID, "\\SB_MAC16");
	pm.module->swap_names(cell, st.mul);

	// SB_MAC16 Input Interface
	SigSpec A = st.sigA;
	log_assert(GetSize(A) == 16);

	SigSpec B = st.sigB;
	log_assert(GetSize(B) == 16);

	SigSpec CD = st.sigCD;
	if (CD.empty())
		CD = RTLIL::Const(0, 32);
	else
		log_assert(GetSize(CD) == 32);

	cell->setPort("\\A", A);
	cell->setPort("\\B", B);
	cell->setPort("\\C", CD.extract(16, 16));
	cell->setPort("\\D", CD.extract(0, 16));

	cell->setParam("\\A_REG", st.ffA ? State::S1 : State::S0);
	cell->setParam("\\B_REG", st.ffB ? State::S1 : State::S0);

	cell->setPort("\\AHOLD", State::S0);
	cell->setPort("\\BHOLD", State::S0);
	cell->setPort("\\CHOLD", State::S0);
	cell->setPort("\\DHOLD", State::S0);

	cell->setPort("\\IRSTTOP", State::S0);
	cell->setPort("\\IRSTBOT", State::S0);

	if (st.clock != SigBit())
	{
		cell->setPort("\\CLK", st.clock);
		cell->setPort("\\CE", State::S1);
		cell->setParam("\\NEG_TRIGGER", st.clock_pol ? State::S0 : State::S1);

		log("  clock: %s (%s)", log_signal(st.clock), st.clock_pol ? "posedge" : "negedge");

		if (st.ffA)
			log(" ffA:%s", log_id(st.ffA));

		if (st.ffB)
			log(" ffB:%s", log_id(st.ffB));

		if (st.ffH)
			log(" ffH:%s", log_id(st.ffH));

		if (st.ffO_lo)
			log(" ffO_lo:%s", log_id(st.ffO_lo));
		if (st.ffO_hi)
			log(" ffO_hi:%s", log_id(st.ffO_hi));

		log("\n");
	}
	else
	{
		cell->setPort("\\CLK", State::S0);
		cell->setPort("\\CE", State::S0);
		cell->setParam("\\NEG_TRIGGER", State::S0);
	}

	// SB_MAC16 Cascade Interface

	cell->setPort("\\SIGNEXTIN", State::Sx);
	cell->setPort("\\SIGNEXTOUT", pm.module->addWire(NEW_ID));

	cell->setPort("\\CI", State::Sx);

	cell->setPort("\\ACCUMCI", State::Sx);
	cell->setPort("\\ACCUMCO", pm.module->addWire(NEW_ID));

	// SB_MAC16 Output Interface

	SigSpec O = st.sigO;
	int O_width = GetSize(O);
	if (O_width == 33) {
		log_assert(st.addAB);
		// If we have a signed multiply-add, then perform sign extension
		// TODO: Need to check CD[31:16] is sign extension of CD[15:0]?
		if (st.addAB->getParam("\\A_SIGNED").as_bool() && st.addAB->getParam("\\B_SIGNED").as_bool())
			pm.module->connect(O[-1], O[-2]);
		else
			cell->setPort("\\CO", O[-1]);
		O.remove(O_width-1);
	}
	else
		cell->setPort("\\CO", pm.module->addWire(NEW_ID));
	log_assert(GetSize(O) <= 32);
	if (GetSize(O) < 32)
		O.append(pm.module->addWire(NEW_ID, 32-GetSize(O)));

	cell->setPort("\\O", O);

	bool accum = false;
	if (st.addAB) {
		if (st.addA)
			accum = (st.ffO_lo && st.ffO_hi && st.addAB->getPort("\\B") == st.sigO);
		else if (st.addB)
			accum = (st.ffO_lo && st.ffO_hi && st.addAB->getPort("\\A") == st.sigO);
		else log_abort();
		if (accum)
			log("  accumulator %s (%s)\n", log_id(st.addAB), log_id(st.addAB->type));
		else
			log("  adder %s (%s)\n", log_id(st.addAB), log_id(st.addAB->type));
		cell->setPort("\\ADDSUBTOP", st.addAB->type == "$add" ? State::S0 : State::S1);
		cell->setPort("\\ADDSUBBOT", st.addAB->type == "$add" ? State::S0 : State::S1);
	} else {
		cell->setPort("\\ADDSUBTOP", State::S0);
		cell->setPort("\\ADDSUBBOT", State::S0);
	}

	cell->setPort("\\ORSTTOP", State::S0);
	cell->setPort("\\ORSTBOT", State::S0);

	cell->setPort("\\OHOLDTOP", State::S0);
	cell->setPort("\\OHOLDBOT", State::S0);

	SigSpec acc_reset = State::S0;
	if (st.muxA)
		acc_reset = st.muxA->getPort("\\S");
	if (st.muxB)
		acc_reset = pm.module->Not(NEW_ID, st.muxB->getPort("\\S"));

	cell->setPort("\\OLOADTOP", acc_reset);
	cell->setPort("\\OLOADBOT", acc_reset);

	// SB_MAC16 Remaining Parameters

	cell->setParam("\\C_REG", State::S0);
	cell->setParam("\\D_REG", State::S0);

	cell->setParam("\\TOP_8x8_MULT_REG", st.ffH ? State::S1 : State::S0);
	cell->setParam("\\BOT_8x8_MULT_REG", st.ffH ? State::S1 : State::S0);
	cell->setParam("\\PIPELINE_16x16_MULT_REG1", st.ffH ? State::S1 : State::S0);
	cell->setParam("\\PIPELINE_16x16_MULT_REG2", State::S0);

	cell->setParam("\\TOPOUTPUT_SELECT", Const(st.ffO_hi ? 1 : (st.addAB ? 0 : 3), 2));
	cell->setParam("\\TOPADDSUB_LOWERINPUT", Const(2, 2));
	cell->setParam("\\TOPADDSUB_UPPERINPUT", accum ? State::S0 : State::S1);
	cell->setParam("\\TOPADDSUB_CARRYSELECT", Const(3, 2));

	cell->setParam("\\BOTOUTPUT_SELECT", Const(st.ffO_lo ? 1 : (st.addAB ? 0 : 3), 2));
	cell->setParam("\\BOTADDSUB_LOWERINPUT", Const(2, 2));
	cell->setParam("\\BOTADDSUB_UPPERINPUT", accum ? State::S0 : State::S1);
	cell->setParam("\\BOTADDSUB_CARRYSELECT", Const(0, 2));

	cell->setParam("\\MODE_8x8", State::S0);
	cell->setParam("\\A_SIGNED", st.mul->getParam("\\A_SIGNED").as_bool());
	cell->setParam("\\B_SIGNED", st.mul->getParam("\\B_SIGNED").as_bool());

	pm.autoremove(st.mul);
	pm.autoremove(st.ffH);
	pm.autoremove(st.addAB);
	if (st.ffO_lo) {
			SigSpec O = st.sigO.extract(0,st.ffO_lo->getParam("\\WIDTH").as_int());
			st.ffO_lo->connections_.at("\\Q").replace(O, pm.module->addWire(NEW_ID, GetSize(O)));
	}
	if (st.ffO_hi) {
			SigSpec O = st.sigO.extract(16,st.ffO_hi->getParam("\\WIDTH").as_int());
			st.ffO_hi->connections_.at("\\Q").replace(O, pm.module->addWire(NEW_ID, GetSize(O)));
	}
}

struct Ice40DspPass : public Pass {
	Ice40DspPass() : Pass("ice40_dsp", "iCE40: map multipliers") { }
	void help() YS_OVERRIDE
	{
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
		log("\n");
		log("    ice40_dsp [options] [selection]\n");
		log("\n");
		log("Map multipliers and multiply-accumulate blocks to iCE40 DSP resources.\n");
		log("\n");
	}
	void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
	{
		log_header(design, "Executing ICE40_DSP pass (map multipliers).\n");

		size_t argidx;
		for (argidx = 1; argidx < args.size(); argidx++)
		{
			// if (args[argidx] == "-singleton") {
			// 	singleton_mode = true;
			// 	continue;
			// }
			break;
		}
		extra_args(args, argidx, design);

		for (auto module : design->selected_modules())
			ice40_dsp_pm(module, module->selected_cells()).run_ice40_dsp(create_ice40_dsp);
	}
} Ice40DspPass;

PRIVATE_NAMESPACE_END
<|endoftext|>