<commit_before>

#include "RFM02.h"

uint8_t _pinFSK;
uint8_t _pinNIRQ;
uint8_t _pinSOMI;
uint8_t _pinSIMO;
uint8_t _pinChipSelect;
uint8_t _pinSerialClock;

// Booster Pack Pins FR5969
    //  7 - P2.2 for SPI_CLK mode
    // 15 - P1.6 for SPI_SIMO mode
	// 14 - P1.7 for SPI_SOMI mode
	//  5 - P2.5 output pin for SPI_CS
    // 18 - P3.0 nIRQ for sending data
    //  3 - P2.6 as FSK input data
    // Set display's VCC and DISP pins to high

static const uint8_t P_CS   = 4;
static const uint8_t P_FSK  = 3;
static const uint8_t P_NIRQ = 18;

// empty constructor
RFM02::RFM02() {
	RFM02(P_CS, P_FSK, P_NIRQ);
}

// constructor with variables
RFM02::RFM02(uint8_t pinChipSelect, uint8_t pinFSK, uint8_t pinNIRQ){
	_pinChipSelect = pinChipSelect;
	_pinFSK = pinFSK;
	_pinNIRQ = pinNIRQ;
}

/*
RFM02::RFM02(uint8_t deviceAddress) {
	RFM02(deviceAddress, CHANNEL);
}
RFM02::RFM02(uint8_t deviceAddress, uint8_t channel) {
	_deviceAddress = deviceAddress;
	_channel = channel;
	_gdo0 = GDO0;
}

*/

void RFM02::begin() {
	digitalWrite(_pinChipSelect, HIGH);
	pinMode(_pinChipSelect, OUTPUT);

	digitalWrite(_pinFSK, HIGH);
	pinMode(_pinFSK, OUTPUT);

	pinMode(P_NIRQ, INPUT);

	pinMode(26, OUTPUT);
	digitalWrite(26, HIGH);
	delay(2000);
	digitalWrite(26, LOW);

	//digitalWrite(SS,HIGH);
	//pinMode(SS,OUTPUT);

	//resetDevice();

	configureDeviceSettings();
	//execStrobeCommand(RFM02_CMD_SRX);
}

void RFM02::writeRegister(uint8_t HighByte, uint8_t LowByte) {
	digitalWrite(_pinChipSelect,LOW);
	SPI.transfer(HighByte);
	SPI.transfer(LowByte);
	digitalWrite(_pinChipSelect,HIGH);
}

void RFM02::configureDeviceSettings() {
	writeRegister(0xCC,0x00);	// read status
	writeRegister(0x90,0x8A);	// 868MHz Band +/- 90kHz Bandbreite
	writeRegister(0xA6,0x86);	// 868 MHz
	writeRegister(0xD0,0x40);	// RATE/2
	writeRegister(0xC8,0x23);	// 4.8kbps
	writeRegister(0xC2,0x20);	// Bit Sync active
	writeRegister(0xB0,0x00);	// 0dBm output power
	writeRegister(0xC0,0x01);	// disable TX

}

// Data via FSK
/******************************************************************************/
/*         Sending data via the FSK-Pin as Input-Pin                          */
/*                                                                            */
/*         After the PowerAmplifier has turned on ( ea=1 ) from rfm02-module  */
/*         comes a clock corresponding to the data-rate set before on nIRQ.   */
/*         The data to be transmitted is bitwise set on the FSK-Pin of the    */
/*         module, after the falling edge of nIRQ. With the following edge    */
/*         of nIRQ this bit is read in and sent out.                          */
/*         nSEL must be high, SCK low, both all the time                      */
/*                                                                            */
/*                                                                            */
/* TESTED: 28.09.2014 with Deviation +/- 90kHz and 435.000 MHz                */
/*                  up to 115.000BPS                                          */
/*                                                                            */
/* Support & Copyright: tigarus.programming@web.de                            */
/******************************************************************************/
void RFM02::RFM02_TX_DataByte_FSK(uint8_t DataByte){
uint8_t i=8;
// PowerAmplifier is here already enabled, impulses on nIRQ corresponding to the
// set data-rate, nSEL is high, SCK is low

      while(i){            // do 8 times..., (any number of bit's will do, also 9 or 121)
        i=i-1;
		digitalWrite(_pinFSK, LOW); //OUT_PORT_REG &= ~FSK; // first set Bitx as '0'
        if( DataByte & BIT7 )   // if not '0' write over with '1'
			//OUT_PORT_REG |= FSK;  // ...write '1' if most significant bit is '1'
			digitalWrite(_pinFSK, HIGH); // ...write '1' if most significant bit is '1'
        //while(!(IN_PORT_REG & nIRQ));  // wait for the 0-1-edge of nIRQ, reading in the data
        //while(IN_PORT_REG & nIRQ);    // wait for 1-0-edge to send the last bit
		while(!(digitalRead(_pinNIRQ))); // wait for the 0-1-edge of nIRQ, reading in the data
		while((digitalRead(_pinNIRQ)));  // wait for the 0-1-edge of nIRQ, reading in the data

        DataByte <<= 1;         // shift DataByte one bit left to write the next bit
      }
}

/*
void SendDataSPI(uint8_t data){
	digitalWrite(_pinChipSelect,LOW);
	SPI.transfer(0xC6);

	 while(i){  // any no of bit's will do, also 9 or 121
        i=i-1;

        SDI_low();                  // already set SDI-Port '0' again for next loop or
        if( data & BIT7 )          // now nIRQ is just been low, if MSB is '1'
            SDI_high();               // set SDI-Port '1'

        while(!(IN_PORT_REG & nIRQ));  // wait for the next high-pulse, data is read by
        while(IN_PORT_REG & nIRQ);     // now, wait for the falling edge

        data <<= 1;          // shift left ( next bit as most significant bit ...)

      } // end while(...)
   digitalWrite(_pinChipSelect,HIGH);
*/
<commit_msg>several changes<commit_after>

#include "RFM02.h"

uint8_t _pinFSK;
uint8_t _pinNIRQ;
uint8_t _pinSOMI;
uint8_t _pinSIMO;
uint8_t _pinChipSelect;
uint8_t _pinSerialClock;

// Booster Pack Pins FR5969
    //  7 - P2.2 for SPI_CLK mode
    // 15 - P1.6 for SPI_SIMO mode
	// 14 - P1.7 for SPI_SOMI mode
	//  5 - P2.5 output pin for SPI_CS
    // 18 - P3.0 nIRQ for sending data
    //  3 - P2.6 as FSK input data
    // Set display's VCC and DISP pins to high

static const uint8_t P_CS   = 4;
static const uint8_t P_FSK  = 3;
static const uint8_t P_NIRQ = 18;

// empty constructor
RFM02::RFM02() {
	RFM02(P_CS, P_FSK, P_NIRQ);
}

// constructor with variables
RFM02::RFM02(uint8_t pinChipSelect, uint8_t pinFSK, uint8_t pinNIRQ){
	_pinChipSelect = pinChipSelect;
	_pinFSK = pinFSK;
	_pinNIRQ = pinNIRQ;
}

/*
RFM02::RFM02(uint8_t deviceAddress) {
	RFM02(deviceAddress, CHANNEL);
}
RFM02::RFM02(uint8_t deviceAddress, uint8_t channel) {
	_deviceAddress = deviceAddress;
	_channel = channel;
	_gdo0 = GDO0;
}

*/

void RFM02::begin() {
	digitalWrite(_pinChipSelect, HIGH);
	pinMode(_pinChipSelect, OUTPUT);

	digitalWrite(_pinFSK, HIGH);
	pinMode(_pinFSK, OUTPUT);

	pinMode(P_NIRQ, INPUT);

	pinMode(26, OUTPUT);
	digitalWrite(26, HIGH);
	delay(2000);
	digitalWrite(26, LOW);

	//digitalWrite(SS,HIGH);
	//pinMode(SS,OUTPUT);

	//resetDevice();

	configureDeviceSettings();
	//execStrobeCommand(RFM02_CMD_SRX);
}

void RFM02::writeRegister(uint8_t HighByte, uint8_t LowByte) {
	digitalWrite(_pinChipSelect,LOW);
	SPI.transfer(HighByte);
	SPI.transfer(LowByte);
	digitalWrite(_pinChipSelect,HIGH);
}

void RFM02::configureDeviceSettings() {
	writeRegister(0xCC,0x00);	// read status
	writeRegister(0x90,0x82);	// 868MHz Band +/- 90kHz Bandbreite
	writeRegister(0xA6,0x86);	// 868.35 MHz
	//writeRegister(0xD0,0x40);	// RATE/2
	writeRegister(0xC8,0x47);	// 4.8kbps
	writeRegister(0xC2,0x20);	// Bit Sync active
	writeRegister(0xB3,0x00);	// 0dBm output power
	writeRegister(0xC0,0x01);	// disable TX

}

// Data via FSK
/******************************************************************************/
/*         Sending data via the FSK-Pin as Input-Pin                          */
/*                                                                            */
/*         After the PowerAmplifier has turned on ( ea=1 ) from rfm02-module  */
/*         comes a clock corresponding to the data-rate set before on nIRQ.   */
/*         The data to be transmitted is bitwise set on the FSK-Pin of the    */
/*         module, after the falling edge of nIRQ. With the following edge    */
/*         of nIRQ this bit is read in and sent out.                          */
/*         nSEL must be high, SCK low, both all the time                      */
/*                                                                            */
/*                                                                            */
/* TESTED: 28.09.2014 with Deviation +/- 90kHz and 435.000 MHz                */
/*                  up to 115.000BPS                                          */
/*                                                                            */
/* Support & Copyright: tigarus.programming@web.de                            */
/******************************************************************************/
void RFM02::RFM02_TX_DataByte_FSK(uint8_t DataByte){
uint8_t i=8;
// PowerAmplifier is here already enabled, impulses on nIRQ corresponding to the
// set data-rate, nSEL is high, SCK is low

      while(i){            // do 8 times..., (any number of bit's will do, also 9 or 121)
        i=i-1;
		digitalWrite(_pinFSK, LOW); //OUT_PORT_REG &= ~FSK; // first set Bitx as '0'
        if( DataByte & BIT7 )   // if not '0' write over with '1'
			//OUT_PORT_REG |= FSK;  // ...write '1' if most significant bit is '1'
			digitalWrite(_pinFSK, HIGH); // ...write '1' if most significant bit is '1'
        //while(!(IN_PORT_REG & nIRQ));  // wait for the 0-1-edge of nIRQ, reading in the data
        //while(IN_PORT_REG & nIRQ);    // wait for 1-0-edge to send the last bit
		while(!(digitalRead(_pinNIRQ))); // wait for the 0-1-edge of nIRQ, reading in the data
		while((digitalRead(_pinNIRQ)));  // wait for the 0-1-edge of nIRQ, reading in the data

        DataByte <<= 1;         // shift DataByte one bit left to write the next bit
      }
}

/*
void SendDataSPI(uint8_t data){
	digitalWrite(_pinChipSelect,LOW);
	SPI.transfer(0xC6);

	 while(i){  // any no of bit's will do, also 9 or 121
        i=i-1;

        SDI_low();                  // already set SDI-Port '0' again for next loop or
        if( data & BIT7 )          // now nIRQ is just been low, if MSB is '1'
            SDI_high();               // set SDI-Port '1'

        while(!(IN_PORT_REG & nIRQ));  // wait for the next high-pulse, data is read by
        while(IN_PORT_REG & nIRQ);     // now, wait for the falling edge

        data <<= 1;          // shift left ( next bit as most significant bit ...)

      } // end while(...)
   digitalWrite(_pinChipSelect,HIGH);
*/
<|endoftext|>


