<commit_before>/*
 * Copyright (c) 2016 Fastly, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */

/*
 * This file implements a test harness for using h2o with LibFuzzer.
 * See http://llvm.org/docs/LibFuzzer.html for more info.
 */

#define H2O_USE_EPOLL 1
#include <string.h>
#include <errno.h>
#include <limits.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/select.h>
#include <sys/wait.h>
#include <unistd.h>
#include <fcntl.h>

#include "h2o.h"
#include "h2o/http1.h"
#include "h2o/http2.h"
#include "h2o/url.h"
#include "h2o/memcached.h"

#if !defined(HTTP1) && !defined(HTTP2)
#error "Please defined one of HTTP1 or HTTP2"
#endif

#if defined(HTTP1) && defined(HTTP2)
#error "Please defined one of HTTP1 or HTTP2, but not both"
#endif

static h2o_globalconf_t config;
static h2o_context_t ctx;
static h2o_accept_ctx_t accept_ctx;
static int client_timeout_ms;
static char unix_listener[PATH_MAX];

/*
 * Registers a request handler with h2o
 */
static h2o_pathconf_t *register_handler(h2o_hostconf_t *hostconf, const char *path, int (*on_req)(h2o_handler_t *, h2o_req_t *))
{
    h2o_pathconf_t *pathconf = h2o_config_register_path(hostconf, path, 0);
    h2o_handler_t *handler = h2o_create_handler(pathconf, sizeof(*handler));
    handler->on_req = on_req;
    return pathconf;
}

/*
 * Request handler used for testing. Returns a basic "200 OK" response.
 */
static int chunked_test(h2o_handler_t *self, h2o_req_t *req)
{
    static h2o_generator_t generator = {NULL, NULL};

    if (!h2o_memis(req->method.base, req->method.len, H2O_STRLIT("GET")))
        return -1;

    h2o_iovec_t body = h2o_strdup(&req->pool, "hello world\n", SIZE_MAX);
    req->res.status = 200;
    req->res.reason = "OK";
    h2o_add_header(&req->pool, &req->res.headers, H2O_TOKEN_CONTENT_TYPE, NULL, H2O_STRLIT("text/plain"));
    h2o_start_response(req, &generator);
    h2o_send(req, &body, 1, H2O_SEND_STATE_FINAL);

    return 0;
}

/* copy from src to dst, return true if src has EOF */
static int drain(int fd)
{
    char buf[4096];
    ssize_t n;

    n = read(fd, buf, sizeof(buf));
    if (n <= 0) {
        return 1;
    }
    return 0;
}

/* A request sent from client thread to h2o server */
struct writer_thread_arg {
    char *buf;
    size_t len;
    int fd;
    h2o_barrier_t barrier;
};

/*
 * Reads writer_thread_arg from fd and stores to buf
 */
static void read_fully(int fd, char *buf, size_t len)
{
    int done = 0;
    while (len) {
        int ret;
        while ((ret = read(fd, buf + done, len)) == -1 && errno == EINTR)
            ;
        if (ret <= 0) {
            abort();
        }
        done += ret;
        len -= ret;
    }
}

/*
 * Writes the writer_thread_args at buf to fd
 */
static void write_fully(int fd, char *buf, size_t len, int abort_on_err)
{
    int done = 0;
    while (len) {
        int ret;
        while ((ret = write(fd, buf + done, len)) == -1 && errno == EINTR)
            ;
        if (ret <= 0) {
            if (abort_on_err)
                abort();
            else
                return;
        }
        done += ret;
        len -= ret;
    }
}

#define OK_RESP                                                                                \
    "HTTP/1.0 200 OK\r\n"                                                                                \
    "Connection: Close\r\n\r\nOk"
#define OK_RESP_LEN (sizeof(OK_RESP) - 1)

void *upstream_thread(void *arg)
{
    char *dirname = (char *)arg;
    char path[PATH_MAX];
    char rbuf[1 * 1024 * 1024];
    snprintf(path, sizeof(path), "/%s/_.sock", dirname);
    int sd = socket(AF_UNIX, SOCK_STREAM, 0);
    if (sd < 0) {
        abort();
    }
    struct sockaddr_un addr;
    memset(&addr, 0, sizeof(addr));
    addr.sun_family = AF_UNIX;
    strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
    if (bind(sd, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
        abort();
    }
    if (listen(sd, 100) != 0) {
        abort();
    }

    while (1) {
        struct sockaddr_un caddr;
        socklen_t slen = 0;
        int cfs = accept(sd, (struct sockaddr *)&caddr, &slen);
        if (cfs < 0) {
            continue;
        }
        read(cfs, rbuf, sizeof(rbuf));
        write_fully(cfs, (char *)OK_RESP, OK_RESP_LEN, 0);
        close(cfs);
    }
}
/*
 * Thread: Loops writing fuzzed req to socket and then reading results back.
 * Acts as a client to h2o. *arg points to file descripter to read
 * writer_thread_args from.
 */
void *writer_thread(void *arg)
{
    int rfd = (long)arg;
    while (1) {
        int pos, sockinp, sockoutp, cnt, len;
        char *buf;
        struct writer_thread_arg *wta;

        /* Get fuzzed request */
        read_fully(rfd, (char *)&wta, sizeof(wta));

        pos = 0;
        sockinp = wta->fd;
        sockoutp = wta->fd;
        cnt = 0;
        buf = wta->buf;
        len = wta->len;

        /*
         * Send fuzzed req and read results until the socket is closed (or
         * something spurious happens)
         */
        while (cnt++ < 20 && (pos < len || sockinp >= 0)) {
#define MARKER "\n--MARK--\n"
            /* send 1 packet */
            if (pos < len) {
                char *p = (char *)memmem(buf + pos, len - pos, MARKER, sizeof(MARKER) - 1);
                if (p) {
                    int l = p - (buf + pos);
                    write(sockoutp, buf + pos, l);
                    pos += l;
                    pos += sizeof(MARKER) - 1;
                }
            } else {
                if (sockinp >= 0) {
                    shutdown(sockinp, SHUT_WR);
                }
            }

            /* drain socket */
            if (sockinp >= 0) {
                struct timeval timeo;
                fd_set rd;
                int n;

                FD_ZERO(&rd);
                FD_SET(sockinp, &rd);
                timeo.tv_sec = 0;
                timeo.tv_usec = client_timeout_ms * 1000;
                n = select(sockinp + 1, &rd, NULL, NULL, &timeo);
                if (n > 0 && FD_ISSET(sockinp, &rd) && drain(sockinp)) {
                    sockinp = -1;
                }
            }
        }
        close(wta->fd);
        h2o_barrier_wait(&wta->barrier);
        h2o_barrier_destroy(&wta->barrier);
        free(wta);
    }
}

/*
 * Creates socket pair and passes fuzzed req to a thread (the HTTP[/2] client)
 * for writing to the target h2o server. Returns the server socket fd.
 */
static int feeder(int sfd, char *buf, size_t len, h2o_barrier_t **barrier)
{
    int pair[2];
    struct writer_thread_arg *wta;

    if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1)
        return -1;

    wta = (struct writer_thread_arg *)malloc(sizeof(*wta));
    wta->fd = pair[0];
    wta->buf = buf;
    wta->len = len;
    h2o_barrier_init(&wta->barrier, 2);
    *barrier = &wta->barrier;

    write_fully(sfd, (char *)&wta, sizeof(wta), 1);
    return pair[1];
}

/*
 * Creates/connects socket pair for client/server interaction and passes
 * fuzzed request to client for sending.
 * Returns server socket fd.
 */
static int create_accepted(int sfd, char *buf, size_t len, h2o_barrier_t **barrier)
{
    int fd;
    h2o_socket_t *sock;
    struct timeval connected_at = *h2o_get_timestamp(&ctx, NULL, NULL);

    /* Create an HTTP[/2] client that will send the fuzzed request */
    fd = feeder(sfd, buf, len, barrier);
    if (fd < 0) {
        abort();
    }

    /* Pass the server socket to h2o and invoke request processing */
    sock = h2o_evloop_socket_create(ctx.loop, fd, H2O_SOCKET_FLAG_IS_ACCEPTED_CONNECTION);

#if defined(HTTP1)
    h2o_http1_accept(&accept_ctx, sock, connected_at);
#else
    h2o_http2_accept(&accept_ctx, sock, connected_at);
#endif

    return fd;
}

/*
 * Returns true if fd if valid. Used to determine when connection is closed.
 */
static int is_valid_fd(int fd)
{
    return fcntl(fd, F_GETFD) != -1 || errno != EBADF;
}

/*
 * Entry point for libfuzzer.
 * See http://llvm.org/docs/LibFuzzer.html for more info
 */
static int init_done;
static int job_queue[2];
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
{
    int c;
    h2o_loop_t *loop;
    h2o_hostconf_t *hostconf;
    pthread_t twriter;
    pthread_t tupstream;

    /*
     * Perform one-time initialization
     */
    if (!init_done) {
        const char *client_timeout_ms_str;
        static char tmpname[] = "/tmp/h2o-fuzz-XXXXXX";
        char *dirname;
        h2o_url_t upstream;
        signal(SIGPIPE, SIG_IGN);

        dirname = mkdtemp(tmpname);
        snprintf(unix_listener, sizeof(unix_listener), "http://[unix://%s/_.sock]/proxy", dirname);
        if ((client_timeout_ms_str = getenv("H2O_FUZZER_CLIENT_TIMEOUT")) != NULL)
            client_timeout_ms = atoi(client_timeout_ms_str);
        if (!client_timeout_ms)
            client_timeout_ms = 10;

        /* Create a single h2o host with multiple request handlers */
        h2o_config_init(&config);
        config.http2.idle_timeout = 10 * 1000;
        config.http1.req_timeout = 10 * 1000;
        config.proxy.io_timeout = 10 * 1000;
        h2o_proxy_config_vars_t proxy_config = {};
        proxy_config.io_timeout = 10 * 1000;
        hostconf = h2o_config_register_host(&config, h2o_iovec_init(H2O_STRLIT(unix_listener)), 65535);
        register_handler(hostconf, "/chunked-test", chunked_test);
        h2o_url_parse(unix_listener, strlen(unix_listener), &upstream);
        h2o_socketpool_t *sockpool = new h2o_socketpool_t();
        h2o_socketpool_target_t *target = h2o_socketpool_target_create(&upstream, NULL);
        h2o_socketpool_init_specific(sockpool, SIZE_MAX /* FIXME */, &target, 1, NULL);
        h2o_socketpool_set_timeout(sockpool, 2000);
        h2o_socketpool_set_ssl_ctx(sockpool, NULL);
        h2o_proxy_register_reverse_proxy(h2o_config_register_path(hostconf, "/reproxy-test", 0), &proxy_config, sockpool);
        h2o_file_register(h2o_config_register_path(hostconf, "/", 0), "./examples/doc_root", NULL, NULL, 0);

        loop = h2o_evloop_create();
        h2o_context_init(&ctx, loop, &config);

        accept_ctx.ctx = &ctx;
        accept_ctx.hosts = config.hosts;

        /* Create a thread to act as the HTTP client */
        if (socketpair(AF_UNIX, SOCK_STREAM, 0, job_queue) != 0) {
            abort();
        }
        if (pthread_create(&twriter, NULL, writer_thread, (void *)(long)job_queue[1]) != 0) {
            abort();
        }
        if (pthread_create(&tupstream, NULL, upstream_thread, dirname) != 0) {
            abort();
        }
        init_done = 1;
    }

    /*
     * Pass fuzzed request to client thread and get h2o server socket for
     * use below
     */
    h2o_barrier_t *end;
    c = create_accepted(job_queue[0], (char *)Data, (size_t)Size, &end);
    if (c < 0) {
        goto Error;
    }

    /* Loop until the connection is closed by the client or server */
    while (is_valid_fd(c)) {
        h2o_evloop_run(ctx.loop, 10);
    }

    h2o_barrier_wait(end);
    return 0;
Error:
    return 1;
}
<commit_msg>fix fuzzer build error<commit_after>/*
 * Copyright (c) 2016 Fastly, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */

/*
 * This file implements a test harness for using h2o with LibFuzzer.
 * See http://llvm.org/docs/LibFuzzer.html for more info.
 */

#define H2O_USE_EPOLL 1
#include <string.h>
#include <errno.h>
#include <limits.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/select.h>
#include <sys/wait.h>
#include <unistd.h>
#include <fcntl.h>

