<commit_before>/**
 * This file is part of the "FnordMetric" project
 *   Copyright (c) 2011-2014 Paul Asmuth, Google Inc.
 *
 * FnordMetric is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License v3.0. You should have received a
 * copy of the GNU General Public License along with this program. If not, see
 * <http://www.gnu.org/licenses/>.
 */
#include <fnordmetric/metricdb/httpapi.h>
#include <fnordmetric/query/queryservice.h>
#include <fnordmetric/metricdb/metricrepository.h>
#include <fnordmetric/metricdb/metrictablerepository.h>
#include <fnordmetric/util/stringutil.h>
#include <fnordmetric/util/inputstream.h>
#include <fnordmetric/util/outputstream.h>
#include <xzero/http/HttpStatus.h>
#include <xzero/http/HttpRequest.h>
#include <xzero/http/HttpResponse.h>
#include <xzero/http/HttpOutput.h>

namespace fnordmetric {
namespace metricdb {

static const char kMetricsUrl[] = "/metrics";
static const char kMetricsUrlPrefix[] = "/metrics/";
static const char kQueryUrl[] = "/query";
static const char kLabelParamPrefix[] = "label[";

HTTPAPI::HTTPAPI(IMetricRepository* metric_repo) : metric_repo_(metric_repo) {}

bool HTTPAPI::handleRequest(
    xzero::HttpRequest* request,
    xzero::HttpResponse* response) {
  util::URI uri(request->unparsedUri());
  std::string path = request->path();
  fnord::util::StringUtil::stripTrailingSlashes(&path);

  // PATH: ^/metrics/?$
  if (path == kMetricsUrl) {
    switch (request->method()) {
      case xzero::HttpMethod::GET:
        renderMetricList(request, response, &uri);
        return true;
      case xzero::HttpMethod::POST:
        insertSample(request, response, &uri);
        return true;
      default:
        return false;
    }
  }

  // PATH: ^/metrics/.*
  if (path.compare(0, sizeof(kMetricsUrlPrefix) - 1, kMetricsUrlPrefix) == 0) {
    // PATH: ^/metrics/(.*)$
    switch (request->method()) {
      case xzero::HttpMethod::GET:
        renderMetricSampleScan(request, response, &uri);
        return true;
      default:
        return false;
    }
  }

  // PATH: ^/query/?*
  if (path == kQueryUrl) {
    switch (request->method()) {
      case xzero::HttpMethod::GET:
      case xzero::HttpMethod::POST:
        executeQuery(request, response, &uri);
        return true;
      default:
        return false;
    }
    return true;
  }

  return false;
}

void HTTPAPI::renderMetricList(
    xzero::HttpRequest* request,
    xzero::HttpResponse* response,
    util::URI* uri) {
  std::string resp;
  std::shared_ptr<util::OutputStream> output_stream(
      new util::StringOutputStream(&resp));
  util::JSONOutputStream json(output_stream);

  json.beginObject();
  json.addObjectEntry("metrics");
  json.beginArray();

  int i = 0;
  for (const auto& metric : metric_repo_->listMetrics()) {
    if (i++ > 0) { json.addComma(); }
    renderMetricJSON(metric, &json);
  }

  json.endArray();
  json.endObject();

  response->setStatus(xzero::HttpStatus::Ok);
  response->addHeader("Content-Type", "application/json; charset=utf-8");
  response->setContentLength(resp.size());
  response->output()->write(
      resp,
      std::bind(&xzero::HttpResponse::completed, response));
}

void HTTPAPI::insertSample(
    xzero::HttpRequest* request,
    xzero::HttpResponse* response,
    util::URI* uri) {
  auto params = uri->queryParams();

  std::string metric_key;
  if (!util::URI::getParam(params, "metric", &metric_key)) {
    response->sendError(
        xzero::HttpStatus::BadRequest,
        "error: invalid metric key: " + metric_key);
    return;
  }

  std::string value_str;
  if (!util::URI::getParam(params, "value", &value_str)) {
    response->sendError(
        xzero::HttpStatus::BadRequest,
        "error: missing ?value=... parameter");
    return;
  }

  std::vector<std::pair<std::string, std::string>> labels;
  for (const auto& param : params) {
    const auto& key = param.first;
    const auto& value = param.second;

    if (key.compare(0, sizeof(kLabelParamPrefix) - 1, kLabelParamPrefix) == 0 &&
        key.back() == ']') {
      auto label_key = key.substr(
          sizeof(kLabelParamPrefix) - 1,
          key.size() - sizeof(kLabelParamPrefix));

      labels.emplace_back(label_key, value);
    }
  }

  double sample_value;
  try {
    sample_value = std::stod(value_str);
  } catch (std::exception& e) {
    response->sendError(
        xzero::HttpStatus::BadRequest,
        "error: invalid value: " + value_str);
    return;
  }

  auto metric = metric_repo_->findOrCreateMetric(metric_key);
  metric->insertSample(sample_value, labels);

  response->setStatus(xzero::HttpStatus::Created);
  response->completed();
}

void HTTPAPI::renderMetricSampleScan(
    xzero::HttpRequest* request,
    xzero::HttpResponse* response,
    util::URI* uri) {
  auto metric_key = uri->path().substr(sizeof(kMetricsUrlPrefix) - 1);
  if (metric_key.size() < 3) {
    response->sendError(
        xzero::HttpStatus::BadRequest,
        "error: invalid metric key: " + metric_key);
    return;
  }

  auto metric = metric_repo_->findMetric(metric_key);
  if (metric == nullptr) {
    response->sendError(
        xzero::HttpStatus::NotFound,
        "metric not found: " + metric_key);
    return;
  }

  std::string resp;
  std::shared_ptr<util::OutputStream> output_stream(
      new util::StringOutputStream(&resp));
  util::JSONOutputStream json(output_stream);

  json.beginObject();

  json.addObjectEntry("metric");
  renderMetricJSON(metric, &json);
  json.addComma();

  json.addObjectEntry("samples");
  json.beginArray();

  int i = 0;
  metric->scanSamples(
      fnord::util::DateTime::epoch(),
      fnord::util::DateTime::now(),
      [&json, &i] (Sample* sample) -> bool {
        if (i++ > 0) { json.addComma(); }
        json.beginObject();

        json.addObjectEntry("time");
        json.addLiteral<uint64_t>(static_cast<uint64_t>(sample->time()));
        json.addComma();

        json.addObjectEntry("value");
        json.addLiteral<double>(sample->value());
        json.addComma();

        json.addObjectEntry("labels");
        json.beginObject();
        auto labels = sample->labels();
        for (int n = 0; n < labels.size(); n++) {
          if (n > 0) {
            json.addComma();
          }

          json.addObjectEntry(labels[n].first);
          json.addString(labels[n].second);
        }
        json.endObject();

        json.endObject();
        return true;
      });

  json.endArray();
  json.endObject();

  response->setStatus(xzero::HttpStatus::Ok);
  response->addHeader("Content-Type", "application/json; charset=utf-8");
  response->setContentLength(resp.size());
  response->output()->write(
      resp,
      std::bind(&xzero::HttpResponse::completed, response));
}

void HTTPAPI::executeQuery(
    xzero::HttpRequest* request,
    xzero::HttpResponse* response,
    util::URI* uri) {

  xzero::Buffer body;
  request->input()->read(&body);

  std::shared_ptr<util::InputStream> input_stream(
      new util::StringInputStream(body.str()));

  std::string resp;
  std::shared_ptr<util::OutputStream> output_stream(
      new util::StringOutputStream(&resp));

  // FIXPAUL move to thread/worker pool
  query::QueryService query_service;
  std::unique_ptr<query::TableRepository> table_repo(
      new MetricTableRepository(metric_repo_));

  try {
    query_service.executeQuery(
        input_stream,
        query::QueryService::FORMAT_JSON,
        output_stream,
        std::move(table_repo));

  } catch (util::RuntimeException e) {
    resp.clear();

    util::JSONOutputStream json(std::move(output_stream));
    json.beginObject();
    json.addObjectEntry("status");
    json.addString("error");
    json.addComma();
    json.addObjectEntry("error");
    json.addString(e.getMessage());
    json.endObject();
  }

  response->setStatus(xzero::HttpStatus::Ok);
  response->addHeader("Content-Type", "application/json; charset=utf-8");
  response->setContentLength(resp.size());
  response->output()->write(
      resp,
      std::bind(&xzero::HttpResponse::completed, response));
}

void HTTPAPI::renderMetricJSON(
    IMetric* metric,
    util::JSONOutputStream* json) const {
  json->beginObject();

  json->addObjectEntry("key");
  json->addString(metric->key());
  json->addComma();

  json->addObjectEntry("total_bytes");
  json->addLiteral<size_t>(metric->totalBytes());
  json->addComma();

  json->addObjectEntry("last_insert");
  json->addLiteral<uint64_t>(static_cast<uint64_t>(metric->lastInsertTime()));
  json->addComma();

  json->addObjectEntry("labels");
  json->beginArray();
  auto labels = metric->labels();
  for (auto cur = labels.begin(); cur != labels.end(); ++cur) {
    if (cur != labels.begin()) {
      json->addComma();
    }
    json->addString(*cur);
  }
  json->endArray();

  json->endObject();
}

}
}
<commit_msg>simple dashboard<commit_after>/**
 * This file is part of the "FnordMetric" project
 *   Copyright (c) 2011-2014 Paul Asmuth, Google Inc.
 *
 * FnordMetric is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License v3.0. You should have received a
 * copy of the GNU General Public License along with this program. If not, see
 * <http://www.gnu.org/licenses/>.
 */
#include <fnordmetric/metricdb/httpapi.h>
#include <fnordmetric/query/queryservice.h>
#include <fnordmetric/metricdb/metricrepository.h>
#include <fnordmetric/metricdb/metrictablerepository.h>
#include <fnordmetric/util/stringutil.h>
#include <fnordmetric/util/inputstream.h>
#include <fnordmetric/util/outputstream.h>
#include <xzero/http/HttpStatus.h>
#include <xzero/http/HttpRequest.h>
#include <xzero/http/HttpResponse.h>
#include <xzero/http/HttpOutput.h>