<commit_before>/* Copyright 2018 Google Inc. All Rights Reserved.

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

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

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

// libevent based request implementation

#include "tensorflow_serving/util/net_http/server/internal/evhttp_request.h"

#include <zlib.h>

#include <cassert>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <string>
#include <vector>

#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "libevent/include/event2/buffer.h"
#include "libevent/include/event2/event.h"
#include "libevent/include/event2/http.h"
#include "libevent/include/event2/keyvalq_struct.h"
#include "tensorflow_serving/util/net_http/compression/gzip_zlib.h"
#include "tensorflow_serving/util/net_http/internal/net_logging.h"
#include "tensorflow_serving/util/net_http/server/public/header_names.h"

namespace tensorflow {
namespace serving {
namespace net_http {

ParsedEvRequest::~ParsedEvRequest() {
  if (decoded_uri) {
    evhttp_uri_free(decoded_uri);
  }

  if (request && evhttp_request_is_owned(request)) {
    evhttp_request_free(request);
  }
}

ParsedEvRequest::ParsedEvRequest(evhttp_request* request_in)
    : request(request_in) {}

bool ParsedEvRequest::decode() {
  switch (evhttp_request_get_command(request)) {
    case EVHTTP_REQ_GET:
      method = "GET";
      break;
    case EVHTTP_REQ_POST:
      method = "POST";
      break;
    case EVHTTP_REQ_HEAD:
      method = "HEAD";
      break;
    case EVHTTP_REQ_PUT:
      method = "PUT";
      break;
    case EVHTTP_REQ_DELETE:
      method = "DELETE";
      break;
    case EVHTTP_REQ_OPTIONS:
      method = "OPTIONS";
      break;
    case EVHTTP_REQ_TRACE:
      method = "TRACE";
      break;
    case EVHTTP_REQ_CONNECT:
      method = "CONNECT";
      break;
    case EVHTTP_REQ_PATCH:
      method = "PATCH";
      break;
    default:
      return false;
  }

  uri = evhttp_request_get_uri(request);

  decoded_uri = evhttp_uri_parse(uri);
  if (decoded_uri == nullptr) {
    return false;
  }

  // NB: need double-check "/" is OK
  path = evhttp_uri_get_path(decoded_uri);
  if (path == nullptr) {
    path = "/";
  }

  path_and_query = path;
  const char* query = evhttp_uri_get_query(decoded_uri);
  if (query != nullptr) {
    path_and_query.push_back('?');
    path_and_query.append(query);
  }

  const char* fragment = evhttp_uri_get_fragment(decoded_uri);
  if (fragment != nullptr) {
    path_and_query.push_back('#');
    path_and_query.append(fragment);
  }

  headers = evhttp_request_get_input_headers(request);

  return true;
}

EvHTTPRequest::EvHTTPRequest(std::unique_ptr<ParsedEvRequest> request,
                             ServerSupport* server)
    : server_(server),
      parsed_request_(std::move(request)),
      output_buf(nullptr) {}

EvHTTPRequest::~EvHTTPRequest() {
  if (output_buf != nullptr) {
    evbuffer_free(output_buf);
  }
}

absl::string_view EvHTTPRequest::uri_path() const {
  return parsed_request_->path_and_query;
}

absl::string_view EvHTTPRequest::http_method() const {
  return parsed_request_->method;
}

bool EvHTTPRequest::Initialize() {
  output_buf = evbuffer_new();
  return output_buf != nullptr;
}

void EvHTTPRequest::WriteResponseBytes(const char* data, int64_t size) {
  assert(size >= 0);
  if (output_buf == nullptr) {
    NET_LOG(FATAL, "Request not initialized.");
    return;
  }

  int ret = evbuffer_add(output_buf, data, static_cast<size_t>(size));
  if (ret == -1) {
    NET_LOG(ERROR, "Failed to write %zu bytes data to output buffer",
            static_cast<size_t>(size));
  }
}

void EvHTTPRequest::WriteResponseString(absl::string_view data) {
  WriteResponseBytes(data.data(), static_cast<int64_t>(data.size()));
}

std::unique_ptr<char[], BlockDeleter> EvHTTPRequest::ReadRequestBytes(
    int64_t* size) {
  evbuffer* input_buf =
      evhttp_request_get_input_buffer(parsed_request_->request);
  if (input_buf == nullptr) {
    *size = 0;
    return nullptr;  // no body
  }

  // possible a reentry after gzip uncompression
  if (evbuffer_get_length(input_buf) == 0) {
    *size = 0;
    return nullptr;  // EOF
  }

  // Uncompress the entire body
  if (NeedUncompressGzipContent()) {
    return ReadRequestGzipBytes(input_buf, size);
  }

  auto buf_size = reinterpret_cast<size_t*>(size);

  *buf_size = evbuffer_get_contiguous_space(input_buf);
  assert(*buf_size > 0);

  char* block = std::allocator<char>().allocate(*buf_size);
  int ret = evbuffer_remove(input_buf, block, *buf_size);

  if (ret != *buf_size) {
    NET_LOG(ERROR, "Unexpected: read less than specified num_bytes : %zu",
            *buf_size);
    std::allocator<char>().deallocate(block, *buf_size);
    *buf_size = 0;
    return nullptr;  // don't return corrupted buffer
  }

  return std::unique_ptr<char[], BlockDeleter>(block, BlockDeleter(*buf_size));
}

std::unique_ptr<char[], BlockDeleter> EvHTTPRequest::ReadRequestGzipBytes(
    evbuffer* input_buf, int64_t* size) {
  std::vector<absl::Span<char>> buf_list;

  size_t body_length = 0;
  while (true) {
    auto buf_size = evbuffer_get_contiguous_space(input_buf);

    if (buf_size == 0) {
      break;  // EOF
    }

    char* block = std::allocator<char>().allocate(buf_size);
    int ret = evbuffer_remove(input_buf, block, buf_size);
    if (ret != buf_size) {
      NET_LOG(ERROR, "Unexpected: read less than specified num_bytes : %zu",
              buf_size);
      std::allocator<char>().deallocate(block, buf_size);
      for (auto buf : buf_list) {
        std::allocator<char>().deallocate(buf.data(), buf.size());
      }
      *size = 0;
      return nullptr;  // don't return corrupted buffer
    }

    body_length += buf_size;
    buf_list.emplace_back(block, buf_size);
  }

  char* comp_body = std::allocator<char>().allocate(body_length);

  size_t pos = 0;
  for (auto buf : buf_list) {
    memcpy(comp_body + pos, buf.data(), buf.size());
    pos += buf.size();
    std::allocator<char>().deallocate(buf.data(), buf.size());
  }

  char* uncomp_body;
  auto uncomp_size = reinterpret_cast<size_t*>(size);
  UncompressGzipBody(comp_body, body_length,
                     reinterpret_cast<void**>(&uncomp_body), uncomp_size);

  std::allocator<char>().deallocate(comp_body, body_length);

  if (uncomp_body != nullptr) {
    return std::unique_ptr<char[], BlockDeleter>(uncomp_body,
                                                 BlockDeleter(*uncomp_size));
  } else {
    NET_LOG(ERROR, "Failed to uncompress the gzipped body");
    *uncomp_size = 0;
    return nullptr;
  }
}

bool EvHTTPRequest::NeedUncompressGzipContent() {
  if (handler_options_ != nullptr &&
      handler_options_->auto_uncompress_input()) {
    auto content_encoding = GetRequestHeader(HTTPHeaders::CONTENT_ENCODING);
    return content_encoding.find("gzip") != absl::string_view::npos;
  }

  return false;
}

void EvHTTPRequest::UncompressGzipBody(void* input, size_t input_size,
                                       void** uncompressed_input,
                                       size_t* uncompressed_input_size) {
  int64_t max = handler_options_->auto_uncompress_max_size() > 0
                    ? handler_options_->auto_uncompress_max_size()
                    : ZLib::kMaxUncompressedBytes;

  // our APIs don't need expose the actual content-length
  *uncompressed_input_size = static_cast<size_t>(max);

  ZLib zlib;
  int err = zlib.UncompressGzipAndAllocate(
      reinterpret_cast<Bytef**>(uncompressed_input),
      reinterpret_cast<uLongf*>(uncompressed_input_size),
      static_cast<Bytef*>(input), static_cast<uLong>(input_size));
  if (err != Z_OK) {
    NET_LOG(ERROR, "Got zlib error: %d", err);
  }
}

// Note: passing string_view incurs a copy of underlying std::string data
// (stack)
absl::string_view EvHTTPRequest::GetRequestHeader(
    absl::string_view header) const {
  std::string header_str(header.data(), header.size());
  return absl::string_view(
      evhttp_find_header(parsed_request_->headers, header_str.c_str()));
}

std::vector<absl::string_view> EvHTTPRequest::request_headers() const {
  auto result = std::vector<absl::string_view>();
  auto ev_headers = parsed_request_->headers;

  for (evkeyval* header = ev_headers->tqh_first; header;
       header = header->next.tqe_next) {
    result.emplace_back(header->key);
  }

  return result;
}

void EvHTTPRequest::OverwriteResponseHeader(absl::string_view header,
                                            absl::string_view value) {
  evkeyvalq* ev_headers =
      evhttp_request_get_output_headers(parsed_request_->request);

  std::string header_str = std::string(header.data(), header.size());
  const char* header_cstr = header_str.c_str();

  evhttp_remove_header(ev_headers, header_cstr);
  evhttp_add_header(ev_headers, header_cstr,
                    std::string(value.data(), value.size()).c_str());
}

void EvHTTPRequest::AppendResponseHeader(absl::string_view header,
                                         absl::string_view value) {
  evkeyvalq* ev_headers =
      evhttp_request_get_output_headers(parsed_request_->request);

  int ret = evhttp_add_header(ev_headers,
                              std::string(header.data(), header.size()).c_str(),
                              std::string(value.data(), value.size()).c_str());

  if (ret != 0) {
    NET_LOG(ERROR,
            "Unexpected: failed to set the request header"
            " %.*s: %.*s",
            static_cast<int>(header.size()), header.data(),
            static_cast<int>(value.size()), value.data());
  }
}

void EvHTTPRequest::PartialReplyWithStatus(HTTPStatusCode status) {
  NET_LOG(FATAL, "PartialReplyWithStatus not implemented.");
}

void EvHTTPRequest::PartialReply() {
  NET_LOG(FATAL, "PartialReplyWithStatus not implemented.");
}

ServerRequestInterface::CallbackStatus
EvHTTPRequest::PartialReplyWithFlushCallback(std::function<void()> callback) {
  NET_LOG(FATAL, "PartialReplyWithStatus not implemented.");
  return CallbackStatus::NOT_SCHEDULED;
}

void EvHTTPRequest::ReplyWithStatus(HTTPStatusCode status) {
  bool result =
      server_->EventLoopSchedule([this, status]() { EvSendReply(status); });

  if (!result) {
    NET_LOG(ERROR, "Failed to EventLoopSchedule ReplyWithStatus()");
    Abort();
    // TODO(wenboz): should have a forced abort that doesn't write back anything
    // to the event-loop
  }
}

void EvHTTPRequest::EvSendReply(HTTPStatusCode status) {
  evhttp_send_reply(parsed_request_->request, static_cast<int>(status), nullptr,
                    output_buf);
  server_->DecOps();
  delete this;
}

void EvHTTPRequest::Reply() { ReplyWithStatus(HTTPStatusCode::OK); }

// Treats this as 500 for now and let libevent decide what to do
// with the connection.
void EvHTTPRequest::Abort() {
  evhttp_send_error(parsed_request_->request, HTTP_INTERNAL, nullptr);
  server_->DecOps();
  delete this;
}

}  // namespace net_http
}  // namespace serving
}  // namespace tensorflow
<commit_msg>Use NullSafeStringView for potentially null pointer returned from libevent<commit_after>/* Copyright 2018 Google Inc. All Rights Reserved.

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

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

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

// libevent based request implementation

#include "tensorflow_serving/util/net_http/server/internal/evhttp_request.h"

#include <zlib.h>

#include <cassert>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <string>
#include <vector>

#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "libevent/include/event2/buffer.h"
#include "libevent/include/event2/event.h"
#include "libevent/include/event2/http.h"
#include "libevent/include/event2/keyvalq_struct.h"
#include "tensorflow_serving/util/net_http/compression/gzip_zlib.h"
#include "tensorflow_serving/util/net_http/internal/net_logging.h"
#include "tensorflow_serving/util/net_http/server/public/header_names.h"

namespace tensorflow {
namespace serving {
namespace net_http {

ParsedEvRequest::~ParsedEvRequest() {
  if (decoded_uri) {
    evhttp_uri_free(decoded_uri);
  }

  if (request && evhttp_request_is_owned(request)) {
    evhttp_request_free(request);
  }
}

ParsedEvRequest::ParsedEvRequest(evhttp_request* request_in)
    : request(request_in) {}

bool ParsedEvRequest::decode() {
  switch (evhttp_request_get_command(request)) {
    case EVHTTP_REQ_GET:
      method = "GET";
      break;
    case EVHTTP_REQ_POST:
      method = "POST";
      break;
    case EVHTTP_REQ_HEAD:
      method = "HEAD";
      break;
    case EVHTTP_REQ_PUT:
      method = "PUT";
      break;
    case EVHTTP_REQ_DELETE:
      method = "DELETE";
      break;
    case EVHTTP_REQ_OPTIONS:
      method = "OPTIONS";
      break;
    case EVHTTP_REQ_TRACE:
      method = "TRACE";
      break;
    case EVHTTP_REQ_CONNECT:
      method = "CONNECT";
      break;
    case EVHTTP_REQ_PATCH:
      method = "PATCH";
      break;
    default:
      return false;
  }

  uri = evhttp_request_get_uri(request);

  decoded_uri = evhttp_uri_parse(uri);
  if (decoded_uri == nullptr) {
    return false;
  }

  // NB: need double-check "/" is OK
  path = evhttp_uri_get_path(decoded_uri);
  if (path == nullptr) {
    path = "/";
  }

  path_and_query = path;
  const char* query = evhttp_uri_get_query(decoded_uri);
  if (query != nullptr) {
    path_and_query.push_back('?');
    path_and_query.append(query);
  }

  const char* fragment = evhttp_uri_get_fragment(decoded_uri);
  if (fragment != nullptr) {
    path_and_query.push_back('#');
    path_and_query.append(fragment);
  }

  headers = evhttp_request_get_input_headers(request);

  return true;
}

EvHTTPRequest::EvHTTPRequest(std::unique_ptr<ParsedEvRequest> request,
                             ServerSupport* server)
    : server_(server),
      parsed_request_(std::move(request)),
      output_buf(nullptr) {}

EvHTTPRequest::~EvHTTPRequest() {
  if (output_buf != nullptr) {
    evbuffer_free(output_buf);
  }
}

absl::string_view EvHTTPRequest::uri_path() const {
  return parsed_request_->path_and_query;
}

absl::string_view EvHTTPRequest::http_method() const {
  return parsed_request_->method;
}

bool EvHTTPRequest::Initialize() {
  output_buf = evbuffer_new();
  return output_buf != nullptr;
}

void EvHTTPRequest::WriteResponseBytes(const char* data, int64_t size) {
  assert(size >= 0);
  if (output_buf == nullptr) {
    NET_LOG(FATAL, "Request not initialized.");
    return;
  }

  int ret = evbuffer_add(output_buf, data, static_cast<size_t>(size));
  if (ret == -1) {
    NET_LOG(ERROR, "Failed to write %zu bytes data to output buffer",
            static_cast<size_t>(size));
  }
}

void EvHTTPRequest::WriteResponseString(absl::string_view data) {
  WriteResponseBytes(data.data(), static_cast<int64_t>(data.size()));
}

std::unique_ptr<char[], BlockDeleter> EvHTTPRequest::ReadRequestBytes(
    int64_t* size) {
  evbuffer* input_buf =
      evhttp_request_get_input_buffer(parsed_request_->request);
  if (input_buf == nullptr) {
    *size = 0;
    return nullptr;  // no body
  }

  // possible a reentry after gzip uncompression
  if (evbuffer_get_length(input_buf) == 0) {
    *size = 0;
    return nullptr;  // EOF
  }

  // Uncompress the entire body
  if (NeedUncompressGzipContent()) {
    return ReadRequestGzipBytes(input_buf, size);
  }

  auto buf_size = reinterpret_cast<size_t*>(size);

  *buf_size = evbuffer_get_contiguous_space(input_buf);
  assert(*buf_size > 0);

  char* block = std::allocator<char>().allocate(*buf_size);
  int ret = evbuffer_remove(input_buf, block, *buf_size);

  if (ret != *buf_size) {
    NET_LOG(ERROR, "Unexpected: read less than specified num_bytes : %zu",
            *buf_size);
    std::allocator<char>().deallocate(block, *buf_size);
    *buf_size = 0;
    return nullptr;  // don't return corrupted buffer
  }

  return std::unique_ptr<char[], BlockDeleter>(block, BlockDeleter(*buf_size));
}

std::unique_ptr<char[], BlockDeleter> EvHTTPRequest::ReadRequestGzipBytes(
    evbuffer* input_buf, int64_t* size) {
  std::vector<absl::Span<char>> buf_list;

  size_t body_length = 0;
  while (true) {
    auto buf_size = evbuffer_get_contiguous_space(input_buf);

    if (buf_size == 0) {
      break;  // EOF
    }

    char* block = std::allocator<char>().allocate(buf_size);
    int ret = evbuffer_remove(input_buf, block, buf_size);
    if (ret != buf_size) {
      NET_LOG(ERROR, "Unexpected: read less than specified num_bytes : %zu",
              buf_size);
      std::allocator<char>().deallocate(block, buf_size);
      for (auto buf : buf_list) {
        std::allocator<char>().deallocate(buf.data(), buf.size());
      }
      *size = 0;
      return nullptr;  // don't return corrupted buffer
    }

    body_length += buf_size;
    buf_list.emplace_back(block, buf_size);
  }

  char* comp_body = std::allocator<char>().allocate(body_length);

  size_t pos = 0;
  for (auto buf : buf_list) {
    memcpy(comp_body + pos, buf.data(), buf.size());
    pos += buf.size();
    std::allocator<char>().deallocate(buf.data(), buf.size());
  }

  char* uncomp_body;
  auto uncomp_size = reinterpret_cast<size_t*>(size);
  UncompressGzipBody(comp_body, body_length,
                     reinterpret_cast<void**>(&uncomp_body), uncomp_size);

  std::allocator<char>().deallocate(comp_body, body_length);

  if (uncomp_body != nullptr) {
    return std::unique_ptr<char[], BlockDeleter>(uncomp_body,
                                                 BlockDeleter(*uncomp_size));
  } else {
    NET_LOG(ERROR, "Failed to uncompress the gzipped body");
    *uncomp_size = 0;
    return nullptr;
  }
}

bool EvHTTPRequest::NeedUncompressGzipContent() {
  if (handler_options_ != nullptr &&
      handler_options_->auto_uncompress_input()) {
    auto content_encoding = GetRequestHeader(HTTPHeaders::CONTENT_ENCODING);
    return content_encoding.find("gzip") != absl::string_view::npos;
  }

  return false;
}

void EvHTTPRequest::UncompressGzipBody(void* input, size_t input_size,
                                       void** uncompressed_input,
                                       size_t* uncompressed_input_size) {
  int64_t max = handler_options_->auto_uncompress_max_size() > 0
                    ? handler_options_->auto_uncompress_max_size()
                    : ZLib::kMaxUncompressedBytes;

  // our APIs don't need expose the actual content-length
  *uncompressed_input_size = static_cast<size_t>(max);

  ZLib zlib;
  int err = zlib.UncompressGzipAndAllocate(
      reinterpret_cast<Bytef**>(uncompressed_input),
      reinterpret_cast<uLongf*>(uncompressed_input_size),
      static_cast<Bytef*>(input), static_cast<uLong>(input_size));
  if (err != Z_OK) {
    NET_LOG(ERROR, "Got zlib error: %d", err);
  }
}

// Note: passing string_view incurs a copy of underlying std::string data
// (stack)
absl::string_view EvHTTPRequest::GetRequestHeader(
    absl::string_view header) const {
  std::string header_str(header.data(), header.size());
  return absl::NullSafeStringView(
      evhttp_find_header(parsed_request_->headers, header_str.c_str()));
}

std::vector<absl::string_view> EvHTTPRequest::request_headers() const {
  auto result = std::vector<absl::string_view>();
  auto ev_headers = parsed_request_->headers;

  for (evkeyval* header = ev_headers->tqh_first; header;
       header = header->next.tqe_next) {
    result.emplace_back(header->key);
  }

  return result;
}

void EvHTTPRequest::OverwriteResponseHeader(absl::string_view header,
                                            absl::string_view value) {
  evkeyvalq* ev_headers =
      evhttp_request_get_output_headers(parsed_request_->request);

  std::string header_str = std::string(header.data(), header.size());
  const char* header_cstr = header_str.c_str();

  evhttp_remove_header(ev_headers, header_cstr);
  evhttp_add_header(ev_headers, header_cstr,
                    std::string(value.data(), value.size()).c_str());
}

void EvHTTPRequest::AppendResponseHeader(absl::string_view header,
                                         absl::string_view value) {
  evkeyvalq* ev_headers =
      evhttp_request_get_output_headers(parsed_request_->request);

  int ret = evhttp_add_header(ev_headers,
                              std::string(header.data(), header.size()).c_str(),
                              std::string(value.data(), value.size()).c_str());

  if (ret != 0) {
    NET_LOG(ERROR,
            "Unexpected: failed to set the request header"
            " %.*s: %.*s",
            static_cast<int>(header.size()), header.data(),
            static_cast<int>(value.size()), value.data());
  }
}

void EvHTTPRequest::PartialReplyWithStatus(HTTPStatusCode status) {
  NET_LOG(FATAL, "PartialReplyWithStatus not implemented.");
}

void EvHTTPRequest::PartialReply() {
  NET_LOG(FATAL, "PartialReplyWithStatus not implemented.");
}

ServerRequestInterface::CallbackStatus
EvHTTPRequest::PartialReplyWithFlushCallback(std::function<void()> callback) {
  NET_LOG(FATAL, "PartialReplyWithStatus not implemented.");
  return CallbackStatus::NOT_SCHEDULED;
}

void EvHTTPRequest::ReplyWithStatus(HTTPStatusCode status) {
  bool result =
      server_->EventLoopSchedule([this, status]() { EvSendReply(status); });

  if (!result) {
    NET_LOG(ERROR, "Failed to EventLoopSchedule ReplyWithStatus()");
    Abort();
    // TODO(wenboz): should have a forced abort that doesn't write back anything
    // to the event-loop
  }
}

void EvHTTPRequest::EvSendReply(HTTPStatusCode status) {
  evhttp_send_reply(parsed_request_->request, static_cast<int>(status), nullptr,
                    output_buf);
  server_->DecOps();
  delete this;
}

void EvHTTPRequest::Reply() { ReplyWithStatus(HTTPStatusCode::OK); }

// Treats this as 500 for now and let libevent decide what to do
// with the connection.
void EvHTTPRequest::Abort() {
  evhttp_send_error(parsed_request_->request, HTTP_INTERNAL, nullptr);
  server_->DecOps();
  delete this;
}

}  // namespace net_http
}  // namespace serving
}  // namespace tensorflow
<|endoftext|>


<commit_before>///
/// @file  phi_sum.cpp
///
/// Copyright (C) 2016 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <primesum-internal.hpp>
#include <primesum.hpp>
#include <generate.hpp>
#include <fast_div.hpp>

#include <stdint.h>

using namespace std;
using namespace primesum;

namespace {

const int primes_[] = { 0, 2, 3, 5, 7, 11, 13, 17, 19, 23 };

maxint_t F(maxint_t u)
{
  return (u * (u + 1)) / 2;
}

template <int SIGN>
maxint_t phi_sum_tiny(maxint_t x, int64_t a)
{
  maxint_t sum = 0;

  for (; a > 0; a--)
  {
    if (x <= primes_[a])
      return sum + SIGN;
    maxint_t x2 = fast_div(x, primes_[a]);
    sum += primes_[a] * phi_sum_tiny<-SIGN>(x2, a - 1);
  }

  sum += SIGN * F(x);

  return sum;
}

template <int SIGN>
maxint_t phi_sum(maxint_t x,
                 int64_t a,
                 vector<int>& primes)
{
  maxint_t sum = 0;

  for (; a > 0; a--)
  {
    if (x <= primes[a])
      return sum + SIGN;
    maxint_t x2 = fast_div(x, primes[a]);
    sum += primes[a] * phi_sum<-SIGN>(x2, a - 1, primes);
  }

  sum += SIGN * F(x);

  return sum;
}

}

namespace primesum {

maxint_t phi_sum(maxint_t x, int64_t a)
{
  if (x < 1)
    return 0;

  if (a < 10)
    return phi_sum_tiny<1>(x, a);

  vector<int> primes = generate_n_primes(a);
  return ::phi_sum<1>(x, a, primes);
}

} // namespace
<commit_msg>Fix 128-bit integer overflow<commit_after>///
/// @file  phi_sum.cpp
///
/// Copyright (C) 2016 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <primesum-internal.hpp>
#include <primesum.hpp>
#include <generate.hpp>
#include <fast_div.hpp>

#include <stdint.h>

using namespace std;
using namespace primesum;

namespace {

const int primes_[] = { 0, 2, 3, 5, 7, 11, 13, 17, 19, 23 };

maxint_t F(maxuint_t u)
{
  return (u * (u + 1)) / 2;
}

template <int SIGN>
maxint_t phi_sum_tiny(maxint_t x, int64_t a)
{
  maxint_t sum = 0;

  for (; a > 0; a--)
  {
    if (x <= primes_[a])
      return sum + SIGN;
    maxint_t x2 = fast_div(x, primes_[a]);
    sum += primes_[a] * phi_sum_tiny<-SIGN>(x2, a - 1);
  }

  sum += SIGN * F(x);

  return sum;
}

template <int SIGN>
maxint_t phi_sum(maxint_t x,
                 int64_t a,
                 vector<int>& primes)
{
  maxint_t sum = 0;

  for (; a > 0; a--)
  {
    if (x <= primes[a])
      return sum + SIGN;
    maxint_t x2 = fast_div(x, primes[a]);
    sum += primes[a] * phi_sum<-SIGN>(x2, a - 1, primes);
  }

  sum += SIGN * F(x);

  return sum;
}

}

namespace primesum {

maxint_t phi_sum(maxint_t x, int64_t a)
{
  if (x < 1)
    return 0;

  if (a < 10)
    return phi_sum_tiny<1>(x, a);

  vector<int> primes = generate_n_primes(a);
  return ::phi_sum<1>(x, a, primes);
}

} // namespace
<|endoftext|>


<commit_before>/*
  +----------------------------------------------------------------------+
  | This file is part of the pinepain/php-v8 PHP extension.              |
  |                                                                      |
  | Copyright (c) 2015-2016 Bogdan Padalko <pinepain@gmail.com>          |
  |                                                                      |
  | Licensed under the MIT license: http://opensource.org/licenses/MIT   |
  |                                                                      |
  | For the full copyright and license information, please view the      |
  | LICENSE file that was distributed with this source or visit          |
  | http://opensource.org/licenses/MIT                                   |
  +----------------------------------------------------------------------+
*/

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <libplatform/libplatform.h>