#include "h2o.h"
#include "h2o/http1.h"
#include "h2o/http2.h"
#include "h2o/url.h"
#include "h2o/memcached.h"

#if !defined(HTTP1) && !defined(HTTP2)
#error "Please defined one of HTTP1 or HTTP2"
#endif

#if defined(HTTP1) && defined(HTTP2)
#error "Please defined one of HTTP1 or HTTP2, but not both"
#endif

static h2o_globalconf_t config;
static h2o_context_t ctx;
static h2o_accept_ctx_t accept_ctx;
static int client_timeout_ms;
static char unix_listener[PATH_MAX];

/*
 * Registers a request handler with h2o
 */
static h2o_pathconf_t *register_handler(h2o_hostconf_t *hostconf, const char *path, int (*on_req)(h2o_handler_t *, h2o_req_t *))
{
    h2o_pathconf_t *pathconf = h2o_config_register_path(hostconf, path, 0);
    h2o_handler_t *handler = h2o_create_handler(pathconf, sizeof(*handler));
    handler->on_req = on_req;
    return pathconf;
}

/*
 * Request handler used for testing. Returns a basic "200 OK" response.
 */
static int chunked_test(h2o_handler_t *self, h2o_req_t *req)
{
    static h2o_generator_t generator = {NULL, NULL};

    if (!h2o_memis(req->method.base, req->method.len, H2O_STRLIT("GET")))
        return -1;

    h2o_iovec_t body = h2o_strdup(&req->pool, "hello world\n", SIZE_MAX);
    req->res.status = 200;
    req->res.reason = "OK";
    h2o_add_header(&req->pool, &req->res.headers, H2O_TOKEN_CONTENT_TYPE, NULL, H2O_STRLIT("text/plain"));
    h2o_start_response(req, &generator);
    h2o_send(req, &body, 1, H2O_SEND_STATE_FINAL);

    return 0;
}

/* copy from src to dst, return true if src has EOF */
static int drain(int fd)
{
    char buf[4096];
    ssize_t n;

    n = read(fd, buf, sizeof(buf));
    if (n <= 0) {
        return 1;
    }
    return 0;
}

/* A request sent from client thread to h2o server */
struct writer_thread_arg {
    char *buf;
    size_t len;
    int fd;
    h2o_barrier_t barrier;
};

/*
 * Reads writer_thread_arg from fd and stores to buf
 */
static void read_fully(int fd, char *buf, size_t len)
{
    int done = 0;
    while (len) {
        int ret;
        while ((ret = read(fd, buf + done, len)) == -1 && errno == EINTR)
            ;
        if (ret <= 0) {
            abort();
        }
        done += ret;
        len -= ret;
    }
}

/*
 * Writes the writer_thread_args at buf to fd
 */
static void write_fully(int fd, char *buf, size_t len, int abort_on_err)
{
    int done = 0;
    while (len) {
        int ret;
        while ((ret = write(fd, buf + done, len)) == -1 && errno == EINTR)
            ;
        if (ret <= 0) {
            if (abort_on_err)
                abort();
            else
                return;
        }
        done += ret;
        len -= ret;
    }
}

#define OK_RESP                                                                                \
    "HTTP/1.0 200 OK\r\n"                                                                                \
    "Connection: Close\r\n\r\nOk"
#define OK_RESP_LEN (sizeof(OK_RESP) - 1)

void *upstream_thread(void *arg)
{
    char *dirname = (char *)arg;
    char path[PATH_MAX];
    char rbuf[1 * 1024 * 1024];
    snprintf(path, sizeof(path), "/%s/_.sock", dirname);
    int sd = socket(AF_UNIX, SOCK_STREAM, 0);
    if (sd < 0) {
        abort();
    }
    struct sockaddr_un addr;
    memset(&addr, 0, sizeof(addr));
    addr.sun_family = AF_UNIX;
    strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
    if (bind(sd, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
        abort();
    }
    if (listen(sd, 100) != 0) {
        abort();
    }

    while (1) {
        struct sockaddr_un caddr;
        socklen_t slen = 0;
        int cfs = accept(sd, (struct sockaddr *)&caddr, &slen);
        if (cfs < 0) {
            continue;
        }
        read(cfs, rbuf, sizeof(rbuf));
        write_fully(cfs, (char *)OK_RESP, OK_RESP_LEN, 0);
        close(cfs);
    }
}
/*
 * Thread: Loops writing fuzzed req to socket and then reading results back.
 * Acts as a client to h2o. *arg points to file descripter to read
 * writer_thread_args from.
 */
void *writer_thread(void *arg)
{
    int rfd = (long)arg;
    while (1) {
        int pos, sockinp, sockoutp, cnt, len;
        char *buf;
        struct writer_thread_arg *wta;

        /* Get fuzzed request */
        read_fully(rfd, (char *)&wta, sizeof(wta));

        pos = 0;
        sockinp = wta->fd;
        sockoutp = wta->fd;
        cnt = 0;
        buf = wta->buf;
        len = wta->len;

        /*
         * Send fuzzed req and read results until the socket is closed (or
         * something spurious happens)
         */
        while (cnt++ < 20 && (pos < len || sockinp >= 0)) {
#define MARKER "\n--MARK--\n"
            /* send 1 packet */
            if (pos < len) {
                char *p = (char *)memmem(buf + pos, len - pos, MARKER, sizeof(MARKER) - 1);
                if (p) {
                    int l = p - (buf + pos);
                    write(sockoutp, buf + pos, l);
                    pos += l;
                    pos += sizeof(MARKER) - 1;
                }
            } else {
                if (sockinp >= 0) {
                    shutdown(sockinp, SHUT_WR);
                }
            }

            /* drain socket */
            if (sockinp >= 0) {
                struct timeval timeo;
                fd_set rd;
                int n;

                FD_ZERO(&rd);
                FD_SET(sockinp, &rd);
                timeo.tv_sec = 0;
                timeo.tv_usec = client_timeout_ms * 1000;
                n = select(sockinp + 1, &rd, NULL, NULL, &timeo);
                if (n > 0 && FD_ISSET(sockinp, &rd) && drain(sockinp)) {
                    sockinp = -1;
                }
            }
        }
        close(wta->fd);
        h2o_barrier_wait(&wta->barrier);
        h2o_barrier_destroy(&wta->barrier);
        free(wta);
    }
}

/*
 * Creates socket pair and passes fuzzed req to a thread (the HTTP[/2] client)
 * for writing to the target h2o server. Returns the server socket fd.
 */
static int feeder(int sfd, char *buf, size_t len, h2o_barrier_t **barrier)
{
    int pair[2];
    struct writer_thread_arg *wta;

    if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1)
        return -1;

    wta = (struct writer_thread_arg *)malloc(sizeof(*wta));
    wta->fd = pair[0];
    wta->buf = buf;
    wta->len = len;
    h2o_barrier_init(&wta->barrier, 2);
    *barrier = &wta->barrier;

    write_fully(sfd, (char *)&wta, sizeof(wta), 1);
    return pair[1];
}

/*
 * Creates/connects socket pair for client/server interaction and passes
 * fuzzed request to client for sending.
 * Returns server socket fd.
 */
static int create_accepted(int sfd, char *buf, size_t len, h2o_barrier_t **barrier)
{
    int fd;
    h2o_socket_t *sock;
    struct timeval connected_at = *h2o_get_timestamp(&ctx, NULL, NULL);

    /* Create an HTTP[/2] client that will send the fuzzed request */
    fd = feeder(sfd, buf, len, barrier);
    if (fd < 0) {
        abort();
    }

    /* Pass the server socket to h2o and invoke request processing */
    sock = h2o_evloop_socket_create(ctx.loop, fd, H2O_SOCKET_FLAG_IS_ACCEPTED_CONNECTION);

#if defined(HTTP1)
    h2o_http1_accept(&accept_ctx, sock, connected_at);
#else
    h2o_http2_accept(&accept_ctx, sock, connected_at);
#endif

    return fd;
}

/*
 * Returns true if fd if valid. Used to determine when connection is closed.
 */
static int is_valid_fd(int fd)
{
    return fcntl(fd, F_GETFD) != -1 || errno != EBADF;
}

/*
 * Entry point for libfuzzer.
 * See http://llvm.org/docs/LibFuzzer.html for more info
 */
static int init_done;
static int job_queue[2];
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
{
    int c;
    h2o_loop_t *loop;
    h2o_hostconf_t *hostconf;
    pthread_t twriter;
    pthread_t tupstream;

    /*
     * Perform one-time initialization
     */
    if (!init_done) {
        const char *client_timeout_ms_str;
        static char tmpname[] = "/tmp/h2o-fuzz-XXXXXX";
        char *dirname;
        h2o_url_t upstream;
        signal(SIGPIPE, SIG_IGN);

        dirname = mkdtemp(tmpname);
        snprintf(unix_listener, sizeof(unix_listener), "http://[unix://%s/_.sock]/proxy", dirname);
        if ((client_timeout_ms_str = getenv("H2O_FUZZER_CLIENT_TIMEOUT")) != NULL)
            client_timeout_ms = atoi(client_timeout_ms_str);
        if (!client_timeout_ms)
            client_timeout_ms = 10;

        /* Create a single h2o host with multiple request handlers */
        h2o_config_init(&config);
        config.http2.idle_timeout = 10 * 1000;
        config.http1.req_timeout = 10 * 1000;
        config.proxy.io_timeout = 10 * 1000;
        h2o_proxy_config_vars_t proxy_config = {};
        proxy_config.io_timeout = 10 * 1000;
        hostconf = h2o_config_register_host(&config, h2o_iovec_init(H2O_STRLIT(unix_listener)), 65535);
        register_handler(hostconf, "/chunked-test", chunked_test);
        h2o_url_parse(unix_listener, strlen(unix_listener), &upstream);
        h2o_socketpool_t *sockpool = new h2o_socketpool_t();
        h2o_socketpool_target_t *target = h2o_socketpool_create_target(&upstream, NULL);
        h2o_socketpool_init_specific(sockpool, SIZE_MAX /* FIXME */, &target, 1, NULL);
        h2o_socketpool_set_timeout(sockpool, 2000);
        h2o_socketpool_set_ssl_ctx(sockpool, NULL);
        h2o_proxy_register_reverse_proxy(h2o_config_register_path(hostconf, "/reproxy-test", 0), &proxy_config, sockpool);
        h2o_file_register(h2o_config_register_path(hostconf, "/", 0), "./examples/doc_root", NULL, NULL, 0);

        loop = h2o_evloop_create();
        h2o_context_init(&ctx, loop, &config);

        accept_ctx.ctx = &ctx;
        accept_ctx.hosts = config.hosts;

        /* Create a thread to act as the HTTP client */
        if (socketpair(AF_UNIX, SOCK_STREAM, 0, job_queue) != 0) {
            abort();
        }
        if (pthread_create(&twriter, NULL, writer_thread, (void *)(long)job_queue[1]) != 0) {
            abort();
        }
        if (pthread_create(&tupstream, NULL, upstream_thread, dirname) != 0) {
            abort();
        }
        init_done = 1;
    }

    /*
     * Pass fuzzed request to client thread and get h2o server socket for
     * use below
     */
    h2o_barrier_t *end;
    c = create_accepted(job_queue[0], (char *)Data, (size_t)Size, &end);
    if (c < 0) {
        goto Error;
    }

    /* Loop until the connection is closed by the client or server */
    while (is_valid_fd(c)) {
        h2o_evloop_run(ctx.loop, 10);
    }

    h2o_barrier_wait(end);
    return 0;
Error:
    return 1;
}
<|endoftext|>