namespace fnordmetric {
namespace metricdb {

static const char kMetricsUrl[] = "/metrics";
static const char kMetricsUrlPrefix[] = "/metrics/";
static const char kQueryUrl[] = "/query";
static const char kLabelParamPrefix[] = "label[";

HTTPAPI::HTTPAPI(IMetricRepository* metric_repo) : metric_repo_(metric_repo) {}

bool HTTPAPI::handleRequest(
    xzero::HttpRequest* request,
    xzero::HttpResponse* response) {
  util::URI uri(request->unparsedUri());
  std::string path = request->path();
  fnord::util::StringUtil::stripTrailingSlashes(&path);

  // PATH: ^/metrics/?$
  if (path == kMetricsUrl) {
    switch (request->method()) {
      case xzero::HttpMethod::GET:
        renderMetricList(request, response, &uri);
        return true;
      case xzero::HttpMethod::POST:
        insertSample(request, response, &uri);
        return true;
      default:
        return false;
    }
  }

  // PATH: ^/metrics/.*
  if (path.compare(0, sizeof(kMetricsUrlPrefix) - 1, kMetricsUrlPrefix) == 0) {
    // PATH: ^/metrics/(.*)$
    switch (request->method()) {
      case xzero::HttpMethod::GET:
        renderMetricSampleScan(request, response, &uri);
        return true;
      default:
        return false;
    }
  }

  // PATH: ^/query/?*
  if (path == kQueryUrl) {
    switch (request->method()) {
      case xzero::HttpMethod::GET:
      case xzero::HttpMethod::POST:
        executeQuery(request, response, &uri);
        return true;
      default:
        return false;
    }
    return true;
  }

  return false;
}

void HTTPAPI::renderMetricList(
    xzero::HttpRequest* request,
    xzero::HttpResponse* response,
    util::URI* uri) {
  std::string resp;
  std::shared_ptr<util::OutputStream> output_stream(
      new util::StringOutputStream(&resp));
  util::JSONOutputStream json(output_stream);

  json.beginObject();
  json.addObjectEntry("metrics");
  json.beginArray();

  int i = 0;
  for (const auto& metric : metric_repo_->listMetrics()) {
    if (i++ > 0) { json.addComma(); }
    renderMetricJSON(metric, &json);
  }

  json.endArray();
  json.endObject();

  response->setStatus(xzero::HttpStatus::Ok);
  response->addHeader("Content-Type", "application/json; charset=utf-8");
  response->setContentLength(resp.size());
  response->output()->write(
      resp,
      std::bind(&xzero::HttpResponse::completed, response));
}

void HTTPAPI::insertSample(
    xzero::HttpRequest* request,
    xzero::HttpResponse* response,
    util::URI* uri) {
  auto params = uri->queryParams();

  std::string metric_key;
  if (!util::URI::getParam(params, "metric", &metric_key)) {
    response->sendError(
        xzero::HttpStatus::BadRequest,
        "error: invalid metric key: " + metric_key);
    return;
  }

  std::string value_str;
  if (!util::URI::getParam(params, "value", &value_str)) {
    response->sendError(
        xzero::HttpStatus::BadRequest,
        "error: missing ?value=... parameter");
    return;
  }

  std::vector<std::pair<std::string, std::string>> labels;
  for (const auto& param : params) {
    const auto& key = param.first;
    const auto& value = param.second;

    if (key.compare(0, sizeof(kLabelParamPrefix) - 1, kLabelParamPrefix) == 0 &&
        key.back() == ']') {
      auto label_key = key.substr(
          sizeof(kLabelParamPrefix) - 1,
          key.size() - sizeof(kLabelParamPrefix));

      labels.emplace_back(label_key, value);
    }
  }

  double sample_value;
  try {
    sample_value = std::stod(value_str);
  } catch (std::exception& e) {
    response->sendError(
        xzero::HttpStatus::BadRequest,
        "error: invalid value: " + value_str);
    return;
  }

  auto metric = metric_repo_->findOrCreateMetric(metric_key);
  metric->insertSample(sample_value, labels);

  response->setStatus(xzero::HttpStatus::Created);
  response->completed();
}

void HTTPAPI::renderMetricSampleScan(
    xzero::HttpRequest* request,
    xzero::HttpResponse* response,
    util::URI* uri) {
  auto metric_key = uri->path().substr(sizeof(kMetricsUrlPrefix) - 1);
  if (metric_key.size() < 3) {
    response->sendError(
        xzero::HttpStatus::BadRequest,
        "error: invalid metric key: " + metric_key);
    return;
  }

  auto metric = metric_repo_->findMetric(metric_key);
  if (metric == nullptr) {
    response->sendError(
        xzero::HttpStatus::NotFound,
        "metric not found: " + metric_key);
    return;
  }

  std::string resp;
  std::shared_ptr<util::OutputStream> output_stream(
      new util::StringOutputStream(&resp));
  util::JSONOutputStream json(output_stream);

  json.beginObject();

  json.addObjectEntry("metric");
  renderMetricJSON(metric, &json);
  json.addComma();

  json.addObjectEntry("samples");
  json.beginArray();

  int i = 0;
  metric->scanSamples(
      fnord::util::DateTime::epoch(),
      fnord::util::DateTime::now(),
      [&json, &i] (Sample* sample) -> bool {
        if (i++ > 0) { json.addComma(); }
        json.beginObject();

        json.addObjectEntry("time");
        json.addLiteral<uint64_t>(static_cast<uint64_t>(sample->time()));
        json.addComma();

        json.addObjectEntry("value");
        json.addLiteral<double>(sample->value());
        json.addComma();

        json.addObjectEntry("labels");
        json.beginObject();
        auto labels = sample->labels();
        for (int n = 0; n < labels.size(); n++) {
          if (n > 0) {
            json.addComma();
          }

          json.addObjectEntry(labels[n].first);
          json.addString(labels[n].second);
        }
        json.endObject();

        json.endObject();
        return true;
      });

  json.endArray();
  json.endObject();

  response->setStatus(xzero::HttpStatus::Ok);
  response->addHeader("Content-Type", "application/json; charset=utf-8");
  response->setContentLength(resp.size());
  response->output()->write(
      resp,
      std::bind(&xzero::HttpResponse::completed, response));
}

void HTTPAPI::executeQuery(
    xzero::HttpRequest* request,
    xzero::HttpResponse* response,
    util::URI* uri) {

  xzero::Buffer body;
  request->input()->read(&body);

  std::shared_ptr<util::InputStream> input_stream(
      new util::StringInputStream(body.str()));

  std::string resp;
  std::shared_ptr<util::OutputStream> output_stream(
      new util::StringOutputStream(&resp));

  // FIXPAUL move to thread/worker pool
  query::QueryService query_service;
  std::unique_ptr<query::TableRepository> table_repo(
      new MetricTableRepository(metric_repo_));

  try {
    query_service.executeQuery(
        input_stream,
        query::QueryService::FORMAT_JSON,
        output_stream,
        std::move(table_repo));

  } catch (util::RuntimeException e) {
    resp.clear();

    util::JSONOutputStream json(std::move(output_stream));
    json.beginObject();
    json.addObjectEntry("status");
    json.addString("error");
    json.addComma();
    json.addObjectEntry("error");
    json.addString(e.getMessage());
    json.endObject();
  }

  response->setStatus(xzero::HttpStatus::Ok);
  response->addHeader("Content-Type", "application/json; charset=utf-8");
  response->addHeader("Access-Control-Allow-Origin", "*");
  response->setContentLength(resp.size());
  response->output()->write(
      resp,
      std::bind(&xzero::HttpResponse::completed, response));
}

void HTTPAPI::renderMetricJSON(
    IMetric* metric,
    util::JSONOutputStream* json) const {
  json->beginObject();

  json->addObjectEntry("key");
  json->addString(metric->key());
  json->addComma();

  json->addObjectEntry("total_bytes");
  json->addLiteral<size_t>(metric->totalBytes());
  json->addComma();

  json->addObjectEntry("last_insert");
  json->addLiteral<uint64_t>(static_cast<uint64_t>(metric->lastInsertTime()));
  json->addComma();

  json->addObjectEntry("labels");
  json->beginArray();
  auto labels = metric->labels();
  for (auto cur = labels.begin(); cur != labels.end(); ++cur) {
    if (cur != labels.begin()) {
      json->addComma();
    }
    json->addString(*cur);
  }
  json->endArray();

  json->endObject();
}

}
}
<|endoftext|>


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

#include "IECore/MessageHandler.h"

#include "IECoreHoudini/ToHoudiniStringAttribConverter.h"

using namespace IECore;