#include "php_v8_a.h"
#include "php_v8.h"
#include <v8.h>

void php_v8_init()
{
    /* Run only once */
    if (PHP_V8_G(v8_initialized)) {
        return;
    }

    v8::V8::InitializeICU(); // TODO: check whether we actually initialized it
    // NOTE: if we use snapshot and extenal startup data then we have to initialize it (see https://codereview.chromium.org/315033002/)
    // v8::V8::InitializeExternalStartupData(NULL);
    v8::Platform *platform = v8::platform::CreateDefaultPlatform();
    v8::V8::InitializePlatform(platform);

//    const char *flags = "--no-hard_abort";
//    v8::V8::SetFlagsFromString(flags, strlen(flags));

    // TODO: remove flags?
    /* Set V8 command line flags (must be done before V8::Initialize()!) */
//    if (PHP_V8_G(v8_flags)) {
//        v8::V8::SetFlagsFromString(PHP_V8_G(v8_flags), strlen(PHP_V8_G(v8_flags)));
//    }

    /* Initialize V8 */
    v8::V8::Initialize();

    /* Run only once */
    PHP_V8_G(v8_initialized) = true;

//    TODO: probably, not necessary to call it on shutdown
//    v8::V8::Dispose();
//    v8::V8::ShutdownPlatform();
}

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
<commit_msg>Do not init ICU as we suppose to use system ICU<commit_after>/*
  +----------------------------------------------------------------------+
  | This file is part of the pinepain/php-v8 PHP extension.              |
  |                                                                      |
  | Copyright (c) 2015-2016 Bogdan Padalko <pinepain@gmail.com>          |
  |                                                                      |
  | Licensed under the MIT license: http://opensource.org/licenses/MIT   |
  |                                                                      |
  | For the full copyright and license information, please view the      |
  | LICENSE file that was distributed with this source or visit          |
  | http://opensource.org/licenses/MIT                                   |
  +----------------------------------------------------------------------+
*/

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <libplatform/libplatform.h>

