<commit_before>// Jubatus: Online machine learning framework for distributed environment
// Copyright (C) 2013 Preferred Infrastructure and Nippon Telegraph and Telephone Corporation.
//
// 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

#ifndef JUBATUS_CLIENT_COMMON_CLIENT_HPP_
#define JUBATUS_CLIENT_COMMON_CLIENT_HPP_

#include <stdint.h>
#include <map>
#include <string>
#include <jubatus/msgpack/rpc/client.h>

namespace jubatus {
namespace client {
namespace common {

class client {
 public:
  client(const std::string& host,
         uint64_t port,
         const std::string& name,
         unsigned int timeout_sec)
      : c_(host, port), name_(name) {
    c_.set_timeout(timeout_sec);
  }

  msgpack::rpc::client& get_client() {
    return c_;
  }

  std::string get_config() {
    msgpack::rpc::future f = c_.call("get_config", name_);
    return f.get<std::string>();
  }

  bool save(const std::string& id) {
    msgpack::rpc::future f = c_.call("save", name_, id);
    return f.get<bool>();
  }

  bool load(const std::string& id) {
    msgpack::rpc::future f = c_.call("load", name_, id);
    return f.get<bool>();
  }

  std::map<std::string, std::map<std::string, std::string> > get_status() {
    msgpack::rpc::future f = c_.call("get_status", name_);
    return f.get<std::map<std::string, std::map<std::string, std::string> > >();
  }

  std::map<std::string, std::map<std::string, std::string> > get_proxy_status() {
    msgpack::rpc::future f = c_.call("get_proxy_status");
    return f.get<std::map<std::string, std::map<std::string, std::string> > >();
  }

 protected:
  msgpack::rpc::client c_;
  std::string name_;
};

}  // namespace common
}  // namespace client
}  // namespace jubatus

#endif  // JUBATUS_CLIENT_COMMON_CLIENT_HPP_
<commit_msg>Fix for cpplint<commit_after>// Jubatus: Online machine learning framework for distributed environment
// Copyright (C) 2013 Preferred Infrastructure and Nippon Telegraph and Telephone Corporation.
//
// 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

#ifndef JUBATUS_CLIENT_COMMON_CLIENT_HPP_
#define JUBATUS_CLIENT_COMMON_CLIENT_HPP_

#include <stdint.h>
#include <map>
#include <string>
#include <jubatus/msgpack/rpc/client.h>

namespace jubatus {
namespace client {
namespace common {

class client {
 public:
  client(const std::string& host,
         uint64_t port,
         const std::string& name,
         unsigned int timeout_sec)
      : c_(host, port), name_(name) {
    c_.set_timeout(timeout_sec);
  }

  msgpack::rpc::client& get_client() {
    return c_;
  }

  std::string get_config() {
    msgpack::rpc::future f = c_.call("get_config", name_);
    return f.get<std::string>();
  }

  bool save(const std::string& id) {
    msgpack::rpc::future f = c_.call("save", name_, id);
    return f.get<bool>();
  }

  bool load(const std::string& id) {
    msgpack::rpc::future f = c_.call("load", name_, id);
    return f.get<bool>();
  }

  std::map<std::string, std::map<std::string, std::string> > get_status() {
    msgpack::rpc::future f = c_.call("get_status", name_);
    return f.get<std::map<std::string, std::map<std::string, std::string> > >();
  }

  std::map<std::string, std::map<std::string, std::string> >
      get_proxy_status() {
    msgpack::rpc::future f = c_.call("get_proxy_status");
    return f.get<std::map<std::string, std::map<std::string, std::string> > >();
  }

 protected:
  msgpack::rpc::client c_;
  std::string name_;
};

}  // namespace common
}  // namespace client
}  // namespace jubatus

#endif  // JUBATUS_CLIENT_COMMON_CLIENT_HPP_
<|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2013-2018 Baptiste Wicht.
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#include <utility>

#include "compute.hpp"
#include "expenses.hpp"
#include "earnings.hpp"
#include "accounts.hpp"

budget::status budget::compute_year_status(){
    auto today = budget::local_day();
    return compute_year_status(today.year(), today.month());
}

budget::status budget::compute_year_status(year year){
    return compute_year_status(year, 12);
}

budget::status budget::compute_year_status(year year, month month){
    budget::status status;

    auto sm = start_month(year);

    for(auto& expense : all_expenses()){
        if(expense.date.year() == year && expense.date.month() >= sm && expense.date.month() <= month){
            status.expenses += expense.amount;
        }
    }

    budget::money year_earnings;
    for(auto& earning : all_earnings()){
        if(earning.date.year() == year && earning.date.month() >= sm && earning.date.month() <= month){
            status.earnings += earning.amount;
        }
    }

    for(unsigned short i = sm; i <= month; ++i){
        budget::month month = i;

        for(auto& c : all_accounts(year, month)){
            status.budget += c.amount;
        }
    }

    status.balance = status.budget + status.earnings - status.expenses;

    return status;
}

budget::status budget::compute_month_status(){
    auto today = budget::local_day();
    return compute_month_status(today.year(), today.month());
}

budget::status budget::compute_month_status(month month){
    auto today = budget::local_day();
    return compute_month_status(today.year(), month);
}

budget::status budget::compute_month_status(year year, month month){
    budget::status status;

    for(auto& expense : all_expenses()){
        if(expense.date.year() == year && expense.date.month() == month){
            status.expenses += expense.amount;
        }
    }

    for(auto& earning : all_earnings()){
        if(earning.date.year() == year && earning.date.month() == month){
            status.earnings += earning.amount;
        }
    }

    for(auto& c : all_accounts(year, month)){
        status.budget += c.amount;
    }

    status.balance = status.budget + status.earnings - status.expenses;

    return std::move(status);
}

budget::status budget::compute_avg_month_status(){
    auto today = budget::local_day();
    return compute_avg_month_status(today.year(), today.month());
}

budget::status budget::compute_avg_month_status(month month){
    auto today = budget::local_day();
    return compute_avg_month_status(today.year(), month);
}

budget::status budget::compute_avg_month_status(year year, month month){
    budget::status avg_status;

    for(budget::month m = 1; m < month; m = m + 1){
        auto status = compute_month_status(year, m);

        avg_status.expenses += status.expenses;
        avg_status.earnings += status.earnings;
        avg_status.budget += status.budget;
        avg_status.balance += status.balance;
    }

    avg_status.expenses /= month.value;
    avg_status.earnings /= month.value;
    avg_status.budget /= month.value;
    avg_status.balance /= month.value;

    return std::move(avg_status);
}
<commit_msg>Fix average status computation<commit_after>//=======================================================================
// Copyright (c) 2013-2018 Baptiste Wicht.
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#include <utility>

#include "compute.hpp"
#include "expenses.hpp"
#include "earnings.hpp"
#include "accounts.hpp"

budget::status budget::compute_year_status(){
    auto today = budget::local_day();
    return compute_year_status(today.year(), today.month());
}

budget::status budget::compute_year_status(year year){
    return compute_year_status(year, 12);
}

budget::status budget::compute_year_status(year year, month month){
    budget::status status;

    auto sm = start_month(year);

    for(auto& expense : all_expenses()){
        if(expense.date.year() == year && expense.date.month() >= sm && expense.date.month() <= month){
            status.expenses += expense.amount;
        }
    }

    budget::money year_earnings;
    for(auto& earning : all_earnings()){
        if(earning.date.year() == year && earning.date.month() >= sm && earning.date.month() <= month){
            status.earnings += earning.amount;
        }
    }

    for(unsigned short i = sm; i <= month; ++i){
        budget::month month = i;

        for(auto& c : all_accounts(year, month)){
            status.budget += c.amount;
        }
    }

    status.balance = status.budget + status.earnings - status.expenses;

    return status;
}

budget::status budget::compute_month_status(){
    auto today = budget::local_day();
    return compute_month_status(today.year(), today.month());
}

budget::status budget::compute_month_status(month month){
    auto today = budget::local_day();
    return compute_month_status(today.year(), month);
}

budget::status budget::compute_month_status(year year, month month){
    budget::status status;

    for(auto& expense : all_expenses()){
        if(expense.date.year() == year && expense.date.month() == month){
            status.expenses += expense.amount;
        }
    }

    for(auto& earning : all_earnings()){
        if(earning.date.year() == year && earning.date.month() == month){
            status.earnings += earning.amount;
        }
    }

    for(auto& c : all_accounts(year, month)){
        status.budget += c.amount;
    }

    status.balance = status.budget + status.earnings - status.expenses;

    return std::move(status);
}

budget::status budget::compute_avg_month_status(){
    auto today = budget::local_day();
    return compute_avg_month_status(today.year(), today.month());
}

budget::status budget::compute_avg_month_status(month month){
    auto today = budget::local_day();
    return compute_avg_month_status(today.year(), month);
}

budget::status budget::compute_avg_month_status(year year, month month){
    budget::status avg_status;

    for(budget::month m = 1; m < month; m = m + 1){
        auto status = compute_month_status(year, m);

        avg_status.expenses += status.expenses;
        avg_status.earnings += status.earnings;
        avg_status.budget += status.budget;
        avg_status.balance += status.balance;
    }

    if(month.value > 1){
        avg_status.expenses /= month.value - 1;
        avg_status.earnings /= month.value - 1;
        avg_status.budget /= month.value - 1;
        avg_status.balance /= month.value - 1;
    }

    return std::move(avg_status);
}
<|endoftext|>


<commit_before>#include <iostream>

#include <SLRenderer/SLRenderer.hpp>
#include <glfw/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtc/matrix_transform.hpp>

// main
int main(int argc, char** argv)
{
	//////////////////////////////////////////////////////////////////////////
	// set error handling
	glfwSetErrorCallback([](int error, const char* description) {
		std::cout << "Error: " << description << std::endl;
	});

	// init glfw
	glfwInit();

	// select OpenGL ES version
	glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
	glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_EGL_CONTEXT_API);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);