namespace IECoreHoudini
{

IE_CORE_DEFINERUNTIMETYPED( ToHoudiniStringVectorAttribConverter );

ToHoudiniAttribConverter::Description<ToHoudiniStringVectorAttribConverter> ToHoudiniStringVectorAttribConverter::m_description( StringVectorData::staticTypeId() );

ToHoudiniStringVectorAttribConverter::ToHoudiniStringVectorAttribConverter( const IECore::Data *data ) :
	ToHoudiniAttribConverter( data, "Converts IECore::StringVectorData to a GB_Attribute on the provided GU_Detail." )
{
	m_indicesParameter = new IntVectorParameter( "indices", "the indices into the source StringVectorData", new IntVectorData() );
	parameters()->addParameter( m_indicesParameter );
}

ToHoudiniStringVectorAttribConverter::~ToHoudiniStringVectorAttribConverter()
{
}

IntVectorParameterPtr ToHoudiniStringVectorAttribConverter::indicesParameter()
{
	return m_indicesParameter;
}

ConstIntVectorParameterPtr ToHoudiniStringVectorAttribConverter::indicesParameter() const
{
	return m_indicesParameter;
}

GA_RWAttributeRef ToHoudiniStringVectorAttribConverter::doConversion( const IECore::Data *data, std::string name, GU_Detail *geo ) const
{
	IECore::msg( IECore::MessageHandler::Error, "ToHoudiniStringVectorAttribConverter", "Does not support Detail attributes." );
	return GA_RWAttributeRef();
}

GA_RWAttributeRef ToHoudiniStringVectorAttribConverter::doConversion( const IECore::Data *data, std::string name, GU_Detail *geo, const GA_Range &range ) const
{
	assert( data );

	const IECore::StringVectorData *stringVectorData = IECore::runTimeCast<const IECore::StringVectorData>( data );
	if ( !stringVectorData )
	{
		throw IECore::Exception( ( boost::format( "ToHoudiniStringVectorAttribConverter::doConversion: PrimitiveVariable \"%s\" does not contain IECore::StringVectorData." ) % name ).str() );
	}

	GA_RWAttributeRef attrRef = geo->addStringTuple( range.getOwner(), name.c_str(), 1 );
	if ( attrRef.isInvalid() )
	{
		throw IECore::Exception( ( boost::format( "ToHoudiniStringVectorAttribConverter::doConversion: Invalid GA_RWAttributeRef returned for PrimitiveVariable \"%s\"." ) % name ).str() );
	}

	if ( !range.isValid() || range.empty() )
	{
		return attrRef;
	}

	GA_Attribute *attr = attrRef.getAttribute();

	const GA_AIFSharedStringTuple *tuple = attr->getAIFSharedStringTuple();

	UT_StringArray strings;
	const std::vector<std::string> &stringVector = stringVectorData->readable();

	const std::vector<int> &indices = ((const IECore::IntVectorData *)m_indicesParameter->getValidatedValue())->readable();
	if ( indices.empty() || stringVector.empty() )
	{
		return attrRef;
	}

	size_t i = 0;
	size_t numIndices = indices.size();
	for ( GA_Iterator it=range.begin(); !it.atEnd(), i < numIndices; ++it, ++i )
	{
		tuple->setString( attr, it.getOffset(), stringVector[ indices[i] ].c_str(), 0 );
	}

	return attrRef;
}

IE_CORE_DEFINERUNTIMETYPED( ToHoudiniStringDetailAttribConverter );

ToHoudiniAttribConverter::Description<ToHoudiniStringDetailAttribConverter> ToHoudiniStringDetailAttribConverter::m_description( StringData::staticTypeId() );

ToHoudiniStringDetailAttribConverter::ToHoudiniStringDetailAttribConverter( const IECore::Data *data ) :
	ToHoudiniAttribConverter( data, "Converts IECore::StringData to a GB_Attribute on the provided GU_Detail." )
{
}

ToHoudiniStringDetailAttribConverter::~ToHoudiniStringDetailAttribConverter()
{
}

GA_RWAttributeRef ToHoudiniStringDetailAttribConverter::doConversion( const IECore::Data *data, std::string name, GU_Detail *geo ) const
{
	assert( data );

	const StringData *stringData = IECore::runTimeCast<const StringData>( data );
	if ( !stringData )
	{
		throw IECore::Exception( ( boost::format( "ToHoudiniStringDetailAttribConverter::doConversion: PrimitiveVariable \"%s\" does not contain IECore::StringData." ) % name ).str() );
	}

	GA_RWAttributeRef attrRef = geo->addStringTuple( GA_ATTRIB_DETAIL, name.c_str(), 1 );
	if ( attrRef.isInvalid() )
	{
		throw IECore::Exception( ( boost::format( "ToHoudiniStringDetailAttribConverter::doConversion: Invalid GA_RWAttributeRef returned for PrimitiveVariable \"%s\"." ) % name ).str() );
	}

	GA_Attribute *attr = attrRef.getAttribute();
	attr->getAIFSharedStringTuple()->setString( attr, 0, stringData->readable().c_str(), 0 );

	return attrRef;
}

GA_RWAttributeRef ToHoudiniStringDetailAttribConverter::doConversion( const IECore::Data *data, std::string name, GU_Detail *geo, const GA_Range &range ) const
{
	throw IECore::Exception( "ToHoudiniStringDetailAttribConverter does not support Element attributes." );
}

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

#include "IECore/MessageHandler.h"

#include "IECoreHoudini/ToHoudiniStringAttribConverter.h"

using namespace IECore;

namespace IECoreHoudini
{

IE_CORE_DEFINERUNTIMETYPED( ToHoudiniStringVectorAttribConverter );

ToHoudiniAttribConverter::Description<ToHoudiniStringVectorAttribConverter> ToHoudiniStringVectorAttribConverter::m_description( StringVectorData::staticTypeId() );

ToHoudiniStringVectorAttribConverter::ToHoudiniStringVectorAttribConverter( const IECore::Data *data ) :
	ToHoudiniAttribConverter( data, "Converts IECore::StringVectorData to a GB_Attribute on the provided GU_Detail." )
{
	m_indicesParameter = new IntVectorParameter( "indices", "the indices into the source StringVectorData", new IntVectorData() );
	parameters()->addParameter( m_indicesParameter );
}

ToHoudiniStringVectorAttribConverter::~ToHoudiniStringVectorAttribConverter()
{
}

IntVectorParameterPtr ToHoudiniStringVectorAttribConverter::indicesParameter()
{
	return m_indicesParameter;
}

ConstIntVectorParameterPtr ToHoudiniStringVectorAttribConverter::indicesParameter() const
{
	return m_indicesParameter;
}

GA_RWAttributeRef ToHoudiniStringVectorAttribConverter::doConversion( const IECore::Data *data, std::string name, GU_Detail *geo ) const
{
	IECore::msg( IECore::MessageHandler::Warning, "ToHoudiniStringVectorAttribConverter", "Does not support Detail attributes. Ignoring \"" + name + "\"" );
	return GA_RWAttributeRef();
}

GA_RWAttributeRef ToHoudiniStringVectorAttribConverter::doConversion( const IECore::Data *data, std::string name, GU_Detail *geo, const GA_Range &range ) const
{
	assert( data );

	const IECore::StringVectorData *stringVectorData = IECore::runTimeCast<const IECore::StringVectorData>( data );
	if ( !stringVectorData )
	{
		throw IECore::Exception( ( boost::format( "ToHoudiniStringVectorAttribConverter::doConversion: PrimitiveVariable \"%s\" does not contain IECore::StringVectorData." ) % name ).str() );
	}

	GA_RWAttributeRef attrRef = geo->addStringTuple( range.getOwner(), name.c_str(), 1 );
	if ( attrRef.isInvalid() )
	{
		throw IECore::Exception( ( boost::format( "ToHoudiniStringVectorAttribConverter::doConversion: Invalid GA_RWAttributeRef returned for PrimitiveVariable \"%s\"." ) % name ).str() );
	}

	if ( !range.isValid() || range.empty() )
	{
		return attrRef;
	}

	GA_Attribute *attr = attrRef.getAttribute();

	const GA_AIFSharedStringTuple *tuple = attr->getAIFSharedStringTuple();

	UT_StringArray strings;
	const std::vector<std::string> &stringVector = stringVectorData->readable();

	const std::vector<int> &indices = ((const IECore::IntVectorData *)m_indicesParameter->getValidatedValue())->readable();
	if ( indices.empty() || stringVector.empty() )
	{
		return attrRef;
	}

	size_t i = 0;
	size_t numIndices = indices.size();
	for ( GA_Iterator it=range.begin(); !it.atEnd(), i < numIndices; ++it, ++i )
	{
		tuple->setString( attr, it.getOffset(), stringVector[ indices[i] ].c_str(), 0 );
	}

	return attrRef;
}

IE_CORE_DEFINERUNTIMETYPED( ToHoudiniStringDetailAttribConverter );

ToHoudiniAttribConverter::Description<ToHoudiniStringDetailAttribConverter> ToHoudiniStringDetailAttribConverter::m_description( StringData::staticTypeId() );

ToHoudiniStringDetailAttribConverter::ToHoudiniStringDetailAttribConverter( const IECore::Data *data ) :
	ToHoudiniAttribConverter( data, "Converts IECore::StringData to a GB_Attribute on the provided GU_Detail." )
{
}

ToHoudiniStringDetailAttribConverter::~ToHoudiniStringDetailAttribConverter()
{
}

GA_RWAttributeRef ToHoudiniStringDetailAttribConverter::doConversion( const IECore::Data *data, std::string name, GU_Detail *geo ) const
{
	assert( data );

	const StringData *stringData = IECore::runTimeCast<const StringData>( data );
	if ( !stringData )
	{
		throw IECore::Exception( ( boost::format( "ToHoudiniStringDetailAttribConverter::doConversion: PrimitiveVariable \"%s\" does not contain IECore::StringData." ) % name ).str() );
	}

	GA_RWAttributeRef attrRef = geo->addStringTuple( GA_ATTRIB_DETAIL, name.c_str(), 1 );
	if ( attrRef.isInvalid() )
	{
		throw IECore::Exception( ( boost::format( "ToHoudiniStringDetailAttribConverter::doConversion: Invalid GA_RWAttributeRef returned for PrimitiveVariable \"%s\"." ) % name ).str() );
	}

	GA_Attribute *attr = attrRef.getAttribute();
	attr->getAIFSharedStringTuple()->setString( attr, 0, stringData->readable().c_str(), 0 );

	return attrRef;
}

GA_RWAttributeRef ToHoudiniStringDetailAttribConverter::doConversion( const IECore::Data *data, std::string name, GU_Detail *geo, const GA_Range &range ) const
{
	throw IECore::Exception( "ToHoudiniStringDetailAttribConverter does not support Element attributes." );
}

} // namespace IECoreHoudini
<|endoftext|>


<commit_before><commit_msg>[FIXING] Fixing formating of the comments in dark_girl.cpp<commit_after><|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: listenercontainers.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-19 12:58:28 $
 *
 *  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_SOURCE_MISC_LISTENERCONTAINERS_HXX
#include "listenercontainers.hxx"
#endif

/** === begin UNO includes === **/
/** === end UNO includes === **/

//........................................................................
namespace frm
{
//........................................................................

    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::lang;
    using namespace ::com::sun::star::form;

    //====================================================================
    //= ResetListeners
    //====================================================================
    //---------------------------------------------------------------------
    bool ResetListeners::implTypedNotify( const Reference< XResetListener >& _rxListener,
        const EventObject& _rEvent )   SAL_THROW( ( Exception ) )
    {
        switch ( m_eCurrentNotificationType )
        {
        case eApproval:
            if ( !_rxListener->approveReset( _rEvent ) )
                return false;
            return true;
        case eFinal:
            _rxListener->resetted( _rEvent );
            break;
        default:
            OSL_ENSURE( sal_False, "ResetListeners::implNotify: invalid notification type!" );
        }
        return true;
    }

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

<commit_msg>INTEGRATION: CWS pchfix02 (1.4.26); FILE MERGED 2006/09/01 17:27:41 kaib 1.4.26.1: #i68856# Added header markers and pch files<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: listenercontainers.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-16 23:58:05 $
 *
 *  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
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_forms.hxx"

#ifndef FORMS_SOURCE_MISC_LISTENERCONTAINERS_HXX
#include "listenercontainers.hxx"
#endif

/** === begin UNO includes === **/
/** === end UNO includes === **/

//........................................................................
namespace frm
{
//........................................................................

    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::lang;
    using namespace ::com::sun::star::form;