#include "php_v8_a.h"
#include "php_v8.h"
#include <v8.h>

void php_v8_init()
{
    /* Run only once */
    if (PHP_V8_G(v8_initialized)) {
        return;
    }

    // NOTE: if we use snapshot and extenal startup data then we have to initialize it (see https://codereview.chromium.org/315033002/)
    // v8::V8::InitializeExternalStartupData(NULL);
    v8::Platform *platform = v8::platform::CreateDefaultPlatform();
    v8::V8::InitializePlatform(platform);

//    const char *flags = "--no-hard_abort";
//    v8::V8::SetFlagsFromString(flags, strlen(flags));

    // TODO: remove flags?
    /* Set V8 command line flags (must be done before V8::Initialize()!) */
//    if (PHP_V8_G(v8_flags)) {
//        v8::V8::SetFlagsFromString(PHP_V8_G(v8_flags), strlen(PHP_V8_G(v8_flags)));
//    }

    /* Initialize V8 */
    v8::V8::Initialize();

    /* Run only once */
    PHP_V8_G(v8_initialized) = true;

//    TODO: probably, not necessary to call it on shutdown
//    v8::V8::Dispose();
//    v8::V8::ShutdownPlatform();
}

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
<|endoftext|>


<commit_before>
#include "polybuild.h"
#include "string.h"
#include "zip.h"

#ifdef _WINDOWS
	#include <windows.h>
	#include <direct.h>
#else
	#include <dirent.h>
	#include <sys/types.h>
	#include <sys/stat.h>
#endif

#include "physfs.h"

#if defined(__APPLE__) && defined(__MACH__)
#include <mach-o/dyld.h>
#endif

using std::vector;

vector<BuildArg> args;
#define MAXFILENAME (2048)

String getArg(String argName) {
	/*
	if(argName == "--config")
		return "ExampleProject.xml";

	if(argName == "--out")
		return "ExampleProject.polyapp";

		*/

	for(int i=0; i < args.size(); i++) {
		if(args[i].name == argName) {
			return args[i].value;
		}
	}
	return "";
}

uLong filetime(
    const char *f,
    tm_zip *tmzip,
    uLong *dt)
{
  int ret=0;
  struct tm* filedate;
  time_t tm_t=0;

  if (strcmp(f,"-")!=0)
  {
    char name[MAXFILENAME+1];
    int len = strlen(f);
    if (len > MAXFILENAME)
      len = MAXFILENAME;

    strncpy(name, f,MAXFILENAME-1);
    /* strncpy doesnt append the trailing NULL, of the string is too long. */
    name[ MAXFILENAME ] = '\0';

    if (name[len - 1] == '/')
      name[len - 1] = '\0';

    /* not all systems allow stat'ing a file with / appended */
#ifdef _WINDOWS

#else
    if (stat(name,&s)==0)
    {
      tm_t = s.st_mtime;
      ret = 1;
    }
#endif
  }
  filedate = localtime(&tm_t);

  tmzip->tm_sec  = filedate->tm_sec;
  tmzip->tm_min  = filedate->tm_min;
  tmzip->tm_hour = filedate->tm_hour;
  tmzip->tm_mday = filedate->tm_mday;
  tmzip->tm_mon  = filedate->tm_mon ;
  tmzip->tm_year = filedate->tm_year;

  return ret;
}

void addFileToZip(zipFile z, String filePath, String pathInZip, bool silent) {
			if(!silent)
				printf("Packaging %s as %s\n", filePath.c_str(), pathInZip.c_str());

                	zip_fileinfo zi;
                	zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour =
			zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = 0;
			 zi.dosDate = 0;
              	 	 zi.internal_fa = 0;
             		   zi.external_fa = 0;
             		   filetime(filePath.c_str(),&zi.tmz_date,&zi.dosDate);

			zipOpenNewFileInZip(z, pathInZip.c_str(), &zi, NULL, 0, NULL, 0, NULL, Z_DEFLATED, 2);

			FILE *f = fopen(filePath.c_str(), "rb");
			fseek(f, 0, SEEK_END);
			long fileSize = ftell(f);
			fseek(f, 0, SEEK_SET);
			char *buf = (char*) malloc(fileSize);
			fread(buf, fileSize, 1, f);
			zipWriteInFileInZip(z, buf, fileSize);
			free(buf);
			fclose(f);

			zipCloseFileInZip(z);

}

void addFolderToZip(zipFile z, String folderPath, String parentFolder, bool silent) {
	std::vector<OSFileEntry> files = OSBasics::parseFolder(folderPath, false);
	for(int i=0; i < files.size(); i++) {
		if(files[i].type == OSFileEntry::TYPE_FILE) {

			String pathInZip;
			if(parentFolder == "") {
				pathInZip = files[i].name;
			} else {
				pathInZip = parentFolder + "/" + files[i].name;
			}

			addFileToZip(z, files[i].fullPath, pathInZip, silent);

		} else {
			if(parentFolder == "") {
				addFolderToZip(z, files[i].fullPath.c_str(), files[i].name, silent);
			} else {
				addFolderToZip(z, files[i].fullPath.c_str(), parentFolder + "/" + files[i].name, silent);
			}
		}
	}
}

#ifdef _WINDOWS
void wtoc(char* Dest, TCHAR* Source, int SourceSize)
{
for(int i = 0; i < SourceSize; ++i)
Dest[i] = (char)Source[i];
}
#endif