// 	// select OpenGL version
// 	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
// 	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
// 	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);

	// create window
	GLFWwindow* window = glfwCreateWindow(800, 600, "GLFW OpenGL3", nullptr, nullptr);

	// set current context
	glfwMakeContextCurrent(window);

	// setup thescene ready for rendering
	int width = 0, height = 0;
	glfwGetFramebufferSize(window, &width, &height);

	//////////////////////////////////////////////////////////////////////////

	// create renderer
	ISLRenderer* renderer = SLRendererFabric::CreateRenderer(SL_RENDERER_TYPE_GL3);
	std::cout << renderer->GetDescription() << std::endl;

	// create buffers
	ISLBuffer* positionBuffer = renderer->CreateBuffer(nullptr, 1024);
	ISLBuffer* noramlBuffer = renderer->CreateBuffer(nullptr, 1024);
	ISLIndexBuffer* indexBuffer = renderer->CreateIndexBuffer(nullptr, 1024);

	// create texture
	ISLTexture2D* baseTexture = renderer->CreateTexture2D(nullptr, 0, 1, 1, SL_PIXEL_DATA_TYPE_RGRA);

	// create mesh and setup buffers
	ISLMesh* mesh = renderer->CreateMesh();
	mesh->SetPositionBuffer(positionBuffer);
	mesh->SetNormalBuffer(noramlBuffer);
	mesh->SetIndexBuffer(indexBuffer);
	mesh->SetBaseTexture(baseTexture);
	mesh->SetBaseColor(1.0f, 1.0f, 1.0f, 1.0f);

	// create model
	glm::mat4 transform(1.0f);
	ISLModel* model = renderer->CreateModel();
	model->AddMesh(mesh);
	model->SetTransform(&transform[0][0]);
	model->SetVisibilityMode(SL_MESH_GROUP_VISIBILITY_MODE_VISIBLE);

	// create camera
	glm::mat4 matProj = glm::lookAt(glm::vec3(0.0f, -10.0f, 0.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
	ISLCamera* camera = renderer->CreateCamera();
	camera->SetProjection(glm::value_ptr(matProj));
	camera->SetNearPlane(0.1f);
	camera->SetFarPlane(100.0f);
	camera->SetViewport(800, 600);

	// create scene
	ISLScene* scene = renderer->CreateScene();
	scene->AddModel(model);
	scene->SetCamera(camera);

	//////////////////////////////////////////////////////////////////////////

	// main loop
	double dt = 0, last_update_time = 0;
	while (!glfwWindowShouldClose(window))
	{
		// render!
		renderer->Render();

		// display and process events through callbacks
		glfwSwapBuffers(window);
		glfwPollEvents();

		// get frame time
		dt = glfwGetTime();
		if ((dt - last_update_time) > 0.2)
			last_update_time = dt;
	}

	//////////////////////////////////////////////////////////////////////////

	// delete camera
	renderer->DeleteCamera(camera);

	// delete model
	renderer->DeleteModel(model);

	// delete mesh
	renderer->DeleteMesh(mesh);

	// delete texture
	renderer->DeleteTexture2D(baseTexture);

	// delete buffers
	renderer->DeleteIndexBuffer(indexBuffer);
	renderer->DeleteBuffer(noramlBuffer);
	renderer->DeleteBuffer(positionBuffer);

	//////////////////////////////////////////////////////////////////////////

	// exit
	glfwTerminate();

	// exit
	return EXIT_SUCCESS;
}<commit_msg>gles2 project fixed<commit_after>#include <iostream>

#include <SLRenderer/SLRenderer.hpp>
#include <glfw/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtc/matrix_transform.hpp>

// main
int main(int argc, char** argv)
{
	//////////////////////////////////////////////////////////////////////////
	// set error handling
	glfwSetErrorCallback([](int error, const char* description) {
		std::cout << "Error: " << description << std::endl;
	});

	// init glfw
	glfwInit();

	// select OpenGL ES version
	glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
	glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_EGL_CONTEXT_API);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);