    //====================================================================
    //= ResetListeners
    //====================================================================
    //---------------------------------------------------------------------
    bool ResetListeners::implTypedNotify( const Reference< XResetListener >& _rxListener,
        const EventObject& _rEvent )   SAL_THROW( ( Exception ) )
    {
        switch ( m_eCurrentNotificationType )
        {
        case eApproval:
            if ( !_rxListener->approveReset( _rEvent ) )
                return false;
            return true;
        case eFinal:
            _rxListener->resetted( _rEvent );
            break;
        default:
            OSL_ENSURE( sal_False, "ResetListeners::implNotify: invalid notification type!" );
        }
        return true;
    }

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

<|endoftext|>


<commit_before>#include <QUrl>
#include <QtNetwork>
#include <QSslError>
#include <QSslConfiguration>
#include <QSslCertificate>

#include "seafile-applet.h"
#include "certs-mgr.h"
#include "ui/main-window.h"
#include "ui/ssl-confirm-dialog.h"
#include "utils/utils.h"
#include "network-mgr.h"

#include "api-client.h"

namespace {

const char *kContentTypeForm = "application/x-www-form-urlencoded";
const char *kAuthHeader = "Authorization";

const int kMaxRedirects = 3;

bool shouldIgnoreRequestError(const QNetworkReply* reply)
{
    return reply->url().toString().contains("/api2/events");
}

} // namespace

QNetworkAccessManager* SeafileApiClient::na_mgr_ = NULL;

SeafileApiClient::SeafileApiClient(QObject *parent)
    : QObject(parent),
      reply_(NULL),
      redirect_count_(0)
{
    if (!na_mgr_) {
        static QNetworkAccessManager mNetworkAccessManager;
        na_mgr_ = &mNetworkAccessManager;
        NetworkManager::instance()->addWatch(na_mgr_);
    }
}

SeafileApiClient::~SeafileApiClient()
{
    if (reply_) {
        reply_->deleteLater();
    }
}

void SeafileApiClient::get(const QUrl& url)
{
    QNetworkRequest request(url);

    if (token_.length() > 0) {
        char buf[1024];
        qsnprintf(buf, sizeof(buf), "Token %s", token_.toUtf8().data());
        request.setRawHeader(kAuthHeader, buf);
    }

    // qWarning("send request, url = %s\n, token = %s\n",
    //        request.url().toString().toUtf8().data(),
    //        request.rawHeader(kAuthHeader).data());

    reply_ = na_mgr_->get(request);

    connect(reply_, SIGNAL(sslErrors(const QList<QSslError>&)),
            this, SLOT(onSslErrors(const QList<QSslError>&)));

    connect(reply_, SIGNAL(finished()), this, SLOT(httpRequestFinished()));
}

void SeafileApiClient::post(const QUrl& url, const QByteArray& data, bool is_put)
{
    body_ = data;
    QNetworkRequest request(url);
    if (token_.length() > 0) {
        char buf[1024];
        qsnprintf(buf, sizeof(buf), "Token %s", token_.toUtf8().data());
        request.setRawHeader(kAuthHeader, buf);
    }
    request.setHeader(QNetworkRequest::ContentTypeHeader, kContentTypeForm);

    if (is_put)
        reply_ = na_mgr_->put(request, body_);
    else
        reply_ = na_mgr_->post(request, body_);

    connect(reply_, SIGNAL(finished()), this, SLOT(httpRequestFinished()));

    connect(reply_, SIGNAL(sslErrors(const QList<QSslError>&)),
            this, SLOT(onSslErrors(const QList<QSslError>&)));
}

void SeafileApiClient::deleteResource(const QUrl& url)
{
    QNetworkRequest request(url);

    if (token_.length() > 0) {
        char buf[1024];
        qsnprintf(buf, sizeof(buf), "Token %s", token_.toUtf8().data());
        request.setRawHeader(kAuthHeader, buf);
    }

    reply_ = na_mgr_->deleteResource(request);

    connect(reply_, SIGNAL(sslErrors(const QList<QSslError>&)),
            this, SLOT(onSslErrors(const QList<QSslError>&)));

    connect(reply_, SIGNAL(finished()), this, SLOT(httpRequestFinished()));
}

void SeafileApiClient::onSslErrors(const QList<QSslError>& errors)
{
    const QUrl url = reply_->url();
    CertsManager *mgr = seafApplet->certsManager();
    Q_FOREACH(const QSslError &error, errors) {
        const QSslCertificate &cert = error.certificate();

        if (cert.isNull()) {
            // The server has no ssl certificate, we do nothing and let the
            // request fail
            // it is a fatal error, no way to recover
            qWarning("the certificate for %s is null", url.toString().toUtf8().data());
            break;
        }

        QSslCertificate saved_cert = mgr->getCertificate(url.toString());

        if (saved_cert.isNull()) {
            // dump certificate information
            qWarning() << "\n= SslError =\n" << error.errorString();
            qWarning() << "\n= Certificate =\n" << dumpCertificate(cert);

            // This is the first time when the client connects to the server.
            if (seafApplet->detailedYesOrNoBox(
                tr("Warning: The ssl certificate of this server is not trusted, proceed anyway?"),
                error.errorString() + "\n" + dumpCertificate(cert), 0, false)) {
                mgr->saveCertificate(url, cert);
                // TODO handle ssl by verifying certificate chain instead
                reply_->ignoreSslErrors();
            }
        } else if (saved_cert == cert) {
            // The user has choosen to trust the certificate before
            // TODO handle ssl by verifying certificate chain instead
            reply_->ignoreSslErrors();
        } else {
            // dump certificate information
            qWarning() << "\n= SslError =\n" << error.errorString();
            qWarning() << "\n= Certificate =\n" << dumpCertificate(cert);
            qWarning() << "\n= Previous Certificate =\n" << dumpCertificate(saved_cert);

            /**
             * The cert which the user had chosen to trust has been changed. It
             * may be either:
             *
             * 1. The server has changed its ssl certificate
             * 2. The user's connection is under security attack
             *
             * Anyway, we'll prompt the user
             */
            SslConfirmDialog dialog(url,
                                    dumpCertificateFingerprint(cert),
                                    dumpCertificateFingerprint(saved_cert),
                                    seafApplet->mainWindow());
            if (dialog.exec() == QDialog::Accepted) {
                // TODO handle ssl by verifying certificate chain instead
                reply_->ignoreSslErrors();
                if (dialog.rememberChoice()) {
                    mgr->saveCertificate(url, cert);
                }
            } else {
                reply_->abort();
                break;
            }
        }
    }
}

void SeafileApiClient::httpRequestFinished()
{
    int code = reply_->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    if (code == 0 && reply_->error() != QNetworkReply::NoError) {
        if (NetworkManager::instance()->shouldRetry(reply_->error())) {
            qWarning("[api] network proxy error, retrying\n");
            resendRequest(reply_->url());
            return;
        }
        if (!shouldIgnoreRequestError(reply_)) {
            qWarning("[api] network error for %s: %s\n", toCStr(reply_->url().toString()),
                   reply_->errorString().toUtf8().data());
        }
        emit networkError(reply_->error(), reply_->errorString());
        return;
    }

    if (handleHttpRedirect()) {
        return;
    }

    if ((code / 100) == 4 || (code / 100) == 5) {
        if (!shouldIgnoreRequestError(reply_)) {
            qWarning("request failed for %s: status code %d\n",
                   reply_->url().toString().toUtf8().data(), code);
        }
        emit requestFailed(code);
        return;
    }

    emit requestSuccess(*reply_);
}

bool SeafileApiClient::handleHttpRedirect()
{
    QVariant redirect_attr = reply_->attribute(QNetworkRequest::RedirectionTargetAttribute);
    if (redirect_attr.isNull()) {
        return false;
    }

    if (redirect_count_++ > kMaxRedirects) {
        // simply treat too many redirects as server side error
        emit requestFailed(500);
        qWarning("too many redirects for %s\n",
               reply_->url().toString().toUtf8().data());
        return true;
    }

    QUrl redirect_url = redirect_attr.toUrl();
    if (redirect_url.isRelative()) {
        redirect_url =  reply_->url().resolved(redirect_url);
    }

    // qWarning("redirect to %s (from %s)\n", redirect_url.toString().toUtf8().data(),
    //        reply_->url().toString().toUtf8().data());
    // don't handle with this, since rename operation returns a 301
    if (reply_->operation() == QNetworkAccessManager::PostOperation)
        return false;

    resendRequest(redirect_url);

    return true;
}

void SeafileApiClient::resendRequest(const QUrl& url)
{
    switch (reply_->operation()) {
    case QNetworkAccessManager::GetOperation:
        reply_->deleteLater();
        get(url);
        break;
    case QNetworkAccessManager::PostOperation:
        post(url, body_, false);
        break;
    case QNetworkAccessManager::PutOperation:
        post(url, body_, true);
        break;
    case QNetworkAccessManager::DeleteOperation:
        reply_->deleteLater();
        deleteResource(url);
        break;
    default:
        reply_->deleteLater();
        qWarning() << "unsupported operation" << reply_->operation()
          << "to" << url.toString()
          << "from" << reply_->url().toString();
        break;
    }
}
<commit_msg>ignore the others of ssl errors if we have dealt with one<commit_after>#include <QUrl>
#include <QtNetwork>
#include <QSslError>
#include <QSslConfiguration>
#include <QSslCertificate>

#include "seafile-applet.h"
#include "certs-mgr.h"
#include "ui/main-window.h"
#include "ui/ssl-confirm-dialog.h"
#include "utils/utils.h"
#include "network-mgr.h"

#include "api-client.h"

namespace {

const char *kContentTypeForm = "application/x-www-form-urlencoded";
const char *kAuthHeader = "Authorization";

const int kMaxRedirects = 3;

bool shouldIgnoreRequestError(const QNetworkReply* reply)
{
    return reply->url().toString().contains("/api2/events");
}

} // namespace

QNetworkAccessManager* SeafileApiClient::na_mgr_ = NULL;

SeafileApiClient::SeafileApiClient(QObject *parent)
    : QObject(parent),
      reply_(NULL),
      redirect_count_(0)
{
    if (!na_mgr_) {
        static QNetworkAccessManager mNetworkAccessManager;
        na_mgr_ = &mNetworkAccessManager;
        NetworkManager::instance()->addWatch(na_mgr_);
    }
}

SeafileApiClient::~SeafileApiClient()
{
    if (reply_) {
        reply_->deleteLater();
    }
}

void SeafileApiClient::get(const QUrl& url)
{
    QNetworkRequest request(url);

    if (token_.length() > 0) {
        char buf[1024];
        qsnprintf(buf, sizeof(buf), "Token %s", token_.toUtf8().data());
        request.setRawHeader(kAuthHeader, buf);
    }

    // qWarning("send request, url = %s\n, token = %s\n",
    //        request.url().toString().toUtf8().data(),
    //        request.rawHeader(kAuthHeader).data());

    reply_ = na_mgr_->get(request);

    connect(reply_, SIGNAL(sslErrors(const QList<QSslError>&)),
            this, SLOT(onSslErrors(const QList<QSslError>&)));

    connect(reply_, SIGNAL(finished()), this, SLOT(httpRequestFinished()));
}

void SeafileApiClient::post(const QUrl& url, const QByteArray& data, bool is_put)
{
    body_ = data;
    QNetworkRequest request(url);
    if (token_.length() > 0) {
        char buf[1024];
        qsnprintf(buf, sizeof(buf), "Token %s", token_.toUtf8().data());
        request.setRawHeader(kAuthHeader, buf);
    }
    request.setHeader(QNetworkRequest::ContentTypeHeader, kContentTypeForm);

    if (is_put)
        reply_ = na_mgr_->put(request, body_);
    else
        reply_ = na_mgr_->post(request, body_);

    connect(reply_, SIGNAL(finished()), this, SLOT(httpRequestFinished()));

    connect(reply_, SIGNAL(sslErrors(const QList<QSslError>&)),
            this, SLOT(onSslErrors(const QList<QSslError>&)));
}

void SeafileApiClient::deleteResource(const QUrl& url)
{
    QNetworkRequest request(url);

    if (token_.length() > 0) {
        char buf[1024];
        qsnprintf(buf, sizeof(buf), "Token %s", token_.toUtf8().data());
        request.setRawHeader(kAuthHeader, buf);
    }

    reply_ = na_mgr_->deleteResource(request);

    connect(reply_, SIGNAL(sslErrors(const QList<QSslError>&)),
            this, SLOT(onSslErrors(const QList<QSslError>&)));

    connect(reply_, SIGNAL(finished()), this, SLOT(httpRequestFinished()));
}

void SeafileApiClient::onSslErrors(const QList<QSslError>& errors)
{
    const QUrl url = reply_->url();
    CertsManager *mgr = seafApplet->certsManager();
    Q_FOREACH(const QSslError &error, errors) {
        const QSslCertificate &cert = error.certificate();

        if (cert.isNull()) {
            // The server has no ssl certificate, we do nothing and let the
            // request fail
            // it is a fatal error, no way to recover
            qWarning("the certificate for %s is null", url.toString().toUtf8().data());
            break;
        }

        QSslCertificate saved_cert = mgr->getCertificate(url.toString());

        if (saved_cert.isNull()) {
            // dump certificate information
            qWarning() << "\n= SslError =\n" << error.errorString();
            qWarning() << "\n= Certificate =\n" << dumpCertificate(cert);

            // This is the first time when the client connects to the server.
            if (seafApplet->detailedYesOrNoBox(
                tr("Warning: The ssl certificate of this server is not trusted, proceed anyway?"),
                error.errorString() + "\n" + dumpCertificate(cert), 0, false)) {
                mgr->saveCertificate(url, cert);
                // TODO handle ssl by verifying certificate chain instead
                reply_->ignoreSslErrors();
            }
            break;
        } else if (saved_cert == cert) {
            // The user has choosen to trust the certificate before
            // TODO handle ssl by verifying certificate chain instead
            reply_->ignoreSslErrors();
            break;
        } else {
            // dump certificate information
            qWarning() << "\n= SslError =\n" << error.errorString();
            qWarning() << "\n= Certificate =\n" << dumpCertificate(cert);
            qWarning() << "\n= Previous Certificate =\n" << dumpCertificate(saved_cert);

            /**
             * The cert which the user had chosen to trust has been changed. It
             * may be either:
             *
             * 1. The server has changed its ssl certificate
             * 2. The user's connection is under security attack
             *
             * Anyway, we'll prompt the user
             */
            SslConfirmDialog dialog(url,
                                    dumpCertificateFingerprint(cert),
                                    dumpCertificateFingerprint(saved_cert),
                                    seafApplet->mainWindow());
            if (dialog.exec() == QDialog::Accepted) {
                // TODO handle ssl by verifying certificate chain instead
                reply_->ignoreSslErrors();
                if (dialog.rememberChoice()) {
                    mgr->saveCertificate(url, cert);
                }
            } else {
                reply_->abort();
                break;
            }
            break;
        }
    }
}

void SeafileApiClient::httpRequestFinished()
{
    int code = reply_->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    if (code == 0 && reply_->error() != QNetworkReply::NoError) {
        if (NetworkManager::instance()->shouldRetry(reply_->error())) {
            qWarning("[api] network proxy error, retrying\n");
            resendRequest(reply_->url());
            return;
        }
        if (!shouldIgnoreRequestError(reply_)) {
            qWarning("[api] network error for %s: %s\n", toCStr(reply_->url().toString()),
                   reply_->errorString().toUtf8().data());
        }
        emit networkError(reply_->error(), reply_->errorString());
        return;
    }

    if (handleHttpRedirect()) {
        return;
    }

    if ((code / 100) == 4 || (code / 100) == 5) {
        if (!shouldIgnoreRequestError(reply_)) {
            qWarning("request failed for %s: status code %d\n",
                   reply_->url().toString().toUtf8().data(), code);
        }
        emit requestFailed(code);
        return;
    }

    emit requestSuccess(*reply_);
}

bool SeafileApiClient::handleHttpRedirect()
{
    QVariant redirect_attr = reply_->attribute(QNetworkRequest::RedirectionTargetAttribute);
    if (redirect_attr.isNull()) {
        return false;
    }

    if (redirect_count_++ > kMaxRedirects) {
        // simply treat too many redirects as server side error
        emit requestFailed(500);
        qWarning("too many redirects for %s\n",
               reply_->url().toString().toUtf8().data());
        return true;
    }

    QUrl redirect_url = redirect_attr.toUrl();
    if (redirect_url.isRelative()) {
        redirect_url =  reply_->url().resolved(redirect_url);
    }

    // qWarning("redirect to %s (from %s)\n", redirect_url.toString().toUtf8().data(),
    //        reply_->url().toString().toUtf8().data());
    // don't handle with this, since rename operation returns a 301
    if (reply_->operation() == QNetworkAccessManager::PostOperation)
        return false;

    resendRequest(redirect_url);

    return true;
}

void SeafileApiClient::resendRequest(const QUrl& url)
{
    switch (reply_->operation()) {
    case QNetworkAccessManager::GetOperation:
        reply_->deleteLater();
        get(url);
        break;
    case QNetworkAccessManager::PostOperation:
        post(url, body_, false);
        break;
    case QNetworkAccessManager::PutOperation:
        post(url, body_, true);
        break;
    case QNetworkAccessManager::DeleteOperation:
        reply_->deleteLater();
        deleteResource(url);
        break;
    default:
        reply_->deleteLater();
        qWarning() << "unsupported operation" << reply_->operation()
          << "to" << url.toString()
          << "from" << reply_->url().toString();
        break;
    }
}
<|endoftext|>


<commit_before>#include "RectCutWithJson.h"
#include "check_params.h"

#include <ee/FileHelper.h>
#include <ee/ImageData.h>
#include <ee/ImageTrim.h>
#include <ee/ImageClip.h>
#include <ee/StringHelper.h>
#include <ee/DummySprite.h>
#include <ee/ImageSaver.h>
#include <ee/DummySymbol.h>
#include <ee/DummySprite.h>
#include <ee/Config.h>
#include <ee/SettingData.h>
#include <ee/SymbolFile.h>

#include <easyimage.h>
#include <easycomplex.h>

#include <sprite2/SymType.h>

namespace edb
{

static const char* IMAGE_DIR = "image";
static const char* JSON_DIR = "json";

std::string RectCutWithJson::Command() const
{
	return "rect-cut-with-json";
}

std::string RectCutWithJson::Description() const
{
	return "cut image by rect and fix json file";
}

std::string RectCutWithJson::Usage() const
{
	return Command() + " [src dir] [dst dir]";
}

int RectCutWithJson::Run(int argc, char *argv[])
{
	// rect-cut-with-json e:/test2/1001 e:/test2/1002

	if (!check_number(this, argc, 3)) return -1;
	if (!check_folder(argv[2])) return -1;

	ee::SettingData& setting = ee::Config::Instance()->GetSettings();
	bool old = setting.pre_multi_alpha;
	setting.pre_multi_alpha = false;

	Trigger(argv[2], argv[3]);

	setting.pre_multi_alpha = true;

	return 0;
}

void RectCutWithJson::Trigger(const std::string& src_dir, const std::string& dst_dir)
{
	std::string out_img_dir = dst_dir + "\\" + IMAGE_DIR;
	ee::FileHelper::MkDir(out_img_dir);
	std::string out_json_dir = dst_dir + "\\" + JSON_DIR;
	ee::FileHelper::MkDir(out_json_dir);

	wxArrayString files;
	ee::FileHelper::FetchAllFiles(src_dir, files);
	for (int i = 0, n = files.size(); i < n; ++i)
	{
		wxFileName filename(files[i]);
		filename.Normalize();
		std::string filepath = filename.GetFullPath();

		std::cout << i << " / " << n << " : " << filepath << "\n";
		int type = ee::SymbolFile::Instance()->Type(filepath);
		switch (type)
		{
		case s2::SYM_IMAGE:
			RectCutImage(src_dir, dst_dir, filepath);
			break;
		case s2::SYM_COMPLEX:
			FixComplex(src_dir, dst_dir, filepath);
			break;
		case s2::SYM_ANIMATION:
			FixAnim(src_dir, dst_dir, filepath);
			break;
		case s2::SYM_SCALE9:
			FixScale9(src_dir, dst_dir, filepath);
			break;
		case s2::SYM_PARTICLE3D:
			FixParticle3d(src_dir, dst_dir, filepath);
			break;
		case s2::SYM_MESH:
			FixMesh(src_dir, dst_dir, filepath);
			break;
		}
	}
}

void RectCutWithJson::RectCutImage(const std::string& src_dir, const std::string& dst_dir,
								   const std::string& filepath) const
{
	std::string out_img_dir = dst_dir + "\\" + IMAGE_DIR;
	std::string out_json_dir = dst_dir + "\\" + JSON_DIR;

	ee::ImageData* img = ee::ImageDataMgr::Instance()->GetItem(filepath);
	ee::ImageTrim trim(*img);
	sm::rect img_r = trim.Trim();
	if (!img_r.IsValid()) {
		img_r.xmin = img_r.ymin = 0;
		img_r.xmax = img->GetWidth();
		img_r.ymax = img->GetHeight();
	}

	ee::ImageClip clip(*img);
	const uint8_t* pixels = clip.Clip(img_r.xmin, img_r.xmax, img_r.ymin, img_r.ymax);
	const sm::vec2& sz = img_r.Size();
	ee::ImageData* img_trimed = new ee::ImageData(pixels, sz.x, sz.y, img->GetChannels());

	std::string filename = ee::FileHelper::GetRelativePath(src_dir, filepath);
	filename = filename.substr(0, filename.find_last_of('.'));
	ee::StringHelper::ReplaceAll(filename, "\\", "%");

	ecomplex::Symbol complex;

	eimage::RegularRectCut rect_cut(pixels, sz.x, sz.y);
	rect_cut.AutoCut();
	const std::vector<eimage::Rect>& rects = rect_cut.GetResult();
	ee::ImageClip img_cut(*img_trimed, true);
	for (int i = 0, n = rects.size(); i < n; ++i)
	{
		const eimage::Rect& r = rects[i];
		const uint8_t* pixels = img_cut.Clip(r.x, r.x+r.w, r.y, r.y+r.h);

		std::string img_name = ee::StringHelper::Format("%s#%d#%d#%d#%d#.png", filename.c_str(), r.x, r.y, r.w, r.h);
		std::string img_out_path = out_img_dir + "\\" + img_name;
		ee::ImageSaver::StoreToFile(pixels, r.w, r.h, img->GetChannels(), img_out_path, ee::ImageSaver::e_png);
		delete[] pixels;

		std::string spr_path = std::string(out_img_dir + "\\" + img_name);
		ee::Sprite* spr = new ee::DummySprite(new ee::DummySymbol(spr_path, r.w, r.h));
		sm::vec2 offset;
		offset.x = img_r.xmin + r.x + r.w * 0.5f - img->GetWidth() * 0.5f;
		offset.y = img_r.ymin + r.y + r.h * 0.5f - img->GetHeight() * 0.5f;
		spr->Translate(offset);
		complex.Add(spr);
	}

	std::string json_out_path = out_json_dir + "\\" + filename + "_complex.json";
	ecomplex::FileStorer::Store(json_out_path, &complex, out_json_dir);

	img->RemoveReference();
	img_trimed->RemoveReference();
}

void RectCutWithJson::FixComplex(const std::string& src_dir, const std::string& dst_dir, const std::string& filepath) const
{
	Json::Value value;
	Json::Reader reader;
	std::locale::global(std::locale(""));
	std::ifstream fin(filepath.c_str());
	std::locale::global(std::locale("C"));
	reader.parse(fin, value);
	fin.close();

	std::string dir = ee::FileHelper::GetFileDir(filepath);
	for (int i = 0, n = value["sprite"].size(); i < n; ++i) {
		FixFilepath(src_dir, dst_dir, dir, value["sprite"][i]["filepath"]);
	}

	Json::StyledStreamWriter writer;
	std::locale::global(std::locale(""));
	std::ofstream fout(filepath.c_str());
	std::locale::global(std::locale("C"));
	writer.write(fout, value);
	fout.close();
}

void RectCutWithJson::FixAnim(const std::string& src_dir, const std::string& dst_dir, const std::string& filepath) const
{
	Json::Value value;
	Json::Reader reader;
	std::locale::global(std::locale(""));
	std::ifstream fin(filepath.c_str());
	std::locale::global(std::locale("C"));
	reader.parse(fin, value);
	fin.close();

	std::string dir = ee::FileHelper::GetFileDir(filepath);
	for (int layer_i = 0, layer_n = value["layer"].size(); layer_i < layer_n; ++layer_i) {
		Json::Value& layer_val = value["layer"][layer_i];
		for (int frame_i = 0, frame_n = layer_val["frame"].size(); frame_i < frame_n; ++frame_i) {
			Json::Value& frame_val = layer_val["frame"][frame_i];
			for (int actor_i = 0, actor_n = frame_val["actor"].size(); actor_i < actor_n; ++actor_i) {
				FixFilepath(src_dir, dst_dir, dir, frame_val["actor"][actor_i]["filepath"]);
			}
		}
	}

	Json::StyledStreamWriter writer;
	std::locale::global(std::locale(""));
	std::ofstream fout(filepath.c_str());
	std::locale::global(std::locale("C"));
	writer.write(fout, value);
	fout.close();
}

void RectCutWithJson::FixScale9(const std::string& src_dir, const std::string& dst_dir, const std::string& filepath) const
{
	Json::Value value;
	Json::Reader reader;
	std::locale::global(std::locale(""));
	std::ifstream fin(filepath.c_str());
	std::locale::global(std::locale("C"));
	reader.parse(fin, value);
	fin.close();

	std::string dir = ee::FileHelper::GetFileDir(filepath);
	for (int i = 0, n = value["sprite"].size(); i < n; ++i) {
		FixFilepath(src_dir, dst_dir, dir, value["sprite"][i]["filepath"]);
	}

	Json::StyledStreamWriter writer;
	std::locale::global(std::locale(""));
	std::ofstream fout(filepath.c_str());
	std::locale::global(std::locale("C"));
	writer.write(fout, value);
	fout.close();
}

void RectCutWithJson::FixParticle3d(const std::string& src_dir, const std::string& dst_dir, const std::string& filepath) const
{
	Json::Value value;
	Json::Reader reader;
	std::locale::global(std::locale(""));
	std::ifstream fin(filepath.c_str());
	std::locale::global(std::locale("C"));
	reader.parse(fin, value);
	fin.close();

	std::string dir = ee::FileHelper::GetFileDir(filepath);
	for (int i = 0, n = value["components"].size(); i < n; ++i) {
		FixFilepath(src_dir, dst_dir, dir, value["components"][i]["filepath"]);
	}

	Json::StyledStreamWriter writer;
	std::locale::global(std::locale(""));
	std::ofstream fout(filepath.c_str());
	std::locale::global(std::locale("C"));
	writer.write(fout, value);
	fout.close();
}

void RectCutWithJson::FixMesh(const std::string& src_dir, const std::string& dst_dir, const std::string& filepath) const
{
	Json::Value value;
	Json::Reader reader;
	std::locale::global(std::locale(""));
	std::ifstream fin(filepath.c_str());
	std::locale::global(std::locale("C"));
	reader.parse(fin, value);
	fin.close();

	std::string dir = ee::FileHelper::GetFileDir(filepath);
	FixFilepath(src_dir, dst_dir, dir, value["base_symbol"]);

	Json::StyledStreamWriter writer;
	std::locale::global(std::locale(""));
	std::ofstream fout(filepath.c_str());
	std::locale::global(std::locale("C"));
	writer.write(fout, value);
	fout.close();
}

void RectCutWithJson::FixFilepath(const std::string& src_dir, const std::string& dst_dir,
								  const std::string& file_dir, Json::Value& val) const
{
	std::string filepath = val.asString();
	if (ee::SymbolFile::Instance()->Type(filepath) != s2::SYM_IMAGE) {
		return;
	}

	filepath = ee::FileHelper::GetAbsolutePath(file_dir, filepath);

	std::string filename = ee::FileHelper::GetRelativePath(src_dir, filepath);
	filename = filename.substr(0, filename.find_last_of('.')) + "_complex.json";

	// todo
	const std::string oldVal = "\\", newVal = "%";
	for(std::string::size_type pos(0); pos != std::string::npos; pos += oldVal.length())
	{
		if((pos = filename.find(oldVal, pos)) != std::string::npos)
			filename.replace(pos, oldVal.length(), newVal);
		else
			break;
	}

	std::string out_json_dir = dst_dir + "\\" + JSON_DIR;
	std::string fixed_filepath = out_json_dir + "\\" + filename;
	val = ee::FileHelper::GetRelativePath(file_dir, fixed_filepath);
}

}<commit_msg>[FIXED] cut png with 3 channels<commit_after>#include "RectCutWithJson.h"
#include "check_params.h"

#include <ee/FileHelper.h>
#include <ee/ImageData.h>
#include <ee/ImageTrim.h>
#include <ee/ImageClip.h>
#include <ee/StringHelper.h>
#include <ee/DummySprite.h>
#include <ee/ImageSaver.h>
#include <ee/DummySymbol.h>
#include <ee/DummySprite.h>
#include <ee/Config.h>
#include <ee/SettingData.h>
#include <ee/SymbolFile.h>

#include <easyimage.h>
#include <easycomplex.h>

#include <sprite2/SymType.h>

namespace edb
{

static const char* IMAGE_DIR = "image";
static const char* JSON_DIR = "json";

std::string RectCutWithJson::Command() const
{
	return "rect-cut-with-json";
}

std::string RectCutWithJson::Description() const
{
	return "cut image by rect and fix json file";
}

std::string RectCutWithJson::Usage() const
{
	return Command() + " [src dir] [dst dir]";
}

int RectCutWithJson::Run(int argc, char *argv[])
{
	// rect-cut-with-json e:/test2/1001 e:/test2/1002

	if (!check_number(this, argc, 3)) return -1;
	if (!check_folder(argv[2])) return -1;

	ee::SettingData& setting = ee::Config::Instance()->GetSettings();
	bool old = setting.pre_multi_alpha;
	setting.pre_multi_alpha = false;

	Trigger(argv[2], argv[3]);

	setting.pre_multi_alpha = true;

	return 0;
}

void RectCutWithJson::Trigger(const std::string& src_dir, const std::string& dst_dir)
{
	std::string out_img_dir = dst_dir + "\\" + IMAGE_DIR;
	ee::FileHelper::MkDir(out_img_dir);
	std::string out_json_dir = dst_dir + "\\" + JSON_DIR;
	ee::FileHelper::MkDir(out_json_dir);

	wxArrayString files;
	ee::FileHelper::FetchAllFiles(src_dir, files);
	for (int i = 0, n = files.size(); i < n; ++i)
	{
		wxFileName filename(files[i]);
		filename.Normalize();
		std::string filepath = filename.GetFullPath();

		std::cout << i << " / " << n << " : " << filepath << "\n";
		int type = ee::SymbolFile::Instance()->Type(filepath);
		switch (type)
		{
		case s2::SYM_IMAGE:
			RectCutImage(src_dir, dst_dir, filepath);
			break;
		case s2::SYM_COMPLEX:
			FixComplex(src_dir, dst_dir, filepath);
			break;
		case s2::SYM_ANIMATION:
			FixAnim(src_dir, dst_dir, filepath);
			break;
		case s2::SYM_SCALE9:
			FixScale9(src_dir, dst_dir, filepath);
			break;
		case s2::SYM_PARTICLE3D:
			FixParticle3d(src_dir, dst_dir, filepath);
			break;
		case s2::SYM_MESH:
			FixMesh(src_dir, dst_dir, filepath);
			break;
		}
	}
}

void RectCutWithJson::RectCutImage(const std::string& src_dir, const std::string& dst_dir,
								   const std::string& filepath) const
{
	std::string out_img_dir = dst_dir + "\\" + IMAGE_DIR;
	std::string out_json_dir = dst_dir + "\\" + JSON_DIR;

	ee::ImageData* img = ee::ImageDataMgr::Instance()->GetItem(filepath);
	if (img->GetChannels() == 3)
	{
		std::string filename = ee::FileHelper::GetRelativePath(src_dir, filepath);
		filename = filename.substr(0, filename.find_last_of('.'));
		ee::StringHelper::ReplaceAll(filename, "\\", "%");

		ecomplex::Symbol complex;

		std::string img_name = ee::StringHelper::Format("%s#%d#%d#%d#%d#.png", filename.c_str(), 0, 0, img->GetWidth(), img->GetHeight());
		std::string img_out_path = out_img_dir + "\\" + img_name;
		ee::ImageSaver::StoreToFile(img->GetPixelData(), img->GetWidth(), img->GetHeight(), img->GetChannels(), img_out_path, ee::ImageSaver::e_png);

		std::string spr_path = std::string(out_img_dir + "\\" + img_name);
		ee::Sprite* spr = new ee::DummySprite(new ee::DummySymbol(spr_path, img->GetWidth(), img->GetHeight()));
		complex.Add(spr);

		std::string json_out_path = out_json_dir + "\\" + filename + "_complex.json";
		ecomplex::FileStorer::Store(json_out_path, &complex, out_json_dir);

		img->RemoveReference();

		return;
	}

	ee::ImageTrim trim(*img);
	sm::rect img_r = trim.Trim();
	if (!img_r.IsValid()) {
		img_r.xmin = img_r.ymin = 0;
		img_r.xmax = img->GetWidth();
		img_r.ymax = img->GetHeight();
	}

	ee::ImageClip clip(*img);
	const uint8_t* pixels = clip.Clip(img_r.xmin, img_r.xmax, img_r.ymin, img_r.ymax);
	const sm::vec2& sz = img_r.Size();
	ee::ImageData* img_trimed = new ee::ImageData(pixels, sz.x, sz.y, img->GetChannels());

	std::string filename = ee::FileHelper::GetRelativePath(src_dir, filepath);
	filename = filename.substr(0, filename.find_last_of('.'));
	ee::StringHelper::ReplaceAll(filename, "\\", "%");

	ecomplex::Symbol complex;

	eimage::RegularRectCut rect_cut(pixels, sz.x, sz.y);
	rect_cut.AutoCut();
	const std::vector<eimage::Rect>& rects = rect_cut.GetResult();
	ee::ImageClip img_cut(*img_trimed, true);
	for (int i = 0, n = rects.size(); i < n; ++i)
	{
		const eimage::Rect& r = rects[i];
		const uint8_t* pixels = img_cut.Clip(r.x, r.x+r.w, r.y, r.y+r.h);

		std::string img_name = ee::StringHelper::Format("%s#%d#%d#%d#%d#.png", filename.c_str(), r.x, r.y, r.w, r.h);
		std::string img_out_path = out_img_dir + "\\" + img_name;
		ee::ImageSaver::StoreToFile(pixels, r.w, r.h, img->GetChannels(), img_out_path, ee::ImageSaver::e_png);
		delete[] pixels;

		std::string spr_path = std::string(out_img_dir + "\\" + img_name);
		ee::Sprite* spr = new ee::DummySprite(new ee::DummySymbol(spr_path, r.w, r.h));
		sm::vec2 offset;
		offset.x = img_r.xmin + r.x + r.w * 0.5f - img->GetWidth() * 0.5f;
		offset.y = img_r.ymin + r.y + r.h * 0.5f - img->GetHeight() * 0.5f;
		spr->Translate(offset);
		complex.Add(spr);
	}

	std::string json_out_path = out_json_dir + "\\" + filename + "_complex.json";
	ecomplex::FileStorer::Store(json_out_path, &complex, out_json_dir);

	img->RemoveReference();
	img_trimed->RemoveReference();
}

void RectCutWithJson::FixComplex(const std::string& src_dir, const std::string& dst_dir, const std::string& filepath) const
{
	Json::Value value;
	Json::Reader reader;
	std::locale::global(std::locale(""));
	std::ifstream fin(filepath.c_str());
	std::locale::global(std::locale("C"));
	reader.parse(fin, value);
	fin.close();

	std::string dir = ee::FileHelper::GetFileDir(filepath);
	for (int i = 0, n = value["sprite"].size(); i < n; ++i) {
		FixFilepath(src_dir, dst_dir, dir, value["sprite"][i]["filepath"]);
	}

	Json::StyledStreamWriter writer;
	std::locale::global(std::locale(""));
	std::ofstream fout(filepath.c_str());
	std::locale::global(std::locale("C"));
	writer.write(fout, value);
	fout.close();
}

void RectCutWithJson::FixAnim(const std::string& src_dir, const std::string& dst_dir, const std::string& filepath) const
{
	Json::Value value;
	Json::Reader reader;
	std::locale::global(std::locale(""));
	std::ifstream fin(filepath.c_str());
	std::locale::global(std::locale("C"));
	reader.parse(fin, value);
	fin.close();

	std::string dir = ee::FileHelper::GetFileDir(filepath);
	for (int layer_i = 0, layer_n = value["layer"].size(); layer_i < layer_n; ++layer_i) {
		Json::Value& layer_val = value["layer"][layer_i];
		for (int frame_i = 0, frame_n = layer_val["frame"].size(); frame_i < frame_n; ++frame_i) {
			Json::Value& frame_val = layer_val["frame"][frame_i];
			for (int actor_i = 0, actor_n = frame_val["actor"].size(); actor_i < actor_n; ++actor_i) {
				FixFilepath(src_dir, dst_dir, dir, frame_val["actor"][actor_i]["filepath"]);
			}
		}
	}

	Json::StyledStreamWriter writer;
	std::locale::global(std::locale(""));
	std::ofstream fout(filepath.c_str());
	std::locale::global(std::locale("C"));
	writer.write(fout, value);
	fout.close();
}

void RectCutWithJson::FixScale9(const std::string& src_dir, const std::string& dst_dir, const std::string& filepath) const
{
	Json::Value value;
	Json::Reader reader;
	std::locale::global(std::locale(""));
	std::ifstream fin(filepath.c_str());
	std::locale::global(std::locale("C"));
	reader.parse(fin, value);
	fin.close();

	std::string dir = ee::FileHelper::GetFileDir(filepath);
	for (int i = 0, n = value["sprite"].size(); i < n; ++i) {
		FixFilepath(src_dir, dst_dir, dir, value["sprite"][i]["filepath"]);
	}

	Json::StyledStreamWriter writer;
	std::locale::global(std::locale(""));
	std::ofstream fout(filepath.c_str());
	std::locale::global(std::locale("C"));
	writer.write(fout, value);
	fout.close();
}

void RectCutWithJson::FixParticle3d(const std::string& src_dir, const std::string& dst_dir, const std::string& filepath) const
{
	Json::Value value;
	Json::Reader reader;
	std::locale::global(std::locale(""));
	std::ifstream fin(filepath.c_str());
	std::locale::global(std::locale("C"));
	reader.parse(fin, value);
	fin.close();

	std::string dir = ee::FileHelper::GetFileDir(filepath);
	for (int i = 0, n = value["components"].size(); i < n; ++i) {
		FixFilepath(src_dir, dst_dir, dir, value["components"][i]["filepath"]);
	}

	Json::StyledStreamWriter writer;
	std::locale::global(std::locale(""));
	std::ofstream fout(filepath.c_str());
	std::locale::global(std::locale("C"));
	writer.write(fout, value);
	fout.close();
}

void RectCutWithJson::FixMesh(const std::string& src_dir, const std::string& dst_dir, const std::string& filepath) const
{
	Json::Value value;
	Json::Reader reader;
	std::locale::global(std::locale(""));
	std::ifstream fin(filepath.c_str());
	std::locale::global(std::locale("C"));
	reader.parse(fin, value);
	fin.close();

	std::string dir = ee::FileHelper::GetFileDir(filepath);
	FixFilepath(src_dir, dst_dir, dir, value["base_symbol"]);

	Json::StyledStreamWriter writer;
	std::locale::global(std::locale(""));
	std::ofstream fout(filepath.c_str());
	std::locale::global(std::locale("C"));
	writer.write(fout, value);
	fout.close();
}

void RectCutWithJson::FixFilepath(const std::string& src_dir, const std::string& dst_dir,
								  const std::string& file_dir, Json::Value& val) const
{
	std::string filepath = val.asString();
	if (ee::SymbolFile::Instance()->Type(filepath) != s2::SYM_IMAGE) {
		return;
	}

	filepath = ee::FileHelper::GetAbsolutePath(file_dir, filepath);

	std::string filename = ee::FileHelper::GetRelativePath(src_dir, filepath);
	filename = filename.substr(0, filename.find_last_of('.')) + "_complex.json";

	// todo
	const std::string oldVal = "\\", newVal = "%";
	for(std::string::size_type pos(0); pos != std::string::npos; pos += oldVal.length())
	{
		if((pos = filename.find(oldVal, pos)) != std::string::npos)
			filename.replace(pos, oldVal.length(), newVal);
		else
			break;
	}

	std::string out_json_dir = dst_dir + "\\" + JSON_DIR;
	std::string fixed_filepath = out_json_dir + "\\" + filename;
	val = ee::FileHelper::GetRelativePath(file_dir, fixed_filepath);
}

}<|endoftext|>


<commit_before>//===----------------------------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// <memory>

// template <class Y, class D> explicit shared_ptr(unique_ptr<Y, D>&&r);

// UNSUPPORTED: asan, msan

#include <memory>
#include <new>
#include <cstdlib>
#include <cassert>

bool throw_next = false;

void* operator new(std::size_t s) throw(std::bad_alloc)
{
    if (throw_next)
        throw std::bad_alloc();
    return std::malloc(s);
}

void  operator delete(void* p) throw()
{
    std::free(p);
}

struct B
{
    static int count;