<commit_before>/* Copyright (c) 2012 Research In Motion Limited.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "app.hpp"

#include <bb/cascades/AbstractPane>
#include <bb/cascades/Application>
#include <bb/cascades/QmlDocument>
#include <bb/data/JsonDataAccess>
#include <bb/cascades/ImageView>
#include <list>

using namespace bb::cascades;

//const char* const App::galleryUrl = "http://imgur.com/gallery/";
const char* const App::galleryUrl = "https://api.imgur.com/3/gallery/";
//https://api.imgur.com/3/gallery/hot/viral/0.json
//https://api.imgur.com/3/gallery/hot/viral/0.json

App::App(QObject *parent) :
		QObject(parent), m_model(new QListDataModel<QObject*>()), iml(NULL)
{
	// Register custom type to QML
	qmlRegisterType<AbstractLoader>();

	m_model->setParent(this);

	// Create the UI
	QmlDocument* qml = QmlDocument::create("asset:///main.qml").parent(this);
	qml->setContextProperty("_app", this);

	root = qml->createRootObject<AbstractPane>();

	Application::instance()->setScene(root);
}

void App::loadGallery(QString type, QString page)
{
	m_model->clear();
	emit modelChanged();

	// Creates the network request and sets the destination URL.
	const QUrl url(galleryUrl + type + "/viral/page/" + page + ".json");
	loadJson(url);
}

void App::loadJson(QUrl url)
{
	QNetworkRequest request(url);
	request.setRawHeader("Authorization", ImageLoader::clientId);

	QSslConfiguration sslConfig = request.sslConfiguration();
	sslConfig.setPeerVerifyMode(QSslSocket::VerifyNone);
	sslConfig.setPeerVerifyDepth(1);
	sslConfig.setProtocol(QSsl::TlsV1);
	sslConfig.setSslOption(QSsl::SslOptionDisableSessionTickets, true);

	request.setSslConfiguration(sslConfig);

	// Creates the network access manager and connects a custom slot to its finished signal
	QNetworkAccessManager *networkAccessManager = new QNetworkAccessManager(this);
	connect(networkAccessManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(jsonReceived(QNetworkReply*)));

	// Sends the HTTP request.
	networkAccessManager->get(request);
}

void App::loadBigImage(QVariantList indexPath)
{
	this->currentIndex = indexPath;

	QObject* o = qvariant_cast<QObject*>(m_model->data(indexPath));
	AbstractLoader *bigImage = qobject_cast<AbstractLoader*>(o);
	if (bigImage->type() == 0)
	{
		iml = new ImageLoader(bigImage->origImageUrl(), bigImage->origImageUrl(), bigImage->title(), this);
		connect(iml, SIGNAL(titleChanged()), this, SLOT(displayImage()));
		iml->load();
	}
	else
	{
		// hm, this is not an image, instead something different
		// -> lets get the next level of json infos
		QUrl url(bigImage->origImageUrl());
		loadJson(url);
	}
}

void App::loadNext()
{
	int currentSize = this->currentIndex[0].toInt();
	if (currentSize < m_model->size() - 1)
	{
		this->currentIndex[0].setValue(currentSize + 1);
		loadBigImage(this->currentIndex);
	}
}

void App::loadImages()
{
	// Call the load() method for each ImageLoader instance inside the model
	qDebug() << "FMI ######## model size:" << m_model->size();
	for (int row = 0; row < m_model->size(); ++row)
	{
		qDebug() << "FMI ######## load picture " << row;
		qobject_cast<AbstractLoader*>(m_model->value(row))->load();
	}
}

bb::cascades::DataModel* App::model() const
{
	return m_model;
}

/*
 * Received gallery json file, now parse the data
 */
void App::jsonReceived(QNetworkReply * reply)
{
	bb::data::JsonDataAccess jda;

	if (reply->error() == QNetworkReply::NoError)
	{
		int available = reply->bytesAvailable();
		QString replyString;

		if (available > 0)
		{
			int bufSize = sizeof(char) * available + sizeof(char);
			QByteArray buffer(bufSize, 0);
			reply->read(buffer.data(), available);
			replyString = QString::fromUtf8(buffer);
		}
		qDebug() << replyString;

		QVariantMap jsonva = jda.loadFromBuffer(replyString).toMap();
		QVariantList jsonvaList = jsonva.find("data")->toList();

		if (jda.hasError())
		{
			bb::data::DataAccessError error = jda.error();
			qDebug() << "JSON loading error: " << error.errorType() << ": " << error.errorMessage();
			return;
		}

		// iterate list
		int i = 0;
		for (QList<QVariant>::iterator it = jsonvaList.begin(); (it != jsonvaList.end() && i < 10); it++)
		{
			QVariantMap image = it->toMap();
			QString title = image["title"].toString();
			bool is_album = image["is_album"].toBool();
			QString link = image["link"].toString();
			QString linkLittle = image["link"].toString().insert(link.length() - 4, "b");

			qDebug() << "FMI ######### adding " << link;
			if (!is_album)
			{
				m_model->append(new ImageLoader(linkLittle, link, title, this));
			}
			else
			{
				if (image.find("images") != image.end())
				{
					std::list<AlbumPic*> *albumPics = 0;
					// we are already in an album, not in the gallery
					QVariantList jsonAlbumList = image.find("images")->toList();
					for (QList<QVariant>::iterator ait = jsonAlbumList.begin(); ait != jsonAlbumList.end(); ait++)
					{
						QVariantMap albumImage = ait->toMap();

						QString description = albumImage["description"].toString();
						QString albumPicUrl = albumImage["link"].toString();
						albumPics->push_back(new AlbumPic(albumPicUrl, description));
					}
					m_model->append(new AlbumLoader(albumPics, link, link, title, this));
				}
				else
				{
					m_model->append(new AlbumLoader(linkLittle, link, title, this));
				}
			}
			i++;
		}
	}
	else
		qDebug() << "FMI ######### error: " << reply->errorString();

	reply->deleteLater();
	loadImages();
}

QVariant App::image() const
{
	QVariant result = "";
	if (iml)
	{ // check pointer
		result = iml->image();
	}

	return result;
}

QString App::imageTitle() const
{
	QString result = "";
	if (iml)
	{ // check pointer
		result = iml->title();
	}

	return result;
}

QUrl App::imageUrl() const
{
	QUrl result;
	if (iml)
	{ // check pointer
		result.setUrl(iml->origImageUrl());
	}
	qDebug() << "FMI ########## ------------  result1:" << result;

	return result;
}

int App::type() const
{
	int result;
	if (iml)
	{ // check pointer
		result = iml->type();
	}
	qDebug() << "FMI ########## ------------  result2:" << result;

	return result;
}

void App::displayImage()
{
	emit imageChanged();
	emit imageTitleChanged();
	emit imageUrlChanged();
}
<commit_msg>working without albums<commit_after>/* Copyright (c) 2012 Research In Motion Limited.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "app.hpp"

#include <bb/cascades/AbstractPane>
#include <bb/cascades/Application>
#include <bb/cascades/QmlDocument>
#include <bb/data/JsonDataAccess>
#include <bb/cascades/ImageView>
#include <list>

using namespace bb::cascades;

//const char* const App::galleryUrl = "http://imgur.com/gallery/";
const char* const App::galleryUrl = "https://api.imgur.com/3/gallery/";
//https://api.imgur.com/3/gallery/hot/viral/0.json
//https://api.imgur.com/3/gallery/hot/viral/0.json

App::App(QObject *parent) :
		QObject(parent), m_model(new QListDataModel<QObject*>()), iml(NULL)
{
	// Register custom type to QML
	qmlRegisterType<AbstractLoader>();

	m_model->setParent(this);

	// Create the UI
	QmlDocument* qml = QmlDocument::create("asset:///main.qml").parent(this);
	qml->setContextProperty("_app", this);

	root = qml->createRootObject<AbstractPane>();

	Application::instance()->setScene(root);
}

void App::loadGallery(QString type, QString page)
{
	m_model->clear();
	emit modelChanged();

	// Creates the network request and sets the destination URL.
	const QUrl url(galleryUrl + type + "/viral/page/" + page + ".json");
	loadJson(url);
}

void App::loadJson(QUrl url)
{
	QNetworkRequest request(url);
	request.setRawHeader("Authorization", ImageLoader::clientId);

	QSslConfiguration sslConfig = request.sslConfiguration();
	sslConfig.setPeerVerifyMode(QSslSocket::VerifyNone);
	sslConfig.setPeerVerifyDepth(1);
	sslConfig.setProtocol(QSsl::TlsV1);
	sslConfig.setSslOption(QSsl::SslOptionDisableSessionTickets, true);

	request.setSslConfiguration(sslConfig);

	// Creates the network access manager and connects a custom slot to its finished signal
	QNetworkAccessManager *networkAccessManager = new QNetworkAccessManager(this);
	connect(networkAccessManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(jsonReceived(QNetworkReply*)));

	// Sends the HTTP request.
	networkAccessManager->get(request);
}

void App::loadBigImage(QVariantList indexPath)
{
	this->currentIndex = indexPath;

	QObject* o = qvariant_cast<QObject*>(m_model->data(indexPath));
	AbstractLoader *bigImage = qobject_cast<AbstractLoader*>(o);
	if (bigImage->type() == 0)
	{
		iml = new ImageLoader(bigImage->origImageUrl(), bigImage->origImageUrl(), bigImage->title(), this);
		connect(iml, SIGNAL(titleChanged()), this, SLOT(displayImage()));
		iml->load();
	}
//	else
//	{
//		// hm, this is not an image, instead something different
//		// -> lets get the next level of json infos
//		QUrl url(bigImage->origImageUrl());
//		loadJson(url);
//	}
}

void App::loadNext()
{
	int currentSize = this->currentIndex[0].toInt();
	if (currentSize < m_model->size() - 1)
	{
		this->currentIndex[0].setValue(currentSize + 1);
		loadBigImage(this->currentIndex);
	}
}

void App::loadImages()
{
	// Call the load() method for each ImageLoader instance inside the model
	qDebug() << "FMI ######## model size:" << m_model->size();
	for (int row = 0; row < m_model->size(); ++row)
	{
		qDebug() << "FMI ######## load picture " << row;
		qobject_cast<AbstractLoader*>(m_model->value(row))->load();
	}
}

bb::cascades::DataModel* App::model() const
{
	return m_model;
}

/*
 * Received gallery json file, now parse the data
 */
void App::jsonReceived(QNetworkReply * reply)
{
	bb::data::JsonDataAccess jda;

	if (reply->error() == QNetworkReply::NoError)
	{
		int available = reply->bytesAvailable();
		QString replyString;

		if (available > 0)
		{
			int bufSize = sizeof(char) * available + sizeof(char);
			QByteArray buffer(bufSize, 0);
			reply->read(buffer.data(), available);
			replyString = QString::fromUtf8(buffer);
		}
		qDebug() << replyString;

		QVariantMap jsonva = jda.loadFromBuffer(replyString).toMap();
		QVariantList jsonvaList = jsonva.find("data")->toList();

		if (jda.hasError())
		{
			bb::data::DataAccessError error = jda.error();
			qDebug() << "JSON loading error: " << error.errorType() << ": " << error.errorMessage();
			return;
		}

		// iterate list
		int i = 0;
		for (QList<QVariant>::iterator it = jsonvaList.begin(); (it != jsonvaList.end() && i < 10); it++)
		{
			QVariantMap image = it->toMap();
			QString title = image["title"].toString();
			bool is_album = image["is_album"].toBool();
			QString link = image["link"].toString();
			QString linkLittle = image["link"].toString().insert(link.length() - 4, "b");

			qDebug() << "FMI ######### adding " << link;
			if (!is_album)
			{
				m_model->append(new ImageLoader(linkLittle, link, title, this));
			}
//			else
//			{
//				if (image.find("images") != image.end())
//				{
//					std::list<AlbumPic*> *albumPics = 0;
//					// we are already in an album, not in the gallery
//					QVariantList jsonAlbumList = image.find("images")->toList();
//					for (QList<QVariant>::iterator ait = jsonAlbumList.begin(); ait != jsonAlbumList.end(); ait++)
//					{
//						QVariantMap albumImage = ait->toMap();
//
//						QString description = albumImage["description"].toString();
//						QString albumPicUrl = albumImage["link"].toString();
//						albumPics->push_back(new AlbumPic(albumPicUrl, description));
//					}
//					m_model->append(new AlbumLoader(albumPics, link, link, title, this));
//				}
//				else
//				{
//					m_model->append(new AlbumLoader(linkLittle, link, title, this));
//				}
//			}
			i++;
		}
	}
	else
		qDebug() << "FMI ######### error: " << reply->errorString();

	reply->deleteLater();
	loadImages();
}

QVariant App::image() const
{
	QVariant result = "";
	if (iml)
	{ // check pointer
		result = iml->image();
	}

	return result;
}

QString App::imageTitle() const
{
	QString result = "";
	if (iml)
	{ // check pointer
		result = iml->title();
	}

	return result;
}

QUrl App::imageUrl() const
{
	QUrl result;
	if (iml)
	{ // check pointer
		result.setUrl(iml->origImageUrl());
	}
	qDebug() << "FMI ########## ------------  result1:" << result;

	return result;
}

int App::type() const
{
	int result;
	if (iml)
	{ // check pointer
		result = iml->type();
	}
	qDebug() << "FMI ########## ------------  result2:" << result;

	return result;
}