// 	// select OpenGL version
// 	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
// 	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
// 	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);

	// create window
	GLFWwindow* window = glfwCreateWindow(800, 600, "GLFW OpenGLES2", nullptr, nullptr);

	// set current context
	glfwMakeContextCurrent(window);

	// setup thescene ready for rendering
	int width = 0, height = 0;
	glfwGetFramebufferSize(window, &width, &height);

	//////////////////////////////////////////////////////////////////////////

	// create renderer
	ISLRenderer* renderer = SLRendererFabric::CreateRenderer(SL_RENDERER_TYPE_GLES2);
	std::cout << renderer->GetDescription() << std::endl;

	// create buffers
	ISLBuffer* positionBuffer = renderer->CreateBuffer(nullptr, 1024);
	ISLBuffer* noramlBuffer = renderer->CreateBuffer(nullptr, 1024);
	ISLIndexBuffer* indexBuffer = renderer->CreateIndexBuffer(nullptr, 1024);

	// create texture
	ISLTexture2D* baseTexture = renderer->CreateTexture2D(nullptr, 0, 1, 1, SL_PIXEL_DATA_TYPE_RGRA);

	// create mesh and setup buffers
	ISLMesh* mesh = renderer->CreateMesh();
	mesh->SetPositionBuffer(positionBuffer);
	mesh->SetNormalBuffer(noramlBuffer);
	mesh->SetIndexBuffer(indexBuffer);
	mesh->SetBaseTexture(baseTexture);
	mesh->SetBaseColor(1.0f, 1.0f, 1.0f, 1.0f);

	// create model
	glm::mat4 transform(1.0f);
	ISLModel* model = renderer->CreateModel();
	model->AddMesh(mesh);
	model->SetTransform(&transform[0][0]);
	model->SetVisibilityMode(SL_MESH_GROUP_VISIBILITY_MODE_VISIBLE);

	// create camera
	glm::mat4 matProj = glm::lookAt(glm::vec3(0.0f, -10.0f, 0.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
	ISLCamera* camera = renderer->CreateCamera();
	camera->SetProjection(glm::value_ptr(matProj));
	camera->SetNearPlane(0.1f);
	camera->SetFarPlane(100.0f);
	camera->SetViewport(800, 600);

	// create scene
	ISLScene* scene = renderer->CreateScene();
	scene->AddModel(model);
	scene->SetCamera(camera);

	//////////////////////////////////////////////////////////////////////////

	// main loop
	double dt = 0, last_update_time = 0;
	while (!glfwWindowShouldClose(window))
	{
		// render!
		renderer->Render();

		// display and process events through callbacks
		glfwSwapBuffers(window);
		glfwPollEvents();

		// get frame time
		dt = glfwGetTime();
		if ((dt - last_update_time) > 0.2)
			last_update_time = dt;
	}

	//////////////////////////////////////////////////////////////////////////

	// delete camera
	renderer->DeleteCamera(camera);

	// delete model
	renderer->DeleteModel(model);

	// delete mesh
	renderer->DeleteMesh(mesh);

	// delete texture
	renderer->DeleteTexture2D(baseTexture);

	// delete buffers
	renderer->DeleteIndexBuffer(indexBuffer);
	renderer->DeleteBuffer(noramlBuffer);
	renderer->DeleteBuffer(positionBuffer);

	//////////////////////////////////////////////////////////////////////////

	// exit
	glfwTerminate();

	// exit
	return EXIT_SUCCESS;
}<|endoftext|>


<commit_before>#include "CarbonLibrary-WifiFork.h"

SparkCarbon::SparkCarbon() {
    _carbonClient = NULL;
}

// IP address with port
bool SparkCarbon::begin(TCPClient * carbonClient, IPAddress carbonServer, uint16_t carbonPort) {
    _carbonClient = carbonClient;
    _carbonServer = carbonServer;
    _carbonPort = carbonPort;

    return true;
}

// IP address without port
bool SparkCarbon::begin(TCPClient * carbonClient, IPAddress carbonServer) {
    _carbonClient = carbonClient;
    _carbonServer = carbonServer;
    _carbonPort = 2003;

    return true;
}

// DNS name with port
bool SparkCarbon::begin(TCPClient * carbonClient, const char *carbonServer, uint16_t carbonPort) {
    _carbonClient = carbonClient;
    _carbonPort = carbonPort;

    // Resolve DNS hostname
    // Adapted from: https://github.com/spark/core-firmware/blob/master/src/spark_wiring_tcpclient.cpp#L47-L63
    uint32_t ip_addr = 0;
    _carbonServer = WiFi.resolve((char*)carbonServer);
    return true;
    // if(gethostbyname((char*)carbonServer, strlen(carbonServer), &ip_addr) > 0) {
    //     IPAddress remote_addr(BYTE_N(ip_addr, 3), BYTE_N(ip_addr, 2), BYTE_N(ip_addr, 1), BYTE_N(ip_addr, 0));
    //     _carbonServer = remote_addr;
    //
    //     return true;
    // } else
    //     return false;

}

// DNS name without port
bool SparkCarbon::begin(TCPClient * carbonClient, const char *carbonServer) {
    _carbonClient = carbonClient;
    _carbonPort = 2003;

    // Resolve DNS hostname
    // Adapted from: https://github.com/spark/core-firmware/blob/master/src/spark_wiring_tcpclient.cpp#L47-L63
    uint32_t ip_addr = 0;
    if(gethostbyname((char*)carbonServer, strlen(carbonServer), &ip_addr) > 0) {
        IPAddress remote_addr(BYTE_N(ip_addr, 3), BYTE_N(ip_addr, 2), BYTE_N(ip_addr, 1), BYTE_N(ip_addr, 0));
        _carbonServer = remote_addr;

        return true;
    } else
        return false;
}

// Send data with a string metric and a string value
bool SparkCarbon::sendData(String carbonMetric, String carbonValue, uint32_t carbonTimestamp) {
    if(_carbonClient->connect(_carbonServer, _carbonPort)) {
        _carbonClient->print(carbonMetric);
        _carbonClient->print(" ");
        _carbonClient->print(carbonValue);
        _carbonClient->print(" ");
        _carbonClient->print(carbonTimestamp);
        _carbonClient->println("");
        delay(10);
        _carbonClient->stop();
        _carbonClient->flush();

        return true;
    } else
        return false;
}

// Send data with a string metric and an integer value
bool SparkCarbon::sendData(String carbonMetric, uint32_t carbonValue, uint32_t carbonTimestamp) {
    if(_carbonClient->connect(_carbonServer, _carbonPort)) {
        _carbonClient->print(carbonMetric);
        _carbonClient->print(" ");
        _carbonClient->print(carbonValue);
        _carbonClient->print(" ");
        _carbonClient->print(carbonTimestamp);
        _carbonClient->println("");
        delay(10);
        _carbonClient->stop();
        _carbonClient->flush();

        return true;
    } else
        return false;
}
<commit_msg>Replace the other gethostbyname with WiFi.Resolve<commit_after>#include "CarbonLibrary-WifiFork.h"

SparkCarbon::SparkCarbon() {
    _carbonClient = NULL;
}

// IP address with port
bool SparkCarbon::begin(TCPClient * carbonClient, IPAddress carbonServer, uint16_t carbonPort) {
    _carbonClient = carbonClient;
    _carbonServer = carbonServer;
    _carbonPort = carbonPort;

    return true;
}

// IP address without port
bool SparkCarbon::begin(TCPClient * carbonClient, IPAddress carbonServer) {
    _carbonClient = carbonClient;
    _carbonServer = carbonServer;
    _carbonPort = 2003;

    return true;
}

// DNS name with port
bool SparkCarbon::begin(TCPClient * carbonClient, const char *carbonServer, uint16_t carbonPort) {
    _carbonClient = carbonClient;
    _carbonPort = carbonPort;

    // Resolve DNS hostname
    // Adapted from: https://github.com/spark/core-firmware/blob/master/src/spark_wiring_tcpclient.cpp#L47-L63
    uint32_t ip_addr = 0;
    _carbonServer = WiFi.resolve((char*)carbonServer);
    return true;
    // if(gethostbyname((char*)carbonServer, strlen(carbonServer), &ip_addr) > 0) {
    //     IPAddress remote_addr(BYTE_N(ip_addr, 3), BYTE_N(ip_addr, 2), BYTE_N(ip_addr, 1), BYTE_N(ip_addr, 0));
    //     _carbonServer = remote_addr;
    //
    //     return true;
    // } else
    //     return false;

}

// DNS name without port
bool SparkCarbon::begin(TCPClient * carbonClient, const char *carbonServer) {
    _carbonClient = carbonClient;
    _carbonPort = 2003;

    // Resolve DNS hostname
    // Adapted from: https://github.com/spark/core-firmware/blob/master/src/spark_wiring_tcpclient.cpp#L47-L63
    uint32_t ip_addr = 0;
    _carbonServer = WiFi.resolve((char*)carbonServer);
    return true;
    // if(gethostbyname((char*)carbonServer, strlen(carbonServer), &ip_addr) > 0) {
    //     IPAddress remote_addr(BYTE_N(ip_addr, 3), BYTE_N(ip_addr, 2), BYTE_N(ip_addr, 1), BYTE_N(ip_addr, 0));
    //     _carbonServer = remote_addr;
    //
    //     return true;
    // } else
    //     return false;
}

// Send data with a string metric and a string value
bool SparkCarbon::sendData(String carbonMetric, String carbonValue, uint32_t carbonTimestamp) {
    if(_carbonClient->connect(_carbonServer, _carbonPort)) {
        _carbonClient->print(carbonMetric);
        _carbonClient->print(" ");
        _carbonClient->print(carbonValue);
        _carbonClient->print(" ");
        _carbonClient->print(carbonTimestamp);
        _carbonClient->println("");
        delay(10);
        _carbonClient->stop();
        _carbonClient->flush();

        return true;
    } else
        return false;
}

// Send data with a string metric and an integer value
bool SparkCarbon::sendData(String carbonMetric, uint32_t carbonValue, uint32_t carbonTimestamp) {
    if(_carbonClient->connect(_carbonServer, _carbonPort)) {
        _carbonClient->print(carbonMetric);
        _carbonClient->print(" ");
        _carbonClient->print(carbonValue);
        _carbonClient->print(" ");
        _carbonClient->print(carbonTimestamp);
        _carbonClient->println("");
        delay(10);
        _carbonClient->stop();
        _carbonClient->flush();

        return true;
    } else
        return false;
}
<|endoftext|>


<commit_before>/*****************************************************************************
 * Project: RooFit                                                           *
 * Package: RooFitCore                                                       *
 * @(#)root/roofitcore:$Id$
 * Authors:                                                                  *
 *   WV, Wouter Verkerke, NIKHEF
 *   GR, Gerhard Raven, NIKHEF/VU                                            *
 *                                                                           *
 * Redistribution and use in source and binary forms,                        *
 * with or without modification, are permitted according to the terms        *
 * listed in LICENSE (http://roofit.sourceforge.net/license.txt)             *
 *****************************************************************************/

/////////////////////////////////////////////////////////////////////////////////////
// BEGIN_HTML
// The class RooEffProd implements the product of a PDF with an efficiency function.
// The normalization integral of the product is calculated numerically, but the
// event generation is handled by a specialized generator context that implements
// the event generation in a more efficient for cases where the PDF has an internal
// generator that is smarter than accept reject.
// END_HTML
//

#include "RooFit.h"
#include "RooEffProd.h"
#include "RooEffGenContext.h"
#include "RooNameReg.h"
#include "RooRealVar.h"

ClassImp(RooEffProd)
  ;

//_____________________________________________________________________________
RooEffProd::RooEffProd(const char *name, const char *title,
                             RooAbsPdf& inPdf, RooAbsReal& inEff) :
  RooAbsPdf(name,title),
  _cacheMgr(this,10),
  _pdf("pdf","pre-efficiency pdf", this,inPdf),
  _eff("eff","efficiency function",this,inEff),
  _nset(0),
  _fixedNset(0)
{
  // Constructor of a a production of p.d.f inPdf with efficiency
  // function inEff.
}

//_____________________________________________________________________________
RooEffProd::RooEffProd(const RooEffProd& other, const char* name) :
  RooAbsPdf(other, name),
  _cacheMgr(other._cacheMgr,this),
  _pdf("pdf",this,other._pdf),
  _eff("acc",this,other._eff),
  _nset(0),
  _fixedNset(0)
{
  // Copy constructor
}

//_____________________________________________________________________________
RooEffProd::~RooEffProd()
{
  // Destructor
}

//_____________________________________________________________________________
Double_t RooEffProd::getValV(const RooArgSet* set) const
{
  // Return p.d.f. value normalized over given set of observables

  _nset = _fixedNset ? _fixedNset : set ;
  return RooAbsPdf::getValV(set) ;
}

//_____________________________________________________________________________
Double_t RooEffProd::evaluate() const
{
  // Calculate and return 'raw' unnormalized value of p.d.f

  return eff()->getVal() * pdf()->getVal(_nset);
}

//_____________________________________________________________________________
RooAbsGenContext* RooEffProd::genContext(const RooArgSet &vars, const RooDataSet *prototype,
                                            const RooArgSet* auxProto, Bool_t verbose) const
{
  // Return specialized generator context for RooEffProds that implements generation
  // in a more efficient way than can be done for generic correlated products

  assert(pdf()!=0);
  assert(eff()!=0);
  return new RooEffGenContext(*this,*pdf(),*eff(),vars,prototype,auxProto,verbose) ;
}

//_____________________________________________________________________________
Int_t RooEffProd::getAnalyticalIntegralWN(RooArgSet& allVars, RooArgSet& analVars,
					  const RooArgSet* normSet, const char* rangeName) const
{
  // Return internal integration capabilities of the p.d.f. Given a set 'allVars' for which
  // integration is requested, returned the largest subset for which internal (analytical)
  // integration is implemented (in argument analVars). The return value is a unique integer
  // code that identifies the integration configuration (integrated observables and range name).
  //
  // This implementation in RooEffProd catches all integrals without normalization and reroutes them
  // through a custom integration routine that properly accounts for the use of normalized p.d.f.
  // in the evaluate() expression, which breaks the default RooAbsPdf normalization handling

  // No special handling required if a normalization set is given
  if (normSet && normSet->getSize()>0) {
    return 0 ;
  }
  // No special handling required if running with a fixed normalization set
  if (_fixedNset) {
    return 0 ;
  }

  // Special handling of integrals w/o normalization set. We need to pass _a_ normalization set
  // to pdf().getVal(nset) in evaluate() because for certain p.d.fs the shape depends on the
  // chosen normalization set. This functions correctly automatically for plain getVal() calls,
  // however when the (numeric) normalization is calculated, getVal() is called without any normalization
  // set causing the normalization to be calculated for a possibly different shape. To fix that
  // integrals over a RooEffProd without normalization setup are explicitly handled here. These integrals
  // are calculated using a clone of the RooEffProd that has a fixed normalization set passed to the
  // underlying p.d.f regardless of the normalization set passed to getVal(). Here the set of observables
  // over which is integrated is passed.

  // Declare that we can analytically integrate all requested observables
  analVars.add(allVars) ;

  // Check if cache was previously created
  Int_t sterileIndex(-1) ;
  CacheElem* cache = (CacheElem*) _cacheMgr.getObj(&allVars,&allVars,&sterileIndex,RooNameReg::ptr(rangeName)) ;
  if (cache) {
    return _cacheMgr.lastIndex()+1;
  }

  // Construct cache with clone of p.d.f that has fixed normalization set that is passed to input pdf
  cache = new CacheElem ;
  cache->_intObs.addClone(allVars) ;
  cache->_clone = (RooEffProd*) clone(Form("%s_clone",GetName())) ;
  cache->_clone->_fixedNset = &cache->_intObs ;
  cache->_int = cache->_clone->createIntegral(cache->_intObs) ;

  // Store cache and return index as code
  Int_t code = _cacheMgr.setObj(&allVars,&allVars,(RooAbsCacheElement*)cache,RooNameReg::ptr(rangeName)) ;

  return code+1 ;
}

//_____________________________________________________________________________
Double_t RooEffProd::analyticalIntegralWN(Int_t code, const RooArgSet* normSet, const char* /*rangeName*/) const
{
  // Return value of integral identified by code, which should be a return value of getAnalyticalIntegralWN,
  // Code zero is always handled and signifies no integration (return value is normalized p.d.f. value)

  // Return analytical integral defined by given scenario code

  // No integration scenario
  if (code==0) {
    return getVal(normSet) ;
  }

  // Partial integration scenarios
  CacheElem* cache = (CacheElem*) _cacheMgr.getObjByIndex(code-1) ;

  return cache->_int->getVal() ;
}

//_____________________________________________________________________________
RooArgList RooEffProd::CacheElem::containedArgs(Action)
{
  // Report all RooAbsArg derived objects contained in Cache Element (used in function optimization and
  // and server redirect management of the cache)

  RooArgList ret(_intObs) ;
  ret.add(*_int) ;
  ret.add(*_clone) ;
  return ret ;
}
<commit_msg><commit_after>/*****************************************************************************
 * Project: RooFit                                                           *
 * Package: RooFitCore                                                       *
 * @(#)root/roofitcore:$Id$
 * Authors:                                                                  *
 *   WV, Wouter Verkerke, NIKHEF
 *   GR, Gerhard Raven, NIKHEF/VU                                            *
 *                                                                           *
 * Redistribution and use in source and binary forms,                        *
 * with or without modification, are permitted according to the terms        *
 * listed in LICENSE (http://roofit.sourceforge.net/license.txt)             *
 *****************************************************************************/

/////////////////////////////////////////////////////////////////////////////////////
// BEGIN_HTML
// The class RooEffProd implements the product of a PDF with an efficiency function.
// The normalization integral of the product is calculated numerically, but the
// event generation is handled by a specialized generator context that implements
// the event generation in a more efficient for cases where the PDF has an internal
// generator that is smarter than accept reject.
// END_HTML
//

#include "RooFit.h"
#include "RooEffProd.h"
#include "RooEffGenContext.h"
#include "RooNameReg.h"
#include "RooRealVar.h"

ClassImp(RooEffProd)
  ;

//_____________________________________________________________________________
RooEffProd::RooEffProd(const char *name, const char *title,
                             RooAbsPdf& inPdf, RooAbsReal& inEff) :
  RooAbsPdf(name,title),
  _cacheMgr(this,10),
  _pdf("pdf","pre-efficiency pdf", this,inPdf),
  _eff("eff","efficiency function",this,inEff),
  _nset(0),
  _fixedNset(0)
{
  // Constructor of a a production of p.d.f inPdf with efficiency
  // function inEff.
}

//_____________________________________________________________________________
RooEffProd::RooEffProd(const RooEffProd& other, const char* name) :
  RooAbsPdf(other, name),
  _cacheMgr(other._cacheMgr,this),
  _pdf("pdf",this,other._pdf),
  _eff("acc",this,other._eff),
  _nset(0),
  _fixedNset(0)
{
  // Copy constructor
}

//_____________________________________________________________________________
RooEffProd::~RooEffProd()
{
  // Destructor
}

//_____________________________________________________________________________
Double_t RooEffProd::getValV(const RooArgSet* set) const
{
  // Return p.d.f. value normalized over given set of observables

  _nset = _fixedNset ? _fixedNset : set ;
  return RooAbsPdf::getValV(set) ;
}

//_____________________________________________________________________________
Double_t RooEffProd::evaluate() const
{
  // Calculate and return 'raw' unnormalized value of p.d.f

  return eff()->getVal() * pdf()->getVal(_nset);
}

//_____________________________________________________________________________
RooAbsGenContext* RooEffProd::genContext(const RooArgSet &vars, const RooDataSet *prototype,
                                            const RooArgSet* auxProto, Bool_t verbose) const
{
  // Return specialized generator context for RooEffProds that implements generation
  // in a more efficient way than can be done for generic correlated products

  assert(pdf()!=0);
  assert(eff()!=0);
  return new RooEffGenContext(*this,*pdf(),*eff(),vars,prototype,auxProto,verbose) ;
}

//_____________________________________________________________________________
Int_t RooEffProd::getAnalyticalIntegralWN(RooArgSet& allVars, RooArgSet& analVars,
					  const RooArgSet* normSet, const char* rangeName) const
{
  // Return internal integration capabilities of the p.d.f. Given a set 'allVars' for which
  // integration is requested, returned the largest subset for which internal (analytical)
  // integration is implemented (in argument analVars). The return value is a unique integer
  // code that identifies the integration configuration (integrated observables and range name).
  //
  // This implementation in RooEffProd catches all integrals without normalization and reroutes them
  // through a custom integration routine that properly accounts for the use of normalized p.d.f.
  // in the evaluate() expression, which breaks the default RooAbsPdf normalization handling

  // No special handling required if a normalization set is given
  if (normSet && normSet->getSize()>0) {
    return 0 ;
  }
  // No special handling required if running with a fixed normalization set
  if (_fixedNset) {
    return 0 ;
  }

  // Special handling of integrals w/o normalization set. We need to pass _a_ normalization set
  // to pdf().getVal(nset) in evaluate() because for certain p.d.fs the shape depends on the
  // chosen normalization set. This functions correctly automatically for plain getVal() calls,
  // however when the (numeric) normalization is calculated, getVal() is called without any normalization
  // set causing the normalization to be calculated for a possibly different shape. To fix that
  // integrals over a RooEffProd without normalization setup are explicitly handled here. These integrals
  // are calculated using a clone of the RooEffProd that has a fixed normalization set passed to the
  // underlying p.d.f regardless of the normalization set passed to getVal(). Here the set of observables
  // over which is integrated is passed.

  // Declare that we can analytically integrate all requested observables
  analVars.add(allVars) ;

  // Check if cache was previously created
  Int_t sterileIndex(-1) ;
  CacheElem* cache = (CacheElem*) _cacheMgr.getObj(&allVars,&allVars,&sterileIndex,RooNameReg::ptr(rangeName)) ;
  if (cache) {
    return _cacheMgr.lastIndex()+1;
  }

  // Construct cache with clone of p.d.f that has fixed normalization set that is passed to input pdf
  cache = new CacheElem ;
  cache->_intObs.addClone(allVars) ;
  cache->_clone = (RooEffProd*) clone(Form("%s_clone",GetName())) ;
  cache->_clone->_fixedNset = &cache->_intObs ;
  cache->_int = cache->_clone->createIntegral(cache->_intObs,rangeName) ;

  // Store cache and return index as code
  Int_t code = _cacheMgr.setObj(&allVars,&allVars,(RooAbsCacheElement*)cache,RooNameReg::ptr(rangeName)) ;

  return code+1 ;
}

//_____________________________________________________________________________
Double_t RooEffProd::analyticalIntegralWN(Int_t code, const RooArgSet* normSet, const char* /*rangeName*/) const
{
  // Return value of integral identified by code, which should be a return value of getAnalyticalIntegralWN,
  // Code zero is always handled and signifies no integration (return value is normalized p.d.f. value)

  // Return analytical integral defined by given scenario code

  // No integration scenario
  if (code==0) {
    return getVal(normSet) ;
  }

  // Partial integration scenarios
  CacheElem* cache = (CacheElem*) _cacheMgr.getObjByIndex(code-1) ;

  return cache->_int->getVal() ;
}

//_____________________________________________________________________________
RooArgList RooEffProd::CacheElem::containedArgs(Action)
{
  // Report all RooAbsArg derived objects contained in Cache Element (used in function optimization and
  // and server redirect management of the cache)

  RooArgList ret(_intObs) ;
  ret.add(*_int) ;
  ret.add(*_clone) ;
  return ret ;
}
<|endoftext|>


<commit_before>/*
 * Copyright 2010-2017 JetBrains s.r.o.
 *
 * 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.
 */

#if KONAN_OBJC_INTEROP

#include <objc/objc.h>
#include <objc/runtime.h>
#include <objc/message.h>
#include <cstdio>
#include <cstdint>

#include "Memory.h"
#include "MemoryPrivate.hpp"

#include "Natives.h"
#include "Utils.h"

extern "C" {

Class Kotlin_Interop_getObjCClass(const char* name);

struct KotlinClassData {
  const TypeInfo* typeInfo;
  int32_t bodyOffset;
};

static inline struct KotlinClassData* GetKotlinClassData(Class clazz) {
  void* ivars = object_getIndexedIvars(reinterpret_cast<id>(clazz));
  return static_cast<struct KotlinClassData*>(ivars);
}

static inline void SetKotlinTypeInfo(Class clazz, const TypeInfo* typeInfo) {
  GetKotlinClassData(clazz)->typeInfo = typeInfo;
}

const TypeInfo* GetObjCKotlinTypeInfo(ObjHeader* obj) RUNTIME_NOTHROW;

const TypeInfo* GetObjCKotlinTypeInfo(ObjHeader* obj) RUNTIME_NOTHROW {
  RuntimeAssert(obj->has_meta_object(), "");
  void* objcPtr = obj->meta_object()->associatedObject_;
  RuntimeAssert(objcPtr != nullptr, "");
  Class clazz = object_getClass(reinterpret_cast<id>(objcPtr));
  return GetKotlinClassData(clazz)->typeInfo;
}

id objc_msgSendSuper2(struct objc_super *super, SEL op, ...);

static void DeallocImp(id self, SEL _cmd) {
  // TODO: doesn't support overriding Kotlin classes.
  Class clazz = object_getClass(self);
  RuntimeAssert(clazz != nullptr, "Must not be null");

  struct KotlinClassData* classData = GetKotlinClassData(clazz);
  void* body = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(self) + classData->bodyOffset);

  const TypeInfo* typeInfo = classData->typeInfo;
  DeinitInstanceBody(typeInfo, body);

  // Call super.dealloc:
  struct objc_super s = {self, clazz};
  auto messenger = reinterpret_cast<void (*) (struct objc_super*, SEL _cmd)>(objc_msgSendSuper2);
  messenger(&s, _cmd);
}

static void AddDeallocMethod(Class clazz) {
  Class nsObjectClass = Kotlin_Interop_getObjCClass("NSObject");

  SEL deallocSelector = sel_registerName("dealloc");
  Method nsObjectDeallocMethod = class_getInstanceMethod(nsObjectClass, deallocSelector);
  RuntimeAssert(nsObjectDeallocMethod != nullptr, "[NSObject dealloc] method not found");

  const char* nsObjectDeallocMethodTypeEncoding = method_getTypeEncoding(nsObjectDeallocMethod);
  RuntimeAssert(nsObjectDeallocMethodTypeEncoding != nullptr, "[NSObject dealloc] method has no encoding provided");

  // TODO: something of the above can be cached.

  BOOL added = class_addMethod(clazz, deallocSelector, (IMP)DeallocImp, nsObjectDeallocMethodTypeEncoding);
  RuntimeAssert(added, "Unable to add dealloc method to Objective-C class");
}

struct ObjCMethodDescription {
  void* (*imp)(void*, void*, ...);
  const char* selector;
  const char* encoding;
};

struct KotlinObjCClassInfo {
  const char* name;

  const char* superclassName;
  const char** protocolNames;

  const struct ObjCMethodDescription* instanceMethods;
  int32_t instanceMethodsNum;

  const struct ObjCMethodDescription* classMethods;
  int32_t classMethodsNum;

  int32_t bodySize;
  int32_t* bodyOffset;

  const TypeInfo* typeInfo;
  const TypeInfo* metaTypeInfo;

  void** createdClass;
};

static void AddMethods(Class clazz, const struct ObjCMethodDescription* methods, int32_t methodsNum) {
  for (int32_t i = 0; i < methodsNum; ++i) {
    const struct ObjCMethodDescription* method = &methods[i];
    BOOL added = class_addMethod(clazz, sel_registerName(method->selector), (IMP)method->imp, method->encoding);
    RuntimeAssert(added == YES, "Unable to add method to Objective-C class");
  }
}

static SimpleMutex classCreationMutex;
static int anonymousClassNextId = 0;

void* CreateKotlinObjCClass(const KotlinObjCClassInfo* info) {
  LockGuard<SimpleMutex> lockGuard(classCreationMutex);

  void* createdClass = *info->createdClass;
  if (createdClass != nullptr) {
    return createdClass;
  }

  char classNameBuffer[64];
  const char* className = info->name;
  if (className == nullptr) {
    snprintf(classNameBuffer, sizeof(classNameBuffer), "kobjc%d", anonymousClassNextId++);
    className = classNameBuffer;
  }

  Class superclass = Kotlin_Interop_getObjCClass(info->superclassName);
  Class newClass = objc_allocateClassPair(superclass, className, sizeof(struct KotlinClassData));
  RuntimeAssert(newClass != nullptr, "Failed to allocate Objective-C class");

  Class newMetaclass = object_getClass(reinterpret_cast<id>(newClass));

  for (size_t i = 0;; ++i) {
    const char* protocolName = info->protocolNames[i];
    if (protocolName == nullptr) break;
    Protocol* proto = objc_getProtocol(protocolName);
    if (proto != nullptr) {
      BOOL added = class_addProtocol(newClass, proto);
      RuntimeAssert(added == YES, "Unable to add protocol to Objective-C class");
      added = class_addProtocol(newMetaclass, proto);
      RuntimeAssert(added == YES, "Unable to add protocol to Objective-C metaclass");
    }
  }

  AddDeallocMethod(newClass);

  AddMethods(newClass, info->instanceMethods, info->instanceMethodsNum);
  AddMethods(newMetaclass, info->classMethods, info->classMethodsNum);

  SetKotlinTypeInfo(newClass, info->typeInfo);
  SetKotlinTypeInfo(newMetaclass, info->metaTypeInfo);

  char bodyTypeEncoding[16];
  snprintf(bodyTypeEncoding, sizeof(bodyTypeEncoding), "[%dc]", info->bodySize);
  BOOL added = class_addIvar(newClass, "kotlinBody", info->bodySize, /* log2(align) = */ 3, bodyTypeEncoding);
  RuntimeAssert(added == YES, "Unable to add ivar to Objective-C class");

  objc_registerClassPair(newClass);

  Ivar body = class_getInstanceVariable(newClass, "kotlinBody");
  RuntimeAssert(body != nullptr, "Unable to get ivar added to Objective-C class");
  int32_t offset = (int32_t)ivar_getOffset(body);
  GetKotlinClassData(newClass)->bodyOffset = offset;
  *info->bodyOffset = offset;

  *info->createdClass = newClass;
  return newClass;
}

void* objc_autoreleasePoolPush();
void objc_autoreleasePoolPop(void* ptr);
id objc_allocWithZone(Class clazz);
id objc_retain(id ptr);
void objc_release(id ptr);

void* Kotlin_objc_autoreleasePoolPush() {
  return objc_autoreleasePoolPush();
}

void Kotlin_objc_autoreleasePoolPop(void* ptr) {
  objc_autoreleasePoolPop(ptr);
}

id Kotlin_objc_allocWithZone(Class clazz) {
  return objc_allocWithZone(clazz);
}

id Kotlin_objc_retain(id ptr) {
  return objc_retain(ptr);
}

void Kotlin_objc_release(id ptr) {
  objc_release(ptr);
}

Class Kotlin_objc_lookUpClass(const char* name) {
  return objc_lookUpClass(name);
}

} // extern "C"