    B() {++count;}
    B(const B&) {++count;}
    virtual ~B() {--count;}
};

int B::count = 0;

struct A
    : public B
{
    static int count;

    A() {++count;}
    A(const A&) {++count;}
    ~A() {--count;}
};

int A::count = 0;

int main()
{
    {
    std::unique_ptr<A> ptr(new A);
    A* raw_ptr = ptr.get();
    std::shared_ptr<B> p(std::move(ptr));
    assert(A::count == 1);
    assert(B::count == 1);
    assert(p.use_count() == 1);
    assert(p.get() == raw_ptr);
    assert(ptr.get() == 0);
    }
    assert(A::count == 0);
    {
    std::unique_ptr<A> ptr(new A);
    A* raw_ptr = ptr.get();
    throw_next = true;
    try
    {
        std::shared_ptr<B> p(std::move(ptr));
        assert(false);
    }
    catch (...)
    {
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
        assert(A::count == 1);
        assert(B::count == 1);
        assert(ptr.get() == raw_ptr);
#else
        assert(A::count == 0);
        assert(B::count == 0);
        assert(ptr.get() == 0);
#endif
    }
    }
    assert(A::count == 0);
}
<commit_msg>Add a test for LWG issue #2399. We already implement this, but now we have a test as well.<commit_after>//===----------------------------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// <memory>

// template <class Y, class D> explicit shared_ptr(unique_ptr<Y, D>&&r);

// UNSUPPORTED: asan, msan

#include <memory>
#include <new>
#include <cstdlib>
#include <cassert>

bool throw_next = false;

void* operator new(std::size_t s) throw(std::bad_alloc)
{
    if (throw_next)
        throw std::bad_alloc();
    return std::malloc(s);
}

void  operator delete(void* p) throw()
{
    std::free(p);
}

struct B
{
    static int count;