int main(int argc, char **argv) {

	PHYSFS_init(argv[0]);

#if defined(__APPLE__) && defined(__MACH__)
    uint32_t bufsize = 2048;
	char path[bufsize];
	_NSGetExecutablePath(path, &bufsize);

	String basePath = path;
	vector<String> cpts = basePath.split("/");
	String installPath = "";
	for(int i=0; i < cpts.size() - 2; i++) {
		installPath = installPath + cpts[i];
		installPath += String("/");
	}
#elif defined (_WINDOWS)
	char path[2049];
	TCHAR tpath[2049];
	GetModuleFileName(NULL, (LPWSTR)tpath, 2048);
	wtoc(path, tpath, 2048);

	String basePath = path;
	vector<String> cpts = basePath.split("\\");
	String installPath = "";
	for(int i=0; i < cpts.size() - 2; i++) {
		installPath = installPath + cpts[i];
		installPath += String("\\");
	}
#else
	String basePath = PHYSFS_getBaseDir();
	vector<String> cpts = basePath.split("/");
	String installPath = "";
	for(int i=0; i < cpts.size() - 2; i++) {
		installPath = installPath + cpts[i];
		installPath += String("/");
	}
#endif

	printf("Polycode build tool v0.8.2\n");

	for(int i=0; i < argc; i++) {
		String argString = String(argv[i]);
		vector<String> bits = argString.split("=");
		if(bits.size() == 2) {
			BuildArg arg;
			arg.name = bits[0];
			arg.value = bits[1];
		//	printf("arg: %s=%s\n", arg.name.c_str(), arg.value.c_str());
			args.push_back(arg);
		}

	}

	if(getArg("--config") == "") {
		printf("\n\nInput config XML missing. Use --config=path to specify.\n\n");
		return 1;
	}

	if(getArg("--out") == "") {
		printf("\n\nOutput file not specified. Use --out=outfile.polyapp to specify.\n\n");
		return 1;
	}

	char dirPath[4099];
#if defined(__APPLE__) && defined(__MACH__)
	getcwd(dirPath, sizeof(dirPath));
#elif defined (_WINDOWS)
	TCHAR tdirpath[4099];
	GetCurrentDirectory(4098, (LPWSTR)tdirpath);
	wtoc(dirPath, tdirpath, 4098);
#else
	getcwd(dirPath, sizeof(dirPath));
#endif

	String currentPath = String(dirPath);

	String configPath = getArg("--config");

	String finalPath = configPath;
	if(configPath[0] != '/' && configPath[1] !=':') {

#ifdef _WINDOWS
		finalPath = currentPath+"\\"+configPath;
#else
		finalPath = currentPath+"/"+configPath;
#endif
	}

	printf("Reading config file from %s\n", finalPath.c_str());

	Object configFile;
	if(!configFile.loadFromXML(finalPath)) {
		printf("Specified config file doesn't exist!\n");
		return 1;
	}
	printf("OK!\n");
	// start required params

	String entryPoint;
	int defaultWidth;
	int defaultHeight;
	int frameRate = 60;
	int antiAliasingLevel = 0;
	int anisotropyLevel = 0;
	bool vSync = false;
	bool fullScreen = false;
	float backgroundColorR = 0.2;
	float backgroundColorG = 0.2;
	float backgroundColorB = 0.2;
	String textureFiltering = "linear";

	if(configFile.root["entryPoint"]) {
		printf("Entry point: %s\n", configFile.root["entryPoint"]->stringVal.c_str());
		entryPoint = configFile.root["entryPoint"]->stringVal;
	} else {
		printf("Required parameter: \"entryPoint\" is missing from config file!\n");
		return 1;
	}

	if(configFile.root["defaultWidth"]) {
		printf("Width: %d\n", configFile.root["defaultWidth"]->intVal);
		defaultWidth = configFile.root["defaultWidth"]->intVal;
	} else {
		printf("Required parameter: \"defaultWidth\" is missing from config file!\n");
		return 1;
	}

	if(configFile.root["defaultHeight"]) {
		printf("Height: %d\n", configFile.root["defaultHeight"]->intVal);
		defaultHeight = configFile.root["defaultHeight"]->intVal;
	} else {
		printf("Required parameter: \"defaultHeight\" is missing from config file!\n");
		return 1;
	}

	// start optional params

	if(configFile.root["frameRate"]) {
		printf("Frame rate: %d\n", configFile.root["frameRate"]->intVal);
		frameRate = configFile.root["frameRate"]->intVal;
	}

	if(configFile.root["textureFiltering"]) {
		printf("Filtering mode: %s\n", configFile.root["textureFiltering"]->stringVal.c_str());
		textureFiltering = configFile.root["textureFiltering"]->stringVal;
	}

	if(configFile.root["antiAliasingLevel"]) {
		printf("Anti-aliasing level: %d\n", configFile.root["antiAliasingLevel"]->intVal);
		antiAliasingLevel = configFile.root["antiAliasingLevel"]->intVal;
	}

	if(configFile.root["anisotropyLevel"]) {
		printf("Anisotropy level: %d\n", configFile.root["anisotropyLevel"]->intVal);
		anisotropyLevel = configFile.root["anisotropyLevel"]->intVal;
	}

	if(configFile.root["vSync"]) {
		vSync = configFile.root["vSync"]->boolVal;
		if(vSync) {
			printf("V-Sync: true\n");
		} else {
			printf("V-Sync: false\n");
		}
	}

	if(configFile.root["fullScreen"]) {
		fullScreen = configFile.root["fullScreen"]->boolVal;
		if(fullScreen) {
			printf("Full-screen: true\n");
		} else {
			printf("Full-screen: false\n");
		}
	}

	if(configFile.root["backgroundColor"]) {
		ObjectEntry *color = configFile.root["backgroundColor"];
		if((*color)["red"] && (*color)["green"] && (*color)["blue"]) {
			backgroundColorR = (*color)["red"]->NumberVal;
			backgroundColorG = (*color)["green"]->NumberVal;
			backgroundColorB = (*color)["blue"]->NumberVal;
			printf("Background color: %f %f %f\n", backgroundColorR, backgroundColorG, backgroundColorB);

		} else {
			printf("backgroundColor node specified, but missing all three color attributes (red,green,blue). Ignoring.\n");
		}
	}

	zipFile z = zipOpen(getArg("--out").c_str(), 0);

	Object runInfo;
	runInfo.root.name = "PolycodeApp";
	runInfo.root.addChild("entryPoint", entryPoint);
	runInfo.root.addChild("defaultHeight", defaultHeight);
	runInfo.root.addChild("defaultWidth", defaultWidth);
	runInfo.root.addChild("frameRate", frameRate);
	runInfo.root.addChild("antiAliasingLevel", antiAliasingLevel);
	runInfo.root.addChild("anisotropyLevel", anisotropyLevel);
	runInfo.root.addChild("vSync", vSync);
	runInfo.root.addChild("fullScreen", fullScreen);
	runInfo.root.addChild("textureFiltering", String(textureFiltering));

	ObjectEntry *color = runInfo.root.addChild("backgroundColor");
	color->addChild("red", backgroundColorR);
	color->addChild("green", backgroundColorG);
	color->addChild("blue", backgroundColorB);

	addFileToZip(z, entryPoint, entryPoint, false);

	if(configFile.root["fonts"]) {
		runInfo.root.addChild(configFile.root["fonts"]);
	}

	if(configFile.root["modules"]) {
#ifdef _WINDOWS
		String modulesPath = installPath + "Modules\\";
#else
		String modulesPath = installPath + "Modules/";
#endif

		ObjectEntry *modules = configFile.root["modules"];
		if(modules) {
			for(int i=0; i < modules->length; i++) {
				printf("Adding module: %s\n", (*modules)[i]->stringVal.c_str());
				String modulePath = modulesPath + (*modules)[i]->stringVal;
#ifdef _WINDOWS
				String moduleAPIPath = modulePath + "\\API";
				String moduleLibPath = modulePath + "\\Lib";
				moduleAPIPath = moduleAPIPath.replace("\\", "/");
				moduleAPIPath = moduleAPIPath.substr(2, moduleAPIPath.length() - 2);
				moduleLibPath = moduleLibPath.replace("\\", "/");
				moduleLibPath = moduleLibPath.substr(2, moduleLibPath.length() - 2);

#else
				String moduleAPIPath = modulePath + "/API";
				String moduleLibPath = modulePath + "/Lib";
#endif
				printf("Path:%s\n", moduleAPIPath.c_str());

				addFolderToZip(z, moduleAPIPath, "", false);
				addFolderToZip(z, moduleLibPath, "__lib", false);

				//String module = configFile.root["entryPoint"]->stringVal;
			}
			runInfo.root.addChild(configFile.root["modules"]);
		}
	}

	if(configFile.root["packedItems"]) {
		ObjectEntry *packed = configFile.root["packedItems"];
		if(packed) {
			for(int i=0; i < packed->length; i++) {
				ObjectEntry *entryPath = (*(*packed)[i])["path"];
				ObjectEntry *entryType = (*(*packed)[i])["type"];
				if(entryPath && entryType) {
					if(entryType->stringVal == "folder") {
						addFolderToZip(z, entryPath->stringVal, entryPath->stringVal, false);
					} else {
						addFileToZip(z, entryPath->stringVal, entryPath->stringVal, false);
					}
				}
			}
			runInfo.root.addChild(configFile.root["packedItems"]);
		}
	}

	runInfo.saveToXML("runinfo_tmp_zzzz.polyrun");
	addFileToZip(z, "runinfo_tmp_zzzz.polyrun", "runinfo.polyrun", true);

	//addFolderToZip(z, getArg("--project"), "");

	zipClose(z, "");

#ifdef _WINDOWS
	char *buffer = _getcwd(NULL, 0);
	String workingDir = String(buffer);
	free(buffer);
	OSBasics::removeItem(workingDir+"/runinfo_tmp_zzzz.polyrun");
#else
	OSBasics::removeItem("runinfo_tmp_zzzz.polyrun");
#endif
	return 0;
}
<commit_msg>Fixed error caused by last pull request<commit_after>
#include "polybuild.h"
#include "string.h"
#include "zip.h"

#ifdef _WINDOWS
	#include <windows.h>
	#include <direct.h>
#else
	#include <dirent.h>
	#include <sys/types.h>
	#include <sys/stat.h>
#endif

#include "physfs.h"

#if defined(__APPLE__) && defined(__MACH__)
#include <mach-o/dyld.h>
#endif

using std::vector;

vector<BuildArg> args;
#define MAXFILENAME (2048)

String getArg(String argName) {
	/*
	if(argName == "--config")
		return "ExampleProject.xml";

	if(argName == "--out")
		return "ExampleProject.polyapp";

		*/

	for(int i=0; i < args.size(); i++) {
		if(args[i].name == argName) {
			return args[i].value;
		}
	}
	return "";
}

uLong filetime(
    const char *f,
    tm_zip *tmzip,
    uLong *dt)
{
  int ret=0;
  struct stat s;
  struct tm* filedate;
  time_t tm_t=0;

  if (strcmp(f,"-")!=0)
  {
    char name[MAXFILENAME+1];
    int len = strlen(f);
    if (len > MAXFILENAME)
      len = MAXFILENAME;

    strncpy(name, f,MAXFILENAME-1);
    /* strncpy doesnt append the trailing NULL, of the string is too long. */
    name[ MAXFILENAME ] = '\0';

    if (name[len - 1] == '/')
      name[len - 1] = '\0';

    /* not all systems allow stat'ing a file with / appended */
#ifdef _WINDOWS

#else
    if (stat(name,&s)==0)
    {
      tm_t = s.st_mtime;
      ret = 1;
    }
#endif
  }
  filedate = localtime(&tm_t);

  tmzip->tm_sec  = filedate->tm_sec;
  tmzip->tm_min  = filedate->tm_min;
  tmzip->tm_hour = filedate->tm_hour;
  tmzip->tm_mday = filedate->tm_mday;
  tmzip->tm_mon  = filedate->tm_mon ;
  tmzip->tm_year = filedate->tm_year;

  return ret;
}

void addFileToZip(zipFile z, String filePath, String pathInZip, bool silent) {
			if(!silent)
				printf("Packaging %s as %s\n", filePath.c_str(), pathInZip.c_str());

                	zip_fileinfo zi;
                	zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour =
			zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = 0;
			 zi.dosDate = 0;
              	 	 zi.internal_fa = 0;
             		   zi.external_fa = 0;
             		   filetime(filePath.c_str(),&zi.tmz_date,&zi.dosDate);

			zipOpenNewFileInZip(z, pathInZip.c_str(), &zi, NULL, 0, NULL, 0, NULL, Z_DEFLATED, 2);

			FILE *f = fopen(filePath.c_str(), "rb");
			fseek(f, 0, SEEK_END);
			long fileSize = ftell(f);
			fseek(f, 0, SEEK_SET);
			char *buf = (char*) malloc(fileSize);
			fread(buf, fileSize, 1, f);
			zipWriteInFileInZip(z, buf, fileSize);
			free(buf);
			fclose(f);

			zipCloseFileInZip(z);

}

void addFolderToZip(zipFile z, String folderPath, String parentFolder, bool silent) {
	std::vector<OSFileEntry> files = OSBasics::parseFolder(folderPath, false);
	for(int i=0; i < files.size(); i++) {
		if(files[i].type == OSFileEntry::TYPE_FILE) {

			String pathInZip;
			if(parentFolder == "") {
				pathInZip = files[i].name;
			} else {
				pathInZip = parentFolder + "/" + files[i].name;
			}

			addFileToZip(z, files[i].fullPath, pathInZip, silent);

		} else {
			if(parentFolder == "") {
				addFolderToZip(z, files[i].fullPath.c_str(), files[i].name, silent);
			} else {
				addFolderToZip(z, files[i].fullPath.c_str(), parentFolder + "/" + files[i].name, silent);
			}
		}
	}
}

#ifdef _WINDOWS
void wtoc(char* Dest, TCHAR* Source, int SourceSize)
{
for(int i = 0; i < SourceSize; ++i)
Dest[i] = (char)Source[i];
}
#endif