#else  // KONAN_OBJC_INTEROP

#include "KAssert.h"

extern "C" {

void* Kotlin_objc_autoreleasePoolPush() {
  RuntimeAssert(false, "Objective-C interop is disabled");
  return nullptr;
}

void Kotlin_objc_autoreleasePoolPop(void* ptr) {
  RuntimeAssert(false, "Objective-C interop is disabled");
}

void* Kotlin_objc_allocWithZone(void* clazz) {
  RuntimeAssert(false, "Objective-C interop is disabled");
  return nullptr;
}

void* Kotlin_objc_retain(void* ptr) {
  RuntimeAssert(false, "Objective-C interop is disabled");
  return nullptr;
}

void Kotlin_objc_release(void* ptr) {
  RuntimeAssert(false, "Objective-C interop is disabled");
}

void* Kotlin_objc_lookUpClass(const char* name) {
  RuntimeAssert(false, "Objective-C interop is disabled");
  return nullptr;
}

} // extern "C"

#endif // KONAN_OBJC_INTEROP
<commit_msg>Fix runtime compilation warnings<commit_after>/*
 * Copyright 2010-2017 JetBrains s.r.o.
 *
 * 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.
 */

#if KONAN_OBJC_INTEROP

#include <objc/objc.h>
#include <objc/runtime.h>
#include <objc/message.h>
#include <cstdio>
#include <cstdint>