void App::displayImage()
{
	emit imageChanged();
	emit imageTitleChanged();
	emit imageUrlChanged();
}
<|endoftext|>


<commit_before><commit_msg>Use more useful floating point format in debug output<commit_after><|endoftext|>


<commit_before>// SciTE - Scintilla based Text Editor
/** @file GUIGTK.cxx
 ** Interface to platform GUI facilities.
 ** Split off from Scintilla's Platform.h to avoid SciTE depending on implementation of Scintilla.
 **/
// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

#include <time.h>

#include <string>

#include <gtk/gtk.h>

#include "Scintilla.h"
#include "ScintillaWidget.h"

#include "GUI.h"

namespace GUI {

gui_string StringFromUTF8(const char *s) {
	if (s)
		return gui_string(s);
	else
		return gui_string("");
}

std::string UTF8FromString(const gui_string &s) {
	return s;
}

gui_string StringFromInteger(int i) {
	char number[32];
	sprintf(number, "%0d", i);
	return gui_string(number);
}

static GtkWidget *PWidget(WindowID wid) {
	return reinterpret_cast<GtkWidget *>(wid);
}

void Window::Destroy() {
	if (wid)
		gtk_widget_destroy(GTK_WIDGET(wid));
	wid = 0;
}

bool Window::HasFocus() {
	return GTK_WIDGET_HAS_FOCUS(wid);
}

Rectangle Window::GetPosition() {
	// Before any size allocated pretend its 1000 wide so not scrolled
	Rectangle rc(0, 0, 1000, 1000);
	if (wid) {
		rc.left = PWidget(wid)->allocation.x;
		rc.top = PWidget(wid)->allocation.y;
		if (PWidget(wid)->allocation.width > 20) {
			rc.right = rc.left + PWidget(wid)->allocation.width;
			rc.bottom = rc.top + PWidget(wid)->allocation.height;
		}
	}
	return rc;
}

void Window::SetPosition(Rectangle rc) {
	GtkAllocation alloc;
	alloc.x = rc.left;
	alloc.y = rc.top;
	alloc.width = rc.Width();
	alloc.height = rc.Height();
	gtk_widget_size_allocate(PWidget(wid), &alloc);
}

Rectangle Window::GetClientPosition() {
	// On GTK+, the client position is the window position
	return GetPosition();
}

void Window::Show(bool show) {
	if (show)
		gtk_widget_show(PWidget(wid));
}

void Window::InvalidateAll() {
	if (wid) {
		gtk_widget_queue_draw(PWidget(wid));
	}
}

void Window::SetTitle(const char *s) {
	gtk_window_set_title(GTK_WINDOW(wid), s);
}

void Menu::CreatePopUp() {
	Destroy();
	mid = gtk_menu_new();
	g_object_ref_sink(G_OBJECT(mid));
}

void Menu::Destroy() {
	if (mid)
		g_object_unref(mid);
	mid = 0;
}

static void  MenuPositionFunc(GtkMenu *, gint *x, gint *y, gboolean *, gpointer userData) {
	sptr_t intFromPointer = reinterpret_cast<sptr_t>(userData);
	*x = intFromPointer & 0xffff;
	*y = intFromPointer >> 16;
}

void Menu::Show(Point pt, Window &) {
	int screenHeight = gdk_screen_height();
	int screenWidth = gdk_screen_width();
	GtkMenu *widget = reinterpret_cast<GtkMenu *>(mid);
	gtk_widget_show_all(GTK_WIDGET(widget));
	GtkRequisition requisition;
	gtk_widget_size_request(GTK_WIDGET(widget), &requisition);
	if ((pt.x + requisition.width) > screenWidth) {
		pt.x = screenWidth - requisition.width;
	}
	if ((pt.y + requisition.height) > screenHeight) {
		pt.y = screenHeight - requisition.height;
	}
	gtk_menu_popup(widget, NULL, NULL, MenuPositionFunc,
		reinterpret_cast<void *>((pt.y << 16) | pt.x), 0,
		gtk_get_current_event_time());
}

ElapsedTime::ElapsedTime() {
	GTimeVal curTime;
	g_get_current_time(&curTime);
	bigBit = curTime.tv_sec;
	littleBit = curTime.tv_usec;
}

double ElapsedTime::Duration(bool reset) {
	GTimeVal curTime;
	g_get_current_time(&curTime);
	long endBigBit = curTime.tv_sec;
	long endLittleBit = curTime.tv_usec;
	double result = 1000000.0 * (endBigBit - bigBit);
	result += endLittleBit - littleBit;
	result /= 1000000.0;
	if (reset) {
		bigBit = endBigBit;
		littleBit = endLittleBit;
	}
	return result;
}

sptr_t ScintillaWindow::Send(unsigned int msg, uptr_t wParam, sptr_t lParam) {
	return scintilla_send_message(SCINTILLA(GetID()), msg, wParam, lParam);
}

sptr_t ScintillaWindow::SendPointer(unsigned int msg, uptr_t wParam, void *lParam) {
	return scintilla_send_message(SCINTILLA(GetID()), msg, wParam, reinterpret_cast<sptr_t>(lParam));
}

bool IsDBCSLeadByte(int codePage, char ch) {
	// Byte ranges found in Wikipedia articles with relevant search strings in each case
	unsigned char uch = static_cast<unsigned char>(ch);
	switch (codePage) {
		case 932:
			// Shift_jis
			return ((uch >= 0x81) && (uch <= 0x9F)) ||
				((uch >= 0xE0) && (uch <= 0xEF));
		case 936:
			// GBK
			return (uch >= 0x81) && (uch <= 0xFE);
		case 950:
			// Big5
			return (uch >= 0x81) && (uch <= 0xFE);
		// Korean EUC-KR may be code page 949.
	}
	return false;
}

}
<commit_msg>Allow building on GTK+ versions before 2.10.<commit_after>// SciTE - Scintilla based Text Editor
/** @file GUIGTK.cxx
 ** Interface to platform GUI facilities.
 ** Split off from Scintilla's Platform.h to avoid SciTE depending on implementation of Scintilla.
 **/
// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

#include <time.h>

#include <string>

#include <gtk/gtk.h>

#include "Scintilla.h"
#include "ScintillaWidget.h"

#include "GUI.h"

namespace GUI {

gui_string StringFromUTF8(const char *s) {
	if (s)
		return gui_string(s);
	else
		return gui_string("");
}

std::string UTF8FromString(const gui_string &s) {
	return s;
}

gui_string StringFromInteger(int i) {
	char number[32];
	sprintf(number, "%0d", i);
	return gui_string(number);
}

static GtkWidget *PWidget(WindowID wid) {
	return reinterpret_cast<GtkWidget *>(wid);
}

void Window::Destroy() {
	if (wid)
		gtk_widget_destroy(GTK_WIDGET(wid));
	wid = 0;
}

bool Window::HasFocus() {
	return GTK_WIDGET_HAS_FOCUS(wid);
}

Rectangle Window::GetPosition() {
	// Before any size allocated pretend its 1000 wide so not scrolled
	Rectangle rc(0, 0, 1000, 1000);
	if (wid) {
		rc.left = PWidget(wid)->allocation.x;
		rc.top = PWidget(wid)->allocation.y;
		if (PWidget(wid)->allocation.width > 20) {
			rc.right = rc.left + PWidget(wid)->allocation.width;
			rc.bottom = rc.top + PWidget(wid)->allocation.height;
		}
	}
	return rc;
}

void Window::SetPosition(Rectangle rc) {
	GtkAllocation alloc;
	alloc.x = rc.left;
	alloc.y = rc.top;
	alloc.width = rc.Width();
	alloc.height = rc.Height();
	gtk_widget_size_allocate(PWidget(wid), &alloc);
}

Rectangle Window::GetClientPosition() {
	// On GTK+, the client position is the window position
	return GetPosition();
}

void Window::Show(bool show) {
	if (show)
		gtk_widget_show(PWidget(wid));
}

void Window::InvalidateAll() {
	if (wid) {
		gtk_widget_queue_draw(PWidget(wid));
	}
}

void Window::SetTitle(const char *s) {
	gtk_window_set_title(GTK_WINDOW(wid), s);
}

void Menu::CreatePopUp() {
	Destroy();
	mid = gtk_menu_new();
#if GLIB_CHECK_VERSION(2,10,0)
	 g_object_ref_sink(G_OBJECT(mid));
#else
	g_object_ref(G_OBJECT(mid));
	gtk_object_sink(GTK_OBJECT(G_OBJECT(mid)));
#endif
}

void Menu::Destroy() {
	if (mid)
		g_object_unref(mid);
	mid = 0;
}

static void  MenuPositionFunc(GtkMenu *, gint *x, gint *y, gboolean *, gpointer userData) {
	sptr_t intFromPointer = reinterpret_cast<sptr_t>(userData);
	*x = intFromPointer & 0xffff;
	*y = intFromPointer >> 16;
}

void Menu::Show(Point pt, Window &) {
	int screenHeight = gdk_screen_height();
	int screenWidth = gdk_screen_width();
	GtkMenu *widget = reinterpret_cast<GtkMenu *>(mid);
	gtk_widget_show_all(GTK_WIDGET(widget));
	GtkRequisition requisition;
	gtk_widget_size_request(GTK_WIDGET(widget), &requisition);
	if ((pt.x + requisition.width) > screenWidth) {
		pt.x = screenWidth - requisition.width;
	}
	if ((pt.y + requisition.height) > screenHeight) {
		pt.y = screenHeight - requisition.height;
	}
	gtk_menu_popup(widget, NULL, NULL, MenuPositionFunc,
		reinterpret_cast<void *>((pt.y << 16) | pt.x), 0,
		gtk_get_current_event_time());
}

ElapsedTime::ElapsedTime() {
	GTimeVal curTime;
	g_get_current_time(&curTime);
	bigBit = curTime.tv_sec;
	littleBit = curTime.tv_usec;
}

double ElapsedTime::Duration(bool reset) {
	GTimeVal curTime;
	g_get_current_time(&curTime);
	long endBigBit = curTime.tv_sec;
	long endLittleBit = curTime.tv_usec;
	double result = 1000000.0 * (endBigBit - bigBit);
	result += endLittleBit - littleBit;
	result /= 1000000.0;
	if (reset) {
		bigBit = endBigBit;
		littleBit = endLittleBit;
	}
	return result;
}

sptr_t ScintillaWindow::Send(unsigned int msg, uptr_t wParam, sptr_t lParam) {
	return scintilla_send_message(SCINTILLA(GetID()), msg, wParam, lParam);
}

sptr_t ScintillaWindow::SendPointer(unsigned int msg, uptr_t wParam, void *lParam) {
	return scintilla_send_message(SCINTILLA(GetID()), msg, wParam, reinterpret_cast<sptr_t>(lParam));
}

bool IsDBCSLeadByte(int codePage, char ch) {
	// Byte ranges found in Wikipedia articles with relevant search strings in each case
	unsigned char uch = static_cast<unsigned char>(ch);
	switch (codePage) {
		case 932:
			// Shift_jis
			return ((uch >= 0x81) && (uch <= 0x9F)) ||
				((uch >= 0xE0) && (uch <= 0xEF));
		case 936:
			// GBK
			return (uch >= 0x81) && (uch <= 0xFE);
		case 950:
			// Big5
			return (uch >= 0x81) && (uch <= 0xFE);
		// Korean EUC-KR may be code page 949.
	}
	return false;
}

}
<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
#if !defined(SOLARISDEFINITIONS_HEADER_GUARD_1357924680)
#define SOLARISDEFINITIONS_HEADER_GUARD_1357924680

// ---------------------------------------------------------------------------
//  A define in the build for each project is also used to control whether
//  the export keyword is from the project's viewpoint or the client's.
//  These defines provide the platform specific keywords that they need
//  to do this.
// ---------------------------------------------------------------------------
#define XALAN_PLATFORM_EXPORT
#define XALAN_PLATFORM_IMPORT
#define XALAN_PLATFORM_EXPORT_FUNCTION(T) T XALAN_PLATFORM_EXPORT
#define XALAN_PLATFORM_IMPORT_FUNCTION(T) T XALAN_PLATFORM_IMPORT

#if __SUNPRO_CC_COMPAT >= 5

#define XALAN_SIZE_T_IN_NAMESPACE_STD
#define XALAN_SIGNAL_IN_STD

// Standard allocators don't seem to work correctly with this compiler.
// I don't know if this is their bug, or ours...
#define XALAN_NO_STD_ALLOCATORS

#else