    B() {++count;}
    B(const B&) {++count;}
    virtual ~B() {--count;}
};

int B::count = 0;

struct A
    : public B
{
    static int count;

    A() {++count;}
    A(const A&) {++count;}
    ~A() {--count;}
};

int A::count = 0;

void fn ( const std::shared_ptr<int> &) {}
void fn ( const std::shared_ptr<B> &) { assert (false); }

int main()
{
    {
    std::unique_ptr<A> ptr(new A);
    A* raw_ptr = ptr.get();
    std::shared_ptr<B> p(std::move(ptr));
    assert(A::count == 1);
    assert(B::count == 1);
    assert(p.use_count() == 1);
    assert(p.get() == raw_ptr);
    assert(ptr.get() == 0);
    }
    assert(A::count == 0);
    {
    std::unique_ptr<A> ptr(new A);
    A* raw_ptr = ptr.get();
    throw_next = true;
    try
    {
        std::shared_ptr<B> p(std::move(ptr));
        assert(false);
    }
    catch (...)
    {
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
        assert(A::count == 1);
        assert(B::count == 1);
        assert(ptr.get() == raw_ptr);
#else
        assert(A::count == 0);
        assert(B::count == 0);
        assert(ptr.get() == 0);
#endif
    }
    }
    assert(A::count == 0);

    // LWG 2399
    {
    throw_next = false;
    fn(std::unique_ptr<int>(new int));
    }
}
<|endoftext|>


<commit_before>// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2015-2016 Oslo and Akershus University College of Applied Sciences
// and Alfred Bratterud
//
// 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.

#ifndef HTTP_REQUEST_LINE_HPP
#define HTTP_REQUEST_LINE_HPP

#include <cctype>
#include <regex>
#include "common.hpp"
#include "methods.hpp"
#include "version.hpp"

namespace http {

//-----------------------------------
// This class represents the request-line
// of an incoming http request message
//-----------------------------------
class Request_Line {
public:
  //-----------------------------------
  // Constructor to create a default
  // request-line which is as follows:
  //
  // <GET / HTTP/1.1>
  //-----------------------------------
  explicit Request_Line() = default;