#include "Memory.h"
#include "MemoryPrivate.hpp"

#include "Natives.h"
#include "Utils.h"

extern "C" {

Class Kotlin_Interop_getObjCClass(const char* name);

struct KotlinClassData {
  const TypeInfo* typeInfo;
  int32_t bodyOffset;
};

static inline struct KotlinClassData* GetKotlinClassData(Class clazz) {
  void* ivars = object_getIndexedIvars(reinterpret_cast<id>(clazz));
  return static_cast<struct KotlinClassData*>(ivars);
}

static inline void SetKotlinTypeInfo(Class clazz, const TypeInfo* typeInfo) {
  GetKotlinClassData(clazz)->typeInfo = typeInfo;
}

const TypeInfo* GetObjCKotlinTypeInfo(ObjHeader* obj) RUNTIME_NOTHROW;

RUNTIME_NOTHROW const TypeInfo* GetObjCKotlinTypeInfo(ObjHeader* obj) {
  RuntimeAssert(obj->has_meta_object(), "");
  void* objcPtr = obj->meta_object()->associatedObject_;
  RuntimeAssert(objcPtr != nullptr, "");
  Class clazz = object_getClass(reinterpret_cast<id>(objcPtr));
  return GetKotlinClassData(clazz)->typeInfo;
}

id objc_msgSendSuper2(struct objc_super *super, SEL op, ...);

static void DeallocImp(id self, SEL _cmd) {
  // TODO: doesn't support overriding Kotlin classes.
  Class clazz = object_getClass(self);
  RuntimeAssert(clazz != nullptr, "Must not be null");

  struct KotlinClassData* classData = GetKotlinClassData(clazz);
  void* body = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(self) + classData->bodyOffset);

  const TypeInfo* typeInfo = classData->typeInfo;
  DeinitInstanceBody(typeInfo, body);

  // Call super.dealloc:
  struct objc_super s = {self, clazz};
  auto messenger = reinterpret_cast<void (*) (struct objc_super*, SEL _cmd)>(objc_msgSendSuper2);
  messenger(&s, _cmd);
}

static void AddDeallocMethod(Class clazz) {
  Class nsObjectClass = Kotlin_Interop_getObjCClass("NSObject");

  SEL deallocSelector = sel_registerName("dealloc");
  Method nsObjectDeallocMethod = class_getInstanceMethod(nsObjectClass, deallocSelector);
  RuntimeAssert(nsObjectDeallocMethod != nullptr, "[NSObject dealloc] method not found");

  const char* nsObjectDeallocMethodTypeEncoding = method_getTypeEncoding(nsObjectDeallocMethod);
  RuntimeAssert(nsObjectDeallocMethodTypeEncoding != nullptr, "[NSObject dealloc] method has no encoding provided");

  // TODO: something of the above can be cached.

  BOOL added = class_addMethod(clazz, deallocSelector, (IMP)DeallocImp, nsObjectDeallocMethodTypeEncoding);
  RuntimeAssert(added, "Unable to add dealloc method to Objective-C class");
}

struct ObjCMethodDescription {
  void* (*imp)(void*, void*, ...);
  const char* selector;
  const char* encoding;
};

struct KotlinObjCClassInfo {
  const char* name;

  const char* superclassName;
  const char** protocolNames;

  const struct ObjCMethodDescription* instanceMethods;
  int32_t instanceMethodsNum;

  const struct ObjCMethodDescription* classMethods;
  int32_t classMethodsNum;

  int32_t bodySize;
  int32_t* bodyOffset;

  const TypeInfo* typeInfo;
  const TypeInfo* metaTypeInfo;

  void** createdClass;
};

