<commit_before>#ifndef _sbl_splay_tree
#define _sbl_splay_tree

namespace sbl {
namespace detail {

template<class NodePtr>
struct SplayTreeNode {
    NodePtr left;   ///< left child
    NodePtr right;  ///< right child
    NodePtr parent; ///< parent node
    SplayTreeNode(): left(NULL), right(NULL), parent(NULL) {}
};

template<class NodePtr, class GetNode, class Expand, class Update>
class SplayTree {
        // Bottom-Up Splay Tree
        // FAQ
        // Q: Why not use Top-Down Splay Tree?
        // A: There are three reasons.
        //    * Update and expand operator wipe out the performance advantages
        //    * The design of Top-Down is too complex (need 3 trees to splay)
        //    * Since we can not be allocated memory, we have no dummy node
    public:
        /// get the node information from NodePtr

        static SplayTreeNode<NodePtr> &get_node(NodePtr a) {
            assert(a != NULL);
            return GetNode()(a);
        }

        static NodePtr get_child(NodePtr a, size_t idx) {
            assert(idx == 0 or idx == 1);
            if (idx == 0)
                return get_left(a);
            else
                return get_right(a);
        }
        static void set_child(NodePtr a, size_t idx, NodePtr b) {
            assert(idx == 0 or idx == 1);
            if (idx == 0)
                set_left(a, b);
            else
                set_right(a, b);
        }

        static NodePtr get_left(NodePtr a) {
            if (a == NULL) return NULL;
            return get_node(a).left;
        }

        static void set_left(NodePtr a, NodePtr b) {
            if (a == NULL) return ;
            get_node(a).left = b;
        }

        static NodePtr get_right(NodePtr a) {
            if (a == NULL) return NULL;
            return get_node(a).right;
        }

        static void set_right(NodePtr a, NodePtr b) {
            if (a == NULL) return ;
            get_node(a).right = b;
        }

        static NodePtr get_parent(NodePtr a) {
            if (a == NULL)return NULL;
            return get_node(a).parent;
        }

        static void set_parent(NodePtr a, NodePtr b) {
            if (a == NULL) return ;
            get_node(a).parent = b;
        }

        static bool is_right(NodePtr x) {
            assert(x != NULL);
            NodePtr y = get_parent(x);
            if (y == NULL) return false;
            return get_right(y) == x;
        }

        static bool is_left(NodePtr x) {
            assert(x != NULL);
            NodePtr y = get_parent(x);
            if (y == NULL) return false;
            return get_left(y) == x;
        }

        static void expand(NodePtr x, NodePtr l, NodePtr r) {
            return Expand()(x, l, r);
        }

        static void update(NodePtr x, NodePtr l, NodePtr r) {
            //cout << "===============================" << endl;
            //std::cout << ::acml::json::dumps(x) << std::endl;
            //std::cout << ::acml::json::dumps(l) << std::endl;
            //std::cout << ::acml::json::dumps(r) << std::endl;
            //cout << "===============================" << endl;
            return Update()(x, l, r);
        }

        static void expand(NodePtr x) {
            expand(x, get_left(x), get_right(x));
        }

        static void update(NodePtr x) {
            update(x, get_left(x), get_right(x));
        }

        static void rotate(NodePtr x) {
            NodePtr y = get_parent(x);
            if (get_parent(y) != NULL) {
                if (get_left(get_parent(y)) == y)
                    set_left(get_parent(y), x);
                else
                    set_right(get_parent(y), x);
            }
            set_parent(x, get_parent(y));
            size_t c = (get_left(y) == x) ? 0 : 1;
            set_child(y, c, get_child(x, 1 - c));
            set_parent(get_child(y, c), y);

            set_child(x, 1 - c, y);
            set_parent(y, x);

            update(y);
            update(x);
        }

        static void splay(NodePtr t) {
            while (get_parent(t) != NULL) {
                NodePtr y = get_parent(t);
                if (get_parent(y) == NULL) {
                    rotate(t);
                } else {
                    bool isZigZig = is_right(t) and is_right(y);
                    bool isZagZag = is_left(t) and is_left(y);
                    if (isZigZig or isZagZag) {
                        // zig-zig or zag-zag
                        rotate(y);
                        rotate(t);
                    } else {
                        // zig-zag or zag-zig
                        rotate(t);
                        rotate(t);
                    }
                }
            }
        }

        template<class Compare3way>
        static NodePtr add(NodePtr root, NodePtr node, Compare3way compare) {
            if (root == NULL)
                return node;
            assert(get_parent(root) == NULL);
            NodePtr current = root; ///< current node we focus
            while (true) {
                expand(current);
                int k = compare(current);
                if (k == -1) {
                    if (get_left(current) == NULL) {
                        set_left(current, node);
                        set_parent(node, current);
                        break;
                    }
                    current = get_left(current);
                } else {
                    if (get_right(current) == NULL) {
                        set_right(current, node);
                        set_parent(node, current);
                        break;
                    }
                    current = get_right(current);
                }
            }
            update(node);
            splay(node);
            return node;
        }

        template<int n>
        struct AlwaysReturn {
            int operator()(...) {
                return n;
            }
        };

        static NodePtr leftmost(NodePtr root) {
            return find(root, AlwaysReturn<1>());
        }

        static NodePtr rightmost(NodePtr root) {
            return find(root, AlwaysReturn<1>());
        }

        static NodePtr del(NodePtr root) {
            if (root == NULL)
                return root;
            NodePtr left = get_left(root);
            NodePtr right = get_right(root);
            expand(root);

            // break left child
            set_left(root, NULL);
            set_parent(left, NULL);

            // break right child
            set_right(root, NULL);
            set_parent(right, NULL);

            if (left == NULL) {
                return right;
            } else {
                left = leftmost(left);
                assert(get_right(left) == NULL);
                set_right(left, right);
                set_parent(right, left);
                update(left);
                return left;
            }
        }

        template<class Compare3way>
        static NodePtr find(NodePtr root, Compare3way compare) {
            if (root == NULL)
                return root;
            NodePtr current = root;
            while (true) {
                assert(current != NULL);
                expand(current);
                int k = compare(current);
                if (k == -1) {
                    if (get_left(current) == NULL)
                        break;
                    current = get_left(current);
                } else if (k == 1) {
                    if (get_right(current) == NULL)
                        break;
                    current = get_right(current);
                } else {
                    assert(k == 0 and "SplayTree:: 3way not in {-1,0,1}");
                    break;
                }
            }
            splay(current);
            return current;
        }

}; // class SplayTree
} // namespace detail
} // namespace sbl
#endif
<commit_msg>fixed a bug in splay tree and add some comments for splay tree<commit_after>#ifndef _sbl_splay_tree
#define _sbl_splay_tree

namespace sbl {
namespace detail {

template<class NodePtr>
struct SplayTreeNode {
    NodePtr left;   ///< left child
    NodePtr right;  ///< right child
    NodePtr parent; ///< parent node
    SplayTreeNode(): left(NULL), right(NULL), parent(NULL) {}
};

template<class NodePtr, class GetNode, class Expand, class Update>
class SplayTree {
        // Bottom-Up Splay Tree
        // FAQ
        // Q: Why not use Top-Down Splay Tree?
        // A: There are three reasons.
        //    * Update and expand operator wipe out the performance advantages
        //    * The design of Top-Down is too complex (need 3 trees to splay)
        //    * Since we can not be allocated memory, we have no dummy node
    public:
        /// get the node information from NodePtr
        static SplayTreeNode<NodePtr> &get_node(NodePtr a) {
            assert(a != NULL);
            return GetNode()(a);
        }

        /// get the child according index {0: left, 1: right}
        static NodePtr get_child(NodePtr a, size_t idx) {
            assert(idx == 0 or idx == 1);
            if (idx == 0)
                return get_left(a);
            else
                return get_right(a);
        }

        /// set the child according index {0: left, 1: right}
        static void set_child(NodePtr a, size_t idx, NodePtr b) {
            assert(idx == 0 or idx == 1);
            if (idx == 0)
                set_left(a, b);
            else
                set_right(a, b);
        }

        /// get left child
        static NodePtr get_left(NodePtr a) {
            if (a == NULL) return NULL;
            return get_node(a).left;
        }

        /// set left child
        static void set_left(NodePtr a, NodePtr b) {
            if (a == NULL) return ;
            get_node(a).left = b;
        }

        /// get right child
        static NodePtr get_right(NodePtr a) {
            if (a == NULL) return NULL;
            return get_node(a).right;
        }

        /// set right child
        static void set_right(NodePtr a, NodePtr b) {
            if (a == NULL) return ;
            get_node(a).right = b;
        }

        /// get parent
        static NodePtr get_parent(NodePtr a) {
            if (a == NULL)return NULL;
            return get_node(a).parent;
        }

        /// set parent
        static void set_parent(NodePtr a, NodePtr b) {
            if (a == NULL) return ;
            get_node(a).parent = b;
        }

        /// check if x is a right child
        static bool is_right(NodePtr x) {
            assert(x != NULL);
            NodePtr y = get_parent(x);
            if (y == NULL) return false;
            return get_right(y) == x;
        }

        /// check if x is a left child
        static bool is_left(NodePtr x) {
            return not is_right(x);
        }

        static void expand(NodePtr parent, NodePtr left, NodePtr right) {
            return Expand()(parent, left, right);
        }

        static void update(NodePtr parent, NodePtr left, NodePtr right) {
            return Update()(parent, left, right);
        }

        /// expand node x information to his children
        static void expand(NodePtr x) {
            expand(x, get_left(x), get_right(x));
        }

        /// update node x information from his children
        static void update(NodePtr x) {
            update(x, get_left(x), get_right(x));
        }

        /// swap x to her father
        static void rotate(NodePtr x) {
            NodePtr y = get_parent(x);
            if (get_parent(y) != NULL) {
                if (get_left(get_parent(y)) == y)
                    set_left(get_parent(y), x);
                else
                    set_right(get_parent(y), x);
            }
            set_parent(x, get_parent(y));
            size_t c = (get_left(y) == x) ? 0 : 1;
            set_child(y, c, get_child(x, 1 - c));
            set_parent(get_child(y, c), y);

            set_child(x, 1 - c, y);
            set_parent(y, x);

            update(y);
            update(x);
        }