int main(int argc, char **argv) {

	PHYSFS_init(argv[0]);

#if defined(__APPLE__) && defined(__MACH__)
    uint32_t bufsize = 2048;
	char path[bufsize];
	_NSGetExecutablePath(path, &bufsize);

	String basePath = path;
	vector<String> cpts = basePath.split("/");
	String installPath = "";
	for(int i=0; i < cpts.size() - 2; i++) {
		installPath = installPath + cpts[i];
		installPath += String("/");
	}
#elif defined (_WINDOWS)
	char path[2049];
	TCHAR tpath[2049];
	GetModuleFileName(NULL, (LPWSTR)tpath, 2048);
	wtoc(path, tpath, 2048);

	String basePath = path;
	vector<String> cpts = basePath.split("\\");
	String installPath = "";
	for(int i=0; i < cpts.size() - 2; i++) {
		installPath = installPath + cpts[i];
		installPath += String("\\");
	}
#else
	String basePath = PHYSFS_getBaseDir();
	vector<String> cpts = basePath.split("/");
	String installPath = "";
	for(int i=0; i < cpts.size() - 2; i++) {
		installPath = installPath + cpts[i];
		installPath += String("/");
	}
#endif

	printf("Polycode build tool v0.8.2\n");

	for(int i=0; i < argc; i++) {
		String argString = String(argv[i]);
		vector<String> bits = argString.split("=");
		if(bits.size() == 2) {
			BuildArg arg;
			arg.name = bits[0];
			arg.value = bits[1];
		//	printf("arg: %s=%s\n", arg.name.c_str(), arg.value.c_str());
			args.push_back(arg);
		}

	}

	if(getArg("--config") == "") {
		printf("\n\nInput config XML missing. Use --config=path to specify.\n\n");
		return 1;
	}

	if(getArg("--out") == "") {
		printf("\n\nOutput file not specified. Use --out=outfile.polyapp to specify.\n\n");
		return 1;
	}

	char dirPath[4099];
#if defined(__APPLE__) && defined(__MACH__)
	getcwd(dirPath, sizeof(dirPath));
#elif defined (_WINDOWS)
	TCHAR tdirpath[4099];
	GetCurrentDirectory(4098, (LPWSTR)tdirpath);
	wtoc(dirPath, tdirpath, 4098);
#else
	getcwd(dirPath, sizeof(dirPath));
#endif

	String currentPath = String(dirPath);

	String configPath = getArg("--config");

	String finalPath = configPath;
	if(configPath[0] != '/' && configPath[1] !=':') {

#ifdef _WINDOWS
		finalPath = currentPath+"\\"+configPath;
#else
		finalPath = currentPath+"/"+configPath;
#endif
	}

	printf("Reading config file from %s\n", finalPath.c_str());

	Object configFile;
	if(!configFile.loadFromXML(finalPath)) {
		printf("Specified config file doesn't exist!\n");
		return 1;
	}
	printf("OK!\n");
	// start required params

	String entryPoint;
	int defaultWidth;
	int defaultHeight;
	int frameRate = 60;
	int antiAliasingLevel = 0;
	int anisotropyLevel = 0;
	bool vSync = false;
	bool fullScreen = false;
	float backgroundColorR = 0.2;
	float backgroundColorG = 0.2;
	float backgroundColorB = 0.2;
	String textureFiltering = "linear";

	if(configFile.root["entryPoint"]) {
		printf("Entry point: %s\n", configFile.root["entryPoint"]->stringVal.c_str());
		entryPoint = configFile.root["entryPoint"]->stringVal;
	} else {
		printf("Required parameter: \"entryPoint\" is missing from config file!\n");
		return 1;
	}

	if(configFile.root["defaultWidth"]) {
		printf("Width: %d\n", configFile.root["defaultWidth"]->intVal);
		defaultWidth = configFile.root["defaultWidth"]->intVal;
	} else {
		printf("Required parameter: \"defaultWidth\" is missing from config file!\n");
		return 1;
	}

	if(configFile.root["defaultHeight"]) {
		printf("Height: %d\n", configFile.root["defaultHeight"]->intVal);
		defaultHeight = configFile.root["defaultHeight"]->intVal;
	} else {
		printf("Required parameter: \"defaultHeight\" is missing from config file!\n");
		return 1;
	}

	// start optional params

	if(configFile.root["frameRate"]) {
		printf("Frame rate: %d\n", configFile.root["frameRate"]->intVal);
		frameRate = configFile.root["frameRate"]->intVal;
	}

	if(configFile.root["textureFiltering"]) {
		printf("Filtering mode: %s\n", configFile.root["textureFiltering"]->stringVal.c_str());
		textureFiltering = configFile.root["textureFiltering"]->stringVal;
	}

	if(configFile.root["antiAliasingLevel"]) {
		printf("Anti-aliasing level: %d\n", configFile.root["antiAliasingLevel"]->intVal);
		antiAliasingLevel = configFile.root["antiAliasingLevel"]->intVal;
	}

	if(configFile.root["anisotropyLevel"]) {
		printf("Anisotropy level: %d\n", configFile.root["anisotropyLevel"]->intVal);
		anisotropyLevel = configFile.root["anisotropyLevel"]->intVal;
	}

	if(configFile.root["vSync"]) {
		vSync = configFile.root["vSync"]->boolVal;
		if(vSync) {
			printf("V-Sync: true\n");
		} else {
			printf("V-Sync: false\n");
		}
	}

	if(configFile.root["fullScreen"]) {
		fullScreen = configFile.root["fullScreen"]->boolVal;
		if(fullScreen) {
			printf("Full-screen: true\n");
		} else {
			printf("Full-screen: false\n");
		}
	}

	if(configFile.root["backgroundColor"]) {
		ObjectEntry *color = configFile.root["backgroundColor"];
		if((*color)["red"] && (*color)["green"] && (*color)["blue"]) {
			backgroundColorR = (*color)["red"]->NumberVal;
			backgroundColorG = (*color)["green"]->NumberVal;
			backgroundColorB = (*color)["blue"]->NumberVal;
			printf("Background color: %f %f %f\n", backgroundColorR, backgroundColorG, backgroundColorB);

		} else {
			printf("backgroundColor node specified, but missing all three color attributes (red,green,blue). Ignoring.\n");
		}
	}

	zipFile z = zipOpen(getArg("--out").c_str(), 0);

	Object runInfo;
	runInfo.root.name = "PolycodeApp";
	runInfo.root.addChild("entryPoint", entryPoint);
	runInfo.root.addChild("defaultHeight", defaultHeight);
	runInfo.root.addChild("defaultWidth", defaultWidth);
	runInfo.root.addChild("frameRate", frameRate);
	runInfo.root.addChild("antiAliasingLevel", antiAliasingLevel);
	runInfo.root.addChild("anisotropyLevel", anisotropyLevel);
	runInfo.root.addChild("vSync", vSync);
	runInfo.root.addChild("fullScreen", fullScreen);
	runInfo.root.addChild("textureFiltering", String(textureFiltering));

	ObjectEntry *color = runInfo.root.addChild("backgroundColor");
	color->addChild("red", backgroundColorR);
	color->addChild("green", backgroundColorG);
	color->addChild("blue", backgroundColorB);

	addFileToZip(z, entryPoint, entryPoint, false);

	if(configFile.root["fonts"]) {
		runInfo.root.addChild(configFile.root["fonts"]);
	}

	if(configFile.root["modules"]) {
#ifdef _WINDOWS
		String modulesPath = installPath + "Modules\\";
#else
		String modulesPath = installPath + "Modules/";
#endif

		ObjectEntry *modules = configFile.root["modules"];
		if(modules) {
			for(int i=0; i < modules->length; i++) {
				printf("Adding module: %s\n", (*modules)[i]->stringVal.c_str());
				String modulePath = modulesPath + (*modules)[i]->stringVal;
#ifdef _WINDOWS
				String moduleAPIPath = modulePath + "\\API";
				String moduleLibPath = modulePath + "\\Lib";
				moduleAPIPath = moduleAPIPath.replace("\\", "/");
				moduleAPIPath = moduleAPIPath.substr(2, moduleAPIPath.length() - 2);
				moduleLibPath = moduleLibPath.replace("\\", "/");
				moduleLibPath = moduleLibPath.substr(2, moduleLibPath.length() - 2);

#else
				String moduleAPIPath = modulePath + "/API";
				String moduleLibPath = modulePath + "/Lib";
#endif
				printf("Path:%s\n", moduleAPIPath.c_str());

				addFolderToZip(z, moduleAPIPath, "", false);
				addFolderToZip(z, moduleLibPath, "__lib", false);

				//String module = configFile.root["entryPoint"]->stringVal;
			}
			runInfo.root.addChild(configFile.root["modules"]);
		}
	}

	if(configFile.root["packedItems"]) {
		ObjectEntry *packed = configFile.root["packedItems"];
		if(packed) {
			for(int i=0; i < packed->length; i++) {
				ObjectEntry *entryPath = (*(*packed)[i])["path"];
				ObjectEntry *entryType = (*(*packed)[i])["type"];
				if(entryPath && entryType) {
					if(entryType->stringVal == "folder") {
						addFolderToZip(z, entryPath->stringVal, entryPath->stringVal, false);
					} else {
						addFileToZip(z, entryPath->stringVal, entryPath->stringVal, false);
					}
				}
			}
			runInfo.root.addChild(configFile.root["packedItems"]);
		}
	}

	runInfo.saveToXML("runinfo_tmp_zzzz.polyrun");
	addFileToZip(z, "runinfo_tmp_zzzz.polyrun", "runinfo.polyrun", true);

	//addFolderToZip(z, getArg("--project"), "");

	zipClose(z, "");

#ifdef _WINDOWS
	char *buffer = _getcwd(NULL, 0);
	String workingDir = String(buffer);
	free(buffer);
	OSBasics::removeItem(workingDir+"/runinfo_tmp_zzzz.polyrun");
#else
	OSBasics::removeItem("runinfo_tmp_zzzz.polyrun");
#endif
	return 0;
}
<|endoftext|>


<commit_before>// Copyright (C) 2011, James Webber.
// Distributed under a 3-clause BSD license.  See COPYING.

#include <map>
#include "../plugin-proto/asserts.hpp"

#include "pipeline_configs.hpp"

void config::dump_config_yaml(config::pipeline_config &pc) {
  using namespace config;

  typedef pipeline_config::job_iterator_type    job_iter_t;
  typedef job_config::section_iterator_type     section_iter_t;
  typedef section_config::stage_iterator_type   stage_iter_t;

  std::map<job_config *, int> job_index;

  std::cout << "---" << std::endl;
  int thread_num = 1;
  for (job_iter_t job = pc.begin(); job != pc.end(); ++job) {
    std::cout << "- thread: " << thread_num << std::endl;
    std::cout << "  sections:" << std::endl;

    section_config *sec = job->job_first();
    do {
      NERVE_ASSERT(&(*job) == &(sec->parent_job()), "link order shouldn't go into another job");
      std::cout << "  - name: \"" << sec->name() << "\"" << std::endl;

      section_config *const prev = sec->pipeline_previous();
      section_config *const next = sec->pipeline_next();
      const char *from = prev ? prev->name() : "(start pipe)";
      const char *to = next ? next->name() : "(end pipe)";

      std::cout << "    prev: \"" << from << "\"" << std::endl;
      std::cout << "    next: \"" << to << "\"" << std::endl;
      std::cout << "    sequences:" << std::endl;

      stage_config::categories last_cat = stage_config::cat_unset;

      for (stage_iter_t stage = sec->begin(); stage != sec->end(); ++stage) {
        if (stage->category() != last_cat) {
          std::cout << "    - type: \"" << stage->category_name() << '"' << std::endl;
          std::cout << "      stages: " << std::endl;
        }

        std::cout << "      - name: \"" << stage->name() << "\"" << std::endl;

        const char *where = ":internal";
        const char *ldelim = "";
        const char *rdelim = "";
        if (! stage->internal()) {
          where = stage->path();
          ldelim = "\"";
          rdelim = "\"";
        }

        std::cout << "        location: " << ldelim << where << rdelim << std::endl;
        std::cout << "        config: ";
        if (stage->configs_given()) {
          std::cout << std::endl;

          typedef stage_config::configs_type configs_type;
          typedef configs_type::pairs_type pairs_type;
          typedef pairs_type::const_iterator iter_t;

          configs_type &cf = *NERVE_CHECK_PTR(stage->configs());
          pairs_type &pairs = cf.pairs();

          for (iter_t conf = pairs.begin(); conf != pairs.end(); ++conf) {
            const char *const key = conf->field();
            const char *const value = conf->value();
            std::cout << "        - [\"" << key << "\", \"" << value << "\"]" << std::endl;;
          }
        }
        else {
          std::cout << "[]" << std::endl;
        }
      }
    } while ((sec = sec->job_next()) != NULL);

    ++thread_num;
  }
}
<commit_msg>Minor prettyness addition.<commit_after>// Copyright (C) 2011, James Webber.
// Distributed under a 3-clause BSD license.  See COPYING.