static void AddMethods(Class clazz, const struct ObjCMethodDescription* methods, int32_t methodsNum) {
  for (int32_t i = 0; i < methodsNum; ++i) {
    const struct ObjCMethodDescription* method = &methods[i];
    BOOL added = class_addMethod(clazz, sel_registerName(method->selector), (IMP)method->imp, method->encoding);
    RuntimeAssert(added == YES, "Unable to add method to Objective-C class");
  }
}

static SimpleMutex classCreationMutex;
static int anonymousClassNextId = 0;

void* CreateKotlinObjCClass(const KotlinObjCClassInfo* info) {
  LockGuard<SimpleMutex> lockGuard(classCreationMutex);

  void* createdClass = *info->createdClass;
  if (createdClass != nullptr) {
    return createdClass;
  }

  char classNameBuffer[64];
  const char* className = info->name;
  if (className == nullptr) {
    snprintf(classNameBuffer, sizeof(classNameBuffer), "kobjc%d", anonymousClassNextId++);
    className = classNameBuffer;
  }

  Class superclass = Kotlin_Interop_getObjCClass(info->superclassName);
  Class newClass = objc_allocateClassPair(superclass, className, sizeof(struct KotlinClassData));
  RuntimeAssert(newClass != nullptr, "Failed to allocate Objective-C class");

  Class newMetaclass = object_getClass(reinterpret_cast<id>(newClass));

  for (size_t i = 0;; ++i) {
    const char* protocolName = info->protocolNames[i];
    if (protocolName == nullptr) break;
    Protocol* proto = objc_getProtocol(protocolName);
    if (proto != nullptr) {
      BOOL added = class_addProtocol(newClass, proto);
      RuntimeAssert(added == YES, "Unable to add protocol to Objective-C class");
      added = class_addProtocol(newMetaclass, proto);
      RuntimeAssert(added == YES, "Unable to add protocol to Objective-C metaclass");
    }
  }

  AddDeallocMethod(newClass);

  AddMethods(newClass, info->instanceMethods, info->instanceMethodsNum);
  AddMethods(newMetaclass, info->classMethods, info->classMethodsNum);

  SetKotlinTypeInfo(newClass, info->typeInfo);
  SetKotlinTypeInfo(newMetaclass, info->metaTypeInfo);

  char bodyTypeEncoding[16];
  snprintf(bodyTypeEncoding, sizeof(bodyTypeEncoding), "[%dc]", info->bodySize);
  BOOL added = class_addIvar(newClass, "kotlinBody", info->bodySize, /* log2(align) = */ 3, bodyTypeEncoding);
  RuntimeAssert(added == YES, "Unable to add ivar to Objective-C class");

  objc_registerClassPair(newClass);

  Ivar body = class_getInstanceVariable(newClass, "kotlinBody");
  RuntimeAssert(body != nullptr, "Unable to get ivar added to Objective-C class");
  int32_t offset = (int32_t)ivar_getOffset(body);
  GetKotlinClassData(newClass)->bodyOffset = offset;
  *info->bodyOffset = offset;

  *info->createdClass = newClass;
  return newClass;
}

void* objc_autoreleasePoolPush();
void objc_autoreleasePoolPop(void* ptr);
id objc_allocWithZone(Class clazz);
id objc_retain(id ptr);
void objc_release(id ptr);

void* Kotlin_objc_autoreleasePoolPush() {
  return objc_autoreleasePoolPush();
}

void Kotlin_objc_autoreleasePoolPop(void* ptr) {
  objc_autoreleasePoolPop(ptr);
}

id Kotlin_objc_allocWithZone(Class clazz) {
  return objc_allocWithZone(clazz);
}

id Kotlin_objc_retain(id ptr) {
  return objc_retain(ptr);
}

void Kotlin_objc_release(id ptr) {
  objc_release(ptr);
}

Class Kotlin_objc_lookUpClass(const char* name) {
  return objc_lookUpClass(name);
}

} // extern "C"

#else  // KONAN_OBJC_INTEROP

#include "KAssert.h"

extern "C" {

void* Kotlin_objc_autoreleasePoolPush() {
  RuntimeAssert(false, "Objective-C interop is disabled");
  return nullptr;
}

void Kotlin_objc_autoreleasePoolPop(void* ptr) {
  RuntimeAssert(false, "Objective-C interop is disabled");
}

void* Kotlin_objc_allocWithZone(void* clazz) {
  RuntimeAssert(false, "Objective-C interop is disabled");
  return nullptr;
}

void* Kotlin_objc_retain(void* ptr) {
  RuntimeAssert(false, "Objective-C interop is disabled");
  return nullptr;
}

void Kotlin_objc_release(void* ptr) {
  RuntimeAssert(false, "Objective-C interop is disabled");
}

void* Kotlin_objc_lookUpClass(const char* name) {
  RuntimeAssert(false, "Objective-C interop is disabled");
  return nullptr;
}

} // extern "C"

#endif // KONAN_OBJC_INTEROP
<|endoftext|>


<commit_before>// Copyright (c) 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/third_party/quiche/src/quic/core/frames/quic_frame.h"

#include "net/third_party/quiche/src/quic/core/quic_constants.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"