        /// splay t to the root
        static void splay(NodePtr t) {
            while (get_parent(t) != NULL) {
                NodePtr y = get_parent(t);
                if (get_parent(y) == NULL) {
                    rotate(t);
                } else {
                    bool isZigZig = is_right(t) and is_right(y);
                    bool isZagZag = is_left(t) and is_left(y);
                    if (isZigZig or isZagZag) {
                        // zig-zig or zag-zag
                        rotate(y);
                        rotate(t);
                    } else {
                        // zig-zag or zag-zig
                        rotate(t);
                        rotate(t);
                    }
                }
            }
        }

        /// add a new node to root according compare.
        /// compare must given a NodePtr and return {-1, 0, 1}
        /// -1: current node bigger, to the left subtree
        /// 0: current node equal to x, to the right subtree
        /// 1: current node smaller, to the right subtree
        /// @return new root
        template<class Compare3way>
        static NodePtr add(NodePtr root, NodePtr node, Compare3way compare) {
            if (root == NULL)
                return node;
            assert(get_parent(root) == NULL);
            NodePtr current = root; ///< current node we focus
            while (true) {
                expand(current);
                int k = compare(current);
                if (k == -1) {
                    if (get_left(current) == NULL) {
                        set_left(current, node);
                        set_parent(node, current);
                        break;
                    }
                    current = get_left(current);
                } else {
                    if (get_right(current) == NULL) {
                        set_right(current, node);
                        set_parent(node, current);
                        break;
                    }
                    current = get_right(current);
                }
            }
            update(node);
            splay(node);
            return node;
        }

    private:
        template<int n>
        struct AlwaysReturn {
            int operator()(...) {
                return n;
            }
        };
    public:

        /// splay the leftmost node
        static NodePtr leftmost(NodePtr root) {
            return find(root, AlwaysReturn<-1>());
        }

        /// splay the rightmost node
        static NodePtr rightmost(NodePtr root) {
            return find(root, AlwaysReturn<1>());
        }

        /// delete the root
        /// @return new root
        static NodePtr del(NodePtr root) {
            if (root == NULL)
                return root;
            NodePtr left = get_left(root);
            NodePtr right = get_right(root);
            expand(root);

            // break left child
            set_left(root, NULL);
            set_parent(left, NULL);

            // break right child
            set_right(root, NULL);
            set_parent(right, NULL);

            if (left == NULL) {
                return right;
            } else {
                left = rightmost(left);
                assert(get_right(left) == NULL);
                set_right(left, right);
                set_parent(right, left);
                update(left);
                return left;
            }
        }

        /// find a node according Compare3way compare.
        /// compare must given a NodePtr and return {-1, 0, 1}
        /// -1: to the left subtree
        /// 0: we found it !!! splay it to the root!
        /// 1: to the right subtree
        /// @return new root (the node we found)
        template<class Compare3way>
        static NodePtr find(NodePtr root, Compare3way compare) {
            if (root == NULL)
                return root;
            NodePtr current = root;
            while (true) {
                assert(current != NULL);
                expand(current);
                int k = compare(current);
                if (k == -1) {
                    if (get_left(current) == NULL)
                        break;
                    current = get_left(current);
                } else if (k == 1) {
                    if (get_right(current) == NULL)
                        break;
                    current = get_right(current);
                } else {
                    assert(k == 0 and "SplayTree:: 3way not in {-1,0,1}");
                    break;
                }
            }
            splay(current);
            return current;
        }

}; // class SplayTree
} // namespace detail
} // namespace sbl
#endif
<|endoftext|>


<commit_before>/*
 * QMicroMapTest.cpp
 *
 *  Created on: May 3, 2011
 *      Author: martinc
 */
#include "QMicroMapTest.h"
#include <iostream>
#include "QStationModelGraphicsItem.h"

/////////////////////////////////////////////////////////////////////////////////////////////////
QMicroMapTest::QMicroMapTest(SpatiaLiteDB& db,
		double xmin,
		double ymin,
		double xmax,
		double ymax,
		std::string backgroundColor,
		QWidget* parent):
QDialog(parent),
_xmin(xmin),
_ymin(ymin),
_xmax(xmax),
_ymax(ymax),
_zoomInc(0.1)
{
	// setting up the Qt form
	setupUi(this);

	// we need a layout manager
	QVBoxLayout* vb = new QVBoxLayout(frame);

	// create the micromap and add to the layout
	_mm = new QMicroMap(db, _xmin, _ymin, _xmax, _ymax, backgroundColor);
	vb->addWidget(_mm);

	// connect signals
	connect(zoomIn,  SIGNAL(released()),       this, SLOT(zoomInSlot()));
	connect(zoomOut, SIGNAL(released()),       this, SLOT(zoomOutSlot()));
	connect(labels,  SIGNAL(stateChanged(int)), _mm, SLOT(labels(int)));

	double wspd = 45;
	double wdir = 15;
	double lon = -86;
	for (double lat = 24.0; lat < 29.0; lat += 0.5) {
		QStationModelGraphicsItem* sm = new QStationModelGraphicsItem(lon, lat, wspd, wdir);
		wspd += 12;
		wdir += 13;
		lon -= 0.5;
		_mm->scene()->addItem(sm);
	}
	wspd = 55;
	wdir = 15;
	lon = -86;
	for (double lat = 27.0; lat >= 24.0; lat -= 0.25) {
		QStationModelGraphicsItem* sm = new QStationModelGraphicsItem(lon, lat, wspd, wdir);
		wspd += 9;
		wdir += 13;
		lon -= 0.7;
		_mm->scene()->addItem(sm);
	}
}

/////////////////////////////////////////////////////////////////////////////////////////////////
QMicroMapTest::~QMicroMapTest() {

}

/////////////////////////////////////////////////////////////////////////////////////////////////
void QMicroMapTest::zoomInSlot() {
	_mm->scale(1.0+_zoomInc, 1.0+_zoomInc);
}

/////////////////////////////////////////////////////////////////////////////////////////////////
void QMicroMapTest::zoomOutSlot() {
	_mm->scale(1.0/(1.0+_zoomInc), 1.0/(1.0+_zoomInc));
}

/////////////////////////////////////////////////////////////////////////////////////////////////
void QMicroMapTest::zoom(double deltax, double deltay) {

	_xmin = _xmin+deltax;
	_xmax = _xmax-deltax;
	_ymin = _ymin+deltay;
	_ymax = _ymax-deltay;
	_mm->drawFeatures(_xmin, _ymin, _xmax, _ymax);
}
<commit_msg>Create a test collection of station models that look something like real observations.<commit_after>/*
 * QMicroMapTest.cpp
 *
 *  Created on: May 3, 2011
 *      Author: martinc
 */
#include "QMicroMapTest.h"
#include <iostream>
#include "QStationModelGraphicsItem.h"

/////////////////////////////////////////////////////////////////////////////////////////////////
QMicroMapTest::QMicroMapTest(SpatiaLiteDB& db,
		double xmin,
		double ymin,
		double xmax,
		double ymax,
		std::string backgroundColor,
		QWidget* parent):
QDialog(parent),
_xmin(xmin),
_ymin(ymin),
_xmax(xmax),
_ymax(ymax),
_zoomInc(0.1)
{
	// setting up the Qt form
	setupUi(this);

	// we need a layout manager
	QVBoxLayout* vb = new QVBoxLayout(frame);

	// create the micromap and add to the layout
	_mm = new QMicroMap(db, _xmin, _ymin, _xmax, _ymax, backgroundColor);
	vb->addWidget(_mm);

	// connect signals
	connect(zoomIn,  SIGNAL(released()),       this, SLOT(zoomInSlot()));
	connect(zoomOut, SIGNAL(released()),       this, SLOT(zoomOutSlot()));
	connect(labels,  SIGNAL(stateChanged(int)), _mm, SLOT(labels(int)));

	double wspd = 45;
	double wdir = 15;
	double lon = -86;
	for (double lat = 24.0; lat < 29.0; lat += 0.5) {
		QStationModelGraphicsItem* sm = new QStationModelGraphicsItem(lon, lat, wspd, wdir);
		wspd += 12;
		wdir += 13;
		lon -= 0.5;
		_mm->scene()->addItem(sm);
	}
	wspd = 55;
	wdir = 15;
	lon = -86;
	for (double lat = 27.0; lat >= 24.0; lat -= 0.25) {
		QStationModelGraphicsItem* sm = new QStationModelGraphicsItem(lon, lat, wspd, wdir);
		wspd += 9;
		wdir += 13;
		lon -= 0.7;
		_mm->scene()->addItem(sm);
	}
}

/////////////////////////////////////////////////////////////////////////////////////////////////
QMicroMapTest::~QMicroMapTest() {

}

/////////////////////////////////////////////////////////////////////////////////////////////////
void QMicroMapTest::zoomInSlot() {
	_mm->scale(1.0+_zoomInc, 1.0+_zoomInc);
}

/////////////////////////////////////////////////////////////////////////////////////////////////
void QMicroMapTest::zoomOutSlot() {
	_mm->scale(1.0/(1.0+_zoomInc), 1.0/(1.0+_zoomInc));
}

/////////////////////////////////////////////////////////////////////////////////////////////////
void QMicroMapTest::zoom(double deltax, double deltay) {

	_xmin = _xmin+deltax;
	_xmax = _xmax-deltax;
	_ymin = _ymin+deltay;
	_ymax = _ymax-deltay;
	_mm->drawFeatures(_xmin, _ymin, _xmax, _ymax);
}
<|endoftext|>


<commit_before>#include "evpp/inner_pre.h"

#include "sync_udp_client.h"
#include "evpp/libevent.h"
#include "evpp/sockets.h"

namespace evpp {
namespace udp {
namespace sync {
Client::Client() {
    sockfd_ = INVALID_SOCKET;
    memset(&remote_addr_, 0, sizeof(remote_addr_));
}

Client::~Client(void) {
    Close();
}

bool Client::Connect(const struct sockaddr_in& addr) {
    memcpy(&remote_addr_, &addr, sizeof(remote_addr_));
    return Connect();
}

bool Client::Connect(const char* host, int port) {
    char buf[32] = {};
    snprintf(buf, sizeof buf, "%s:%d", host, port);
    return Connect(buf);
}

bool Client::Connect(const struct sockaddr_storage& addr) {
    memcpy(&remote_addr_, &addr, sizeof(remote_addr_));
    return Connect();
}

bool Client::Connect(const char* addr/*host:port*/) {
    remote_addr_ = sock::ParseFromIPPort(addr);
    return Connect();
}

bool Client::Connect(const struct sockaddr& addr) {
    memcpy(&remote_addr_, &addr, sizeof(remote_addr_));
    return Connect();
}

bool Client::Connect() {
    sockfd_ = ::socket(AF_INET, SOCK_DGRAM, 0);
    sock::SetReuseAddr(sockfd_);

    struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&remote_addr_);
    socklen_t addrlen = sizeof(*addr);
    int ret = ::connect(sockfd_, addr, addrlen);