// Sun Workshop 4.2 _does_ support new cast syntax, but it's
// broken with extra cv-qualifiers, so we'll use old-style casts.
#define XALAN_OLD_STYLE_CASTS

// Standard allocators don't seem to work correctly with STLport.
// I don't know if this is their bug, or ours...
#define XALAN_NO_STD_ALLOCATORS

#define XALAN_STLPORT_STL
#define XALAN_NO_DEFAULT_BUILTIN_ARRAY_INITIALIZATION
#define XALAN_OLD_STREAMS
#define XALAN_NO_NAMESPACES
#define XALAN_NO_MUTABLE
#define XALAN_SGI_BASED_STL
#define XALAN_NO_MEMBER_TEMPLATES
#define XALAN_BOOL_AS_INT
#define XALAN_NO_DEFAULT_TEMPLATE_ARGUMENTS
#define XALAN_NO_COVARIANT_RETURN_TYPE

// STL Port Definitions
#define __STL_NO_SGI_IOSTREAMS
#define _REENTRANT
#include <stl/_config.h>

#endif

#define XALAN_NO_STD_NUMERIC_LIMITS
#define XALAN_XALANDOMCHAR_USHORT_MISMATCH
#define XALAN_POSIX2_AVAILABLE

#define XALAN_UNALIGNED

#endif	// SOLARISDEFINITIONS_HEADER_GUARD_1357924680
<commit_msg>Use a different macro to control compilation.  Fixes problem with earlier versions of the compiler which don't support certain language features.<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
#if !defined(SOLARISDEFINITIONS_HEADER_GUARD_1357924680)
#define SOLARISDEFINITIONS_HEADER_GUARD_1357924680

// ---------------------------------------------------------------------------
//  A define in the build for each project is also used to control whether
//  the export keyword is from the project's viewpoint or the client's.
//  These defines provide the platform specific keywords that they need
//  to do this.
// ---------------------------------------------------------------------------
#define XALAN_PLATFORM_EXPORT
#define XALAN_PLATFORM_IMPORT
#define XALAN_PLATFORM_EXPORT_FUNCTION(T) T XALAN_PLATFORM_EXPORT
#define XALAN_PLATFORM_IMPORT_FUNCTION(T) T XALAN_PLATFORM_IMPORT

#if __SUNPRO_CC >= 0x530

#define XALAN_SIZE_T_IN_NAMESPACE_STD
#define XALAN_SIGNAL_IN_STD

// Standard allocators don't seem to work correctly with this compiler.
// I don't know if this is their bug, or ours...
#define XALAN_NO_STD_ALLOCATORS

#else

// Sun Workshop 4.2 _does_ support new cast syntax, but it's
// broken with extra cv-qualifiers, so we'll use old-style casts.
#define XALAN_OLD_STYLE_CASTS

// Standard allocators don't seem to work correctly with STLport.
// I don't know if this is their bug, or ours...
#define XALAN_NO_STD_ALLOCATORS

#define XALAN_STLPORT_STL
#define XALAN_NO_DEFAULT_BUILTIN_ARRAY_INITIALIZATION
#define XALAN_OLD_STREAMS
#define XALAN_NO_NAMESPACES
#define XALAN_NO_MUTABLE
#define XALAN_SGI_BASED_STL
#define XALAN_NO_MEMBER_TEMPLATES
#define XALAN_BOOL_AS_INT
#define XALAN_NO_DEFAULT_TEMPLATE_ARGUMENTS
#define XALAN_NO_COVARIANT_RETURN_TYPE

// STL Port Definitions
#define __STL_NO_SGI_IOSTREAMS
#define _REENTRANT
#include <stl/_config.h>

#endif

#define XALAN_NO_STD_NUMERIC_LIMITS
#define XALAN_XALANDOMCHAR_USHORT_MISMATCH
#define XALAN_POSIX2_AVAILABLE

#define XALAN_UNALIGNED

#endif	// SOLARISDEFINITIONS_HEADER_GUARD_1357924680
<|endoftext|>


<commit_before>// Copyright 2013 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 "chrome/browser/chromeos/input_method/component_extension_ime_manager_impl.h"

#include "base/logging.h"
#include "chrome/browser/extensions/component_loader.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_system.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/common/extensions/extension_file_util.h"
#include "chrome/common/extensions/extension_l10n_util.h"
#include "chrome/common/extensions/extension_manifest_constants.h"
#include "content/public/browser/browser_thread.h"

namespace chromeos {

namespace {

struct WhitelistedComponentExtensionIME {
  const char* id;
  const char* path;
} whitelisted_component_extension[] = {
  {
    "fpfbhcjppmaeaijcidgiibchfbnhbelj",
    "/usr/share/chromeos-assets/input_methods/nacl_mozc",
  },
};

extensions::ComponentLoader* GetComponentLoader() {
  Profile* profile = ProfileManager::GetDefaultProfileOrOffTheRecord();
  extensions::ExtensionSystem* extension_system =
      extensions::ExtensionSystem::Get(profile);
  ExtensionService* extension_service = extension_system->extension_service();
  return extension_service->component_loader();
}
}  // namespace

ComponentExtensionIMEManagerImpl::ComponentExtensionIMEManagerImpl()
    : is_initialized_(false),
      weak_ptr_factory_(this) {
}

ComponentExtensionIMEManagerImpl::~ComponentExtensionIMEManagerImpl() {
}

std::vector<ComponentExtensionIME> ComponentExtensionIMEManagerImpl::ListIME() {
  DCHECK(thread_checker_.CalledOnValidThread());
  return component_extension_list_;
}

bool ComponentExtensionIMEManagerImpl::Load(const std::string& extension_id,
                                            const base::FilePath& file_path) {
  DCHECK(thread_checker_.CalledOnValidThread());
  if (loaded_extension_id_.find(extension_id) != loaded_extension_id_.end())
    return false;
  const std::string loaded_extension_id =
      GetComponentLoader()->AddOrReplace(file_path);
  DCHECK_EQ(loaded_extension_id, extension_id);
  loaded_extension_id_.insert(extension_id);
  return true;
}

bool ComponentExtensionIMEManagerImpl::Unload(const std::string& extension_id,
                                              const base::FilePath& file_path) {
  DCHECK(thread_checker_.CalledOnValidThread());
  if (loaded_extension_id_.find(extension_id) == loaded_extension_id_.end())
    return false;
  GetComponentLoader()->Remove(extension_id);
  loaded_extension_id_.erase(extension_id);
  return true;
}

scoped_ptr<DictionaryValue> ComponentExtensionIMEManagerImpl::GetManifest(
    const base::FilePath& file_path) {
  std::string error;
  scoped_ptr<DictionaryValue> manifest(
      extension_file_util::LoadManifest(file_path, &error));
  if (!manifest.get())
    LOG(ERROR) << "Failed at getting manifest";
  if (!extension_l10n_util::LocalizeExtension(file_path,
                                              manifest.get(),
                                              &error))
    LOG(ERROR) << "Localization failed";

  return manifest.Pass();
}

void ComponentExtensionIMEManagerImpl::Initialize(
    const scoped_refptr<base::SequencedTaskRunner>& file_task_runner,
    const base::Closure& callback) {
  DCHECK(!is_initialized_);
  std::vector<ComponentExtensionIME>* component_extension_ime_list
      = new std::vector<ComponentExtensionIME>;
  file_task_runner->PostTaskAndReply(
      FROM_HERE,
      base::Bind(&ComponentExtensionIMEManagerImpl::ReadComponentExtensionsInfo,
                 base::Unretained(component_extension_ime_list)),
      base::Bind(
          &ComponentExtensionIMEManagerImpl::OnReadComponentExtensionsInfo,
          weak_ptr_factory_.GetWeakPtr(),
          base::Owned(component_extension_ime_list),
          callback));
}

bool ComponentExtensionIMEManagerImpl::IsInitialized() {
  return is_initialized_;
}

// static
bool ComponentExtensionIMEManagerImpl::ReadEngineComponent(
    const DictionaryValue& dict,
    IBusComponent::EngineDescription* out) {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
  DCHECK(out);
  std::string type;
  if (!dict.GetString(extension_manifest_keys::kType, &type))
    return false;
  if (type != "ime")
    return false;
  if (!dict.GetString(extension_manifest_keys::kId, &out->engine_id))
    return false;
  if (!dict.GetString(extension_manifest_keys::kName, &out->display_name))
    return false;
  if (!dict.GetString(extension_manifest_keys::kLanguage, &out->language_code))
    return false;

  const ListValue* layouts = NULL;
  if (!dict.GetList(extension_manifest_keys::kLayouts, &layouts))
    return false;

  if (layouts->GetSize() > 0) {
    if (!layouts->GetString(0, &out->layout))
      return false;
  }
  return true;
}

// static
bool ComponentExtensionIMEManagerImpl::ReadExtensionInfo(
    const DictionaryValue& manifest,
    ComponentExtensionIME* out) {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
  if (!manifest.GetString(extension_manifest_keys::kDescription,
                          &out->description))
    return false;
  // TODO(nona): option page handling.
  return true;
}

// static
void ComponentExtensionIMEManagerImpl::ReadComponentExtensionsInfo(
    std::vector<ComponentExtensionIME>* out_imes) {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
  DCHECK(out_imes);
  for (size_t i = 0; i < arraysize(whitelisted_component_extension); ++i) {
    const base::FilePath extension_path = base::FilePath(
        whitelisted_component_extension[i].path);

    scoped_ptr<DictionaryValue> manifest = GetManifest(extension_path);
    if (!manifest.get())
      continue;

    ComponentExtensionIME component_ime;
    if (!ReadExtensionInfo(*manifest.get(), &component_ime))
      continue;

    const ListValue* component_list;
    if (!manifest->GetList(extension_manifest_keys::kInputComponents,
                           &component_list))
      continue;

    for (size_t i = 0; i < component_list->GetSize(); ++i) {
      const DictionaryValue* dictionary;
      if (!component_list->GetDictionary(i, &dictionary))
        continue;

      IBusComponent::EngineDescription engine;
      ReadEngineComponent(*dictionary, &engine);
      component_ime.engines.push_back(engine);
    }
    out_imes->push_back(component_ime);
  }
}

void ComponentExtensionIMEManagerImpl::OnReadComponentExtensionsInfo(
    std::vector<ComponentExtensionIME>* result,
    const base::Closure& callback) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK(result);
  component_extension_list_ = *result;
  is_initialized_ = true;
  callback.Run();
}

}  // namespace chromeos
<commit_msg>Avoid crash when the component extension is not exists.<commit_after>// Copyright 2013 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 "chrome/browser/chromeos/input_method/component_extension_ime_manager_impl.h"

#include "base/file_util.h"
#include "base/logging.h"
#include "chrome/browser/extensions/component_loader.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_system.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/common/extensions/extension_file_util.h"
#include "chrome/common/extensions/extension_l10n_util.h"
#include "chrome/common/extensions/extension_manifest_constants.h"
#include "content/public/browser/browser_thread.h"