namespace quic {

QuicFrame::QuicFrame() {}

QuicFrame::QuicFrame(QuicPaddingFrame padding_frame)
    : padding_frame(padding_frame) {}

QuicFrame::QuicFrame(QuicStreamFrame stream_frame)
    : stream_frame(stream_frame) {}

QuicFrame::QuicFrame(QuicCryptoFrame* crypto_frame)
    : type(CRYPTO_FRAME), crypto_frame(crypto_frame) {}

QuicFrame::QuicFrame(QuicAckFrame* frame) : type(ACK_FRAME), ack_frame(frame) {}

QuicFrame::QuicFrame(QuicMtuDiscoveryFrame frame)
    : mtu_discovery_frame(frame) {}

QuicFrame::QuicFrame(QuicStopWaitingFrame frame) : stop_waiting_frame(frame) {}

QuicFrame::QuicFrame(QuicPingFrame frame) : ping_frame(frame) {}

QuicFrame::QuicFrame(QuicRstStreamFrame* frame)
    : type(RST_STREAM_FRAME), rst_stream_frame(frame) {}

QuicFrame::QuicFrame(QuicConnectionCloseFrame* frame)
    : type(CONNECTION_CLOSE_FRAME), connection_close_frame(frame) {}

QuicFrame::QuicFrame(QuicGoAwayFrame* frame)
    : type(GOAWAY_FRAME), goaway_frame(frame) {}

QuicFrame::QuicFrame(QuicWindowUpdateFrame* frame)
    : type(WINDOW_UPDATE_FRAME), window_update_frame(frame) {}

QuicFrame::QuicFrame(QuicBlockedFrame* frame)
    : type(BLOCKED_FRAME), blocked_frame(frame) {}

QuicFrame::QuicFrame(QuicNewConnectionIdFrame* frame)
    : type(NEW_CONNECTION_ID_FRAME), new_connection_id_frame(frame) {}

QuicFrame::QuicFrame(QuicRetireConnectionIdFrame* frame)
    : type(RETIRE_CONNECTION_ID_FRAME), retire_connection_id_frame(frame) {}

QuicFrame::QuicFrame(QuicMaxStreamsFrame frame) : max_streams_frame(frame) {}

QuicFrame::QuicFrame(QuicStreamsBlockedFrame frame)
    : streams_blocked_frame(frame) {}

QuicFrame::QuicFrame(QuicPathResponseFrame* frame)
    : type(PATH_RESPONSE_FRAME), path_response_frame(frame) {}

QuicFrame::QuicFrame(QuicPathChallengeFrame* frame)
    : type(PATH_CHALLENGE_FRAME), path_challenge_frame(frame) {}

QuicFrame::QuicFrame(QuicStopSendingFrame* frame)
    : type(STOP_SENDING_FRAME), stop_sending_frame(frame) {}

QuicFrame::QuicFrame(QuicMessageFrame* frame)
    : type(MESSAGE_FRAME), message_frame(frame) {}

QuicFrame::QuicFrame(QuicNewTokenFrame* frame)
    : type(NEW_TOKEN_FRAME), new_token_frame(frame) {}

void DeleteFrames(QuicFrames* frames) {
  for (QuicFrame& frame : *frames) {
    DeleteFrame(&frame);
  }
  frames->clear();
}

void DeleteFrame(QuicFrame* frame) {
  switch (frame->type) {
    // Frames smaller than a pointer are inlined, so don't need to be deleted.
    case PADDING_FRAME:
    case MTU_DISCOVERY_FRAME:
    case PING_FRAME:
    case MAX_STREAMS_FRAME:
    case STOP_WAITING_FRAME:
    case STREAMS_BLOCKED_FRAME:
    case STREAM_FRAME:
      break;
    case ACK_FRAME:
      delete frame->ack_frame;
      break;
    case RST_STREAM_FRAME:
      delete frame->rst_stream_frame;
      break;
    case CONNECTION_CLOSE_FRAME:
      delete frame->connection_close_frame;
      break;
    case GOAWAY_FRAME:
      delete frame->goaway_frame;
      break;
    case BLOCKED_FRAME:
      delete frame->blocked_frame;
      break;
    case WINDOW_UPDATE_FRAME:
      delete frame->window_update_frame;
      break;
    case PATH_CHALLENGE_FRAME:
      delete frame->path_challenge_frame;
      break;
    case STOP_SENDING_FRAME:
      delete frame->stop_sending_frame;
      break;
    case NEW_CONNECTION_ID_FRAME:
      delete frame->new_connection_id_frame;
      break;
    case RETIRE_CONNECTION_ID_FRAME:
      delete frame->retire_connection_id_frame;
      break;
    case PATH_RESPONSE_FRAME:
      delete frame->path_response_frame;
      break;
    case MESSAGE_FRAME:
      delete frame->message_frame;
      break;
    case CRYPTO_FRAME:
      delete frame->crypto_frame;
      break;
    case NEW_TOKEN_FRAME:
      delete frame->new_token_frame;
      break;

    case NUM_FRAME_TYPES:
      DCHECK(false) << "Cannot delete type: " << frame->type;
  }
}

void RemoveFramesForStream(QuicFrames* frames, QuicStreamId stream_id) {
  auto it = frames->begin();
  while (it != frames->end()) {
    if (it->type != STREAM_FRAME || it->stream_frame.stream_id != stream_id) {
      ++it;
      continue;
    }
    it = frames->erase(it);
  }
}

bool IsControlFrame(QuicFrameType type) {
  switch (type) {
    case RST_STREAM_FRAME:
    case GOAWAY_FRAME:
    case WINDOW_UPDATE_FRAME:
    case BLOCKED_FRAME:
    case STREAMS_BLOCKED_FRAME:
    case MAX_STREAMS_FRAME:
    case PING_FRAME:
    case STOP_SENDING_FRAME:
      return true;
    default:
      return false;
  }
}

QuicControlFrameId GetControlFrameId(const QuicFrame& frame) {
  switch (frame.type) {
    case RST_STREAM_FRAME:
      return frame.rst_stream_frame->control_frame_id;
    case GOAWAY_FRAME:
      return frame.goaway_frame->control_frame_id;
    case WINDOW_UPDATE_FRAME:
      return frame.window_update_frame->control_frame_id;
    case BLOCKED_FRAME:
      return frame.blocked_frame->control_frame_id;
    case STREAMS_BLOCKED_FRAME:
      return frame.streams_blocked_frame.control_frame_id;
    case MAX_STREAMS_FRAME:
      return frame.max_streams_frame.control_frame_id;
    case PING_FRAME:
      return frame.ping_frame.control_frame_id;
    case STOP_SENDING_FRAME:
      return frame.stop_sending_frame->control_frame_id;
    default:
      return kInvalidControlFrameId;
  }
}

void SetControlFrameId(QuicControlFrameId control_frame_id, QuicFrame* frame) {
  switch (frame->type) {
    case RST_STREAM_FRAME:
      frame->rst_stream_frame->control_frame_id = control_frame_id;
      return;
    case GOAWAY_FRAME:
      frame->goaway_frame->control_frame_id = control_frame_id;
      return;
    case WINDOW_UPDATE_FRAME:
      frame->window_update_frame->control_frame_id = control_frame_id;
      return;
    case BLOCKED_FRAME:
      frame->blocked_frame->control_frame_id = control_frame_id;
      return;
    case PING_FRAME:
      frame->ping_frame.control_frame_id = control_frame_id;
      return;
    case STREAMS_BLOCKED_FRAME:
      frame->streams_blocked_frame.control_frame_id = control_frame_id;
      return;
    case MAX_STREAMS_FRAME:
      frame->max_streams_frame.control_frame_id = control_frame_id;
      return;
    case STOP_SENDING_FRAME:
      frame->stop_sending_frame->control_frame_id = control_frame_id;
      return;
    default:
      QUIC_BUG
          << "Try to set control frame id of a frame without control frame id";
  }
}

QuicFrame CopyRetransmittableControlFrame(const QuicFrame& frame) {
  QuicFrame copy;
  switch (frame.type) {
    case RST_STREAM_FRAME:
      copy = QuicFrame(new QuicRstStreamFrame(*frame.rst_stream_frame));
      break;
    case GOAWAY_FRAME:
      copy = QuicFrame(new QuicGoAwayFrame(*frame.goaway_frame));
      break;
    case WINDOW_UPDATE_FRAME:
      copy = QuicFrame(new QuicWindowUpdateFrame(*frame.window_update_frame));
      break;
    case BLOCKED_FRAME:
      copy = QuicFrame(new QuicBlockedFrame(*frame.blocked_frame));
      break;
    case PING_FRAME:
      copy = QuicFrame(QuicPingFrame(frame.ping_frame.control_frame_id));
      break;
    case STOP_SENDING_FRAME:
      copy = QuicFrame(new QuicStopSendingFrame(*frame.stop_sending_frame));
      break;
    case STREAMS_BLOCKED_FRAME:
      copy = QuicFrame(QuicStreamsBlockedFrame(frame.streams_blocked_frame));
      break;
    case MAX_STREAMS_FRAME:
      copy = QuicFrame(QuicMaxStreamsFrame(frame.max_streams_frame));
      break;
    default:
      QUIC_BUG << "Try to copy a non-retransmittable control frame: " << frame;
      copy = QuicFrame(QuicPingFrame(kInvalidControlFrameId));
      break;
  }
  return copy;
}

std::ostream& operator<<(std::ostream& os, const QuicFrame& frame) {
  switch (frame.type) {
    case PADDING_FRAME: {
      os << "type { PADDING_FRAME } " << frame.padding_frame;
      break;
    }
    case RST_STREAM_FRAME: {
      os << "type { RST_STREAM_FRAME } " << *(frame.rst_stream_frame);
      break;
    }
    case CONNECTION_CLOSE_FRAME: {
      os << "type { CONNECTION_CLOSE_FRAME } "
         << *(frame.connection_close_frame);
      break;
    }
    case GOAWAY_FRAME: {
      os << "type { GOAWAY_FRAME } " << *(frame.goaway_frame);
      break;
    }
    case WINDOW_UPDATE_FRAME: {
      os << "type { WINDOW_UPDATE_FRAME } " << *(frame.window_update_frame);
      break;
    }
    case BLOCKED_FRAME: {
      os << "type { BLOCKED_FRAME } " << *(frame.blocked_frame);
      break;
    }
    case STREAM_FRAME: {
      os << "type { STREAM_FRAME } " << frame.stream_frame;
      break;
    }
    case ACK_FRAME: {
      os << "type { ACK_FRAME } " << *(frame.ack_frame);
      break;
    }
    case STOP_WAITING_FRAME: {
      os << "type { STOP_WAITING_FRAME } " << frame.stop_waiting_frame;
      break;
    }
    case PING_FRAME: {
      os << "type { PING_FRAME } " << frame.ping_frame;
      break;
    }
    case MTU_DISCOVERY_FRAME: {
      os << "type { MTU_DISCOVERY_FRAME } ";
      break;
    }
    case NEW_CONNECTION_ID_FRAME:
      os << "type { NEW_CONNECTION_ID } " << *(frame.new_connection_id_frame);
      break;
    case RETIRE_CONNECTION_ID_FRAME:
      os << "type { RETIRE_CONNECTION_ID } "
         << *(frame.retire_connection_id_frame);
      break;
    case MAX_STREAMS_FRAME:
      os << "type { MAX_STREAMS } " << frame.max_streams_frame;
      break;
    case STREAMS_BLOCKED_FRAME:
      os << "type { STREAMS_BLOCKED } " << frame.streams_blocked_frame;
      break;
    case PATH_RESPONSE_FRAME:
      os << "type { PATH_RESPONSE } " << *(frame.path_response_frame);
      break;
    case PATH_CHALLENGE_FRAME:
      os << "type { PATH_CHALLENGE } " << *(frame.path_challenge_frame);
      break;
    case STOP_SENDING_FRAME:
      os << "type { STOP_SENDING } " << *(frame.stop_sending_frame);
      break;
    case MESSAGE_FRAME:
      os << "type { MESSAGE_FRAME }" << *(frame.message_frame);
      break;
    case NEW_TOKEN_FRAME:
      os << "type { NEW_TOKEN_FRAME }" << *(frame.new_token_frame);
      break;
    default: {
      QUIC_LOG(ERROR) << "Unknown frame type: " << frame.type;
      break;
    }
  }
  return os;
}

}  // namespace quic
<commit_msg>gfe-relnote: (n/a) Emit CRYPTO_FRAME in operator<<(QuicFrame). Logging only change.<commit_after>// Copyright (c) 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/third_party/quiche/src/quic/core/frames/quic_frame.h"

#include "net/third_party/quiche/src/quic/core/quic_constants.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"

