2010/09/11


以前、twitter上で「STL以上、Boost未満な使い心地のライブラリが欲しい。ネットワーク関連込みの。」とつぶやいた所、id:faith_and_braveさんから返事貰った。
Faith and Brave Twitter / Faith and Brave

CLX or Message-Pack or Pocoあたりでしょうか RT @mattn_jp: STL以上、Boost未満な使い心地のライブラリが欲しい。ネットワーク関連込みの。

http://twitter.com/cpp_akira/status/21234425525
CLXは実は前から知っていて何度か捨てコードに使わせて頂いていたのですが、SSL越しにproxyが使えなかったので、ネットワーク関連のコードには使ってませんでした。
まぁでも一応書いて判断すべきかなと思って、僕的な答えとして、さらーーーっと書いた。
CONSUMER_KEY と CONSUMER_SECRET を書き換えて実行して下さい。xAuth認証を使ってtwitterにステータスをポストします。

#include <iostream>
#include <sstream>
#include <clx/base64.h>
#include <clx/hexdump.h>
#include <clx/date_time.h>
#include <clx/format.h>
#include <clx/hmac.h>
#include <clx/https.h>
#include <clx/random.h>
#include <clx/salgorithm.h>
#include <clx/sha1.h>
#include <clx/uri.h>

std::string url_encode(const std::string& url) {
    std::ostringstream rets;
    for(size_t n = 0; n < url.size(); n++) {
        unsigned char c = (unsigned char)url[n];
        if (isalnum(c) || c == '_' || c == '.' || c == '-')
            rets << c;
        else {
            char buf[8];
            sprintf(buf, "%02X", (int)c);
            rets << '%' << buf[0] << buf[1];
        }
    }
    return rets.str();
}


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

    if (argc != 4) {
        std::cerr << "usage: " << argv[0]
            << " [username] [password] [message]" << std::endl;
        return -1;
    }

    clx::date_time now;
    clx::random<unsigned int> randgen;
    randgen.engine().seed(time(0));

    std::string consumer_key = "CONSUMER_KEY";
    std::string consumer_secret = "CONSUMER_SECRET";
    std::string username = argv[1];
    std::string password = argv[2];
    std::string message = argv[3];

    std::stringstream ss;
    std::string times = clx::str(clx::format("%s") % now.c_time());
    std::string nonce = clx::hexdump(times);

    ss << "oauth_consumer_key=" << consumer_key
       << "&oauth_nonce=" << nonce
       << "&oauth_signature_method=" << "HMAC-SHA1"
       << "&oauth_timestamp=" << times
       << "&oauth_version=" << "1.0"
       << "&x_auth_mode=" << "client_auth"
       << "&x_auth_password=" << password
       << "&x_auth_username=" << username;

    std::string key = consumer_secret + "&";
    std::string val = "POST&";

    val += url_encode("https://api.twitter.com/oauth/access_token");
    val += "&";
    val += url_encode(ss.str());
    char* hmac = (char*)clx::hmac<clx::sha1>(
            key.c_str(), key.size(), val.c_str(), val.size()).code();
    std::string hm = clx::base64::encode(hmac, 20);

    ss << "&oauth_signature=" << url_encode(hm);

    clx::https session(clx::uri::encode("api.twitter.com"), 443);
    session.post(clx::uri::encode("/oauth/access_token"), ss.str());

    std::vector<std::string> item;
    std::map<std::string, std::string> params;
    clx::split_if(session.body(), item, clx::is_any_of(LITERAL("&")));
    for (unsigned int i = 0; i < item.size(); i++) {
        std::string tok = item.at(i);
        size_t pos = tok.find_first_of("=");
        params[tok.substr(0, pos)] = clx::uri::decode(tok.substr(pos+1));
    }


    ss.str("");
    ss.clear(std::stringstream::goodbit);

    ss << "oauth_consumer_key=" << consumer_key
       << "&oauth_nonce=" << nonce
       << "&oauth_signature_method=" << "HMAC-SHA1"
       << "&oauth_timestamp=" << times
       << "&oauth_token=" << params["oauth_token"]
       << "&oauth_version=" << "1.0"
       << "&status=" << url_encode(message);

    key = consumer_secret + "&" + params["oauth_token_secret"];
    val = "POST&";

    val += url_encode("https://api.twitter.com/1/statuses/update.json");
    val += "&";
    val += url_encode(ss.str());
    hmac = (char*)clx::hmac<clx::sha1>(
            key.c_str(), key.size(), val.c_str(), val.size()).code();
    hm= clx::base64::encode(hmac, 20);

    ss << "&oauth_signature=" << url_encode(hm);

    session.post(clx::uri::encode("/1/statuses/update.json"), ss.str());
    std::cout << session.body() << std::endl;

    return 0;
}

/* vim:set et sw=4: */
URLまわりと、POSTパラメータ構築に便利なのがあっても良いかなと思った。あーそれboost::asioでも言えるか。
Posted at by



2010/08/10


「new 式」 で、変数を 式 として指定することはできますか? | OKWave
via: ときどきの雑記帳
ところでpermalinkがおかしい気がする。あと最近のときどきの雑記帳はときどきどころでない気がするw
「new 式」 で、変数を 式 として指定することはできますか?

例えば次のような感じで、変数clの内容によりclassAあるいはclassBをnew
するようなことがしたいです。
class base [ ... };
class classA : public base { .... };
class classB : public base { .... };
classA* ca;
classB* cb;
base* cl;
cl = classA;
ca = new cl;
cl = classB;
ca = new cl;

これにより、多種のclassをnewする際にいちいち
pa = new classA;
pb = new classB;
pc = new classC;
pd = new classD;
............
としないで、
for (n=0; n<xxx; n++)
p[n] = new cl[n];
…みたいに簡潔に書けないかなと考えてます。
よろしくお願いします。
こんな?
#include <iostream>

using namespace std;

class base {
public:
    virtual void hello() const =0;
};

class classA : public base { void hello() const { cout << "classA\n"; }};
class classB : public base { void hello() const { cout << "classB\n"; }};
class classC : public base { void hello() const { cout << "classC\n"; }};
class classD : public base { void hello() const { cout << "classD\n"; }};

template<typename T> base* create() {
    return new T;
}

int main(){
    typedef base* (*factory)();
    factory p[] = {
        create<classA>,
        create<classB>,
        create<classC>,
        create<classD>
    };
    for (int n = 0; n < 4; n++)
        p[n]()->hello();
}
Posted at by



2010/06/18


今じゃぁgcc4が一般的なので、状況変わったかな?と思ったのでWindowsで再度試してみた。
Big Sky :: シャア専用memcpy

試してみた memcpy 最適化 - id:kazuhookuのメモ置き場バイト単位でコピーするアホなコードの方が、勝手にベクトル化される分、gcc 内蔵のヤツより最大3倍高速なんだってwwwx64じ...

http://mattn.kaoriya.net/software/gcc/20080617134829.htm
前回は効果が無かったけど、今回は --------------------------------------------------------------------------
gcc (GCC) 4.4.0
Copyright (C) 2009 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
--------------------------------------------------------------------------

# gcc -O3 -ftree-vectorize -msse2 test.c

adhock memcpy: 1.625031
normal memcpy: 3.734447

# gcc -O3 -ftree-vectorize -ftree-vectorizer-verbose=5 -mmmx -msse3 test.c

adhock memcpy: 1.609581
normal memcpy: 3.750480

# gcc test.c

adhock memcpy: 79.642154
normal memcpy: 4.968845

確かに3倍近いスコアが出てる。もうmemcpyとかinlineでいいんでね?
Posted at by