namespace chromeos {

namespace {

struct WhitelistedComponentExtensionIME {
  const char* id;
  const char* path;
} whitelisted_component_extension[] = {
  {
    "fpfbhcjppmaeaijcidgiibchfbnhbelj",
    "/usr/share/chromeos-assets/input_methods/nacl_mozc",
  },
};

extensions::ComponentLoader* GetComponentLoader() {
  Profile* profile = ProfileManager::GetDefaultProfileOrOffTheRecord();
  extensions::ExtensionSystem* extension_system =
      extensions::ExtensionSystem::Get(profile);
  ExtensionService* extension_service = extension_system->extension_service();
  return extension_service->component_loader();
}
}  // namespace

ComponentExtensionIMEManagerImpl::ComponentExtensionIMEManagerImpl()
    : is_initialized_(false),
      weak_ptr_factory_(this) {
}

ComponentExtensionIMEManagerImpl::~ComponentExtensionIMEManagerImpl() {
}

std::vector<ComponentExtensionIME> ComponentExtensionIMEManagerImpl::ListIME() {
  DCHECK(thread_checker_.CalledOnValidThread());
  return component_extension_list_;
}

bool ComponentExtensionIMEManagerImpl::Load(const std::string& extension_id,
                                            const base::FilePath& file_path) {
  DCHECK(thread_checker_.CalledOnValidThread());
  if (loaded_extension_id_.find(extension_id) != loaded_extension_id_.end())
    return false;
  const std::string loaded_extension_id =
      GetComponentLoader()->AddOrReplace(file_path);
  DCHECK_EQ(loaded_extension_id, extension_id);
  loaded_extension_id_.insert(extension_id);
  return true;
}

bool ComponentExtensionIMEManagerImpl::Unload(const std::string& extension_id,
                                              const base::FilePath& file_path) {
  DCHECK(thread_checker_.CalledOnValidThread());
  if (loaded_extension_id_.find(extension_id) == loaded_extension_id_.end())
    return false;
  GetComponentLoader()->Remove(extension_id);
  loaded_extension_id_.erase(extension_id);
  return true;
}

scoped_ptr<DictionaryValue> ComponentExtensionIMEManagerImpl::GetManifest(
    const base::FilePath& file_path) {
  std::string error;
  scoped_ptr<DictionaryValue> manifest(
      extension_file_util::LoadManifest(file_path, &error));
  if (!manifest.get())
    LOG(ERROR) << "Failed at getting manifest";
  if (!extension_l10n_util::LocalizeExtension(file_path,
                                              manifest.get(),
                                              &error))
    LOG(ERROR) << "Localization failed";

  return manifest.Pass();
}

void ComponentExtensionIMEManagerImpl::Initialize(
    const scoped_refptr<base::SequencedTaskRunner>& file_task_runner,
    const base::Closure& callback) {
  DCHECK(!is_initialized_);
  std::vector<ComponentExtensionIME>* component_extension_ime_list
      = new std::vector<ComponentExtensionIME>;
  file_task_runner->PostTaskAndReply(
      FROM_HERE,
      base::Bind(&ComponentExtensionIMEManagerImpl::ReadComponentExtensionsInfo,
                 base::Unretained(component_extension_ime_list)),
      base::Bind(
          &ComponentExtensionIMEManagerImpl::OnReadComponentExtensionsInfo,
          weak_ptr_factory_.GetWeakPtr(),
          base::Owned(component_extension_ime_list),
          callback));
}

bool ComponentExtensionIMEManagerImpl::IsInitialized() {
  return is_initialized_;
}

// static
bool ComponentExtensionIMEManagerImpl::ReadEngineComponent(
    const DictionaryValue& dict,
    IBusComponent::EngineDescription* out) {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
  DCHECK(out);
  std::string type;
  if (!dict.GetString(extension_manifest_keys::kType, &type))
    return false;
  if (type != "ime")
    return false;
  if (!dict.GetString(extension_manifest_keys::kId, &out->engine_id))
    return false;
  if (!dict.GetString(extension_manifest_keys::kName, &out->display_name))
    return false;
  if (!dict.GetString(extension_manifest_keys::kLanguage, &out->language_code))
    return false;

  const ListValue* layouts = NULL;
  if (!dict.GetList(extension_manifest_keys::kLayouts, &layouts))
    return false;

  if (layouts->GetSize() > 0) {
    if (!layouts->GetString(0, &out->layout))
      return false;
  }
  return true;
}

// static
bool ComponentExtensionIMEManagerImpl::ReadExtensionInfo(
    const DictionaryValue& manifest,
    ComponentExtensionIME* out) {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
  if (!manifest.GetString(extension_manifest_keys::kDescription,
                          &out->description))
    return false;
  // TODO(nona): option page handling.
  return true;
}

// static
void ComponentExtensionIMEManagerImpl::ReadComponentExtensionsInfo(
    std::vector<ComponentExtensionIME>* out_imes) {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
  DCHECK(out_imes);
  for (size_t i = 0; i < arraysize(whitelisted_component_extension); ++i) {
    const base::FilePath extension_path = base::FilePath(
        whitelisted_component_extension[i].path);

    if (!file_util::PathExists(extension_path))
      continue;

    scoped_ptr<DictionaryValue> manifest = GetManifest(extension_path);
    if (!manifest.get())
      continue;

    ComponentExtensionIME component_ime;
    if (!ReadExtensionInfo(*manifest.get(), &component_ime))
      continue;

    const ListValue* component_list;
    if (!manifest->GetList(extension_manifest_keys::kInputComponents,
                           &component_list))
      continue;

    for (size_t i = 0; i < component_list->GetSize(); ++i) {
      const DictionaryValue* dictionary;
      if (!component_list->GetDictionary(i, &dictionary))
        continue;

      IBusComponent::EngineDescription engine;
      ReadEngineComponent(*dictionary, &engine);
      component_ime.engines.push_back(engine);
    }
    out_imes->push_back(component_ime);
  }
}

void ComponentExtensionIMEManagerImpl::OnReadComponentExtensionsInfo(
    std::vector<ComponentExtensionIME>* result,
    const base::Closure& callback) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK(result);
  component_extension_list_ = *result;
  is_initialized_ = true;
  callback.Run();
}

}  // namespace chromeos
<|endoftext|>


<commit_before>#include <ossim/elevation/ossimDtedElevationDatabase.h>
#include <ossim/base/ossimDirectory.h>
#include <ossim/base/ossimGeoidManager.h>
#include <ossim/base/ossimNotify.h>
#include <ossim/base/ossimPreferences.h>
#include <ossim/base/ossimTrace.h>
#include <sstream>
#include <iomanip>
#include <cstdlib> /* for abs(int) */

static ossimTrace traceDebug("ossimDtedElevationDatabase:debug");
RTTI_DEF1(ossimDtedElevationDatabase, "ossimDtedElevationDatabase", ossimElevationCellDatabase);

ossimDtedElevationDatabase::ossimDtedElevationDatabase()
   : ossimElevationCellDatabase(),
     m_extension(""),
     m_upcase(false),
     m_lastHandler(0),
     m_mutex()
{
}

ossimDtedElevationDatabase::ossimDtedElevationDatabase(const ossimDtedElevationDatabase& rhs)
   : ossimElevationCellDatabase(rhs),
     m_extension(rhs.m_extension),
     m_upcase(rhs.m_upcase),
     m_lastHandler(0), // Do not copy this to get a unique handler for thread.
     m_mutex()
{
}

ossimDtedElevationDatabase::~ossimDtedElevationDatabase()
{
}

ossimObject* ossimDtedElevationDatabase::dup() const
{
   ossimDtedElevationDatabase* duped = new ossimDtedElevationDatabase(*this);
   return duped;
}

double ossimDtedElevationDatabase::getHeightAboveMSL(const ossimGpt& gpt)
{
   if(!isSourceEnabled())
      return ossim::nan();
   std::lock_guard<std::mutex> lock(m_mutex);
   double result = ossim::nan();
   if(m_lastHandler.valid() && m_lastHandler->pointHasCoverage(gpt))
   {
      result = m_lastHandler->getHeightAboveMSL(gpt);
   }
   else
   {
      m_lastHandler = getOrCreateCellHandler(gpt);
      if(m_lastHandler.valid())
         result = m_lastHandler->getHeightAboveMSL(gpt);
   }

   return result;
}

double ossimDtedElevationDatabase::getHeightAboveEllipsoid(const ossimGpt& gpt)
{
   double h = getHeightAboveMSL(gpt);
   if(h != ossim::nan())
   {
      double offset = getOffsetFromEllipsoid(gpt);

      h += offset;
   }

   return h;
}
bool ossimDtedElevationDatabase::open(const ossimString& connectionString)
{
   bool result = false;
   ossimFilename file = ossimFilename(connectionString);

   result = openDtedDirectory(file);

   return result;
}

bool ossimDtedElevationDatabase::openDtedDirectory(const ossimFilename& dir)
{
   if(traceDebug())
   {
      ossimNotify(ossimNotifyLevel_DEBUG)
         << "ossimDtedElevationDatabase::open entered ...\n"
         << "dir: " << dir << "\n";
   }

   bool result = dir.isDir();
   if(result)
   {
      if ( m_extension.size() == 0 )
      {
         //---
         // This sets extension by doing a directory scan and is now depricated.
         // Use "extension" key in preferences to avoid this.  Example:
         // elevation_manager.elevation_source0.extension: dt2
         //---
         result = inititializeExtension( dir );
         if ( !result && traceDebug() )
         {
            ossimNotify(ossimNotifyLevel_DEBUG)
               << "ossimDtedElevationDatabase::open: WARNING "
               << "Scan for dted extension failed!\n"
               << "Can be set in ossim preferences.  Example:\n"
               << "elevation_manager.elevation_source0.extension: .dt2\n";
         }
      }

      // Set the geoid:
      if( !m_geoid.valid() )
      {
         m_geoid = ossimGeoidManager::instance()->findGeoidByShortName("geoid1996", false);
         if(!m_geoid.valid()&&traceDebug())
         {
            ossimNotify(ossimNotifyLevel_DEBUG)
               << "ossimDtedElevationDatabase::open: WARNING "
               << "Unable to load goeid grid 1996 for DTED database\n";
         }
      }

   }

   if(traceDebug())
   {
      ossimNotify(ossimNotifyLevel_DEBUG)
         << "ossimDtedElevationDatabase::open result:" << (result?"true":"false") << "\n";
   }
   return result;
}

bool ossimDtedElevationDatabase::getAccuracyInfo(ossimElevationAccuracyInfo& info, const ossimGpt& gpt) const
{
   bool result = false;

   m_mutex.lock();
   ossimDtedElevationDatabase* thisPtr = const_cast<ossimDtedElevationDatabase*>(this);
   ossimRefPtr<ossimElevCellHandler> tempHandler = thisPtr->getOrCreateCellHandler(gpt);
   m_mutex.unlock();

   if(tempHandler.valid())
   {
      result = tempHandler->getAccuracyInfo(info, gpt);
   }
  return result;
}

void ossimDtedElevationDatabase::createRelativePath(ossimFilename& file, const ossimGpt& gpt)const
{
   ossimFilename lon, lat;
   int ilon = static_cast<int>(floor(gpt.lond()));

   if (ilon < 0)
   {
      lon = m_upcase?"W":"w";
   }
   else
   {
      lon = m_upcase?"E":"e";
   }

   ilon = abs(ilon);
   std::ostringstream  s1;
   s1 << std::setfill('0') << std::setw(3)<< ilon;

   lon += s1.str().c_str();//ossimString::toString(ilon);

   int ilat =  static_cast<int>(floor(gpt.latd()));
   if (ilat < 0)
   {
      lat += m_upcase?"S":"s";
   }
   else
   {
      lat += m_upcase?"N":"n";
   }

   ilat = abs(ilat);
   std::ostringstream  s2;

   s2<< std::setfill('0') << std::setw(2)<< ilat;

   lat += s2.str().c_str();

   file = lon.dirCat(lat+m_extension);
}

ossimRefPtr<ossimElevCellHandler> ossimDtedElevationDatabase::createCell(const ossimGpt& gpt)
{
   ossimRefPtr<ossimElevCellHandler> result = 0;
   ossimFilename f;
   createFullPath(f, gpt);
   if(f.exists())
   {
      ossimRefPtr<ossimDtedHandler> h = new ossimDtedHandler(f, m_memoryMapCellsFlag);
      if (!(h->getErrorStatus()))
      {
         result = h.get();
      }
   }
   return result;
}

bool ossimDtedElevationDatabase::loadState(const ossimKeywordlist& kwl, const char* prefix )
{
   bool result = ossimElevationCellDatabase::loadState(kwl, prefix);
   if(result)
   {
      if(!m_connectionString.empty()&&ossimFilename(m_connectionString).exists())
      {
         // Look for "extension" keyword.
         std::string pref = (prefix?prefix:"");
         std::string key = "extension";
         ossimString val = ossimPreferences::instance()->preferencesKWL().findKey( pref, key );
         if ( val.size() )
         {
            if ( val.string()[0] != '.' )
            {
               m_extension = ".";
               m_extension += val;

               ossimNotify(ossimNotifyLevel_WARN)
                  << "\nossimDtedElevationDatabase::loadState: WARNING\n"
                  << "Key value for \"extension\" does not start with a dot!\n"
                  << "Consider changing \"" << val << "\" to \"" << m_extension << "\"\n"
                  << std::endl;
            }
            else
            {
               m_extension = val;
            }
         }
         else if ( traceDebug() )
         {
            ossimNotify(ossimNotifyLevel_DEBUG)
               << "\nossimDtedElevationDatabase::loadState: NOTICE\n"
               << "Key lookup for \"extension\" failed!\n"
               << "Can be set in ossim preferences.  Example:\n"
               << pref << key << ": .dt2\n\n";
         }

         key = "upcase";
         val = ossimPreferences::instance()->preferencesKWL().findKey( pref, key );
         if ( val.size() )
         {
            m_upcase = val.toBool();
         }
         else if ( traceDebug() )
         {
            ossimNotify(ossimNotifyLevel_DEBUG)
               << "\nossimDtedElevationDatabase::loadState: NOTICE\n"
               << "Key lookup for \"upcase\" failed!\n"
               << "Can be set in ossim preferences.  Example:\n"
               << pref << key << ": false\n\n";
         }

         result = open(m_connectionString);
      }
      else
      {
         // can't open the connection because it does not exists or empty
         result = false;
      }
   }

   return result;
}