namespace quic {

QuicFrame::QuicFrame() {}

QuicFrame::QuicFrame(QuicPaddingFrame padding_frame)
    : padding_frame(padding_frame) {}

QuicFrame::QuicFrame(QuicStreamFrame stream_frame)
    : stream_frame(stream_frame) {}

QuicFrame::QuicFrame(QuicCryptoFrame* crypto_frame)
    : type(CRYPTO_FRAME), crypto_frame(crypto_frame) {}

QuicFrame::QuicFrame(QuicAckFrame* frame) : type(ACK_FRAME), ack_frame(frame) {}

QuicFrame::QuicFrame(QuicMtuDiscoveryFrame frame)
    : mtu_discovery_frame(frame) {}

QuicFrame::QuicFrame(QuicStopWaitingFrame frame) : stop_waiting_frame(frame) {}

QuicFrame::QuicFrame(QuicPingFrame frame) : ping_frame(frame) {}

QuicFrame::QuicFrame(QuicRstStreamFrame* frame)
    : type(RST_STREAM_FRAME), rst_stream_frame(frame) {}

QuicFrame::QuicFrame(QuicConnectionCloseFrame* frame)
    : type(CONNECTION_CLOSE_FRAME), connection_close_frame(frame) {}

QuicFrame::QuicFrame(QuicGoAwayFrame* frame)
    : type(GOAWAY_FRAME), goaway_frame(frame) {}

QuicFrame::QuicFrame(QuicWindowUpdateFrame* frame)
    : type(WINDOW_UPDATE_FRAME), window_update_frame(frame) {}

QuicFrame::QuicFrame(QuicBlockedFrame* frame)
    : type(BLOCKED_FRAME), blocked_frame(frame) {}

QuicFrame::QuicFrame(QuicNewConnectionIdFrame* frame)
    : type(NEW_CONNECTION_ID_FRAME), new_connection_id_frame(frame) {}

QuicFrame::QuicFrame(QuicRetireConnectionIdFrame* frame)
    : type(RETIRE_CONNECTION_ID_FRAME), retire_connection_id_frame(frame) {}

QuicFrame::QuicFrame(QuicMaxStreamsFrame frame) : max_streams_frame(frame) {}

QuicFrame::QuicFrame(QuicStreamsBlockedFrame frame)
    : streams_blocked_frame(frame) {}

QuicFrame::QuicFrame(QuicPathResponseFrame* frame)
    : type(PATH_RESPONSE_FRAME), path_response_frame(frame) {}

QuicFrame::QuicFrame(QuicPathChallengeFrame* frame)
    : type(PATH_CHALLENGE_FRAME), path_challenge_frame(frame) {}

QuicFrame::QuicFrame(QuicStopSendingFrame* frame)
    : type(STOP_SENDING_FRAME), stop_sending_frame(frame) {}

QuicFrame::QuicFrame(QuicMessageFrame* frame)
    : type(MESSAGE_FRAME), message_frame(frame) {}

QuicFrame::QuicFrame(QuicNewTokenFrame* frame)
    : type(NEW_TOKEN_FRAME), new_token_frame(frame) {}

void DeleteFrames(QuicFrames* frames) {
  for (QuicFrame& frame : *frames) {
    DeleteFrame(&frame);
  }
  frames->clear();
}

void DeleteFrame(QuicFrame* frame) {
  switch (frame->type) {
    // Frames smaller than a pointer are inlined, so don't need to be deleted.
    case PADDING_FRAME:
    case MTU_DISCOVERY_FRAME:
    case PING_FRAME:
    case MAX_STREAMS_FRAME:
    case STOP_WAITING_FRAME:
    case STREAMS_BLOCKED_FRAME:
    case STREAM_FRAME:
      break;
    case ACK_FRAME:
      delete frame->ack_frame;
      break;
    case RST_STREAM_FRAME:
      delete frame->rst_stream_frame;
      break;
    case CONNECTION_CLOSE_FRAME:
      delete frame->connection_close_frame;
      break;
    case GOAWAY_FRAME:
      delete frame->goaway_frame;
      break;
    case BLOCKED_FRAME:
      delete frame->blocked_frame;
      break;
    case WINDOW_UPDATE_FRAME:
      delete frame->window_update_frame;
      break;
    case PATH_CHALLENGE_FRAME:
      delete frame->path_challenge_frame;
      break;
    case STOP_SENDING_FRAME:
      delete frame->stop_sending_frame;
      break;
    case NEW_CONNECTION_ID_FRAME:
      delete frame->new_connection_id_frame;
      break;
    case RETIRE_CONNECTION_ID_FRAME:
      delete frame->retire_connection_id_frame;
      break;
    case PATH_RESPONSE_FRAME:
      delete frame->path_response_frame;
      break;
    case MESSAGE_FRAME:
      delete frame->message_frame;
      break;
    case CRYPTO_FRAME:
      delete frame->crypto_frame;
      break;
    case NEW_TOKEN_FRAME:
      delete frame->new_token_frame;
      break;

    case NUM_FRAME_TYPES:
      DCHECK(false) << "Cannot delete type: " << frame->type;
  }
}

void RemoveFramesForStream(QuicFrames* frames, QuicStreamId stream_id) {
  auto it = frames->begin();
  while (it != frames->end()) {
    if (it->type != STREAM_FRAME || it->stream_frame.stream_id != stream_id) {
      ++it;
      continue;
    }
    it = frames->erase(it);
  }
}

bool IsControlFrame(QuicFrameType type) {
  switch (type) {
    case RST_STREAM_FRAME:
    case GOAWAY_FRAME:
    case WINDOW_UPDATE_FRAME:
    case BLOCKED_FRAME:
    case STREAMS_BLOCKED_FRAME:
    case MAX_STREAMS_FRAME:
    case PING_FRAME:
    case STOP_SENDING_FRAME:
      return true;
    default:
      return false;
  }
}

QuicControlFrameId GetControlFrameId(const QuicFrame& frame) {
  switch (frame.type) {
    case RST_STREAM_FRAME:
      return frame.rst_stream_frame->control_frame_id;
    case GOAWAY_FRAME:
      return frame.goaway_frame->control_frame_id;
    case WINDOW_UPDATE_FRAME:
      return frame.window_update_frame->control_frame_id;
    case BLOCKED_FRAME:
      return frame.blocked_frame->control_frame_id;
    case STREAMS_BLOCKED_FRAME:
      return frame.streams_blocked_frame.control_frame_id;
    case MAX_STREAMS_FRAME:
      return frame.max_streams_frame.control_frame_id;
    case PING_FRAME:
      return frame.ping_frame.control_frame_id;
    case STOP_SENDING_FRAME:
      return frame.stop_sending_frame->control_frame_id;
    default:
      return kInvalidControlFrameId;
  }
}

void SetControlFrameId(QuicControlFrameId control_frame_id, QuicFrame* frame) {
  switch (frame->type) {
    case RST_STREAM_FRAME:
      frame->rst_stream_frame->control_frame_id = control_frame_id;
      return;
    case GOAWAY_FRAME:
      frame->goaway_frame->control_frame_id = control_frame_id;
      return;
    case WINDOW_UPDATE_FRAME:
      frame->window_update_frame->control_frame_id = control_frame_id;
      return;
    case BLOCKED_FRAME:
      frame->blocked_frame->control_frame_id = control_frame_id;
      return;
    case PING_FRAME:
      frame->ping_frame.control_frame_id = control_frame_id;
      return;
    case STREAMS_BLOCKED_FRAME:
      frame->streams_blocked_frame.control_frame_id = control_frame_id;
      return;
    case MAX_STREAMS_FRAME:
      frame->max_streams_frame.control_frame_id = control_frame_id;
      return;
    case STOP_SENDING_FRAME:
      frame->stop_sending_frame->control_frame_id = control_frame_id;
      return;
    default:
      QUIC_BUG
          << "Try to set control frame id of a frame without control frame id";
  }
}

QuicFrame CopyRetransmittableControlFrame(const QuicFrame& frame) {
  QuicFrame copy;
  switch (frame.type) {
    case RST_STREAM_FRAME:
      copy = QuicFrame(new QuicRstStreamFrame(*frame.rst_stream_frame));
      break;
    case GOAWAY_FRAME:
      copy = QuicFrame(new QuicGoAwayFrame(*frame.goaway_frame));
      break;
    case WINDOW_UPDATE_FRAME:
      copy = QuicFrame(new QuicWindowUpdateFrame(*frame.window_update_frame));
      break;
    case BLOCKED_FRAME:
      copy = QuicFrame(new QuicBlockedFrame(*frame.blocked_frame));
      break;
    case PING_FRAME:
      copy = QuicFrame(QuicPingFrame(frame.ping_frame.control_frame_id));
      break;
    case STOP_SENDING_FRAME:
      copy = QuicFrame(new QuicStopSendingFrame(*frame.stop_sending_frame));
      break;
    case STREAMS_BLOCKED_FRAME:
      copy = QuicFrame(QuicStreamsBlockedFrame(frame.streams_blocked_frame));
      break;
    case MAX_STREAMS_FRAME:
      copy = QuicFrame(QuicMaxStreamsFrame(frame.max_streams_frame));
      break;
    default:
      QUIC_BUG << "Try to copy a non-retransmittable control frame: " << frame;
      copy = QuicFrame(QuicPingFrame(kInvalidControlFrameId));
      break;
  }
  return copy;
}

std::ostream& operator<<(std::ostream& os, const QuicFrame& frame) {
  switch (frame.type) {
    case PADDING_FRAME: {
      os << "type { PADDING_FRAME } " << frame.padding_frame;
      break;
    }
    case RST_STREAM_FRAME: {
      os << "type { RST_STREAM_FRAME } " << *(frame.rst_stream_frame);
      break;
    }
    case CONNECTION_CLOSE_FRAME: {
      os << "type { CONNECTION_CLOSE_FRAME } "
         << *(frame.connection_close_frame);
      break;
    }
    case GOAWAY_FRAME: {
      os << "type { GOAWAY_FRAME } " << *(frame.goaway_frame);
      break;
    }
    case WINDOW_UPDATE_FRAME: {
      os << "type { WINDOW_UPDATE_FRAME } " << *(frame.window_update_frame);
      break;
    }
    case BLOCKED_FRAME: {
      os << "type { BLOCKED_FRAME } " << *(frame.blocked_frame);
      break;
    }
    case STREAM_FRAME: {
      os << "type { STREAM_FRAME } " << frame.stream_frame;
      break;
    }
    case ACK_FRAME: {
      os << "type { ACK_FRAME } " << *(frame.ack_frame);
      break;
    }
    case STOP_WAITING_FRAME: {
      os << "type { STOP_WAITING_FRAME } " << frame.stop_waiting_frame;
      break;
    }
    case PING_FRAME: {
      os << "type { PING_FRAME } " << frame.ping_frame;
      break;
    }
    case CRYPTO_FRAME: {
      os << "type { CRYPTO_FRAME } " << frame.crypto_frame;
      break;
    }
    case MTU_DISCOVERY_FRAME: {
      os << "type { MTU_DISCOVERY_FRAME } ";
      break;
    }
    case NEW_CONNECTION_ID_FRAME:
      os << "type { NEW_CONNECTION_ID } " << *(frame.new_connection_id_frame);
      break;
    case RETIRE_CONNECTION_ID_FRAME:
      os << "type { RETIRE_CONNECTION_ID } "
         << *(frame.retire_connection_id_frame);
      break;
    case MAX_STREAMS_FRAME:
      os << "type { MAX_STREAMS } " << frame.max_streams_frame;
      break;
    case STREAMS_BLOCKED_FRAME:
      os << "type { STREAMS_BLOCKED } " << frame.streams_blocked_frame;
      break;
    case PATH_RESPONSE_FRAME:
      os << "type { PATH_RESPONSE } " << *(frame.path_response_frame);
      break;
    case PATH_CHALLENGE_FRAME:
      os << "type { PATH_CHALLENGE } " << *(frame.path_challenge_frame);
      break;
    case STOP_SENDING_FRAME:
      os << "type { STOP_SENDING } " << *(frame.stop_sending_frame);
      break;
    case MESSAGE_FRAME:
      os << "type { MESSAGE_FRAME }" << *(frame.message_frame);
      break;
    case NEW_TOKEN_FRAME:
      os << "type { NEW_TOKEN_FRAME }" << *(frame.new_token_frame);
      break;
    default: {
      QUIC_LOG(ERROR) << "Unknown frame type: " << frame.type;
      break;
    }
  }
  return os;
}

}  // namespace quic
<|endoftext|>