  //-----------------------------------
  // Constructor to construct a request-line
  // from the incoming character stream of
  // data which is a <std::string> object
  //
  // @tparam (std::string) request - The character stream of
  //                                 data
  //-----------------------------------
  template <typename Request>
  explicit Request_Line(Request&& request);

  // Copy / move constructors
  Request_Line(Request_Line&) = default;
  Request_Line(Request_Line&&) = default;
  ~Request_Line() noexcept = default;
  Request_Line& operator = (Request_Line&) = default;
  Request_Line& operator = (Request_Line&&) = default;

  //-----------------------------------
  // Get the method of the message
  //
  // @return - The method of the message
  //-----------------------------------
  const Method& get_method() const noexcept;

  //-----------------------------------
  // Set the method of the message
  //
  // @param method - The method of the message
  //-----------------------------------
  void set_method(const Method& method);

  //-----------------------------------
  // Get the URI of the message
  //
  // @return - The URI of the message
  //-----------------------------------
  const URI& get_uri() const noexcept;

  //-----------------------------------
  // Set the URI of the message
  //
  // @param uri - The URI of the message
  //-----------------------------------
  void set_uri(const URI& uri);

  //-----------------------------------
  // Get the version of the message
  //
  // @return - The version of the message
  //-----------------------------------
  const Version& get_version() const noexcept;