bool ossimDtedElevationDatabase::saveState(ossimKeywordlist& kwl, const char* prefix)const
{
   kwl.add(prefix, "extension", m_extension, true);
   kwl.add(prefix, "upcase", m_upcase, true);

   bool result = ossimElevationCellDatabase::saveState(kwl, prefix);

   return result;
}

std::ostream& ossimDtedElevationDatabase::print(ostream& out) const
{
   ossimKeywordlist kwl;
   saveState(kwl);
   out << "\nossimDtedElevationDatabase @ "<< (ossim_uint64) this << "\n"
         << kwl <<ends;
   return out;
}

bool ossimDtedElevationDatabase::inititializeExtension( const ossimFilename& dir )
{
   ossim_uint32 count = 0;
   ossim_uint32 maxCount = 10;
   ossimDirectory od;
   bool result = od.open(dir);
   if(result)
   {
      result = false;
      ossimFilename f;
      // Get the first directory.
      od.getFirst(f, ossimDirectory::OSSIM_DIR_DIRS);

      do
      {
         ++count;
         // Must be a directory.
         if (f.isDir())
         {
            // Discard any full path.
            ossimFilename fileOnly = f.file();

            // Downcase it. Note have sites with upper case. (drb)
            // fileOnly.downcase();

            //---
            // Longitude subdir check:
            // Must start with 'e', 'E', 'w' or 'W'.
            //---
            bool foundCell = ( ( (fileOnly.c_str()[0] == 'e') ||
                                 (fileOnly.c_str()[0] == 'w') ||
                                 (fileOnly.c_str()[0] == 'E') ||
                                 (fileOnly.c_str()[0] == 'W') ) &&
                               (fileOnly.size() == 4));
            if(foundCell)
            {
               ossim_uint32 maxCount2 = 10;
               ossim_uint32 count2 = 0;
               ossimDirectory d2;

               // Open the longitude subdir:
               if(d2.open(f))
               {
                  d2.getFirst(f, ossimDirectory::OSSIM_DIR_FILES);
                  do
                  {
                     // The DTED directory may be polluted with cell statistics files and other
                     // non-DEM items. Skip if not of the expected extension (OLK 10/2017):
                     if (f.ext().match("[dD][tT][0-2]").empty())
                        continue;

                     ossimRefPtr<ossimDtedHandler> dtedHandler = new ossimDtedHandler();
                     if(dtedHandler->open(f, false))
                     {
                        if(traceDebug())
                        {
                           ossimNotify(ossimNotifyLevel_DEBUG)
                              << "ossimDtedElevationDatabase::open: Found dted file " << f << "\n";
                        }
                        result = true;
                        m_extension = "."+f.ext();
                        m_connectionString = dir;
                        m_meanSpacing = dtedHandler->getMeanSpacingMeters();
                     }
                     dtedHandler->close();
                     dtedHandler = 0;
                     ++count2;
                  } while(!result&&d2.getNext(f)&&(count2 < maxCount2));
               }
            }
         }
      } while(!result&&(od.getNext(f))&&(count < maxCount));
   }

   return result;

} // End: ossimDtedElevationDatabase::inititializeExtension( dir )
<commit_msg>Added comments<commit_after>#include <ossim/elevation/ossimDtedElevationDatabase.h>
#include <ossim/base/ossimDirectory.h>
#include <ossim/base/ossimGeoidManager.h>
#include <ossim/base/ossimNotify.h>
#include <ossim/base/ossimPreferences.h>
#include <ossim/base/ossimTrace.h>
#include <sstream>
#include <iomanip>
#include <cstdlib> /* for abs(int) */

static ossimTrace traceDebug("ossimDtedElevationDatabase:debug");
RTTI_DEF1(ossimDtedElevationDatabase, "ossimDtedElevationDatabase", ossimElevationCellDatabase);

ossimDtedElevationDatabase::ossimDtedElevationDatabase()
   : ossimElevationCellDatabase(),
     m_extension(""),
     m_upcase(false),
     m_lastHandler(0),
     m_mutex()
{
}

ossimDtedElevationDatabase::ossimDtedElevationDatabase(const ossimDtedElevationDatabase& rhs)
   : ossimElevationCellDatabase(rhs),
     m_extension(rhs.m_extension),
     m_upcase(rhs.m_upcase),
     m_lastHandler(0), // Do not copy this to get a unique handler for thread.
     m_mutex()
{
}

ossimDtedElevationDatabase::~ossimDtedElevationDatabase()
{
}

ossimObject* ossimDtedElevationDatabase::dup() const
{
   ossimDtedElevationDatabase* duped = new ossimDtedElevationDatabase(*this);
   return duped;
}

double ossimDtedElevationDatabase::getHeightAboveMSL(const ossimGpt& gpt)
{
   if(!isSourceEnabled())
      return ossim::nan();
   std::lock_guard<std::mutex> lock(m_mutex);
   double result = ossim::nan();
   if(m_lastHandler.valid() && m_lastHandler->pointHasCoverage(gpt))
   {
      result = m_lastHandler->getHeightAboveMSL(gpt);
   }
   else
   {
      m_lastHandler = getOrCreateCellHandler(gpt);
      if(m_lastHandler.valid())
         result = m_lastHandler->getHeightAboveMSL(gpt);
   }

   return result;
}

double ossimDtedElevationDatabase::getHeightAboveEllipsoid(const ossimGpt& gpt)
{
   double h = getHeightAboveMSL(gpt);
   if(h != ossim::nan())
   {
      double offset = getOffsetFromEllipsoid(gpt);

      h += offset;
   }

   return h;
}
bool ossimDtedElevationDatabase::open(const ossimString& connectionString)
{
   bool result = false;
   ossimFilename file = ossimFilename(connectionString);

   result = openDtedDirectory(file);

   return result;
}

bool ossimDtedElevationDatabase::openDtedDirectory(const ossimFilename& dir)
{
   if(traceDebug())
   {
      ossimNotify(ossimNotifyLevel_DEBUG)
         << "ossimDtedElevationDatabase::open entered ...\n"
         << "dir: " << dir << "\n";
   }

   bool result = dir.isDir();
   if(result)
   {
      if ( m_extension.size() == 0 )
      {
         //---
         // This sets extension by doing a directory scan for files with "dt*".
         // Use "extension" key in preferences to avoid this.  Example:
         // elevation_manager.elevation_source0.extension: dt2.
         //---
         result = inititializeExtension( dir );
         if ( !result && traceDebug() )
         {
            ossimNotify(ossimNotifyLevel_DEBUG)
               << "ossimDtedElevationDatabase::open: WARNING "
               << "Scan for dted extension failed!\n"
               << "Can be set in ossim preferences.  Example:\n"
               << "elevation_manager.elevation_source0.extension: .dt2\n";
         }
      }

      // Set the geoid:
      if( !m_geoid.valid() )
      {
         m_geoid = ossimGeoidManager::instance()->findGeoidByShortName("geoid1996", false);
         if(!m_geoid.valid()&&traceDebug())
         {
            ossimNotify(ossimNotifyLevel_DEBUG)
               << "ossimDtedElevationDatabase::open: WARNING "
               << "Unable to load goeid grid 1996 for DTED database\n";
         }
      }

   }

   if(traceDebug())
   {
      ossimNotify(ossimNotifyLevel_DEBUG)
         << "ossimDtedElevationDatabase::open result:" << (result?"true":"false") << "\n";
   }
   return result;
}

bool ossimDtedElevationDatabase::getAccuracyInfo(ossimElevationAccuracyInfo& info, const ossimGpt& gpt) const
{
   bool result = false;

   m_mutex.lock();
   ossimDtedElevationDatabase* thisPtr = const_cast<ossimDtedElevationDatabase*>(this);
   ossimRefPtr<ossimElevCellHandler> tempHandler = thisPtr->getOrCreateCellHandler(gpt);
   m_mutex.unlock();

   if(tempHandler.valid())
   {
      result = tempHandler->getAccuracyInfo(info, gpt);
   }
  return result;
}

void ossimDtedElevationDatabase::createRelativePath(ossimFilename& file, const ossimGpt& gpt)const
{
   ossimFilename lon, lat;
   int ilon = static_cast<int>(floor(gpt.lond()));

   if (ilon < 0)
   {
      lon = m_upcase?"W":"w";
   }
   else
   {
      lon = m_upcase?"E":"e";
   }

   ilon = abs(ilon);
   std::ostringstream  s1;
   s1 << std::setfill('0') << std::setw(3)<< ilon;

   lon += s1.str().c_str();//ossimString::toString(ilon);

   int ilat =  static_cast<int>(floor(gpt.latd()));
   if (ilat < 0)
   {
      lat += m_upcase?"S":"s";
   }
   else
   {
      lat += m_upcase?"N":"n";
   }

   ilat = abs(ilat);
   std::ostringstream  s2;

   s2<< std::setfill('0') << std::setw(2)<< ilat;

   lat += s2.str().c_str();

   file = lon.dirCat(lat+m_extension);
}

ossimRefPtr<ossimElevCellHandler> ossimDtedElevationDatabase::createCell(const ossimGpt& gpt)
{
   ossimRefPtr<ossimElevCellHandler> result = 0;
   ossimFilename f;
   createFullPath(f, gpt);
   if(f.exists())
   {
      ossimRefPtr<ossimDtedHandler> h = new ossimDtedHandler(f, m_memoryMapCellsFlag);
      if (!(h->getErrorStatus()))
      {
         result = h.get();
      }
   }
   return result;
}

bool ossimDtedElevationDatabase::loadState(const ossimKeywordlist& kwl, const char* prefix )
{
   bool result = ossimElevationCellDatabase::loadState(kwl, prefix);
   if(result)
   {
      if(!m_connectionString.empty()&&ossimFilename(m_connectionString).exists())
      {
         // Look for "extension" keyword.
         std::string pref = (prefix?prefix:"");
         std::string key = "extension";
         ossimString val = ossimPreferences::instance()->preferencesKWL().findKey( pref, key );
         if ( val.size() )
         {
            if ( val.string()[0] != '.' )
            {
               m_extension = ".";
               m_extension += val;

               ossimNotify(ossimNotifyLevel_WARN)
                  << "\nossimDtedElevationDatabase::loadState: WARNING\n"
                  << "Key value for \"extension\" does not start with a dot!\n"
                  << "Consider changing \"" << val << "\" to \"" << m_extension << "\"\n"
                  << std::endl;
            }
            else
            {
               m_extension = val;
            }
         }
         else if ( traceDebug() )
         {
            ossimNotify(ossimNotifyLevel_DEBUG)
               << "\nossimDtedElevationDatabase::loadState: NOTICE\n"
               << "Key lookup for \"extension\" failed!\n"
               << "Can be set in ossim preferences.  Example:\n"
               << pref << key << ": .dt2\n\n";
         }

         key = "upcase";
         val = ossimPreferences::instance()->preferencesKWL().findKey( pref, key );
         if ( val.size() )
         {
            m_upcase = val.toBool();
         }
         else if ( traceDebug() )
         {
            ossimNotify(ossimNotifyLevel_DEBUG)
               << "\nossimDtedElevationDatabase::loadState: NOTICE\n"
               << "Key lookup for \"upcase\" failed!\n"
               << "Can be set in ossim preferences.  Example:\n"
               << pref << key << ": false\n\n";
         }

         result = open(m_connectionString);
      }
      else
      {
         // can't open the connection because it does not exists or empty
         result = false;
      }
   }

   return result;
}

bool ossimDtedElevationDatabase::saveState(ossimKeywordlist& kwl, const char* prefix)const
{
   kwl.add(prefix, "extension", m_extension, true);
   kwl.add(prefix, "upcase", m_upcase, true);

   bool result = ossimElevationCellDatabase::saveState(kwl, prefix);

   return result;
}

std::ostream& ossimDtedElevationDatabase::print(ostream& out) const
{
   ossimKeywordlist kwl;
   saveState(kwl);
   out << "\nossimDtedElevationDatabase @ "<< (ossim_uint64) this << "\n"
         << kwl <<ends;
   return out;
}

