A simple EventEmitter in C++

EventEmitter coming with node.js is handy most of the time, and I implement this useful utility in C++ after finishing writing Functor. Yes, we need Functor to make it much more easier to write this fabulous utility. (Why don't you use lamdba? I'll talk about that later in this post)

It's extremely simple to use EventEmitter in node.js

const EventEmitter = require('events');

class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter();
myEmitter.on('event', () => {
    console.log('an event occurred!');
});
myEmitter.emit('event');

——https://nodejs.org/api/events.html

And the C++ version of EventEmitter need to be as easy as it is in node.js. As a matter of fact, this class made it.

#include <iostream>
#include <sstream>
#include <thread>
#include <vector>
#include "EventEmitter.hpp"

using namespace std;

class emitter : public EventEmitter {
};

int main(int argc, const char * argv[]) {
    emitter emitter;
    emitter.on("event", [&emitter](int data) {
        ostringstream osstream;
        osstream << "data: " << data << '\n';
        std::cout << osstream.str();
    });

    vector<thread> threads;
    for (int i = 0; i < 10; i++) {
        threads.emplace_back([&emitter, i]() {
            emitter.emit("event", i);
        });
    }

    for (auto &t : threads) t.join();
}

继续阅读A simple EventEmitter in C++

A simple EventEmitter in C++

node.js里面的EventEmitter非常好用,于是上次写完Functor之后,就顺理成章的写了这个EventEmitter,或者说,就是为了实现这个EventEmitter才写的Functor(后文会提到为什么要Functor,毕竟如果只看Functor本身的话,还不如直接用lamdba方便)。

在node.js中,使用EventEmitter非常简单,

const EventEmitter = require('events');

class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter();
myEmitter.on('event', () => {
    console.log('an event occurred!');
});
myEmitter.emit('event');

——https://nodejs.org/api/events.html

那么现在这个C++版的EventEmitter也必须做到这样简单易用,事实上,它也的确和node.js的使用方式类似。

#include <iostream>
#include <sstream>
#include <thread>
#include <vector>
#include "EventEmitter.hpp"

using namespace std;

class emitter : public EventEmitter {
};

int main(int argc, const char * argv[]) {
    emitter emitter;
    emitter.on("event", [&emitter](int data) {
        ostringstream osstream;
        osstream << "data: " << data << '\n';
        std::cout << osstream.str();
    });

    vector<thread> threads;
    for (int i = 0; i < 10; i++) {
        threads.emplace_back([&emitter, i]() {
            emitter.emit("event", i);
        });
    }

    for (auto &t : threads) t.join();
}

继续阅读A simple EventEmitter in C++

Module Check——Usage of std::enable_if

最近写代码的时候,总能在不少STL的函数声明里看见可爱的std::enable_if,虽然自己偶尔用过,不过也只是直接用STL库里的std::is_arithmetic之类。

于是就去Google了std::enable_if,然后参考了如下几篇post,写了一个较为通用的Module Check。

所以还是先从一个小的问题开始讲起吧~

假设我们做了一个中间类作为接口,这个中间类有一个模版构造函数,它接受一个类实例和一个double类型的参数,并且总是调用一个固定的实例方法。

class Intermediate {
public:
    template <typename T>
    Intermediate(const T& object, double value) {
        object.method(value);
    }
};

现在我们有如下的类,

class A {
public:
    void method(double d) const {
        std::cout<<d<<'\n';
    }
};

class B {
public:
    void method(int i) const {
        std::cout<<i<<'\n';
    }
};

虽然如下代码可以编译运行,但是假如我们希望只有类A被这样调用才有效呢?

Intermediate inter_a_1(a, 2.33); // print 2.33
Intermediate inter_b_1(b, 2.33); // print 2

继续阅读Module Check——Usage of std::enable_if

A simple xterm256 wrapper in C++

如果你的terminal支持xterm-256color模式的话,就可以在terminal中使用256种颜色。利用这256种色彩,可以做出很棒/很酷的效果。比如vim的语法高亮。

这里简单的实现了一个C++类,与cout的行为相同,仅在输出类xterm256::color的实例时做处理,将紧随其后的、截止下一个xterm256::color类实例前的文字输出为对应的颜色。

xterm256::color使用3个unsigned short作为初始化参数,依次对应RGB。在输出时,由于仅有256种色彩,将自动转为与xterm-256color颜色表欧氏距离最近的一种颜色。

简要的使用例子及截图如下

继续阅读A simple xterm256 wrapper in C++

C++下的通用K-means Algorithm模版

之前写过一篇利用k-means算法来计算图像中主要颜色的文章,K-means聚类算法计算给定图像中主要颜色。于是今天顺便写了个较为通用的C++下的K-means算法模版。

有一个主要的模版,还有一个稍有变化的模版,仅体现在传入的第三个参数上。

主要的参数如下,

Parameter Description
k 聚类的种数
min_diff 收束条件,旧的cluster中心与新的之间变化的距离
data1 std::vector<数据类型>
data2 std::vector<std::pair<数据类型, 该实例的统计个数>>
center 传入std::vector<std::pair<数据类型, 该实例的统计个数>>,返回该组数据的中心值
distance 传入给定数据中的两个元素, 返回它们的距离

返回值都是包含k个该种类型的元素的std::vector

继续阅读C++下的通用K-means Algorithm模版

数据库系统概论——C++实现求解 属性集X关于函数依赖集F的闭包 & 给定函数依赖集F的最小覆盖

所以再过几个小时就要考《数据库系统概论》了,看书看到一半手痒了,就把书上的两个算法用C++实现了一遍,这两个算法是

  • 求属性集X在U上的函数依赖集F的闭包
  • 求给定函数依赖集F的最小覆盖

详细的算法都写在注释里了~

继续阅读数据库系统概论——C++实现求解 属性集X关于函数依赖集F的闭包 & 给定函数依赖集F的最小覆盖

wget漏洞CVE-2016-4971

前几天wget出了一个洞,

On a server redirect from HTTP to a FTP resource, wget would trust the HTTP server and uses the name in the redirected URL as the destination filename.

——https://people.canonical.com/~ubuntu-security/cve/2016/CVE-2016-4971.html

即,当wget请求一个HTTP站点上的文件时,如果HTTP服务器将它重定向到一个FTP服务器的话,wget将使用HTTP服务器所给出的在FTP服务器上的文件的名字。

如果我们重定向到一个名为.bash_profile的文件,而且用户下载文件的目录下又正好是默认的登录目录,且没有这个.bash_profile的话, 我们的目的就达到了。我们可以在.bash_profile中写上恶意代码,下一次该用户登录上来时,这些恶意代码就会自动被执行,于是23333

继续阅读wget漏洞CVE-2016-4971

在非越狱的iOS上安装系统级的自定字体

在很久之前写过一个笔记,iOS上CoreText加载字体并使用,然后今天做的是在非越狱的iOS上安装系统级的自定字体,其实就是模拟Apple Configurator生成配置文件,然后安装字体,方便的地方在于不需要用电脑,也不必下载Apple Configurator,直接在下面的表单里填上对应的项即可。





填写好基本的信息——字体链接、描述、名字——之后,就可以点“INSTALL FONT”了。

那么这个有什么用呢?在支持自定字体的程序中(比如Pages、Numbers、Keynote等等),我们可以使用自己喜欢的字体,不用越狱,也不用打开iFunbox一类的软件折腾。

继续阅读在非越狱的iOS上安装系统级的自定字体