  //-----------------------------------
  // Set the version of the message
  //
  // @param version - The version of the message
  //-----------------------------------
  void set_version(const Version& version) noexcept;

  //-----------------------------------
  // Get a string representation of this
  // class
  //
  // @return - A string representation
  //-----------------------------------
  std::string to_string() const;

  //-----------------------------------
  // Operator to transform this class
  // into string form
  //-----------------------------------
  operator std::string () const;
  //-----------------------------------
private:
  //-----------------------------------
  // Class data members
  //-----------------------------------
  Method  method_  { GET };
  URI     uri_     {"/"};
  Version version_ {1U, 1U};
}; //< class Request_Line

  class Request_line_error : public std::runtime_error {
    using runtime_error::runtime_error;
  };

/**--v----------- Implementation Details -----------v--**/

template <typename Request>
inline Request_Line::Request_Line(Request&& request) {
  if (request.empty() or request.size() < 16 /*<-(16) minimum request length */) {
    return;
  }

  // Extract HTTP method
  std::string request_line = {request.substr(0, request.find("\r\n"))};

  // Should identify strings according to RFC 2616 sect.5.1
  // https://tools.ietf.org/html/rfc2616#section-5.1
  std::regex re_request_line {
    "\\s*(GET|POST|PUT|DELETE|OPTIONS|HEAD|TRACE|CONNECT) " // Method
      "(\\S+) " // URI
      "HTTP/(\\d+)\\.(\\d+)" // Version Major.Minor
      };

  std::smatch m;
  auto matched = std::regex_match(request_line,m, re_request_line);

  if (not matched)
    throw Request_line_error("Invalid request line: " + request_line);

  method_ = method::code(m[1]);
  uri_ = URI {m[2]};
  unsigned maj = static_cast<unsigned>(std::stoul(m[3]));
  unsigned min = static_cast<unsigned>(std::stoul(m[4]));
  version_ = Version{maj, min};

  // Trim the request for further processing
  request = request.substr(request.find("\r\n") + 2);
}

inline const Method& Request_Line::get_method() const noexcept {
  return method_;
}

inline void Request_Line::set_method(const Method& method) {
  method_ = method;
}

inline const URI& Request_Line::get_uri() const noexcept {
  return uri_;
}

inline void Request_Line::set_uri(const URI& uri) {
  uri_ = uri;
}

inline const Version& Request_Line::get_version() const noexcept {
  return version_;
}

inline void Request_Line::set_version(const Version& version) noexcept {
  version_ = version;
}

inline std::string Request_Line::to_string() const {
  return method::str(method_)+" "+uri_.to_string()+" "
    +version_.to_string();
}

inline Request_Line::operator std::string () const {
  std::ostringstream req_line;
  //-----------------------------
  req_line << method_  << " "
           << uri_     << " "
           << version_ << "\r\n";
 //------------------------------
  return req_line.str();
}

inline std::ostream& operator << (std::ostream& output_device, const Request_Line& req_line) {
  return output_device << req_line.to_string();
}

/**--^----------- Implementation Details -----------^--**/

} //< namespace http

#endif //< HTTP_REQUEST_LINE_HPP
<commit_msg>Fix for missing copy constructor in URI<commit_after>// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2015-2016 Oslo and Akershus University College of Applied Sciences
// and Alfred Bratterud
//
// 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.

#ifndef HTTP_REQUEST_LINE_HPP
#define HTTP_REQUEST_LINE_HPP

#include <cctype>
#include <regex>
#include "common.hpp"
#include "methods.hpp"
#include "version.hpp"

namespace http {

//-----------------------------------
// This class represents the request-line
// of an incoming http request message
//-----------------------------------
class Request_Line {
public:
  //-----------------------------------
  // Constructor to create a default
  // request-line which is as follows:
  //
  // <GET / HTTP/1.1>
  //-----------------------------------
  explicit Request_Line() = default;

  //-----------------------------------
  // Constructor to construct a request-line
  // from the incoming character stream of
  // data which is a <std::string> object
  //
  // @tparam (std::string) request - The character stream of
  //                                 data
  //-----------------------------------
  template <typename Request>
  explicit Request_Line(Request&& request);

  // Copy / move constructors
  Request_Line(Request_Line&) = default;
  Request_Line(Request_Line&&) = default;
  ~Request_Line() noexcept = default;
  Request_Line& operator = (Request_Line&) = default;
  Request_Line& operator = (Request_Line&&) = default;

  //-----------------------------------
  // Get the method of the message
  //
  // @return - The method of the message
  //-----------------------------------
  const Method& get_method() const noexcept;

  //-----------------------------------
  // Set the method of the message
  //
  // @param method - The method of the message
  //-----------------------------------
  void set_method(const Method& method);

  //-----------------------------------
  // Get the URI of the message
  //
  // @return - The URI of the message
  //-----------------------------------
  const URI& get_uri() const noexcept;

  //-----------------------------------
  // Set the URI of the message
  //
  // @param uri - The URI of the message
  //-----------------------------------
  void set_uri(const URI& uri);

  //-----------------------------------
  // Get the version of the message
  //
  // @return - The version of the message
  //-----------------------------------
  const Version& get_version() const noexcept;

  //-----------------------------------
  // Set the version of the message
  //
  // @param version - The version of the message
  //-----------------------------------
  void set_version(const Version& version) noexcept;

  //-----------------------------------
  // Get a string representation of this
  // class
  //
  // @return - A string representation
  //-----------------------------------
  std::string to_string() const;

  //-----------------------------------
  // Operator to transform this class
  // into string form
  //-----------------------------------
  operator std::string () const;
  //-----------------------------------
private:
  //-----------------------------------
  // Class data members
  //-----------------------------------
  Method  method_  { GET };
  URI     uri_     {"/"};
  Version version_ {1U, 1U};
}; //< class Request_Line

  class Request_line_error : public std::runtime_error {
    using runtime_error::runtime_error;
  };

/**--v----------- Implementation Details -----------v--**/

template <typename Request>
inline Request_Line::Request_Line(Request&& request) {
  if (request.empty() or request.size() < 16 /*<-(16) minimum request length */) {
    return;
  }

  // Extract HTTP method
  std::string request_line = {request.substr(0, request.find("\r\n"))};

  // Should identify strings according to RFC 2616 sect.5.1
  // https://tools.ietf.org/html/rfc2616#section-5.1
  std::regex re_request_line {
    "\\s*(GET|POST|PUT|DELETE|OPTIONS|HEAD|TRACE|CONNECT) " // Method
      "(\\S+) " // URI
      "HTTP/(\\d+)\\.(\\d+)" // Version Major.Minor
      };

  std::smatch m;
  auto matched = std::regex_match(request_line,m, re_request_line);

  if (not matched)
    throw Request_line_error("Invalid request line: " + request_line);

  method_ = method::code(m[1]);
  //uri_ = URI {m[2]};
  new (&uri_) URI(m[2]);
  unsigned maj = static_cast<unsigned>(std::stoul(m[3]));
  unsigned min = static_cast<unsigned>(std::stoul(m[4]));
  version_ = Version{maj, min};

  // Trim the request for further processing
  request = request.substr(request.find("\r\n") + 2);
}

inline const Method& Request_Line::get_method() const noexcept {
  return method_;
}

inline void Request_Line::set_method(const Method& method) {
  method_ = method;
}

inline const URI& Request_Line::get_uri() const noexcept {
  return uri_;
}

inline void Request_Line::set_uri(const URI& uri) {
  //uri_ = uri;
  new (&uri_) URI(uri);
}

inline const Version& Request_Line::get_version() const noexcept {
  return version_;
}

inline void Request_Line::set_version(const Version& version) noexcept {
  version_ = version;
}

inline std::string Request_Line::to_string() const {
  return method::str(method_)+" "+uri_.to_string()+" "
    +version_.to_string();
}

inline Request_Line::operator std::string () const {
  std::ostringstream req_line;
  //-----------------------------
  req_line << method_  << " "
           << uri_     << " "
           << version_ << "\r\n";
 //------------------------------
  return req_line.str();
}

inline std::ostream& operator << (std::ostream& output_device, const Request_Line& req_line) {
  return output_device << req_line.to_string();
}

/**--^----------- Implementation Details -----------^--**/

} //< namespace http

#endif //< HTTP_REQUEST_LINE_HPP
<|endoftext|>