bool ossimDtedElevationDatabase::inititializeExtension( const ossimFilename& dir )
{
   ossim_uint32 count = 0;
   ossim_uint32 maxCount = 10;
   ossimDirectory od;
   bool result = od.open(dir);
   if(result)
   {
      result = false;
      ossimFilename f;
      // Get the first directory.
      od.getFirst(f, ossimDirectory::OSSIM_DIR_DIRS);

      do
      {
         ++count;
         // Must be a directory.
         if (f.isDir())
         {
            // Discard any full path.
            ossimFilename fileOnly = f.file();

            // Downcase it. Note have sites with upper case. (drb)
            // fileOnly.downcase();

            //---
            // Longitude subdir check:
            // Must start with 'e', 'E', 'w' or 'W'.
            //---
            bool foundCell = ( ( (fileOnly.c_str()[0] == 'e') ||
                                 (fileOnly.c_str()[0] == 'w') ||
                                 (fileOnly.c_str()[0] == 'E') ||
                                 (fileOnly.c_str()[0] == 'W') ) &&
                               (fileOnly.size() == 4));
            if(foundCell)
            {
               ossim_uint32 maxCount2 = 10;
               ossim_uint32 count2 = 0;
               ossimDirectory d2;

               // Open the longitude subdir:
               if(d2.open(f))
               {
                  d2.getFirst(f, ossimDirectory::OSSIM_DIR_FILES);
                  do
                  {
                     // The DTED directory may be polluted with cell statistics files and other
                     // non-DEM items. Skip if not of the expected extension (OLK 10/2017):
                     if (f.ext().match("[dD][tT][0-2]").empty())
                        continue;

                     ossimRefPtr<ossimDtedHandler> dtedHandler = new ossimDtedHandler();
                     if(dtedHandler->open(f, false))
                     {
                        if(traceDebug())
                        {
                           ossimNotify(ossimNotifyLevel_DEBUG)
                              << "ossimDtedElevationDatabase::open: Found dted file " << f << "\n";
                        }
                        result = true;
                        m_extension = "."+f.ext();
                        m_connectionString = dir;
                        m_meanSpacing = dtedHandler->getMeanSpacingMeters();
                     }
                     dtedHandler->close();
                     dtedHandler = 0;
                     ++count2;
                  } while(!result&&d2.getNext(f)&&(count2 < maxCount2));
               }
            }
         }
      } while(!result&&(od.getNext(f))&&(count < maxCount));
   }

   return result;

} // End: ossimDtedElevationDatabase::inititializeExtension( dir )
<|endoftext|>


<commit_before>float rotx, roty, rotz;

class Player{
	public:
	float x,y,z;
	float lookat_x,lookat_y,lookat_z;
};

class Level{
	private:
	string cur_level_path;
	string cur_level;
	Model_OBJ *room;
	Model_OBJ *inv;
	Model_OBJ *player;
	int g_rotation;
	Player *p;
	bool flipped;

	public:
	Level(string &l);
	void display();
	void keyPress(unsigned char ch, int x, int y);
	void specialKeyPress(int key, int x, int y);
	void flip();
};
void Level::flip()
{
	flipped = !flipped;
}

Level::Level(string &l)
{
	cur_level = l;
	cur_level_path = "../rooms/" + l +"_alt.obj";
	inv = new Model_OBJ;
	player = new Model_OBJ;
	room = new Model_OBJ;
	inv->Load("../rooms/Level_1.obj");
	player->Load("../models/Tux.obj");
	room->Load(&cur_level_path[0]);	//&cur_level_path[0]  might avoid warning but is it safe?
	g_rotation = 0;
	p = new Player;
	p->x = 0; p->y = -1; p->z = -3;
	p->lookat_x = 0; p->lookat_y = 1; p->lookat_z = 0;
}

void Level::display()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();
	glRotatef(roty, 0, 1, 0);
	glRotatef(rotx, 1, 0, 0);
	glTranslatef(p->x,p->y,p->z);
	player->Draw();
	if(flipped){
		glRotatef(180,1,0,0);
	}
	//gluLookAt( p->x,p->y,p->z - 2, p->lookat_x + p->x,p->lookat_y,p->lookat_z +p->z, 0,1,0);
	room->Draw();
	glRotatef(180,1,0,0);
	inv->Draw();
	glutSwapBuffers();
	glFlush();
}

void Level::keyPress(unsigned char key, int x, int y)
{
	cout<<key<<endl;
	//normal key press events
	if( key == 'w')
	{
		p->z+=0.3;
	}
	else if( key == 's')
	{
		p->z-=0.3;
	}
	else if(key == 'a')
	{
		p->x+=0.3;
	}
	else if(key == 'd')
	{
		p->x-=0.3;
	}
	else if(key == 'q')
	{
		flip();
	}
	glutPostRedisplay();
}

void Level::specialKeyPress(int key,int x,int y)
{
	if ( key == GLUT_KEY_LEFT )
	{
		roty += 1.0;
		if(roty>=360)roty-=360;
	}
	if ( key == GLUT_KEY_RIGHT )
	{
		roty -= 1.0;
		if(roty<=0)roty+=360;
	}
	if ( key == GLUT_KEY_UP )
	{
		rotx += 1.0;
		if(rotx>=360)rotx-=360;
	}
	if ( key == GLUT_KEY_DOWN )
	{
		rotx -= 1.0;
		if(rotx<=0)rotx+=360;
	}
	glutPostRedisplay();
	//Handle arrow, function keys etc
}
<commit_msg>Test colour<commit_after>float rotx, roty, rotz;

class Player{
	public:
	float x,y,z;
	float lookat_x,lookat_y,lookat_z;
};

class Level{
	private:
	string cur_level_path;
	string cur_level;
	Model_OBJ *room;
	Model_OBJ *inv;
	Model_OBJ *player;
	int g_rotation;
	Player *p;
	bool flipped;

	public:
	Level(string &l);
	void display();
	void keyPress(unsigned char ch, int x, int y);
	void specialKeyPress(int key, int x, int y);
	void flip();
};
void Level::flip()
{
	flipped = !flipped;
}

Level::Level(string &l)
{
	cur_level = l;
	cur_level_path = "../rooms/" + l +"_alt.obj";
	inv = new Model_OBJ;
	player = new Model_OBJ;
	room = new Model_OBJ;
	inv->Load("../rooms/Level_1.obj");
	player->Load("../models/Tux.obj");
	room->Load(&cur_level_path[0]);	//&cur_level_path[0]  might avoid warning but is it safe?
	g_rotation = 0;
	p = new Player;
	p->x = 0; p->y = -1; p->z = -3;
	p->lookat_x = 0; p->lookat_y = 1; p->lookat_z = 0;
}

void Level::display()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();
	glRotatef(roty, 0, 1, 0);
	glRotatef(rotx, 1, 0, 0);
	glTranslatef(p->x,p->y,p->z);
	glColor3f(1,1,1);
	player->Draw();
	if(flipped){
		glRotatef(180,1,0,0);
	}
	//gluLookAt( p->x,p->y,p->z - 2, p->lookat_x + p->x,p->lookat_y,p->lookat_z +p->z, 0,1,0);
	glColor3f(0,1,0);
	room->Draw();
	glRotatef(180,1,0,0);
	inv->Draw();
	glutSwapBuffers();
	glFlush();
}

void Level::keyPress(unsigned char key, int x, int y)
{
	cout<<key<<endl;
	//normal key press events
	if( key == 'w')
	{
		p->z+=0.3;
	}
	else if( key == 's')
	{
		p->z-=0.3;
	}
	else if(key == 'a')
	{
		p->x+=0.3;
	}
	else if(key == 'd')
	{
		p->x-=0.3;
	}
	else if(key == 'q')
	{
		flip();
	}
	glutPostRedisplay();
}

void Level::specialKeyPress(int key,int x,int y)
{
	if ( key == GLUT_KEY_LEFT )
	{
		roty += 1.0;
		if(roty>=360)roty-=360;
	}
	if ( key == GLUT_KEY_RIGHT )
	{
		roty -= 1.0;
		if(roty<=0)roty+=360;
	}
	if ( key == GLUT_KEY_UP )
	{
		rotx += 1.0;
		if(rotx>=360)rotx-=360;
	}
	if ( key == GLUT_KEY_DOWN )
	{
		rotx -= 1.0;
		if(rotx<=0)rotx+=360;
	}
	glutPostRedisplay();
	//Handle arrow, function keys etc
}
<|endoftext|>


<commit_before>#include <iostream>
#include <gtest/gtest.h>
#include "../pipeline.h"
#include "../channel.h"
#include <thread>

class ChannelTest : testing::Test { };

using cmd = cu::pipeline<int>;

cmd::link generator()
{
	return [](cmd::in&, cmd::out& yield)
	{
		for (auto& s : {100, 200, 300})
		{
			std::cout << "I am generator and push " << s << std::endl;
			yield(s);
		}
	};
}

cmd::link link1()
{
	return [](cmd::in& source, cmd::out& yield)
	{
		for (auto& s : source)
		{
			std::cout << "I am link1 and push " << s << std::endl;
			yield(s);
		}
	};
}

cmd::link link2()
{
	return [](cmd::in& source, cmd::out& yield)
	{
		for (auto& s : source)
		{
			std::cout << "I am link2 and push " << s << std::endl;
			yield(s);
		}
	};
}

cmd::link link3()
{
	return [](cmd::in& source, cmd::out& yield)
	{
		for (auto& s : source)
		{
			std::cout << "I am link3 and push " << s << std::endl;
			yield(s);
		}
	};
}

int filter(int s)
{
	std::cout << "I am filter and push " << s*2 << std::endl;
	return s*2;
}

void filter2(int s)
{
	std::cout << "I am filter received " << s << " but not modified" << std::endl;
}

TEST(ChannelTest, goroutines_or_something_like_that)
{
	// pipeline
	// cmd(generator(), link1(), link2(), link3());

	auto handler = [](int s) {
		std::cout << "<fib> received: " << s << " but not modified" << std::endl;
	};

	// channel
	cu::channel<int> go(filter, filter2, handler);
	std::thread t1([&](){
		go << 100;
	});
	std::thread t2([&](){
		go << 200;
	});
	std::cout << "recv1 is " << go.get() << std::endl;
	std::cout << "recv2 is " << go.get() << std::endl;
	t1.join();
	t2.join();
}

<commit_msg>Update test_channel.cpp<commit_after>#include <iostream>
#include <gtest/gtest.h>
#include "../pipeline.h"
#include "../channel.h"
#include <thread>

class ChannelTest : testing::Test { };

using cmd = cu::pipeline<int>;

cmd::link generator()
{
	return [](cmd::in&, cmd::out& yield)
	{
		for (auto& s : {100, 200, 300})
		{
			std::cout << "I am generator and push " << s << std::endl;
			yield(s);
		}
	};
}

cmd::link link1()
{
	return [](cmd::in& source, cmd::out& yield)
	{
		for (auto& s : source)
		{
			std::cout << "I am link1 and push " << s << std::endl;
			yield(s);
		}
	};
}

cmd::link link2()
{
	return [](cmd::in& source, cmd::out& yield)
	{
		for (auto& s : source)
		{
			std::cout << "I am link2 and push " << s << std::endl;
			yield(s);
		}
	};
}

cmd::link link3()
{
	return [](cmd::in& source, cmd::out& yield)
	{
		for (auto& s : source)
		{
			std::cout << "I am link3 and push " << s << std::endl;
			yield(s);
		}
	};
}

void filter1(int s)
{
	std::cout << "1. I am filter received " << s << " but not modified" << std::endl;
}

int filter2(int s)
{
	std::cout << "2. I am filter and push " << s*2 << std::endl;
	return s*2;
}

TEST(ChannelTest, goroutines_or_something_like_that)
{
	// pipeline
	// cmd(generator(), link1(), link2(), link3());

	auto handler = [](int s) {
		std::cout << "3. received: " << s << " but not modified" << std::endl;
	};

	// channel
	cu::channel<int> go(filter2, handler);
	go.connect(filter1);
	std::thread t1([&](){
		go << 100;
	});
	std::thread t2([&](){
		go << 200;
	});
	std::cout << "4. recv1 is " << go.get() << std::endl;
	std::cout << "4. recv2 is " << go.get() << std::endl;
	t1.join();
	t2.join();
}
<|endoftext|>


<commit_before><commit_msg>remove gamepad hint from credits<commit_after><|endoftext|>