#include <map>
#include "../plugin-proto/asserts.hpp"

#include "pipeline_configs.hpp"

void config::dump_config_yaml(config::pipeline_config &pc) {
  using namespace config;

  typedef pipeline_config::job_iterator_type    job_iter_t;
  typedef job_config::section_iterator_type     section_iter_t;
  typedef section_config::stage_iterator_type   stage_iter_t;

  std::map<job_config *, int> job_index;

  std::cout << "---" << std::endl;
  int thread_num = 1;
  for (job_iter_t job = pc.begin(); job != pc.end(); ++job) {
    std::cout << "- thread: " << thread_num << std::endl;
    std::cout << "  sections:" << std::endl;

    section_config *sec = job->job_first();
    do {
      NERVE_ASSERT(&(*job) == &(sec->parent_job()), "link order shouldn't go into another job");
      std::cout << "  - name: \"" << sec->name() << "\"" << std::endl;

      section_config *const prev = sec->pipeline_previous();
      section_config *const next = sec->pipeline_next();
      const char *from = prev ? prev->name() : ":start_pipe";
      const char *to = next ? next->name() : ":end_pipe";
      const char *to_delim = next ? "\"" : "";
      const char *from_delim = prev ? "\"" : "";

      std::cout << "    prev: " << from_delim << from << from_delim << std::endl;
      std::cout << "    next: " << to_delim << to << to_delim << std::endl;
      std::cout << "    sequences:" << std::endl;

      stage_config::categories last_cat = stage_config::cat_unset;

      for (stage_iter_t stage = sec->begin(); stage != sec->end(); ++stage) {
        if (stage->category() != last_cat) {
          std::cout << "    - type: \"" << stage->category_name() << '"' << std::endl;
          std::cout << "      stages: " << std::endl;
        }

        std::cout << "      - name: \"" << stage->name() << "\"" << std::endl;

        const char *where = ":internal";
        const char *ldelim = "";
        const char *rdelim = "";
        if (! stage->internal()) {
          where = stage->path();
          ldelim = "\"";
          rdelim = "\"";
        }

        std::cout << "        location: " << ldelim << where << rdelim << std::endl;
        std::cout << "        config: ";
        if (stage->configs_given()) {
          std::cout << std::endl;

          typedef stage_config::configs_type configs_type;
          typedef configs_type::pairs_type pairs_type;
          typedef pairs_type::const_iterator iter_t;

          configs_type &cf = *NERVE_CHECK_PTR(stage->configs());
          pairs_type &pairs = cf.pairs();

          for (iter_t conf = pairs.begin(); conf != pairs.end(); ++conf) {
            const char *const key = conf->field();
            const char *const value = conf->value();
            std::cout << "        - [\"" << key << "\", \"" << value << "\"]" << std::endl;;
          }
        }
        else {
          std::cout << "[]" << std::endl;
        }
      }
    } while ((sec = sec->job_next()) != NULL);

    ++thread_num;
  }
}
<|endoftext|>


<commit_before>#include "math.hpp"
#include "client\pointers.hpp"
#include "common_helpers.hpp"

namespace intercept {
    namespace sqf {
        namespace __math {
            float random(float max_) {
                return game_value(host::functions.invoke_raw_unary(client::__sqf::unary__random__scalar_nan__ret__scalar_nan, max_));
            }

            float abs(float value_) {
                return __helpers::__number_unary_number(client::__sqf::unary__abs__scalar_nan__ret__scalar_nan, value_);
            }

            float acos(float value_) {
                return __helpers::__number_unary_number(client::__sqf::unary__acos__scalar_nan__ret__scalar_nan, value_);
            }

            float asin(float value_) {
                return __helpers::__number_unary_number(client::__sqf::unary__asin__scalar_nan__ret__scalar_nan, value_);
            }

            float atan(float value_) {
                return __helpers::__number_unary_number(client::__sqf::unary__atan__scalar_nan__ret__scalar_nan, value_);
            }

            float atg(float value_) {
                return __helpers::__number_unary_number(client::__sqf::unary__atg__scalar_nan__ret__scalar_nan, value_);
            }

            float ceil(float value_) {
                return __helpers::__number_unary_number(client::__sqf::unary__ceil__scalar_nan__ret__scalar_nan, value_);
            }

            float cos(float value_) {
                return __helpers::__number_unary_number(client::__sqf::unary__cos__scalar_nan__ret__scalar_nan, value_);
            }

            float deg(float value_) {
                return __helpers::__number_unary_number(client::__sqf::unary__deg__scalar_nan__ret__scalar_nan, value_);
            }

            float exp(float value_) {
                return __helpers::__number_unary_number(client::__sqf::unary__exp__scalar_nan__ret__scalar_nan, value_);
            }

            float floor(float value_) {
                return __helpers::__number_unary_number(client::__sqf::unary__floor__scalar_nan__ret__scalar_nan, value_);
            }

            float ln(float value_) {
                return __helpers::__number_unary_number(client::__sqf::unary__ln__scalar_nan__ret__scalar_nan, value_);
            }

            float log(float value_) {
                return __helpers::__number_unary_number(client::__sqf::unary__log__scalar_nan__ret__scalar_nan, value_);
            }

            float rad(float value_) {
                return __helpers::__number_unary_number(client::__sqf::unary__rad__scalar_nan__ret__scalar_nan, value_);
            }

            float round(float value_) {
                return __helpers::__number_unary_number(client::__sqf::unary__round__scalar_nan__ret__scalar_nan, value_);
            }

            float sin(float value_) {
                return __helpers::__number_unary_number(client::__sqf::unary__sin__scalar_nan__ret__scalar_nan, value_);
            }

            float sqrt(float value_) {
                return __helpers::__number_unary_number(client::__sqf::unary__sqrt__scalar_nan__ret__scalar_nan, value_);
            }

            float tan(float value_) {
                return __helpers::__number_unary_number(client::__sqf::unary__tan__scalar_nan__ret__scalar_nan, value_);
            }

            float tg(float value_) {
                return __helpers::__number_unary_number(client::__sqf::unary__tg__scalar_nan__ret__scalar_nan, value_);
            }
        }
    }
}
<commit_msg>Properly remove math.cpp<commit_after><|endoftext|>


<commit_before>/* * * * * * * * * * * * *\
|*             ╔═╗ v0.3  *|
|* ╔═╦═╦═══╦═══╣ ╚═╦═╦═╗ *|
|* ║ ╔═╣ '╔╬═╗╚╣ ║ ║  '║ *|
|* ╚═╝ ╚═══╩═══╩═╩═╣ ╔═╝ *|
|* * * * * * * * * ╚═╝ * *|
|* Manipulation tool for *|
|*    ESRI Shapefiles    *|
|* * * * * * * * * * * * *|
|* http://www.npolar.no/ *|
\* * * * * * * * * * * * */

#include "polygon.hpp"
#include <algorithm>
#include <new>

namespace reshp
{
    polygon::intersection::intersection(reshp::polygon::ring* ring, reshp::polygon::ring* intersector_ring) :
        ring(ring),
        segment(NULL),
        segment_index(-1),
        intersector(intersector_ring)
    {
    }

    polygon::intersection::intersector::intersector(reshp::polygon::ring* ring) :
        ring(ring),
        segment(NULL),
        segment_index(-1)
    {
    }

    polygon::ring::ring() :
        type(polygon::ring::outer)
    {
    }

    void polygon::ring::calculate_aabb()
    {
        aabb.initialize(); // Initialize AABB with min/max extremes

        for(unsigned i = 0; i < segments.size(); ++i)
        {
            aabb.min.x = std::min(aabb.min.x, segments[i].start.x);
            aabb.min.y = std::min(aabb.min.y, segments[i].start.y);
            aabb.max.x = std::max(aabb.max.x, segments[i].start.x);
            aabb.max.y = std::max(aabb.max.y, segments[i].start.y);
        }
    }

    bool polygon::ring::contains(const reshp::point& point) const
    {
        bool inside = false;

        for(unsigned i = 0, j = segments.size() - 1; i < segments.size(); j = i++)
        {
            if(((segments[i].start.y > point.y) != (segments[j].start.y > point.y))
            && (point.x < (segments[j].start.x - segments[i].start.x) * (point.y - segments[i].start.y) / (segments[j].start.y - segments[i].start.y) + segments[i].start.x))
                inside = !inside;
        }

        return inside;
    }

    bool polygon::ring::inside(const reshp::polygon::ring& other) const
    {
        if(!aabb.inside(other.aabb))
            return false;

        for(unsigned i = 0; i < segments.size(); ++i)
            if(!other.contains(segments[i].start))
                return false;

        return true;
    }

    bool polygon::ring::intersects() const
    {
        // TODO: Efficiency test

        for(unsigned i = 0, s = segments.size(); i < s - 2; ++i)
            for(unsigned j = i + 1; j < segments.size(); ++j)
                if(j - i > 1 && j < (s - 1) + i)
                    if(segments[i].intersects(segments[j]))
                        return true;

        return false;
    }

    bool polygon::ring::intersects(const reshp::polygon::ring& other, std::vector<reshp::polygon::intersection>* intersections) const
    {
        if(!aabb.intersects(other.aabb) && !other.aabb.intersects(aabb))
            return false;

        if(intersections)
            intersections->clear();

        reshp::polygon::ring* mutable_this = const_cast<reshp::polygon::ring*>(this);
        reshp::polygon::ring* mutable_other = const_cast<reshp::polygon::ring*>(&other);
        reshp::polygon::intersection intersection(mutable_this, mutable_other);

        for(unsigned tseg = 0; tseg < this->segments.size(); ++tseg)
        {
            intersection.segment = &mutable_this->segments[tseg];
            intersection.segment_index = tseg;

            for(unsigned oseg = 0; oseg < other.segments.size(); ++oseg)
            {
                intersection.intersector.segment = &mutable_other->segments[oseg];
                intersection.intersector.segment_index = oseg;

                if(intersection.segment->intersects(*intersection.intersector.segment, &intersection.point))
                {
                    if(!intersections)
                        return true;

                    intersections->push_back(intersection);
                }
            }
        }

        if(intersections && intersections->size())
            return true;

        return false;
    }

    polygon::polygon()
    {
    }

    polygon::polygon(const reshp::polygon& poly) :
        aabb(poly.aabb),
        rings(poly.rings)
    {
    }

    polygon::polygon(const reshp::shp::polygon& poly)
    {
        for(int32_t part = 0; part < poly.num_parts; ++part)
        {
            reshp::polygon::ring ring;
            int32_t first_index = poly.parts[part];
            reshp::point first(poly.points[first_index].x, poly.points[first_index].y);

            for(int32_t p = first_index + 1; p < poly.num_points; ++p)
            {
                reshp::segment segment(reshp::point(poly.points[p - 1].x, poly.points[p - 1].y),
                                       reshp::point(poly.points[p].x, poly.points[p].y));

                ring.segments.push_back(segment);

                if(segment.end == first)
                    break;
            }

            int sum = 0;

            for(unsigned s = 0, ss = ring.segments.size(); s < ss; ++s)
                sum += (ring.segments[s].end.x - ring.segments[s].start.x) * (ring.segments[s].end.y - ring.segments[s].start.y);

            // Clockwise: Outer, Counter-clockwise: Inner
            ring.type = (sum > 0 ? ring::outer : ring::inner);

            ring.calculate_aabb();
            rings.push_back(ring);
        }

        calculate_aabb();
    }