    if (ret != 0) {
        LOG_ERROR << "Failed to connect to remote "
                  << sock::ToIPPort(&remote_addr_)
                  << ", errno=" << errno << " " << strerror(errno);
        Close();
        return false;
    }

    connected_ = true;
    return true;
}

void Client::Close() {
    EVUTIL_CLOSESOCKET(sockfd_);
}

std::string Client::DoRequest(const std::string& data, uint32_t timeout_ms) {
    if (!Send(data)) {
        int eno = errno;
        LOG_ERROR << "sent failed, errno=" << eno << " " << strerror(eno) << " , dlen=" << data.size();
        return "";
    }

    sock::SetTimeout(sockfd_, timeout_ms);

    size_t buf_size = 1472; // The UDP max payload size
    MessagePtr msg(new Message(sockfd_, buf_size));
    socklen_t addrLen = sizeof(struct sockaddr);
    int readn = ::recvfrom(sockfd_, msg->WriteBegin(), buf_size, 0, msg->mutable_remote_addr(), &addrLen);
    int err = errno;
    if (readn >= 0) {
        msg->WriteBytes(readn);
        return std::string(msg->data(), msg->size());
    } else {
        LOG_ERROR << "errno=" << err << " " << strerror(err) << " recvfrom return -1";
    }

    return "";
}

std::string Client::DoRequest(const std::string& remote_ip, int port, const std::string& udp_package_data, uint32_t timeout_ms) {
    Client c;
    if (!c.Connect(remote_ip.data(), port)) {
        return "";
    }

    return c.DoRequest(udp_package_data, timeout_ms);
}

bool Client::Send(const char* msg, size_t len) {
    if (connected_) {
        int sentn = ::send(sockfd(), msg, len, 0);
        return sentn == len;
    }

    struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&remote_addr_);
    socklen_t addrlen = sizeof(*addr);
    int sentn = ::sendto(sockfd(),
                         msg, len, 0,
                         addr,
                         addrlen);
    return sentn > 0;
}

bool Client::Send(const std::string& msg) {
    return Send(msg.data(), msg.size());
}

bool Client::Send(const std::string& msg, const struct sockaddr_in& addr) {
    return Client::Send(msg.data(), msg.size(), addr);
}

bool Client::Send(const char* msg, size_t len, const struct sockaddr_in& addr) {
    Client c;
    if (!c.Connect(addr)) {
        return false;
    }

    return c.Send(msg, len);
}

bool Client::Send(const MessagePtr& msg) {
    return Client::Send(msg->data(), msg->size(), *reinterpret_cast<const struct sockaddr_in*>(msg->remote_addr()));
}

bool Client::Send(const Message* msg) {
    return Client::Send(msg->data(), msg->size(), *reinterpret_cast<const struct sockaddr_in*>(msg->remote_addr()));
}

}
}
}

<commit_msg>Fix compile warnnig<commit_after>#include "evpp/inner_pre.h"

#include "sync_udp_client.h"
#include "evpp/libevent.h"
#include "evpp/sockets.h"

namespace evpp {
namespace udp {
namespace sync {
Client::Client() {
    sockfd_ = INVALID_SOCKET;
    memset(&remote_addr_, 0, sizeof(remote_addr_));
}

Client::~Client(void) {
    Close();
}

bool Client::Connect(const struct sockaddr_in& addr) {
    memcpy(&remote_addr_, &addr, sizeof(remote_addr_));
    return Connect();
}

bool Client::Connect(const char* host, int port) {
    char buf[32] = {};
    snprintf(buf, sizeof buf, "%s:%d", host, port);
    return Connect(buf);
}

bool Client::Connect(const struct sockaddr_storage& addr) {
    memcpy(&remote_addr_, &addr, sizeof(remote_addr_));
    return Connect();
}

bool Client::Connect(const char* addr/*host:port*/) {
    remote_addr_ = sock::ParseFromIPPort(addr);
    return Connect();
}

bool Client::Connect(const struct sockaddr& addr) {
    memcpy(&remote_addr_, &addr, sizeof(remote_addr_));
    return Connect();
}

bool Client::Connect() {
    sockfd_ = ::socket(AF_INET, SOCK_DGRAM, 0);
    sock::SetReuseAddr(sockfd_);

    struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&remote_addr_);
    socklen_t addrlen = sizeof(*addr);
    int ret = ::connect(sockfd_, addr, addrlen);

    if (ret != 0) {
        LOG_ERROR << "Failed to connect to remote "
                  << sock::ToIPPort(&remote_addr_)
                  << ", errno=" << errno << " " << strerror(errno);
        Close();
        return false;
    }

    connected_ = true;
    return true;
}

void Client::Close() {
    EVUTIL_CLOSESOCKET(sockfd_);
}

std::string Client::DoRequest(const std::string& data, uint32_t timeout_ms) {
    if (!Send(data)) {
        int eno = errno;
        LOG_ERROR << "sent failed, errno=" << eno << " " << strerror(eno) << " , dlen=" << data.size();
        return "";
    }

    sock::SetTimeout(sockfd_, timeout_ms);

    size_t buf_size = 1472; // The UDP max payload size
    MessagePtr msg(new Message(sockfd_, buf_size));
    socklen_t addrLen = sizeof(struct sockaddr);
    int readn = ::recvfrom(sockfd_, msg->WriteBegin(), buf_size, 0, msg->mutable_remote_addr(), &addrLen);
    int err = errno;
    if (readn >= 0) {
        msg->WriteBytes(readn);
        return std::string(msg->data(), msg->size());
    } else {
        LOG_ERROR << "errno=" << err << " " << strerror(err) << " recvfrom return -1";
    }

    return "";
}

std::string Client::DoRequest(const std::string& remote_ip, int port, const std::string& udp_package_data, uint32_t timeout_ms) {
    Client c;
    if (!c.Connect(remote_ip.data(), port)) {
        return "";
    }

    return c.DoRequest(udp_package_data, timeout_ms);
}

bool Client::Send(const char* msg, size_t len) {
    if (connected_) {
        int sentn = ::send(sockfd(), msg, len, 0);
        return static_cast<size_t>(sentn) == len;
    }

    struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&remote_addr_);
    socklen_t addrlen = sizeof(*addr);
    int sentn = ::sendto(sockfd(),
                         msg, len, 0,
                         addr,
                         addrlen);
    return sentn > 0;
}

bool Client::Send(const std::string& msg) {
    return Send(msg.data(), msg.size());
}

bool Client::Send(const std::string& msg, const struct sockaddr_in& addr) {
    return Client::Send(msg.data(), msg.size(), addr);
}

bool Client::Send(const char* msg, size_t len, const struct sockaddr_in& addr) {
    Client c;
    if (!c.Connect(addr)) {
        return false;
    }

    return c.Send(msg, len);
}

bool Client::Send(const MessagePtr& msg) {
    return Client::Send(msg->data(), msg->size(), *reinterpret_cast<const struct sockaddr_in*>(msg->remote_addr()));
}

bool Client::Send(const Message* msg) {
    return Client::Send(msg->data(), msg->size(), *reinterpret_cast<const struct sockaddr_in*>(msg->remote_addr()));
}

}
}
}

<|endoftext|>


<commit_before>#include <jni.h>
#include <unistd.h>
#include <stdint.h>
#include <mpv/stream_cb.h>

#include "main.h"

static int android_content_open(void *user_data, char *uri, mpv_stream_cb_info *info);
static int64_t callback_read(void *cookie, char *buf, uint64_t nbytes);
static int64_t callback_seek(void *cookie, int64_t offset);
static void callback_close(void *cookie);

static bool methods_initialized = false;
static JavaVM *g_vm;
static jobject appcontext;
static jclass
    android_net_Uri;
static jmethodID
    android_net_Uri_parse, android_content_Context_getContentResolver,
    android_content_ContentResolver_openFileDescriptor,
    android_os_ParcelFileDescriptor_detachFd;

void android_content_init(JNIEnv *env, jobject appctx) {
    if (methods_initialized)
        return;
    env->GetJavaVM(&g_vm);
    appcontext = env->NewGlobalRef(appctx);

    #define FIND_CLASS(name) reinterpret_cast<jclass>(env->NewGlobalRef(env->FindClass(name)))
    android_net_Uri = FIND_CLASS("android/net/Uri");
    android_net_Uri_parse = env->GetStaticMethodID(android_net_Uri,
        "parse", "(Ljava/lang/String;)Landroid/net/Uri;");
    jclass android_content_Context = FIND_CLASS("android/content/Context");
    android_content_Context_getContentResolver = env->GetMethodID(android_content_Context,
        "getContentResolver", "()Landroid/content/ContentResolver;");
    jclass android_content_ContentResolver = FIND_CLASS("android/content/ContentResolver");
    android_content_ContentResolver_openFileDescriptor = env->GetMethodID(android_content_ContentResolver,
        "openFileDescriptor", "(Landroid/net/Uri;Ljava/lang/String;)Landroid/os/ParcelFileDescriptor;");
    jclass android_os_ParcelFileDescriptor = FIND_CLASS("android/os/ParcelFileDescriptor");
    android_os_ParcelFileDescriptor_detachFd = env->GetMethodID(android_os_ParcelFileDescriptor,
        "detachFd", "()I");
    #undef FIND_CLASS

    methods_initialized = true;
}

void android_content_register(mpv_handle *mpv) {
    mpv_stream_cb_add_ro(mpv, "content", NULL, android_content_open);
}

bool acquire_java_stuff(JavaVM *vm, JNIEnv **env)
{
    int ret = vm->GetEnv((void**) env, JNI_VERSION_1_6);
    if (ret == JNI_EDETACHED)
        return vm->AttachCurrentThread(env, NULL) == 0;
    else
        return ret == JNI_OK;
}