    void polygon::calculate_aabb()
    {
        aabb.initialize(); // Initialize AABB with min/max extremes

        for(unsigned i = 0; i < rings.size(); ++i)
        {
            aabb.min.x = std::min(aabb.min.x, rings[i].aabb.min.x);
            aabb.min.y = std::min(aabb.min.y, rings[i].aabb.min.y);
            aabb.max.x = std::max(aabb.max.x, rings[i].aabb.max.x);
            aabb.max.y = std::max(aabb.max.y, rings[i].aabb.max.y);
        }
    }

    bool polygon::contains(const reshp::point& point) const
    {
        bool inside = false;

        // Return false if point is inside inner ring (hole)
        for(unsigned r = 0; r < rings.size(); ++r)
        {
            if(rings[r].contains(point))
            {
                if(rings[r].type == reshp::polygon::ring::inner)
                {
                    return false;
                }
                else if(!inside)
                    inside = true;
            }
        }

        return inside;
    }

    bool polygon::inside(const reshp::polygon& other) const
    {
        if(!aabb.inside(other.aabb))
            return false;

        for(unsigned tring = 0; tring < this->rings.size(); ++tring)
            for(unsigned oring = 0; oring < other.rings.size(); ++oring)
                if(!this->rings[tring].inside(other.rings[oring]))
                    return false;

        return true;
    }

    bool polygon::intersects() const
    {
        for(unsigned i = 0; i < rings.size(); ++i)
        {
            if(rings[i].intersects())
                return true;

            for(unsigned j = i + 1; j < rings.size(); ++j)
                if(rings[i].intersects(rings[j]))
                    return true;
        }

        return false;
    }

    bool polygon::intersects(const reshp::polygon& other, std::vector<reshp::polygon::intersection>* intersections) const
    {
        if(!aabb.intersects(other.aabb) && !other.aabb.intersects(aabb))
            return false;

        if(intersections)
            intersections->clear();

        for(unsigned tring = 0; tring < this->rings.size(); ++tring)
            for(unsigned oring = 0; oring < other.rings.size(); ++oring)
                if(this->rings[tring].intersects(other.rings[oring], intersections))
                    if(!intersections)
                        return true;

        if(intersections)
            return intersections->size();

        return false;
    }

    void polygon::operator>> (reshp::shp::polygon& poly) const
    {
        poly.box[0] = aabb.min.x;
        poly.box[1] = aabb.min.y;
        poly.box[2] = aabb.max.x;
        poly.box[3] = aabb.max.y;

        unsigned points = 0, parts = rings.size();

        for(unsigned p = 0; p < parts; ++p)
            points += rings[p].segments.size() + 1;

        if(poly.parts)
            delete poly.parts;

        if(poly.points)
            delete poly.points;

        if((poly.parts = new (std::nothrow) int32_t[parts]))
        {
            if((poly.points = new (std::nothrow) reshp::shp::point[points]))
            {
                for(unsigned r = 0; r < parts; ++r)
                {
                    poly.parts[poly.num_parts++] = poly.num_points;

                    for(unsigned s = 0; s < rings[r].segments.size(); ++s)
                        poly.points[poly.num_points++] = reshp::shp::point(rings[r].segments[s].start.x, rings[r].segments[s].start.y);

                    poly.points[poly.num_points++] = reshp::shp::point(rings[r].segments[0].start.x, rings[r].segments[0].start.y);
                }
            }
        }
    }
}
<commit_msg>Fixed a bug with polygon ring direction-calculations<commit_after>/* * * * * * * * * * * * *\
|*             ╔═╗ v0.3  *|
|* ╔═╦═╦═══╦═══╣ ╚═╦═╦═╗ *|
|* ║ ╔═╣ '╔╬═╗╚╣ ║ ║  '║ *|
|* ╚═╝ ╚═══╩═══╩═╩═╣ ╔═╝ *|
|* * * * * * * * * ╚═╝ * *|
|* Manipulation tool for *|
|*    ESRI Shapefiles    *|
|* * * * * * * * * * * * *|
|* http://www.npolar.no/ *|
\* * * * * * * * * * * * */

#include "polygon.hpp"
#include <algorithm>
#include <new>

namespace reshp
{
    polygon::intersection::intersection(reshp::polygon::ring* ring, reshp::polygon::ring* intersector_ring) :
        ring(ring),
        segment(NULL),
        segment_index(-1),
        intersector(intersector_ring)
    {
    }

    polygon::intersection::intersector::intersector(reshp::polygon::ring* ring) :
        ring(ring),
        segment(NULL),
        segment_index(-1)
    {
    }

    polygon::ring::ring() :
        type(polygon::ring::outer)
    {
    }

    void polygon::ring::calculate_aabb()
    {
        aabb.initialize(); // Initialize AABB with min/max extremes

        for(unsigned i = 0; i < segments.size(); ++i)
        {
            aabb.min.x = std::min(aabb.min.x, segments[i].start.x);
            aabb.min.y = std::min(aabb.min.y, segments[i].start.y);
            aabb.max.x = std::max(aabb.max.x, segments[i].start.x);
            aabb.max.y = std::max(aabb.max.y, segments[i].start.y);
        }
    }

    bool polygon::ring::contains(const reshp::point& point) const
    {
        bool inside = false;

        for(unsigned i = 0, j = segments.size() - 1; i < segments.size(); j = i++)
        {
            if(((segments[i].start.y > point.y) != (segments[j].start.y > point.y))
            && (point.x < (segments[j].start.x - segments[i].start.x) * (point.y - segments[i].start.y) / (segments[j].start.y - segments[i].start.y) + segments[i].start.x))
                inside = !inside;
        }

        return inside;
    }

    bool polygon::ring::inside(const reshp::polygon::ring& other) const
    {
        if(!aabb.inside(other.aabb))
            return false;

        for(unsigned i = 0; i < segments.size(); ++i)
            if(!other.contains(segments[i].start))
                return false;

        return true;
    }

    bool polygon::ring::intersects() const
    {
        // TODO: Efficiency test

        for(unsigned i = 0, s = segments.size(); i < s - 2; ++i)
            for(unsigned j = i + 1; j < segments.size(); ++j)
                if(j - i > 1 && j < (s - 1) + i)
                    if(segments[i].intersects(segments[j]))
                        return true;

        return false;
    }

    bool polygon::ring::intersects(const reshp::polygon::ring& other, std::vector<reshp::polygon::intersection>* intersections) const
    {
        if(!aabb.intersects(other.aabb) && !other.aabb.intersects(aabb))
            return false;

        if(intersections)
            intersections->clear();

        reshp::polygon::ring* mutable_this = const_cast<reshp::polygon::ring*>(this);
        reshp::polygon::ring* mutable_other = const_cast<reshp::polygon::ring*>(&other);
        reshp::polygon::intersection intersection(mutable_this, mutable_other);

        for(unsigned tseg = 0; tseg < this->segments.size(); ++tseg)
        {
            intersection.segment = &mutable_this->segments[tseg];
            intersection.segment_index = tseg;

            for(unsigned oseg = 0; oseg < other.segments.size(); ++oseg)
            {
                intersection.intersector.segment = &mutable_other->segments[oseg];
                intersection.intersector.segment_index = oseg;

                if(intersection.segment->intersects(*intersection.intersector.segment, &intersection.point))
                {
                    if(!intersections)
                        return true;

                    intersections->push_back(intersection);
                }
            }
        }

        if(intersections && intersections->size())
            return true;

        return false;
    }

    polygon::polygon()
    {
    }

    polygon::polygon(const reshp::polygon& poly) :
        aabb(poly.aabb),
        rings(poly.rings)
    {
    }

    polygon::polygon(const reshp::shp::polygon& poly)
    {
        for(int32_t part = 0; part < poly.num_parts; ++part)
        {
            reshp::polygon::ring ring;
            int32_t first_index = poly.parts[part];
            reshp::point first(poly.points[first_index].x, poly.points[first_index].y);

            for(int32_t p = first_index + 1; p < poly.num_points; ++p)
            {
                reshp::segment segment(reshp::point(poly.points[p - 1].x, poly.points[p - 1].y),
                                       reshp::point(poly.points[p].x, poly.points[p].y));

                ring.segments.push_back(segment);

                if(segment.end == first)
                    break;
            }

            int sum = 0;

            for(unsigned s = 0; s < ring.segments.size(); ++s)
                sum += (ring.segments[s].end.x - ring.segments[s].start.x) * (ring.segments[s].end.y + ring.segments[s].start.y);

            // Clockwise: Outer, Counter-clockwise: Inner
            ring.type = (sum > 0 ? ring::outer : ring::inner);

            ring.calculate_aabb();
            rings.push_back(ring);
        }

        calculate_aabb();
    }

    void polygon::calculate_aabb()
    {
        aabb.initialize(); // Initialize AABB with min/max extremes

        for(unsigned i = 0; i < rings.size(); ++i)
        {
            aabb.min.x = std::min(aabb.min.x, rings[i].aabb.min.x);
            aabb.min.y = std::min(aabb.min.y, rings[i].aabb.min.y);
            aabb.max.x = std::max(aabb.max.x, rings[i].aabb.max.x);
            aabb.max.y = std::max(aabb.max.y, rings[i].aabb.max.y);
        }
    }

    bool polygon::contains(const reshp::point& point) const
    {
        bool inside = false;

        // Return false if point is inside inner ring (hole)
        for(unsigned r = 0; r < rings.size(); ++r)
        {
            if(rings[r].contains(point))
            {
                if(rings[r].type == reshp::polygon::ring::inner)
                {
                    return false;
                }
                else if(!inside)
                    inside = true;
            }
        }

        return inside;
    }

    bool polygon::inside(const reshp::polygon& other) const
    {
        if(!aabb.inside(other.aabb))
            return false;

        for(unsigned tring = 0; tring < this->rings.size(); ++tring)
            for(unsigned oring = 0; oring < other.rings.size(); ++oring)
                if(!this->rings[tring].inside(other.rings[oring]))
                    return false;

        return true;
    }

    bool polygon::intersects() const
    {
        for(unsigned i = 0; i < rings.size(); ++i)
        {
            if(rings[i].intersects())
                return true;

            for(unsigned j = i + 1; j < rings.size(); ++j)
                if(rings[i].intersects(rings[j]))
                    return true;
        }

        return false;
    }

    bool polygon::intersects(const reshp::polygon& other, std::vector<reshp::polygon::intersection>* intersections) const
    {
        if(!aabb.intersects(other.aabb) && !other.aabb.intersects(aabb))
            return false;

        if(intersections)
            intersections->clear();

        for(unsigned tring = 0; tring < this->rings.size(); ++tring)
            for(unsigned oring = 0; oring < other.rings.size(); ++oring)
                if(this->rings[tring].intersects(other.rings[oring], intersections))
                    if(!intersections)
                        return true;

        if(intersections)
            return intersections->size();

        return false;
    }

    void polygon::operator>> (reshp::shp::polygon& poly) const
    {
        poly.box[0] = aabb.min.x;
        poly.box[1] = aabb.min.y;
        poly.box[2] = aabb.max.x;
        poly.box[3] = aabb.max.y;

        unsigned points = 0, parts = rings.size();

        for(unsigned p = 0; p < parts; ++p)
            points += rings[p].segments.size() + 1;

        if(poly.parts)
            delete poly.parts;

        if(poly.points)
            delete poly.points;

        if((poly.parts = new (std::nothrow) int32_t[parts]))
        {
            if((poly.points = new (std::nothrow) reshp::shp::point[points]))
            {
                for(unsigned r = 0; r < parts; ++r)
                {
                    poly.parts[poly.num_parts++] = poly.num_points;

                    for(unsigned s = 0; s < rings[r].segments.size(); ++s)
                        poly.points[poly.num_points++] = reshp::shp::point(rings[r].segments[s].start.x, rings[r].segments[s].start.y);

                    poly.points[poly.num_points++] = reshp::shp::point(rings[r].segments[0].start.x, rings[r].segments[0].start.y);
                }
            }
        }
    }
}
<|endoftext|>