static int android_content_open(void *user_data, char *uri, mpv_stream_cb_info *info)
{
    JNIEnv *env;
    if (!acquire_java_stuff(g_vm, &env))
        return MPV_ERROR_LOADING_FAILED;

    jstring url = env->NewStringUTF(uri);
    jstring mode = env->NewStringUTF("r");
    jobject j_uri = NULL;
    jobject content_resolver = NULL;
    jobject parcel_fd = NULL;
    int fd;

    j_uri = env->CallStaticObjectMethod(android_net_Uri, android_net_Uri_parse, url);
    if (env->ExceptionCheck())
        goto error;

    content_resolver = env->CallObjectMethod(appcontext, android_content_Context_getContentResolver);
    if (env->ExceptionCheck())
        goto error;

    parcel_fd = env->CallObjectMethod(content_resolver, android_content_ContentResolver_openFileDescriptor, j_uri, mode);
    if (env->ExceptionCheck())
        goto error;

    fd = env->CallIntMethod(parcel_fd, android_os_ParcelFileDescriptor_detachFd);
    if (env->ExceptionCheck())
        goto error;

    env->DeleteLocalRef(url);
    env->DeleteLocalRef(mode);
    env->DeleteLocalRef(j_uri);
    env->DeleteLocalRef(content_resolver);
    env->DeleteLocalRef(parcel_fd);
    g_vm->DetachCurrentThread();

    info->cookie = (void*)(intptr_t) fd; // would break if sizeof(int) > sizeof(void*)
    info->read_fn = callback_read;
    info->seek_fn = callback_seek;
    info->size_fn = NULL;
    info->close_fn = callback_close;

    return 0;

error:
    env->ExceptionClear();
    env->DeleteLocalRef(url);
    env->DeleteLocalRef(mode);
    if (j_uri)
        env->DeleteLocalRef(j_uri);
    if (content_resolver)
        env->DeleteLocalRef(content_resolver);
    if (parcel_fd)
        env->DeleteLocalRef(parcel_fd);
    g_vm->DetachCurrentThread();

    return MPV_ERROR_LOADING_FAILED;
}

static int64_t callback_read(void *cookie, char *buf, uint64_t nbytes)
{
    int fd = (int)(intptr_t) cookie;
    return read(fd, buf, nbytes);
}

static int64_t callback_seek(void *cookie, int64_t offset)
{
    int fd = (int)(intptr_t) cookie;
    off_t ret = lseek(fd, offset, SEEK_SET);
    return (ret == (off_t)-1) ? MPV_ERROR_GENERIC : ret;
}

static void callback_close(void *cookie)
{
    int fd = (int)(intptr_t) cookie;
    close(fd);
}
<commit_msg>app/jni: Clean up unused JNI global refs<commit_after>#include <jni.h>
#include <unistd.h>
#include <stdint.h>
#include <mpv/stream_cb.h>

#include "main.h"

static int android_content_open(void *user_data, char *uri, mpv_stream_cb_info *info);
static int64_t callback_read(void *cookie, char *buf, uint64_t nbytes);
static int64_t callback_seek(void *cookie, int64_t offset);
static void callback_close(void *cookie);

static bool methods_initialized = false;
static JavaVM *g_vm;
static jobject appcontext;
static jclass
    android_net_Uri;
static jmethodID
    android_net_Uri_parse, android_content_Context_getContentResolver,
    android_content_ContentResolver_openFileDescriptor,
    android_os_ParcelFileDescriptor_detachFd;

void android_content_init(JNIEnv *env, jobject appctx) {
    if (methods_initialized)
        return;
    env->GetJavaVM(&g_vm);
    appcontext = env->NewGlobalRef(appctx);

    #define FIND_CLASS(name) reinterpret_cast<jclass>(env->NewGlobalRef(env->FindClass(name)))
    android_net_Uri = FIND_CLASS("android/net/Uri");
    android_net_Uri_parse = env->GetStaticMethodID(android_net_Uri,
        "parse", "(Ljava/lang/String;)Landroid/net/Uri;");
    jclass android_content_Context = FIND_CLASS("android/content/Context");
    android_content_Context_getContentResolver = env->GetMethodID(android_content_Context,
        "getContentResolver", "()Landroid/content/ContentResolver;");
    env->DeleteGlobalRef(android_content_Context);
    jclass android_content_ContentResolver = FIND_CLASS("android/content/ContentResolver");
    android_content_ContentResolver_openFileDescriptor = env->GetMethodID(android_content_ContentResolver,
        "openFileDescriptor", "(Landroid/net/Uri;Ljava/lang/String;)Landroid/os/ParcelFileDescriptor;");
    env->DeleteGlobalRef(android_content_ContentResolver);
    jclass android_os_ParcelFileDescriptor = FIND_CLASS("android/os/ParcelFileDescriptor");
    android_os_ParcelFileDescriptor_detachFd = env->GetMethodID(android_os_ParcelFileDescriptor,
        "detachFd", "()I");
    env->DeleteGlobalRef(android_os_ParcelFileDescriptor);
    #undef FIND_CLASS

    methods_initialized = true;
}

void android_content_register(mpv_handle *mpv) {
    mpv_stream_cb_add_ro(mpv, "content", NULL, android_content_open);
}

bool acquire_java_stuff(JavaVM *vm, JNIEnv **env)
{
    int ret = vm->GetEnv((void**) env, JNI_VERSION_1_6);
    if (ret == JNI_EDETACHED)
        return vm->AttachCurrentThread(env, NULL) == 0;
    else
        return ret == JNI_OK;
}

static int android_content_open(void *user_data, char *uri, mpv_stream_cb_info *info)
{
    JNIEnv *env;
    if (!acquire_java_stuff(g_vm, &env))
        return MPV_ERROR_LOADING_FAILED;

    jstring url = env->NewStringUTF(uri);
    jstring mode = env->NewStringUTF("r");
    jobject j_uri = NULL;
    jobject content_resolver = NULL;
    jobject parcel_fd = NULL;
    int fd;

    j_uri = env->CallStaticObjectMethod(android_net_Uri, android_net_Uri_parse, url);
    if (env->ExceptionCheck())
        goto error;

    content_resolver = env->CallObjectMethod(appcontext, android_content_Context_getContentResolver);
    if (env->ExceptionCheck())
        goto error;

    parcel_fd = env->CallObjectMethod(content_resolver, android_content_ContentResolver_openFileDescriptor, j_uri, mode);
    if (env->ExceptionCheck())
        goto error;

    fd = env->CallIntMethod(parcel_fd, android_os_ParcelFileDescriptor_detachFd);
    if (env->ExceptionCheck())
        goto error;

    env->DeleteLocalRef(url);
    env->DeleteLocalRef(mode);
    env->DeleteLocalRef(j_uri);
    env->DeleteLocalRef(content_resolver);
    env->DeleteLocalRef(parcel_fd);
    g_vm->DetachCurrentThread();

    info->cookie = (void*)(intptr_t) fd; // would break if sizeof(int) > sizeof(void*)
    info->read_fn = callback_read;
    info->seek_fn = callback_seek;
    info->size_fn = NULL;
    info->close_fn = callback_close;

    return 0;

error:
    env->ExceptionClear();
    env->DeleteLocalRef(url);
    env->DeleteLocalRef(mode);
    if (j_uri)
        env->DeleteLocalRef(j_uri);
    if (content_resolver)
        env->DeleteLocalRef(content_resolver);
    if (parcel_fd)
        env->DeleteLocalRef(parcel_fd);
    g_vm->DetachCurrentThread();

    return MPV_ERROR_LOADING_FAILED;
}

static int64_t callback_read(void *cookie, char *buf, uint64_t nbytes)
{
    int fd = (int)(intptr_t) cookie;
    return read(fd, buf, nbytes);
}

static int64_t callback_seek(void *cookie, int64_t offset)
{
    int fd = (int)(intptr_t) cookie;
    off_t ret = lseek(fd, offset, SEEK_SET);
    return (ret == (off_t)-1) ? MPV_ERROR_GENERIC : ret;
}

static void callback_close(void *cookie)
{
    int fd = (int)(intptr_t) cookie;
    close(fd);
}
<|endoftext|>


<commit_before>#include <QCoreApplication>
#include <wakeproto.h>
#include "wakeserver.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    WakeServer ws;

    return a.exec();
}
<commit_msg>NEW: WakeServer running in background<commit_after>#include <QCoreApplication>
#include <wakeproto.h>
#include "wakeserver.h"
#include <unistd.h>

void daemonize()
{
    if(QCoreApplication::arguments().contains("--no-daemon"))
        return;

    switch (fork())
    {
        case 0:  break;
        case -1: exit(-1);
        default: exit(0);
    }
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    WakeServer ws;
    daemonize();
    return a.exec();
}
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include "osl/detail/android-bootstrap.h"

extern "C"
{
    extern void * animcore_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * avmedia_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * dba_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * dbaxml_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * evtatt_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * fileacc_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * frm_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * fsstorage_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * fwk_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * fwl_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * fwm_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * hwp_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * hyphen_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * lng_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * lnth_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * lotuswordpro_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * oox_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * sb_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * sc_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * scd_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * scfilt_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * sd_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * sdd_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * sm_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * smd_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * spell_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * svgfilter_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * sw_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * swd_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * t602filter_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * textfd_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * unoxml_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * unordf_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * wpftdraw_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * wpftwriter_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * xmlfd_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * xmlsecurity_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * xo_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * xof_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
}

extern "C"
__attribute__ ((visibility("default")))
const lib_to_component_mapping *
lo_get_libmap(void)
{
    static lib_to_component_mapping map[] = {
        { "libanimcorelo.a", animcore_component_getFactory },
        { "libavmedialo.a", avmedia_component_getFactory },
        { "libdbalo.a", dba_component_getFactory },
        { "libdbaxmllo.a", dbaxml_component_getFactory },
        { "libevtattlo.a", evtatt_component_getFactory },
        { "libfileacc.a", fileacc_component_getFactory },
        { "libfrmlo.a", frm_component_getFactory },
        { "libfsstorage.uno.a", fsstorage_component_getFactory },
        { "libfwklo.a", fwk_component_getFactory },
        { "libfwllo.a", fwl_component_getFactory },
        { "libfwmlo.a", fwm_component_getFactory },
        { "libhwplo.a", hwp_component_getFactory },
        { "libhyphenlo.a", hyphen_component_getFactory },
        { "liblnglo.a", lng_component_getFactory },
        { "liblnthlo.a", lnth_component_getFactory },
        { "liblwpftlo.a", lotuswordpro_component_getFactory },
        { "libooxlo.a", oox_component_getFactory },
        { "libscdlo.a", scd_component_getFactory },
        { "libscfiltlo.a", scfilt_component_getFactory },
        { "libsblo.a", sb_component_getFactory },
        { "libsclo.a", sc_component_getFactory },
        { "libsddlo.a", sdd_component_getFactory },
        { "libsdlo.a", sd_component_getFactory },
        { "libsmdlo.a", smd_component_getFactory },
        { "libsmlo.a", sm_component_getFactory },
        { "libsvgfilterlo.a", svgfilter_component_getFactory },
        { "libswdlo.a", swd_component_getFactory },
        { "libswlo.a", sw_component_getFactory },
        { "libt602filterlo.a", t602filter_component_getFactory },
        { "libtextfdlo.a", textfd_component_getFactory },
        { "libunordflo.a", unordf_component_getFactory },
        { "libunoxmllo.a", unoxml_component_getFactory },
        { "libwpftdrawlo.a", wpftdraw_component_getFactory },
        { "libwpftwriterlo.a", wpftwriter_component_getFactory },
        { "libxmlfdlo.a", xmlfd_component_getFactory },
        { "libxmlsecurity.a", xmlsecurity_component_getFactory },
        { "libxoflo.a", xof_component_getFactory },
        { "libxolo.a", xo_component_getFactory },
        { NULL, NULL }
    };

    return map;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>Need the protocolhandler and spell libraries<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include "osl/detail/android-bootstrap.h"

extern "C"
{
    extern void * animcore_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * avmedia_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * dba_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * dbaxml_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * evtatt_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * fileacc_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * frm_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * fsstorage_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * fwk_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * fwl_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * fwm_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * hwp_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * hyphen_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * lng_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * lnth_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * lotuswordpro_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * oox_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * protocolhandler_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * sb_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * sc_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * scd_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * scfilt_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * sd_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * sdd_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * sm_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * smd_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * spell_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * svgfilter_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * sw_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * swd_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * t602filter_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * textfd_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * unoxml_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * unordf_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * wpftdraw_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * wpftwriter_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * xmlfd_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * xmlsecurity_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * xo_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
    extern void * xof_component_getFactory( const char * pImplName, void * pServiceManager, void * pRegistryKey );
}

extern "C"
__attribute__ ((visibility("default")))
const lib_to_component_mapping *
lo_get_libmap(void)
{
    static lib_to_component_mapping map[] = {
        { "libanimcorelo.a", animcore_component_getFactory },
        { "libavmedialo.a", avmedia_component_getFactory },
        { "libdbalo.a", dba_component_getFactory },
        { "libdbaxmllo.a", dbaxml_component_getFactory },
        { "libevtattlo.a", evtatt_component_getFactory },
        { "libfileacc.a", fileacc_component_getFactory },
        { "libfrmlo.a", frm_component_getFactory },
        { "libfsstorage.uno.a", fsstorage_component_getFactory },
        { "libfwklo.a", fwk_component_getFactory },
        { "libfwllo.a", fwl_component_getFactory },
        { "libfwmlo.a", fwm_component_getFactory },
        { "libhwplo.a", hwp_component_getFactory },
        { "libhyphenlo.a", hyphen_component_getFactory },
        { "liblnglo.a", lng_component_getFactory },
        { "liblnthlo.a", lnth_component_getFactory },
        { "liblwpftlo.a", lotuswordpro_component_getFactory },
        { "libooxlo.a", oox_component_getFactory },
        { "libprotocolhandlerlo.a", protocolhandler_component_getFactory },
        { "libscdlo.a", scd_component_getFactory },
        { "libscfiltlo.a", scfilt_component_getFactory },
        { "libsblo.a", sb_component_getFactory },
        { "libsclo.a", sc_component_getFactory },
        { "libsddlo.a", sdd_component_getFactory },
        { "libsdlo.a", sd_component_getFactory },
        { "libsmdlo.a", smd_component_getFactory },
        { "libsmlo.a", sm_component_getFactory },
        { "libspelllo.a", spell_component_getFactory },
        { "libsvgfilterlo.a", svgfilter_component_getFactory },
        { "libswdlo.a", swd_component_getFactory },
        { "libswlo.a", sw_component_getFactory },
        { "libt602filterlo.a", t602filter_component_getFactory },
        { "libtextfdlo.a", textfd_component_getFactory },
        { "libunordflo.a", unordf_component_getFactory },
        { "libunoxmllo.a", unoxml_component_getFactory },
        { "libwpftdrawlo.a", wpftdraw_component_getFactory },
        { "libwpftwriterlo.a", wpftwriter_component_getFactory },
        { "libxmlfdlo.a", xmlfd_component_getFactory },
        { "libxmlsecurity.a", xmlsecurity_component_getFactory },
        { "libxoflo.a", xof_component_getFactory },
        { "libxolo.a", xo_component_getFactory },
        { NULL, NULL }
    };

    return map;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>// Copyright (c) 2006-2008 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 "base/timer.h"

#include <math.h>
#if defined(OS_WIN)
#include <mmsystem.h>
#endif

#include "base/atomic_sequence_num.h"
#include "base/logging.h"
#include "base/message_loop.h"
#include "base/task.h"

namespace base {

// A sequence number for all allocated times (used to break ties when
// comparing times in the TimerManager, and assure FIFO execution sequence).
static AtomicSequenceNumber timer_id_counter_;

//-----------------------------------------------------------------------------
// Timer

Timer::Timer(int delay, Task* task, bool repeating)
    : task_(task),
      delay_(delay),
      repeating_(repeating) {
  timer_id_ = timer_id_counter_.GetNext();
  DCHECK(delay >= 0);
  Reset();
}

Timer::Timer(Time fire_time, Task* task)
    : fire_time_(fire_time),
      task_(task),
      repeating_(false) {
  timer_id_ = timer_id_counter_.GetNext();

  // TODO(darin): kill off this stuff
  creation_time_ = Time::Now();
  delay_ = static_cast<int>((fire_time_ - creation_time_).InMilliseconds());
  DCHECK(delay_ >= 0);
  DHISTOGRAM_COUNTS(L"Timer.Durations", delay_);
}

void Timer::Reset() {
  creation_time_ = Time::Now();
  fire_time_ = creation_time_ + TimeDelta::FromMilliseconds(delay_);
  DHISTOGRAM_COUNTS(L"Timer.Durations", delay_);
}

//-----------------------------------------------------------------------------
// TimerPQueue

void TimerPQueue::RemoveTimer(Timer* timer) {
  const std::vector<Timer*>::iterator location =
      find(c.begin(), c.end(), timer);
  if (location != c.end()) {
    c.erase(location);
    make_heap(c.begin(), c.end(), TimerComparison());
  }
}

bool TimerPQueue::ContainsTimer(const Timer* timer) const {
  return find(c.begin(), c.end(), timer) != c.end();
}

//-----------------------------------------------------------------------------
// TimerManager

TimerManager::TimerManager(MessageLoop* message_loop)
    : use_broken_delay_(false),
      message_loop_(message_loop) {
#if defined(OS_WIN)
  // We've experimented with all sorts of timers, and initially tried
  // to avoid using timeBeginPeriod because it does affect the system
  // globally.  However, after much investigation, it turns out that all
  // of the major plugins (flash, windows media 9-11, and quicktime)
  // already use timeBeginPeriod to increase the speed of the clock.
  // Since the browser must work with these plugins, the browser already
  // needs to support a fast clock.  We may as well use this ourselves,
  // as it really is the best timer mechanism for our needs.
  timeBeginPeriod(1);
#endif
}

TimerManager::~TimerManager() {
#if defined(OS_WIN)
  // Match timeBeginPeriod() from construction.
  timeEndPeriod(1);
#endif

  // Be nice to unit tests, and discard and delete all timers along with the
  // embedded task objects by handing off to MessageLoop (which would have Run()
  // and optionally deleted the objects).
  while (timers_.size()) {
    Timer* pending = timers_.top();
    timers_.pop();
    message_loop_->DiscardTimer(pending);
  }
}

Timer* TimerManager::StartTimer(int delay, Task* task, bool repeating) {
  Timer* t = new Timer(delay, task, repeating);
  StartTimer(t);
  return t;
}

void TimerManager::StopTimer(Timer* timer) {
  // Make sure the timer is actually running.
  if (!IsTimerRunning(timer))
    return;
  // Kill the active timer, and remove the pending entry from the queue.
  if (timer != timers_.top()) {
    timers_.RemoveTimer(timer);
  } else {
    timers_.pop();
    DidChangeNextTimer();
  }
}

void TimerManager::ResetTimer(Timer* timer) {
  StopTimer(timer);
  timer->Reset();
  StartTimer(timer);
}

bool TimerManager::IsTimerRunning(const Timer* timer) const {
  return timers_.ContainsTimer(timer);
}

Timer* TimerManager::PeekTopTimer() {
  if (timers_.empty())
    return NULL;
  return timers_.top();
}

bool TimerManager::RunSomePendingTimers() {
  bool did_work = false;
  // Process a small group of timers.  Cap the maximum number of timers we can
  // process so we don't deny cycles to other parts of the process when lots of
  // timers have been set.
  const int kMaxTimersPerCall = 2;
  for (int i = 0; i < kMaxTimersPerCall; ++i) {
    if (timers_.empty() || timers_.top()->fire_time() > Time::Now())
      break;

    // Get a pending timer.  Deal with updating the timers_ queue and setting
    // the TopTimer.  We'll execute the timer task only after the timer queue
    // is back in a consistent state.
    Timer* pending = timers_.top();

    // If pending task isn't invoked_later, then it must be possible to run it
    // now (i.e., current task needs to be reentrant).
    // TODO(jar): We may block tasks that we can queue from being popped.
    if (!message_loop_->NestableTasksAllowed() &&
        !pending->task()->owned_by_message_loop_)
      break;

    timers_.pop();
    did_work = true;

    // If the timer is repeating, add it back to the list of timers to process.
    if (pending->repeating()) {
      pending->Reset();
      timers_.push(pending);
    }

    message_loop_->RunTimerTask(pending);
  }

  // Restart the WM_TIMER (if necessary).
  if (did_work)
    DidChangeNextTimer();

  return did_work;
}

// Note: Caller is required to call timer->Reset() before calling StartTimer().
// TODO(jar): change API so that Reset() is called as part of StartTimer, making
// the API a little less error prone.
void TimerManager::StartTimer(Timer* timer) {
  // Make sure the timer is not running.
  if (IsTimerRunning(timer))
    return;

  timers_.push(timer);  // Priority queue will sort the timer into place.

  if (timers_.top() == timer)  // We are new head of queue.
    DidChangeNextTimer();
}

Time TimerManager::GetNextFireTime() const {
  if (timers_.empty())
    return Time();

  return timers_.top()->fire_time();
}

void TimerManager::DidChangeNextTimer() {
  // Determine if the next timer expiry actually changed...
  if (!timers_.empty()) {
    const Time& expiry = timers_.top()->fire_time();
    if (expiry == next_timer_expiry_)
      return;
    next_timer_expiry_ = expiry;
  } else {
    next_timer_expiry_ = Time();
  }
  message_loop_->DidChangeNextTimerExpiry();
}

//-----------------------------------------------------------------------------
// BaseTimer_Helper

void BaseTimer_Helper::OrphanDelayedTask() {
  if (delayed_task_) {
    delayed_task_->timer_ = NULL;
    delayed_task_ = NULL;
  }
}

void BaseTimer_Helper::InitiateDelayedTask(TimerTask* timer_task) {
  OrphanDelayedTask();

  delayed_task_ = timer_task;
  delayed_task_->timer_ = this;
  MessageLoop::current()->PostDelayedTask(
      FROM_HERE, timer_task, static_cast<int>(delay_.InMilliseconds()));
}

}  // namespace base
<commit_msg>Remove assertion in Timer() because it was too aggressive.  Instead, we need to just treat a negative delay as a zero delay.<commit_after>// Copyright (c) 2006-2008 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 "base/timer.h"

#include <math.h>
#if defined(OS_WIN)
#include <mmsystem.h>
#endif

#include "base/atomic_sequence_num.h"
#include "base/logging.h"
#include "base/message_loop.h"
#include "base/task.h"

namespace base {

// A sequence number for all allocated times (used to break ties when
// comparing times in the TimerManager, and assure FIFO execution sequence).
static AtomicSequenceNumber timer_id_counter_;

//-----------------------------------------------------------------------------
// Timer

Timer::Timer(int delay, Task* task, bool repeating)
    : task_(task),
      delay_(delay),
      repeating_(repeating) {
  timer_id_ = timer_id_counter_.GetNext();
  DCHECK(delay >= 0);
  Reset();
}

Timer::Timer(Time fire_time, Task* task)
    : fire_time_(fire_time),
      task_(task),
      repeating_(false) {
  timer_id_ = timer_id_counter_.GetNext();

  // TODO(darin): kill off this stuff.  because we are forced to compute 'now'
  // in order to determine the delay, it is possible that our fire time could
  // be in the past.  /sigh/
  creation_time_ = Time::Now();
  delay_ = static_cast<int>((fire_time_ - creation_time_).InMilliseconds());
  if (delay_ < 0)
    delay_ = 0;
  DHISTOGRAM_COUNTS(L"Timer.Durations", delay_);
}

void Timer::Reset() {
  creation_time_ = Time::Now();
  fire_time_ = creation_time_ + TimeDelta::FromMilliseconds(delay_);
  DHISTOGRAM_COUNTS(L"Timer.Durations", delay_);
}

//-----------------------------------------------------------------------------
// TimerPQueue

void TimerPQueue::RemoveTimer(Timer* timer) {
  const std::vector<Timer*>::iterator location =
      find(c.begin(), c.end(), timer);
  if (location != c.end()) {
    c.erase(location);
    make_heap(c.begin(), c.end(), TimerComparison());
  }
}

bool TimerPQueue::ContainsTimer(const Timer* timer) const {
  return find(c.begin(), c.end(), timer) != c.end();
}

//-----------------------------------------------------------------------------
// TimerManager

TimerManager::TimerManager(MessageLoop* message_loop)
    : use_broken_delay_(false),
      message_loop_(message_loop) {
#if defined(OS_WIN)
  // We've experimented with all sorts of timers, and initially tried
  // to avoid using timeBeginPeriod because it does affect the system
  // globally.  However, after much investigation, it turns out that all
  // of the major plugins (flash, windows media 9-11, and quicktime)
  // already use timeBeginPeriod to increase the speed of the clock.
  // Since the browser must work with these plugins, the browser already
  // needs to support a fast clock.  We may as well use this ourselves,
  // as it really is the best timer mechanism for our needs.
  timeBeginPeriod(1);
#endif
}

TimerManager::~TimerManager() {
#if defined(OS_WIN)
  // Match timeBeginPeriod() from construction.
  timeEndPeriod(1);
#endif

  // Be nice to unit tests, and discard and delete all timers along with the
  // embedded task objects by handing off to MessageLoop (which would have Run()
  // and optionally deleted the objects).
  while (timers_.size()) {
    Timer* pending = timers_.top();
    timers_.pop();
    message_loop_->DiscardTimer(pending);
  }
}

Timer* TimerManager::StartTimer(int delay, Task* task, bool repeating) {
  Timer* t = new Timer(delay, task, repeating);
  StartTimer(t);
  return t;
}

void TimerManager::StopTimer(Timer* timer) {
  // Make sure the timer is actually running.
  if (!IsTimerRunning(timer))
    return;
  // Kill the active timer, and remove the pending entry from the queue.
  if (timer != timers_.top()) {
    timers_.RemoveTimer(timer);
  } else {
    timers_.pop();
    DidChangeNextTimer();
  }
}

void TimerManager::ResetTimer(Timer* timer) {
  StopTimer(timer);
  timer->Reset();
  StartTimer(timer);
}

bool TimerManager::IsTimerRunning(const Timer* timer) const {
  return timers_.ContainsTimer(timer);
}

Timer* TimerManager::PeekTopTimer() {
  if (timers_.empty())
    return NULL;
  return timers_.top();
}

bool TimerManager::RunSomePendingTimers() {
  bool did_work = false;
  // Process a small group of timers.  Cap the maximum number of timers we can
  // process so we don't deny cycles to other parts of the process when lots of
  // timers have been set.
  const int kMaxTimersPerCall = 2;
  for (int i = 0; i < kMaxTimersPerCall; ++i) {
    if (timers_.empty() || timers_.top()->fire_time() > Time::Now())
      break;

    // Get a pending timer.  Deal with updating the timers_ queue and setting
    // the TopTimer.  We'll execute the timer task only after the timer queue
    // is back in a consistent state.
    Timer* pending = timers_.top();

    // If pending task isn't invoked_later, then it must be possible to run it
    // now (i.e., current task needs to be reentrant).
    // TODO(jar): We may block tasks that we can queue from being popped.
    if (!message_loop_->NestableTasksAllowed() &&
        !pending->task()->owned_by_message_loop_)
      break;

    timers_.pop();
    did_work = true;

    // If the timer is repeating, add it back to the list of timers to process.
    if (pending->repeating()) {
      pending->Reset();
      timers_.push(pending);
    }

    message_loop_->RunTimerTask(pending);
  }

  // Restart the WM_TIMER (if necessary).
  if (did_work)
    DidChangeNextTimer();

  return did_work;
}

// Note: Caller is required to call timer->Reset() before calling StartTimer().
// TODO(jar): change API so that Reset() is called as part of StartTimer, making
// the API a little less error prone.
void TimerManager::StartTimer(Timer* timer) {
  // Make sure the timer is not running.
  if (IsTimerRunning(timer))
    return;

  timers_.push(timer);  // Priority queue will sort the timer into place.

  if (timers_.top() == timer)  // We are new head of queue.
    DidChangeNextTimer();
}

Time TimerManager::GetNextFireTime() const {
  if (timers_.empty())
    return Time();

  return timers_.top()->fire_time();
}

void TimerManager::DidChangeNextTimer() {
  // Determine if the next timer expiry actually changed...
  if (!timers_.empty()) {
    const Time& expiry = timers_.top()->fire_time();
    if (expiry == next_timer_expiry_)
      return;
    next_timer_expiry_ = expiry;
  } else {
    next_timer_expiry_ = Time();
  }
  message_loop_->DidChangeNextTimerExpiry();
}

//-----------------------------------------------------------------------------
// BaseTimer_Helper

void BaseTimer_Helper::OrphanDelayedTask() {
  if (delayed_task_) {
    delayed_task_->timer_ = NULL;
    delayed_task_ = NULL;
  }
}

void BaseTimer_Helper::InitiateDelayedTask(TimerTask* timer_task) {
  OrphanDelayedTask();

  delayed_task_ = timer_task;
  delayed_task_->timer_ = this;
  MessageLoop::current()->PostDelayedTask(
      FROM_HERE, timer_task, static_cast<int>(delay_.InMilliseconds()));
}

}  // namespace base
<|endoftext|>


<commit_before>#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <vector>

#include "objc/runtime.h"
#include "visibility.h"

#include <windows.h>
#define RtlAddGrowableFunctionTable ClangIsConfusedByTypedefReturnTypes
#include <rtlsupportapi.h>

#ifndef __has_builtin
#define __has_builtin(x) 0
#endif

#if !__has_builtin(__builtin_unreachable)
#define __builtin_unreachable abort
#endif

struct _MSVC_TypeDescriptor
{
	const void* pVFTable;
	void* spare;
	char name[0];
};

struct _MSVC_CatchableType
{
	unsigned int flags;
	unsigned long type;
	int mdisp;
	int pdisp;
	int vdisp;
	int size;
	unsigned long copyFunction;
};

struct _MSVC_CatchableTypeArray
{
	int count;
	unsigned long types[0];
};

struct _MSVC_ThrowInfo
{
	unsigned int attributes;
	unsigned long pfnUnwind;
	unsigned long pfnForwardCompat;
	unsigned long pCatchableTypeArray;
};

#if defined(_WIN64)
#define IMAGE_RELATIVE(ptr, base) (static_cast<unsigned long>((ptr ? ((uintptr_t)ptr - (uintptr_t)base) : (uintptr_t)nullptr)))
#else
#define IMAGE_RELATIVE(ptr, base) reinterpret_cast<unsigned long>((ptr))
#endif

extern "C" void __stdcall _CxxThrowException(void*, _MSVC_ThrowInfo*);

namespace
{

static std::string mangleObjcObject()
{
#if defined(__SIZEOF_POINTER__) && __SIZEOF_POINTER__ == 8
	return ".PEAUobjc_object@@";
#else
	return ".PAUobjc_object@@";
#endif
}

static std::string mangleStructNamed(const char* className)
{
	// 32-bit:
	//  .PAUxxx@@ = ?? struct xxx * `RTTI Type Descriptor'
	// 64-bit:
	//  .PEAUxxx@@ = ?? struct xxx * __ptr64 `RTTI Type Descriptor'
	//return
	auto r =
#if defined(__SIZEOF_POINTER__) && __SIZEOF_POINTER__ == 8
		std::string(".PEAU") +
#else
		std::string(".PAU") +
#endif
		className + "@@";
	return r;
}

void fillCatchableType(_MSVC_CatchableType* exceptType)
{
	exceptType->flags = 1;
	exceptType->mdisp = 0;
	exceptType->pdisp = -1;
	exceptType->vdisp = 0;
	exceptType->size = sizeof(id);
	exceptType->copyFunction = 0;
}

} // <anonymous-namespace>

struct X {};
PUBLIC extern "C" void objc_exception_rethrow(void* exc);

PUBLIC extern "C" void objc_exception_throw(id object)
{
	// Base used for image-relative addresses.
	char x;
	// This is the base vtable for all RTTI entries
	static const void* typeid_vtable = *(void**)&typeid(void *);

	SEL rethrow_sel = sel_registerName("rethrow");
	if ((nil != object) &&
		(class_respondsToSelector(object_getClass(object), rethrow_sel)))
	{
		IMP rethrow = objc_msg_lookup(object, rethrow_sel);
		rethrow(object, rethrow_sel);
		// Should not be reached!  If it is, then the rethrow method actually
		// didn't, so we throw it normally.
	}

	SEL processException_sel = sel_registerName("_processException");
	if ((nil != object) &&
		(class_respondsToSelector(object_getClass(object), processException_sel)))
	{
		IMP processException = objc_msg_lookup(object, processException_sel);
		processException(object, processException_sel);
	}

	// The 'id' base type will be taking up a spot in the list:
	size_t typeCount = 1;

	// Get count of all types in exception
	for (Class cls = object_getClass(object); cls != Nil; cls = class_getSuperclass(cls), ++typeCount)
		;

	// Unfortunately we can't put this in a real function since the alloca has to be in this stack frame:
#define CREATE_TYPE_DESCRIPTOR(desc, symName) \
	desc = reinterpret_cast<_MSVC_TypeDescriptor*>(alloca(sizeof(_MSVC_TypeDescriptor) + symName.size() + 1 /* null terminator */)); \
	desc->pVFTable = typeid_vtable; \
	desc->spare = nullptr; \
	strcpy_s(desc->name, symName.size() + 1, symName.c_str());

	auto exceptTypes =
		(_MSVC_CatchableTypeArray*)_alloca(sizeof(_MSVC_CatchableTypeArray) + sizeof(_MSVC_CatchableType*) * typeCount);
	exceptTypes->count = typeCount;

	// Add exception type and all base types to throw information
	size_t curTypeIndex = 0;
	for (Class cls = object_getClass(object); cls != Nil; cls = class_getSuperclass(cls))
	{
		auto exceptType = (_MSVC_CatchableType*)_alloca(sizeof(_MSVC_CatchableType));
		fillCatchableType(exceptType);

		auto mangledName = mangleStructNamed(class_getName(cls));
		_MSVC_TypeDescriptor *ty;
		CREATE_TYPE_DESCRIPTOR(ty, mangledName);
		exceptType->type = IMAGE_RELATIVE(ty, &x);
		exceptTypes->types[curTypeIndex++] = IMAGE_RELATIVE(exceptType, &x);
	}

	// Add id (struct objc_object*)
	auto exceptType = (_MSVC_CatchableType*)_alloca(sizeof(_MSVC_CatchableType));
	fillCatchableType(exceptType);
	auto idName = mangleObjcObject();
	_MSVC_TypeDescriptor *ty;
	CREATE_TYPE_DESCRIPTOR(ty, idName);
	exceptType->type = IMAGE_RELATIVE(ty, &x);
	exceptTypes->types[curTypeIndex++] = IMAGE_RELATIVE(exceptType, &x);

	_MSVC_ThrowInfo ti = {
		0, // attributes
		0, // pfnUnwind
		0, // pfnForwardCompat
		IMAGE_RELATIVE(exceptTypes, &x) // pCatchableTypeArray
	};
#	define EH_EXCEPTION_NUMBER ('msc' | 0xE0000000)
#	define EH_MAGIC_NUMBER1 0x19930520
#	define EXCEPTION_NONCONTINUABLE 0x1
	EXCEPTION_RECORD  exception;
	exception.ExceptionCode = EH_EXCEPTION_NUMBER;
	exception.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
	exception.ExceptionRecord = nullptr;
	exception.ExceptionAddress = nullptr;
	// The fourth parameter is the base address of the image (for us, this stack
	// frame), but we only use image-relative 32-bit addresses on 64-bit
	// platforms.  On 32-bit platforms, we use 32-bit absolute addresses.
	exception.NumberParameters = sizeof(void*) == 4 ? 3 : 4;
	exception.ExceptionInformation[0] = EH_MAGIC_NUMBER1;
	exception.ExceptionInformation[1] = reinterpret_cast<ULONG_PTR>(&object);
	exception.ExceptionInformation[2] = reinterpret_cast<ULONG_PTR>(&ti);
	exception.ExceptionInformation[3] = reinterpret_cast<ULONG_PTR>(&x);

#ifdef _WIN64
 	RtlRaiseException(&exception);
#else
	RaiseException(exception.ExceptionCode,
		exception.ExceptionFlags,
		exception.NumberParameters,
		exception.ExceptionInformation);
#endif
	__builtin_unreachable();
}

PUBLIC extern "C" void objc_exception_rethrow(void* exc)
{
	_CxxThrowException(nullptr, nullptr);
	__builtin_unreachable();
}

<commit_msg>Fix Windows build.<commit_after>#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <vector>

#include "objc/runtime.h"
#include "visibility.h"

#include <windows.h>
#define RtlAddGrowableFunctionTable ClangIsConfusedByTypedefReturnTypes
#include <rtlsupportapi.h>

#ifndef __has_builtin
#define __has_builtin(x) 0
#endif

#if !__has_builtin(__builtin_unreachable)
#define __builtin_unreachable abort
#endif

struct _MSVC_TypeDescriptor
{
	const void* pVFTable;
	void* spare;
	char name[0];
};

struct _MSVC_CatchableType
{
	unsigned int flags;
	unsigned long type;
	int mdisp;
	int pdisp;
	int vdisp;
	int size;
	unsigned long copyFunction;
};

struct _MSVC_CatchableTypeArray
{
	int count;
	unsigned long types[0];
};

struct _MSVC_ThrowInfo
{
	unsigned int attributes;
	unsigned long pfnUnwind;
	unsigned long pfnForwardCompat;
	unsigned long pCatchableTypeArray;
};

#if defined(_WIN64)
#define IMAGE_RELATIVE(ptr, base) (static_cast<unsigned long>((ptr ? ((uintptr_t)ptr - (uintptr_t)base) : (uintptr_t)nullptr)))
#else
#define IMAGE_RELATIVE(ptr, base) reinterpret_cast<unsigned long>((ptr))
#endif

extern "C" void __stdcall _CxxThrowException(void*, _MSVC_ThrowInfo*);

namespace
{

static std::string mangleObjcObject()
{
#if defined(__SIZEOF_POINTER__) && __SIZEOF_POINTER__ == 8
	return ".PEAUobjc_object@@";
#else
	return ".PAUobjc_object@@";
#endif
}

static std::string mangleStructNamed(const char* className)
{
	// 32-bit:
	//  .PAUxxx@@ = ?? struct xxx * `RTTI Type Descriptor'
	// 64-bit:
	//  .PEAUxxx@@ = ?? struct xxx * __ptr64 `RTTI Type Descriptor'
	//return
	auto r =
#if defined(__SIZEOF_POINTER__) && __SIZEOF_POINTER__ == 8
		std::string(".PEAU") +
#else
		std::string(".PAU") +
#endif
		className + "@@";
	return r;
}

void fillCatchableType(_MSVC_CatchableType* exceptType)
{
	exceptType->flags = 1;
	exceptType->mdisp = 0;
	exceptType->pdisp = -1;
	exceptType->vdisp = 0;
	exceptType->size = sizeof(id);
	exceptType->copyFunction = 0;
}

} // <anonymous-namespace>

struct X {};
OBJC_PUBLIC extern "C" void objc_exception_rethrow(void* exc);

OBJC_PUBLIC extern "C" void objc_exception_throw(id object)
{
	// Base used for image-relative addresses.
	char x;
	// This is the base vtable for all RTTI entries
	static const void* typeid_vtable = *(void**)&typeid(void *);

	SEL rethrow_sel = sel_registerName("rethrow");
	if ((nil != object) &&
		(class_respondsToSelector(object_getClass(object), rethrow_sel)))
	{
		IMP rethrow = objc_msg_lookup(object, rethrow_sel);
		rethrow(object, rethrow_sel);
		// Should not be reached!  If it is, then the rethrow method actually
		// didn't, so we throw it normally.
	}

	SEL processException_sel = sel_registerName("_processException");
	if ((nil != object) &&
		(class_respondsToSelector(object_getClass(object), processException_sel)))
	{
		IMP processException = objc_msg_lookup(object, processException_sel);
		processException(object, processException_sel);
	}

	// The 'id' base type will be taking up a spot in the list:
	size_t typeCount = 1;

	// Get count of all types in exception
	for (Class cls = object_getClass(object); cls != Nil; cls = class_getSuperclass(cls), ++typeCount)
		;

	// Unfortunately we can't put this in a real function since the alloca has to be in this stack frame:
#define CREATE_TYPE_DESCRIPTOR(desc, symName) \
	desc = reinterpret_cast<_MSVC_TypeDescriptor*>(alloca(sizeof(_MSVC_TypeDescriptor) + symName.size() + 1 /* null terminator */)); \
	desc->pVFTable = typeid_vtable; \
	desc->spare = nullptr; \
	strcpy_s(desc->name, symName.size() + 1, symName.c_str());

	auto exceptTypes =
		(_MSVC_CatchableTypeArray*)_alloca(sizeof(_MSVC_CatchableTypeArray) + sizeof(_MSVC_CatchableType*) * typeCount);
	exceptTypes->count = typeCount;

	// Add exception type and all base types to throw information
	size_t curTypeIndex = 0;
	for (Class cls = object_getClass(object); cls != Nil; cls = class_getSuperclass(cls))
	{
		auto exceptType = (_MSVC_CatchableType*)_alloca(sizeof(_MSVC_CatchableType));
		fillCatchableType(exceptType);

		auto mangledName = mangleStructNamed(class_getName(cls));
		_MSVC_TypeDescriptor *ty;
		CREATE_TYPE_DESCRIPTOR(ty, mangledName);
		exceptType->type = IMAGE_RELATIVE(ty, &x);
		exceptTypes->types[curTypeIndex++] = IMAGE_RELATIVE(exceptType, &x);
	}

	// Add id (struct objc_object*)
	auto exceptType = (_MSVC_CatchableType*)_alloca(sizeof(_MSVC_CatchableType));
	fillCatchableType(exceptType);
	auto idName = mangleObjcObject();
	_MSVC_TypeDescriptor *ty;
	CREATE_TYPE_DESCRIPTOR(ty, idName);
	exceptType->type = IMAGE_RELATIVE(ty, &x);
	exceptTypes->types[curTypeIndex++] = IMAGE_RELATIVE(exceptType, &x);

	_MSVC_ThrowInfo ti = {
		0, // attributes
		0, // pfnUnwind
		0, // pfnForwardCompat
		IMAGE_RELATIVE(exceptTypes, &x) // pCatchableTypeArray
	};
#	define EH_EXCEPTION_NUMBER ('msc' | 0xE0000000)
#	define EH_MAGIC_NUMBER1 0x19930520
#	define EXCEPTION_NONCONTINUABLE 0x1
	EXCEPTION_RECORD  exception;
	exception.ExceptionCode = EH_EXCEPTION_NUMBER;
	exception.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
	exception.ExceptionRecord = nullptr;
	exception.ExceptionAddress = nullptr;
	// The fourth parameter is the base address of the image (for us, this stack
	// frame), but we only use image-relative 32-bit addresses on 64-bit
	// platforms.  On 32-bit platforms, we use 32-bit absolute addresses.
	exception.NumberParameters = sizeof(void*) == 4 ? 3 : 4;
	exception.ExceptionInformation[0] = EH_MAGIC_NUMBER1;
	exception.ExceptionInformation[1] = reinterpret_cast<ULONG_PTR>(&object);
	exception.ExceptionInformation[2] = reinterpret_cast<ULONG_PTR>(&ti);
	exception.ExceptionInformation[3] = reinterpret_cast<ULONG_PTR>(&x);

#ifdef _WIN64
 	RtlRaiseException(&exception);
#else
	RaiseException(exception.ExceptionCode,
		exception.ExceptionFlags,
		exception.NumberParameters,
		exception.ExceptionInformation);
#endif
	__builtin_unreachable();
}

OBJC_PUBLIC extern "C" void objc_exception_rethrow(void* exc)
{
	_CxxThrowException(nullptr, nullptr);
	__builtin_unreachable();
}

<|endoftext|>


<commit_before>#include <string>
#include <gtest/gtest.h>
#include <prophy/detail/decoder.hpp>
#include "generated/Arrays.pp.hpp"
#include "generated/Dynfields.pp.hpp"
#include "util.hpp"

using namespace testing;
using namespace prophy;
using namespace prophy::detail;

TEST(encoding, decode_builtin_scalars)
{
    std::vector<uint8_t> data = bytes("\x01\x00\x00\x00");
    {
        const uint8_t* pos = data.data();
        const uint8_t* end = data.data() + data.size();
        uint32_t x = 0;

        EXPECT_TRUE(do_decode<native>(x, pos, end));
        EXPECT_EQ(data.data() + data.size(), pos);
        EXPECT_EQ(1, x);
    }
    {
        const uint8_t* pos = data.data() + 1;
        const uint8_t* end = data.data() + data.size();
        uint32_t x = 0;

        EXPECT_FALSE(do_decode<native>(x, pos, end));
        EXPECT_EQ(data.data() + 1, pos);
        EXPECT_EQ(0, x);
    }
}

TEST(encoding, decode_struct_failures)
{
    Builtin x;
    std::vector<uint8_t> data = bytes("\x01\x00\x00\x00\x02\x00\x00");

    EXPECT_FALSE(x.decode(data.data(), data.size()));
    EXPECT_EQ(1, x.x);
    EXPECT_EQ(0, x.y);

    data = bytes("\x03\x00\x00\x00\x04\x00\x00\x00\x00");

    EXPECT_FALSE(x.decode(data.data(), data.size()));
    EXPECT_EQ(3, x.x);
    EXPECT_EQ(4, x.y);

    data = bytes("\x05\x00\x00\x00");

    EXPECT_FALSE(x.decode(data.data(), data.size()));
    EXPECT_EQ(5, x.x);
    EXPECT_EQ(4, x.y);
}

TEST(encoding, endianness)
{
    size_t size;
    std::vector<char> data(1024);

    DynfieldsScalarpartialpad x;
    x.x.x = bytes("abc");
    x.y.x = bytes("d");
    x.z.x = bytes("efghi");

    size = x.encode<native>(data.data());
    EXPECT_EQ(28, size);
    EXPECT_EQ(std::string(
            "\x03\x00\x00\x00" "abc" "\x00"
            "\x01\x00\x00\x00" "d" "\x00\x00\x00"
            "\x05\x00\x00\x00" "efghi" "\x00\x00\x00",
            size), std::string(data.data(), size));

    size = x.encode<little>(data.data());
    EXPECT_EQ(28, size);
    EXPECT_EQ(std::string(
            "\x03\x00\x00\x00" "abc" "\x00"
            "\x01\x00\x00\x00" "d" "\x00\x00\x00"
            "\x05\x00\x00\x00" "efghi" "\x00\x00\x00",
            size), std::string(data.data(), size));

    size = x.encode<big>(data.data());
    EXPECT_EQ(28, size);
    EXPECT_EQ(std::string(
            "\x00\x00\x00\x03" "abc" "\x00"
            "\x00\x00\x00\x01" "d" "\x00\x00\x00"
            "\x00\x00\x00\x05" "efghi" "\x00\x00\x00",
            size), std::string(data.data(), size));
}
<commit_msg>failure cases tested<commit_after>#include <string>
#include <gtest/gtest.h>
#include <prophy/detail/decoder.hpp>
#include "generated/Arrays.pp.hpp"
#include "generated/Dynfields.pp.hpp"
#include "util.hpp"

using namespace testing;
using namespace prophy;
using namespace prophy::detail;

TEST(encoding, decode_builtin_scalars)
{
    std::vector<uint8_t> data = bytes("\x01\x00\x00\x00");
    {
        const uint8_t* pos = data.data();
        const uint8_t* end = data.data() + data.size();
        uint32_t x = 0;

        EXPECT_TRUE(do_decode<native>(x, pos, end));
        EXPECT_EQ(data.data() + data.size(), pos);
        EXPECT_EQ(1, x);
    }
    {
        const uint8_t* pos = data.data() + 1;
        const uint8_t* end = data.data() + data.size();
        uint32_t x = 0;

        EXPECT_FALSE(do_decode<native>(x, pos, end));
        EXPECT_EQ(data.data() + 1, pos);
        EXPECT_EQ(0, x);
    }
}

TEST(encoding, decode_struct_failures)
{
    Builtin x;
    std::vector<uint8_t> data = bytes("\x01\x00\x00\x00\x02\x00\x00");

    EXPECT_FALSE(x.decode(data.data(), data.size()));
    EXPECT_EQ(1, x.x);
    EXPECT_EQ(0, x.y);

    data = bytes("\x03\x00\x00\x00\x04\x00\x00\x00\x00");

    EXPECT_FALSE(x.decode(data.data(), data.size()));
    EXPECT_EQ(3, x.x);
    EXPECT_EQ(4, x.y);

    data = bytes("\x05\x00\x00\x00");

    EXPECT_FALSE(x.decode(data.data(), data.size()));
    EXPECT_EQ(5, x.x);
    EXPECT_EQ(4, x.y);
}

TEST(encoding, decode_vector_failures)
{
    BuiltinDynamic x;
    std::vector<uint8_t> data = bytes("\x01\x00\x00"); //not enough to decode counter

    EXPECT_FALSE(x.decode(data.data(), data.size()));
    EXPECT_EQ(0, x.x.size());

    data = bytes("\x01\x00\x00\x00"); // no array elements

    EXPECT_FALSE(x.decode(data.data(), data.size()));
    EXPECT_EQ(1, x.x.size());
    EXPECT_EQ(0, x.x[0]);

    data = bytes("\x01\x00\x00\x00\x02\x00\x00"); // one byte short

    EXPECT_FALSE(x.decode(data.data(), data.size()));
    EXPECT_EQ(1, x.x.size());
    EXPECT_EQ(0, x.x[0]);

    data = bytes("\x01\x00\x00\x00\x02\x00\x00\x00\x00"); // one byte too much

    EXPECT_FALSE(x.decode(data.data(), data.size()));
    EXPECT_EQ(1, x.x.size());
    EXPECT_EQ(2, x.x[0]);
}

TEST(encoding, endianness)
{
    size_t size;
    std::vector<char> data(1024);

    DynfieldsScalarpartialpad x;
    x.x.x = bytes("abc");
    x.y.x = bytes("d");
    x.z.x = bytes("efghi");

    size = x.encode<native>(data.data());
    EXPECT_EQ(28, size);
    EXPECT_EQ(std::string(
            "\x03\x00\x00\x00" "abc" "\x00"
            "\x01\x00\x00\x00" "d" "\x00\x00\x00"
            "\x05\x00\x00\x00" "efghi" "\x00\x00\x00",
            size), std::string(data.data(), size));

    size = x.encode<little>(data.data());
    EXPECT_EQ(28, size);
    EXPECT_EQ(std::string(
            "\x03\x00\x00\x00" "abc" "\x00"
            "\x01\x00\x00\x00" "d" "\x00\x00\x00"
            "\x05\x00\x00\x00" "efghi" "\x00\x00\x00",
            size), std::string(data.data(), size));

    size = x.encode<big>(data.data());
    EXPECT_EQ(28, size);
    EXPECT_EQ(std::string(
            "\x00\x00\x00\x03" "abc" "\x00"
            "\x00\x00\x00\x01" "d" "\x00\x00\x00"
            "\x00\x00\x00\x05" "efghi" "\x00\x00\x00",
            size), std::string(data.data(), size));
}
<|endoftext|>