<commit_before>/*
 * OpenSSL utilities.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#ifndef BENG_PROXY_SSL_UNIQUE_HXX
#define BENG_PROXY_SSL_UNIQUE_HXX

#include <openssl/ssl.h>

#include <memory>

struct OpenSslDelete {
    void operator()(SSL *ssl) {
        SSL_free(ssl);
    }

    void operator()(SSL_CTX *ssl_ctx) {
        SSL_CTX_free(ssl_ctx);
    }

    void operator()(X509 *x509) {
        X509_free(x509);
    }

    void operator()(X509_NAME *name) {
        X509_NAME_free(name);
    }

    void operator()(X509_EXTENSION *ext) {
        X509_EXTENSION_free(ext);
    }

    void operator()(EC_KEY *key) {
        EC_KEY_free(key);
    }

    void operator()(EVP_PKEY *key) {
        EVP_PKEY_free(key);
    }

    void operator()(EVP_PKEY_CTX *key) {
        EVP_PKEY_CTX_free(key);
    }

    void operator()(BIO *bio) {
        BIO_free(bio);
    }
};

using UniqueSSL = std::unique_ptr<SSL, OpenSslDelete>;
using UniqueSSL_CTX = std::unique_ptr<SSL_CTX, OpenSslDelete>;
using UniqueX509 = std::unique_ptr<X509, OpenSslDelete>;
using UniqueX509_NAME = std::unique_ptr<X509_NAME, OpenSslDelete>;
using UniqueX509_EXTENSION = std::unique_ptr<X509_EXTENSION, OpenSslDelete>;
using UniqueEC_KEY = std::unique_ptr<EC_KEY, OpenSslDelete>;
using UniqueEVP_PKEY = std::unique_ptr<EVP_PKEY, OpenSslDelete>;
using UniqueEVP_PKEY_CTX = std::unique_ptr<EVP_PKEY_CTX, OpenSslDelete>;
using UniqueBIO = std::unique_ptr<BIO, OpenSslDelete>;

#endif
<commit_msg>ssl/Unique: add overload for GENERAL_NAMES<commit_after>/*
 * OpenSSL utilities.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#ifndef BENG_PROXY_SSL_UNIQUE_HXX
#define BENG_PROXY_SSL_UNIQUE_HXX

#include <openssl/ssl.h>
#include <openssl/x509v3.h>

#include <memory>

struct OpenSslDelete {
    void operator()(SSL *ssl) {
        SSL_free(ssl);
    }

    void operator()(SSL_CTX *ssl_ctx) {
        SSL_CTX_free(ssl_ctx);
    }

    void operator()(X509 *x509) {
        X509_free(x509);
    }

    void operator()(X509_NAME *name) {
        X509_NAME_free(name);
    }

    void operator()(X509_EXTENSION *ext) {
        X509_EXTENSION_free(ext);
    }

    void operator()(GENERAL_NAMES *gn) {
        GENERAL_NAMES_free(gn);
    }

    void operator()(EC_KEY *key) {
        EC_KEY_free(key);
    }

    void operator()(EVP_PKEY *key) {
        EVP_PKEY_free(key);
    }

    void operator()(EVP_PKEY_CTX *key) {
        EVP_PKEY_CTX_free(key);
    }

    void operator()(BIO *bio) {
        BIO_free(bio);
    }
};

using UniqueSSL = std::unique_ptr<SSL, OpenSslDelete>;
using UniqueSSL_CTX = std::unique_ptr<SSL_CTX, OpenSslDelete>;
using UniqueX509 = std::unique_ptr<X509, OpenSslDelete>;
using UniqueX509_NAME = std::unique_ptr<X509_NAME, OpenSslDelete>;
using UniqueX509_EXTENSION = std::unique_ptr<X509_EXTENSION, OpenSslDelete>;
using UniqueGENERAL_NAMES = std::unique_ptr<GENERAL_NAMES, OpenSslDelete>;
using UniqueEC_KEY = std::unique_ptr<EC_KEY, OpenSslDelete>;
using UniqueEVP_PKEY = std::unique_ptr<EVP_PKEY, OpenSslDelete>;
using UniqueEVP_PKEY_CTX = std::unique_ptr<EVP_PKEY_CTX, OpenSslDelete>;
using UniqueBIO = std::unique_ptr<BIO, OpenSslDelete>;

#endif
<|endoftext|>


<commit_before><commit_msg>Add const to read-only variables.<commit_after><|endoftext|>


<commit_before>
/*
 * Funambol is a mobile platform developed by Funambol, Inc.
 * Copyright (C) 2003 - 2007 Funambol, Inc.
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License version 3 as published by
 * the Free Software Foundation with the addition of the following permission
 * added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
 * WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE
 * WARRANTY OF NON INFRINGEMENT  OF THIRD PARTY RIGHTS.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, see http://www.gnu.org/licenses or write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301 USA.
 *
 * You can contact Funambol, Inc. headquarters at 643 Bair Island Road, Suite
 * 305, Redwood City, CA 94063, USA, or at email address info@funambol.com.
 *
 * The interactive user interfaces in modified source and object code versions
 * of this program must display Appropriate Legal Notices, as required under
 * Section 5 of the GNU Affero General Public License version 3.
 *
 * In accordance with Section 7(b) of the GNU Affero General Public License
 * version 3, these Appropriate Legal Notices must retain the display of the
 * "Powered by Funambol" logo. If the display of the logo is not reasonably
 * feasible for technical reasons, the Appropriate Legal Notices must display
 * the words "Powered by Funambol".
 */
#include "base/fscapi.h"
#include "base/util/utils.h"
#include "spds/spdsutils.h"
#include "base/quoted-printable.h"
#include "base/globalsdef.h"

#define BASE64 "base64"
#define QUOTED_PRINTABLE "quoted-printable"

BEGIN_NAMESPACE

// Base64 encoding for files (with newline)
char *uuencode(const char *msg, int len);

SyncMode syncModeCode(const char* syncMode) {

    if (strcmp(syncMode,"slow") == 0)
        return SYNC_SLOW;
    else if (strcmp(syncMode,"two-way") == 0)
        return SYNC_TWO_WAY;
    else if (strcmp(syncMode,"one-way") == 0)               // deprecated
        return SYNC_ONE_WAY_FROM_SERVER;
    else if (strcmp(syncMode,"one-way-server") == 0 ||      // deprecated
             strcmp(syncMode,"one-way-from-server") == 0 )
        return SYNC_ONE_WAY_FROM_SERVER;
    else if (strcmp(syncMode,"one-way-client") == 0 ||      // deprecated
             strcmp(syncMode,"one-way-from-client") == 0)
        return SYNC_ONE_WAY_FROM_CLIENT;
    else if (strcmp(syncMode,"refresh")             == 0 || // deprecated
             strcmp(syncMode,"refresh-server")      == 0 || // deprecated
             strcmp(syncMode,"refresh-from-server") == 0  )
        return SYNC_REFRESH_FROM_SERVER;
    else if (strcmp(syncMode,"refresh-client") == 0 ||      // deprecated
             strcmp(syncMode,"refresh-from-client") == 0)
        return SYNC_REFRESH_FROM_CLIENT;
    //--------- Funambol extension --------------------
    else if (strcmp(syncMode,"smart-one-way-from-client") == 0)
        return SYNC_SMART_ONE_WAY_FROM_CLIENT;
    else if (strcmp(syncMode,"smart-one-way-from-server") == 0)
        return SYNC_SMART_ONE_WAY_FROM_SERVER;
    else if (strcmp(syncMode,"incremental-smart-one-way-from-client") == 0)
        return SYNC_INCREMENTAL_SMART_ONE_WAY_FROM_CLIENT;
    else if (strcmp(syncMode,"incremental-smart-one-way-from-server") == 0)
        return SYNC_INCREMENTAL_SMART_ONE_WAY_FROM_SERVER;
    else if (strcmp(syncMode, "addrchange") == 0)
        return SYNC_ADDR_CHANGE_NOTIFICATION;
    return SYNC_NONE;
}

const char *syncModeKeyword(SyncMode syncMode) {
    switch (syncMode) {
        case SYNC_SLOW:
            return "slow";
        case SYNC_TWO_WAY:
            return "two-way";
        case SYNC_ONE_WAY_FROM_SERVER:
            return "one-way-from-server";
        case SYNC_ONE_WAY_FROM_CLIENT:
            return "one-way-from-client";
        case SYNC_REFRESH_FROM_SERVER:
            return "refresh-from-server";
        case SYNC_REFRESH_FROM_CLIENT:
            return "refresh-from-client";
        case SYNC_ADDR_CHANGE_NOTIFICATION:
            return "addrchange";
        case SYNC_NONE:
            return "none";
        case SYNC_TWO_WAY_BY_SERVER:
            return "two-way-by-server";
        case SYNC_ONE_WAY_FROM_CLIENT_BY_SERVER:
            return "one-way-from-client-by-server";
        case SYNC_REFRESH_FROM_CLIENT_BY_SERVER:
            return "refresh-from-client-by-server";
        case SYNC_ONE_WAY_FROM_SERVER_BY_SERVER:
            return "one-way-from-server-by-server";
        case SYNC_REFRESH_FROM_SERVER_BY_SERVER:
            return "refresh-from-server-by-server";
        case SYNC_SMART_ONE_WAY_FROM_CLIENT:
            return "smart-one-way-from-client";
        case SYNC_SMART_ONE_WAY_FROM_SERVER:
            return "smart-one-way-from-server";
        case SYNC_INCREMENTAL_SMART_ONE_WAY_FROM_CLIENT:
            return "incremental-smart-one-way-from-client";
        case SYNC_INCREMENTAL_SMART_ONE_WAY_FROM_SERVER:
            return "incremental-smart-one-way-from-server";
    }

    return "";
}

SyncItemStatus** toSyncItemStatusArray(ArrayList& items) {

    int l = items.size();

    if (l < 1) {
        return NULL;
    }

    SyncItemStatus** itemArrayStatus = new SyncItemStatus*[l];

    for (int i=0; i<l; ++i) {
        itemArrayStatus[i] = (SyncItemStatus*)((ArrayElement*)items[i])->clone();
    }

    return itemArrayStatus;
}

SyncItem** toSyncItemArray(ArrayList& items) {
    int l = items.size();

    if (l < 1) {
        return NULL;
    }

    SyncItem** itemArray = new SyncItem*[l];

    for (int i=0; i<l; ++i) {
        itemArray[i] = (SyncItem*)((ArrayElement*)items[i])->clone();
    }

    return itemArray;
}

/*
 * Encode the message in base64, splitting the result in lines of 72 columns
 * each.
 */
char *uuencode(const char *msg, int len)
{
    int i, step=54, dlen=0;

    char *ret = new char[ len * 2 ]; // b64 is 4/3, but we have also the newlines....
    for(i=0; i<len; i+=step) {
        if(len-i < step)
            step = len-i;
        dlen += b64_encode(ret+dlen, (void *)(msg+i), step);
        if(getLastErrorCode() != 0){
            delete [] ret;
            return NULL;
        }
        ret[dlen++]='\n';
    }

    // Terminate the string
    ret[dlen]=0;
    return ret;
}

// Get a line from the char buffer msg
// line endings are discarded
// Return the first character after the newline
static const char *getLine(const char *msg, char **line) {
    // Null message?
    if (!msg)
        return 0;
    // End of string
    if ( *msg == 0)
        return 0;

    const char *next = strpbrk(msg, "\r\n\0");
    int linelen;

    if(!next) {
        linelen = strlen(msg);
        next = msg+linelen;
    }
    else
        linelen = next-msg;

    *line= new char[linelen+1];
    strncpy(*line, msg, linelen );
    (*line)[linelen]=0;

    while (*next == '\r' || *next == '\n') {
        next++;
    }
    return next;
}

char* b64EncodeWithSpaces(const char *msg, int len) {
    int i, step=54, dlen=0;

    char* res = new char[len*3]; // b64 is 4/3, but we have also the newlines....
    memset(res, 0, len*3);
    res[0] = ' ';
    res[1] = ' ';
    res[2] = ' ';
    res[3] = ' ';
    char* ret = &res[4];
    for(i=0; i<len; i+=step) {
        if(len-i < step) {
            step = len-i;
        }
        dlen += b64_encode(ret+dlen, (void *)(msg+i), step);
        ret[dlen++]='\r';
        ret[dlen++]='\n';
        ret[dlen++]=' ';
        ret[dlen++]=' ';
        ret[dlen++]=' ';
        ret[dlen++]=' ';
    }

    // Terminate the string
    ret[dlen]=0;
    int ll = strlen(res);
    return res;
}

// This functions works for standard encoded files with new line every
// 72 characters. It does not work if the line length is not multiple of 4.
int uudecode(const char *msg, char **binmsg, size_t *binlen)
{
    // Convert the string
    const char *buf = msg;
    if (!buf)
        return -1;

    const char *cursor = buf;
    char *line;
    // Make room for the destination (3/4 of the original)
    int outlen = strlen(buf)/4 * 3 + 1;
    char *out = new char[outlen+1];
    memset(out, 0, outlen);
    int len = 0, nl=0;

    while( (cursor=getLine(cursor, &line)) != 0) {
        if (strstr(line, "]]") != 0)
            break;
        nl++;
        len += b64_decode(out+len, line);
        if ( getLastErrorCode() != 0){
            delete [] line;
            return -1;
        }

        delete [] line;
    }
    //delete [] buf;
    // Terminate the string
    out[len]=0;
    // Set return parameters
    *binmsg = out;
    *binlen = len;
    return 0;
}

char *loadAndConvert(const char *filename, const char *encoding)
{
    char *msg = 0;
    bool binary = true;
    size_t msglen=0;
    char *ret = 0;

    if(!filename)
        return 0;

    if( strcmp(encoding, "base64") == 0 ) {
        binary = true;
    }

    // Read file
    if(!readFile(filename, &msg, &msglen, binary))
        return 0;
    // Encode the file
    if( strcmp(encoding, BASE64) == 0 ) {
        ret = uuencode(msg, msglen);
        delete [] msg;
    }
    else if( strcmp(encoding, QUOTED_PRINTABLE) == 0 ) {
        if(qp_isNeed(msg))
            ret = qp_encode(msg);
        delete [] msg;
    }
    else {  // Default 8bit
        ret = msg;
    }
    return ret;
}

int convertAndSave(const char *filename,
                   const char *s,
                   const char *encoding)
{
    char *buf, *name = stringdup(filename);
    bool binary = true;
    size_t len;

    if(!name)
        return -1;

    // Decode the file
    if( strcmp(encoding, BASE64) == 0 ) {
        if( uudecode(s, &buf, &len) ) {
            return -1;
        }
        binary = true;
    } else if( strcmp(encoding, QUOTED_PRINTABLE) == 0 ) {
        if (s == NULL)
            return -1;

        buf = qp_decode(s);
        len = strlen(buf);
        binary = true;
    }
    else {      // Default UTF-8
        buf = stringdup(s);
        len = strlen(buf);
    }
    saveFile(name, buf, len, binary);
    delete [] buf;
    delete [] name;
    return 0;
}

const char* getSourceName(const char *uri)
{
#if 0
// FIXME
    char nodeName = new char[];
    strcpy(nodeName, rootContext); strcat(nodeName, CONTEXT_SPDS_SOURCES);

    node = dmt->readManagementNode(nodeName);
    if ( ! node ) {
        //lastErrorCode = ERR_INVALID_CONTEXT;
        //sprintf(lastErrorMsg, ERRMSG_INVALID_CONTEXT, nodeName);
        setErrorf(ERR_INVALID_CONTEXT, ERRMSG_INVALID_CONTEXT, nodeName);
        goto finally;
    }
    n = node->getChildrenMaxCount();
    for()
#else
        // FIXME
        return stringdup(uri);
#endif
}

int indent(StringBuffer& content, int space){

    StringBuffer buf;
    char* startingBuf = new char[space +1];
    memset(startingBuf, ' ', space);
    startingBuf[space] = 0;
    buf = startingBuf;

    char* spacebuf = new char[space +2];
    spacebuf[0] = '\n';
    memset((spacebuf+1), ' ', space);
    spacebuf[space+1] = 0;
    content.replaceAll("\n", spacebuf);
    buf.append(content);
    content = buf;
    delete [] spacebuf;
    delete [] startingBuf;
    return 0;
}

END_NAMESPACE

<commit_msg>Code cleanup: avoid warning for unused variable<commit_after>
/*
 * Funambol is a mobile platform developed by Funambol, Inc.
 * Copyright (C) 2003 - 2007 Funambol, Inc.
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License version 3 as published by
 * the Free Software Foundation with the addition of the following permission
 * added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
 * WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE
 * WARRANTY OF NON INFRINGEMENT  OF THIRD PARTY RIGHTS.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, see http://www.gnu.org/licenses or write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301 USA.
 *
 * You can contact Funambol, Inc. headquarters at 643 Bair Island Road, Suite
 * 305, Redwood City, CA 94063, USA, or at email address info@funambol.com.
 *
 * The interactive user interfaces in modified source and object code versions
 * of this program must display Appropriate Legal Notices, as required under
 * Section 5 of the GNU Affero General Public License version 3.
 *
 * In accordance with Section 7(b) of the GNU Affero General Public License
 * version 3, these Appropriate Legal Notices must retain the display of the
 * "Powered by Funambol" logo. If the display of the logo is not reasonably
 * feasible for technical reasons, the Appropriate Legal Notices must display
 * the words "Powered by Funambol".
 */
#include "base/fscapi.h"
#include "base/util/utils.h"
#include "spds/spdsutils.h"
#include "base/quoted-printable.h"
#include "base/globalsdef.h"

#define BASE64 "base64"
#define QUOTED_PRINTABLE "quoted-printable"

BEGIN_NAMESPACE

// Base64 encoding for files (with newline)
char *uuencode(const char *msg, int len);

SyncMode syncModeCode(const char* syncMode) {

    if (strcmp(syncMode,"slow") == 0)
        return SYNC_SLOW;
    else if (strcmp(syncMode,"two-way") == 0)
        return SYNC_TWO_WAY;
    else if (strcmp(syncMode,"one-way") == 0)               // deprecated
        return SYNC_ONE_WAY_FROM_SERVER;
    else if (strcmp(syncMode,"one-way-server") == 0 ||      // deprecated
             strcmp(syncMode,"one-way-from-server") == 0 )
        return SYNC_ONE_WAY_FROM_SERVER;
    else if (strcmp(syncMode,"one-way-client") == 0 ||      // deprecated
             strcmp(syncMode,"one-way-from-client") == 0)
        return SYNC_ONE_WAY_FROM_CLIENT;
    else if (strcmp(syncMode,"refresh")             == 0 || // deprecated
             strcmp(syncMode,"refresh-server")      == 0 || // deprecated
             strcmp(syncMode,"refresh-from-server") == 0  )
        return SYNC_REFRESH_FROM_SERVER;
    else if (strcmp(syncMode,"refresh-client") == 0 ||      // deprecated
             strcmp(syncMode,"refresh-from-client") == 0)
        return SYNC_REFRESH_FROM_CLIENT;
    //--------- Funambol extension --------------------
    else if (strcmp(syncMode,"smart-one-way-from-client") == 0)
        return SYNC_SMART_ONE_WAY_FROM_CLIENT;
    else if (strcmp(syncMode,"smart-one-way-from-server") == 0)
        return SYNC_SMART_ONE_WAY_FROM_SERVER;
    else if (strcmp(syncMode,"incremental-smart-one-way-from-client") == 0)
        return SYNC_INCREMENTAL_SMART_ONE_WAY_FROM_CLIENT;
    else if (strcmp(syncMode,"incremental-smart-one-way-from-server") == 0)
        return SYNC_INCREMENTAL_SMART_ONE_WAY_FROM_SERVER;
    else if (strcmp(syncMode, "addrchange") == 0)
        return SYNC_ADDR_CHANGE_NOTIFICATION;
    return SYNC_NONE;
}

const char *syncModeKeyword(SyncMode syncMode) {
    switch (syncMode) {
        case SYNC_SLOW:
            return "slow";
        case SYNC_TWO_WAY:
            return "two-way";
        case SYNC_ONE_WAY_FROM_SERVER:
            return "one-way-from-server";
        case SYNC_ONE_WAY_FROM_CLIENT:
            return "one-way-from-client";
        case SYNC_REFRESH_FROM_SERVER:
            return "refresh-from-server";
        case SYNC_REFRESH_FROM_CLIENT:
            return "refresh-from-client";
        case SYNC_ADDR_CHANGE_NOTIFICATION:
            return "addrchange";
        case SYNC_NONE:
            return "none";
        case SYNC_TWO_WAY_BY_SERVER:
            return "two-way-by-server";
        case SYNC_ONE_WAY_FROM_CLIENT_BY_SERVER:
            return "one-way-from-client-by-server";
        case SYNC_REFRESH_FROM_CLIENT_BY_SERVER:
            return "refresh-from-client-by-server";
        case SYNC_ONE_WAY_FROM_SERVER_BY_SERVER:
            return "one-way-from-server-by-server";
        case SYNC_REFRESH_FROM_SERVER_BY_SERVER:
            return "refresh-from-server-by-server";
        case SYNC_SMART_ONE_WAY_FROM_CLIENT:
            return "smart-one-way-from-client";
        case SYNC_SMART_ONE_WAY_FROM_SERVER:
            return "smart-one-way-from-server";
        case SYNC_INCREMENTAL_SMART_ONE_WAY_FROM_CLIENT:
            return "incremental-smart-one-way-from-client";
        case SYNC_INCREMENTAL_SMART_ONE_WAY_FROM_SERVER:
            return "incremental-smart-one-way-from-server";
    }

    return "";
}

SyncItemStatus** toSyncItemStatusArray(ArrayList& items) {

    int l = items.size();

    if (l < 1) {
        return NULL;
    }

    SyncItemStatus** itemArrayStatus = new SyncItemStatus*[l];

    for (int i=0; i<l; ++i) {
        itemArrayStatus[i] = (SyncItemStatus*)((ArrayElement*)items[i])->clone();
    }

    return itemArrayStatus;
}

SyncItem** toSyncItemArray(ArrayList& items) {
    int l = items.size();

    if (l < 1) {
        return NULL;
    }

    SyncItem** itemArray = new SyncItem*[l];

    for (int i=0; i<l; ++i) {
        itemArray[i] = (SyncItem*)((ArrayElement*)items[i])->clone();
    }

    return itemArray;
}

/*
 * Encode the message in base64, splitting the result in lines of 72 columns
 * each.
 */
char *uuencode(const char *msg, int len)
{
    int i, step=54, dlen=0;

    char *ret = new char[ len * 2 ]; // b64 is 4/3, but we have also the newlines....
    for(i=0; i<len; i+=step) {
        if(len-i < step)
            step = len-i;
        dlen += b64_encode(ret+dlen, (void *)(msg+i), step);
        if(getLastErrorCode() != 0){
            delete [] ret;
            return NULL;
        }
        ret[dlen++]='\n';
    }

    // Terminate the string
    ret[dlen]=0;
    return ret;
}

// Get a line from the char buffer msg
// line endings are discarded
// Return the first character after the newline
static const char *getLine(const char *msg, char **line) {
    // Null message?
    if (!msg)
        return 0;
    // End of string
    if ( *msg == 0)
        return 0;

    const char *next = strpbrk(msg, "\r\n\0");
    int linelen;

    if(!next) {
        linelen = strlen(msg);
        next = msg+linelen;
    }
    else
        linelen = next-msg;

    *line= new char[linelen+1];
    strncpy(*line, msg, linelen );
    (*line)[linelen]=0;

    while (*next == '\r' || *next == '\n') {
        next++;
    }
    return next;
}

char* b64EncodeWithSpaces(const char *msg, int len) {
    int i, step=54, dlen=0;

    char* res = new char[len*3]; // b64 is 4/3, but we have also the newlines....
    memset(res, 0, len*3);
    res[0] = ' ';
    res[1] = ' ';
    res[2] = ' ';
    res[3] = ' ';
    char* ret = &res[4];
    for(i=0; i<len; i+=step) {
        if(len-i < step) {
            step = len-i;
        }
        dlen += b64_encode(ret+dlen, (void *)(msg+i), step);
        ret[dlen++]='\r';
        ret[dlen++]='\n';
        ret[dlen++]=' ';
        ret[dlen++]=' ';
        ret[dlen++]=' ';
        ret[dlen++]=' ';
    }

    // Terminate the string
    ret[dlen]=0;
    return res;
}

// This functions works for standard encoded files with new line every
// 72 characters. It does not work if the line length is not multiple of 4.
int uudecode(const char *msg, char **binmsg, size_t *binlen)
{
    // Convert the string
    const char *buf = msg;
    if (!buf)
        return -1;

    const char *cursor = buf;
    char *line;
    // Make room for the destination (3/4 of the original)
    int outlen = strlen(buf)/4 * 3 + 1;
    char *out = new char[outlen+1];
    memset(out, 0, outlen);
    int len = 0, nl=0;

    while( (cursor=getLine(cursor, &line)) != 0) {
        if (strstr(line, "]]") != 0)
            break;
        nl++;
        len += b64_decode(out+len, line);
        if ( getLastErrorCode() != 0){
            delete [] line;
            return -1;
        }

        delete [] line;
    }
    //delete [] buf;
    // Terminate the string
    out[len]=0;
    // Set return parameters
    *binmsg = out;
    *binlen = len;
    return 0;
}

char *loadAndConvert(const char *filename, const char *encoding)
{
    char *msg = 0;
    bool binary = true;
    size_t msglen=0;
    char *ret = 0;

    if(!filename)
        return 0;

    if( strcmp(encoding, "base64") == 0 ) {
        binary = true;
    }

    // Read file
    if(!readFile(filename, &msg, &msglen, binary))
        return 0;
    // Encode the file
    if( strcmp(encoding, BASE64) == 0 ) {
        ret = uuencode(msg, msglen);
        delete [] msg;
    }
    else if( strcmp(encoding, QUOTED_PRINTABLE) == 0 ) {
        if(qp_isNeed(msg))
            ret = qp_encode(msg);
        delete [] msg;
    }
    else {  // Default 8bit
        ret = msg;
    }
    return ret;
}

int convertAndSave(const char *filename,
                   const char *s,
                   const char *encoding)
{
    char *buf, *name = stringdup(filename);
    bool binary = true;
    size_t len;

    if(!name)
        return -1;

    // Decode the file
    if( strcmp(encoding, BASE64) == 0 ) {
        if( uudecode(s, &buf, &len) ) {
            return -1;
        }
        binary = true;
    } else if( strcmp(encoding, QUOTED_PRINTABLE) == 0 ) {
        if (s == NULL)
            return -1;

        buf = qp_decode(s);
        len = strlen(buf);
        binary = true;
    }
    else {      // Default UTF-8
        buf = stringdup(s);
        len = strlen(buf);
    }
    saveFile(name, buf, len, binary);
    delete [] buf;
    delete [] name;
    return 0;
}

const char* getSourceName(const char *uri)
{
#if 0
// FIXME
    char nodeName = new char[];
    strcpy(nodeName, rootContext); strcat(nodeName, CONTEXT_SPDS_SOURCES);

    node = dmt->readManagementNode(nodeName);
    if ( ! node ) {
        //lastErrorCode = ERR_INVALID_CONTEXT;
        //sprintf(lastErrorMsg, ERRMSG_INVALID_CONTEXT, nodeName);
        setErrorf(ERR_INVALID_CONTEXT, ERRMSG_INVALID_CONTEXT, nodeName);
        goto finally;
    }
    n = node->getChildrenMaxCount();
    for()
#else
        // FIXME
        return stringdup(uri);
#endif
}

int indent(StringBuffer& content, int space){

    StringBuffer buf;
    char* startingBuf = new char[space +1];
    memset(startingBuf, ' ', space);
    startingBuf[space] = 0;
    buf = startingBuf;

    char* spacebuf = new char[space +2];
    spacebuf[0] = '\n';
    memset((spacebuf+1), ' ', space);
    spacebuf[space+1] = 0;
    content.replaceAll("\n", spacebuf);
    buf.append(content);
    content = buf;
    delete [] spacebuf;
    delete [] startingBuf;
    return 0;
}

END_NAMESPACE

<|endoftext|>


<commit_before>//
// This file is part of the Marble Desktop Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2006-2007 Torsten Rahn <tackat@kde.org>"
// Copyright 2007      Inge Wallin  <ingwa@kde.org>"
//

#include "KdeMainWindow.h"

#include <QClipboard>
#include <QtGui/QLabel>
#include <QtGui/QPainter>

#include <KApplication>
#include <KIcon>
#include <KLocale>
#include <KActionCollection>
#include <KStandardAction>
#include <KStatusBar>
#include <KMessageBox>
#include <KFileDialog>
#include <KToggleFullScreenAction>
#include <KPrinter>

#include "settings.h"

// #include <KPrintDialogPage>

MainWindow::MainWindow(QWidget *parent)
    : KXmlGuiWindow(parent)
{
    m_controlView = new ControlView(this);
    setCentralWidget( m_controlView );

    setupActions();
    setXMLFile("marbleui.rc");

    // Create the statusbar and populate it with initial data.
    createStatusBar();
    connect( m_controlView->marbleWidget(), SIGNAL( zoomChanged( int ) ),
             this,                          SLOT( showZoom( int ) ) );
    showZoom( m_controlView->marbleWidget()->zoom() );

    setAutoSaveSettings();
}

MainWindow::~MainWindow()
{
    writeSettings();
}

void MainWindow::setupActions()
{
    // Action: Print Map
    m_printMapAction = KStandardAction::print( this, SLOT( printMapScreenShot() ), actionCollection() );

    // Action: Export Map
    m_exportMapAction = new KAction( this );
    actionCollection()->addAction( "exportMap", m_exportMapAction );
    m_exportMapAction->setText( i18n( "&Export Map..." ) );
    m_exportMapAction->setIcon( KIcon( "document-save-as" ) );
    m_exportMapAction->setShortcut( Qt::CTRL + Qt::Key_S );
    connect( m_exportMapAction, SIGNAL(triggered( bool ) ),
             this,              SLOT( exportMapScreenShot() ) );

    // Action: Copy Map to the Clipboard
    m_copyMapAction = KStandardAction::copy( this, SLOT( copyMap() ), actionCollection() );
    m_copyMapAction->setText( i18n( "&Copy Map" ) );

    // Action: Open a Gpx or a Kml File
    m_openAct = KStandardAction::open( this, SLOT( openFile() ), actionCollection() );
    m_openAct->setText( i18n( "&Open Map..." ) );
//     m_openAct->setStatusTip( tr( "Open a file for viewing on
//             Marble"));

    // Standard actions.  So far only Quit.
    KStandardAction::quit( kapp, SLOT( closeAllWindows() ), actionCollection() );

    m_sideBarAct = new KAction( i18n("Show &Navigation Panel"), this );
    actionCollection()->addAction( "options_show_sidebar", m_sideBarAct );
    m_sideBarAct->setShortcut( Qt::Key_F9 );
    m_sideBarAct->setCheckable( true );
    m_sideBarAct->setChecked( true );
    m_sideBarAct->setStatusTip( i18n( "Show Navigation Panel" ) );
    connect( m_sideBarAct, SIGNAL( triggered( bool ) ), this, SLOT( showSideBar( bool ) ) );

    m_fullScreenAct = KStandardAction::fullScreen( 0, 0, this, actionCollection() );
    connect( m_fullScreenAct, SIGNAL( triggered( bool ) ), this, SLOT( showFullScreen( bool ) ) );

    setupGUI();
}

void MainWindow::createStatusBar()
{
    // This hides the normal statusbar contents until clearMessage() is called.
    //statusBar()->showMessage( i18n( "Ready" ) );

    m_zoomLabel = new QLabel( statusBar() );
    statusBar()->addWidget(m_zoomLabel);
}

void MainWindow::saveProperties( KConfigGroup &group )
{
    Q_UNUSED( group )
}

void MainWindow::readProperties( const KConfigGroup &group )
{
    Q_UNUSED( group )
}

void MainWindow::writeSettings()
{
     double homeLon = 0;
     double homeLat = 0;
     int homeZoom = 0;
     m_controlView->marbleWidget()->home( homeLon, homeLat, homeZoom );
     MarbleSettings::setHomeLongitude( homeLon );
     MarbleSettings::setHomeLatitude( homeLat );
     MarbleSettings::setHomeZoom( homeZoom );
     MarbleSettings::self()->writeConfig();
}

void MainWindow::readSettings()
{
     m_controlView->marbleWidget()->setHome(
        MarbleSettings::homeLongitude(),
        MarbleSettings::homeLatitude(),
        MarbleSettings::homeZoom()
     );
     m_controlView->marbleWidget()->goHome();
}

void MainWindow::showZoom(int zoom)
{
  m_zoomLabel->setText( i18n( "Zoom: %1", QString("%1").arg ( zoom, 4 ) ) );
}

void MainWindow::exportMapScreenShot()
{
    QPixmap  mapPixmap = m_controlView->mapScreenShot();

    QString  fileName = KFileDialog::getSaveFileName( QDir::homePath(),
                                                      i18n( "Images (*.jpg *.png)" ),
                                                      this, i18n("Export Map") );

    if ( !fileName.isEmpty() ) {
        bool  success = mapPixmap.save( fileName );
        if ( !success ) {
            KMessageBox::error( this, i18nc( "Application name", "Marble" ),
                                i18n( "An error occurred while trying to save the file.\n" ),
                                KMessageBox::Notify );
        }
    }
}

void MainWindow::printMapScreenShot()
{
    QPixmap       mapPixmap = m_controlView->mapScreenShot();
    QSize         printSize = mapPixmap.size();
    KPrinter      printer;

    if ( printer.setup( this ) ) {

        QRect  mapPageRect = printer.pageRect();

        printSize.scale( ( printer.pageRect() ).size(), Qt::KeepAspectRatio );

        QPoint  printTopLeft( mapPageRect.x() + mapPageRect.width() / 2
                              - printSize.width() / 2,
                              mapPageRect.y() + mapPageRect.height() / 2
                              - printSize.height() / 2 );

        QRect     mapPrintRect( printTopLeft, printSize );
        QPainter  painter( &printer );

        painter.drawPixmap( mapPrintRect, mapPixmap, mapPixmap.rect() );
    }
}

void MainWindow::openFile()
{
    QString fileName;
    fileName = KFileDialog::getOpenFileName( KUrl(),
                                    i18n("*.gpx|GPS Data\n*.kml"),
                                            this, i18n("Open File")
                                           );/*
    fileName = QFileDialog::getOpenFileName(this, tr("Open File"),
                                            QString(),
                            tr("GPS Data(*.gpx);;KML(*.kml)"));*/

    if ( ! fileName.isNull() ) {
        QString extension = fileName.section( '.', -1 );

        if ( extension.compare( "gpx", Qt::CaseInsensitive ) == 0 ) {
            m_controlView->marbleWidget()->openGpxFile( fileName );
        }
        else if ( extension.compare( "kml", Qt::CaseInsensitive ) == 0 ) {
            m_controlView->marbleWidget()->addPlaceMarkFile( fileName );
        }
    }
}

#include "KdeMainWindow.moc"
<commit_msg>of course, any settings will be happily ignored if i won't readSettings() at startup...<commit_after>//
// This file is part of the Marble Desktop Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2006-2007 Torsten Rahn <tackat@kde.org>"
// Copyright 2007      Inge Wallin  <ingwa@kde.org>"
//

#include "KdeMainWindow.h"

#include <QClipboard>
#include <QtGui/QLabel>
#include <QtGui/QPainter>

#include <KApplication>
#include <KIcon>
#include <KLocale>
#include <KActionCollection>
#include <KStandardAction>
#include <KStatusBar>
#include <KMessageBox>
#include <KFileDialog>
#include <KToggleFullScreenAction>
#include <KPrinter>

#include "settings.h"

// #include <KPrintDialogPage>

MainWindow::MainWindow(QWidget *parent)
    : KXmlGuiWindow(parent)
{
    m_controlView = new ControlView(this);
    setCentralWidget( m_controlView );

    setupActions();
    setXMLFile("marbleui.rc");

    // Create the statusbar and populate it with initial data.
    createStatusBar();
    connect( m_controlView->marbleWidget(), SIGNAL( zoomChanged( int ) ),
             this,                          SLOT( showZoom( int ) ) );
    showZoom( m_controlView->marbleWidget()->zoom() );

    setAutoSaveSettings();
}

MainWindow::~MainWindow()
{
    writeSettings();
}

void MainWindow::setupActions()
{
    // Action: Print Map
    m_printMapAction = KStandardAction::print( this, SLOT( printMapScreenShot() ), actionCollection() );

    // Action: Export Map
    m_exportMapAction = new KAction( this );
    actionCollection()->addAction( "exportMap", m_exportMapAction );
    m_exportMapAction->setText( i18n( "&Export Map..." ) );
    m_exportMapAction->setIcon( KIcon( "document-save-as" ) );
    m_exportMapAction->setShortcut( Qt::CTRL + Qt::Key_S );
    connect( m_exportMapAction, SIGNAL(triggered( bool ) ),
             this,              SLOT( exportMapScreenShot() ) );

    // Action: Copy Map to the Clipboard
    m_copyMapAction = KStandardAction::copy( this, SLOT( copyMap() ), actionCollection() );
    m_copyMapAction->setText( i18n( "&Copy Map" ) );

    // Action: Open a Gpx or a Kml File
    m_openAct = KStandardAction::open( this, SLOT( openFile() ), actionCollection() );
    m_openAct->setText( i18n( "&Open Map..." ) );
//     m_openAct->setStatusTip( tr( "Open a file for viewing on
//             Marble"));

    // Standard actions.  So far only Quit.
    KStandardAction::quit( kapp, SLOT( closeAllWindows() ), actionCollection() );

    m_sideBarAct = new KAction( i18n("Show &Navigation Panel"), this );
    actionCollection()->addAction( "options_show_sidebar", m_sideBarAct );
    m_sideBarAct->setShortcut( Qt::Key_F9 );
    m_sideBarAct->setCheckable( true );
    m_sideBarAct->setChecked( true );
    m_sideBarAct->setStatusTip( i18n( "Show Navigation Panel" ) );
    connect( m_sideBarAct, SIGNAL( triggered( bool ) ), this, SLOT( showSideBar( bool ) ) );

    m_fullScreenAct = KStandardAction::fullScreen( 0, 0, this, actionCollection() );
    connect( m_fullScreenAct, SIGNAL( triggered( bool ) ), this, SLOT( showFullScreen( bool ) ) );

    setupGUI();

    readSettings();
}

void MainWindow::createStatusBar()
{
    // This hides the normal statusbar contents until clearMessage() is called.
    //statusBar()->showMessage( i18n( "Ready" ) );

    m_zoomLabel = new QLabel( statusBar() );
    statusBar()->addWidget(m_zoomLabel);
}

void MainWindow::saveProperties( KConfigGroup &group )
{
    Q_UNUSED( group )
}

void MainWindow::readProperties( const KConfigGroup &group )
{
    Q_UNUSED( group )
}

void MainWindow::writeSettings()
{
     double homeLon = 0;
     double homeLat = 0;
     int homeZoom = 0;
     m_controlView->marbleWidget()->home( homeLon, homeLat, homeZoom );
     MarbleSettings::setHomeLongitude( homeLon );
     MarbleSettings::setHomeLatitude( homeLat );
     MarbleSettings::setHomeZoom( homeZoom );
     MarbleSettings::self()->writeConfig();
}

void MainWindow::readSettings()
{
     m_controlView->marbleWidget()->setHome(
        MarbleSettings::homeLongitude(),
        MarbleSettings::homeLatitude(),
        MarbleSettings::homeZoom()
     );
     m_controlView->marbleWidget()->goHome();
}

void MainWindow::showZoom(int zoom)
{
  m_zoomLabel->setText( i18n( "Zoom: %1", QString("%1").arg ( zoom, 4 ) ) );
}

void MainWindow::exportMapScreenShot()
{
    QPixmap  mapPixmap = m_controlView->mapScreenShot();

    QString  fileName = KFileDialog::getSaveFileName( QDir::homePath(),
                                                      i18n( "Images (*.jpg *.png)" ),
                                                      this, i18n("Export Map") );

    if ( !fileName.isEmpty() ) {
        bool  success = mapPixmap.save( fileName );
        if ( !success ) {
            KMessageBox::error( this, i18nc( "Application name", "Marble" ),
                                i18n( "An error occurred while trying to save the file.\n" ),
                                KMessageBox::Notify );
        }
    }
}

void MainWindow::printMapScreenShot()
{
    QPixmap       mapPixmap = m_controlView->mapScreenShot();
    QSize         printSize = mapPixmap.size();
    KPrinter      printer;

    if ( printer.setup( this ) ) {

        QRect  mapPageRect = printer.pageRect();

        printSize.scale( ( printer.pageRect() ).size(), Qt::KeepAspectRatio );

        QPoint  printTopLeft( mapPageRect.x() + mapPageRect.width() / 2
                              - printSize.width() / 2,
                              mapPageRect.y() + mapPageRect.height() / 2
                              - printSize.height() / 2 );

        QRect     mapPrintRect( printTopLeft, printSize );
        QPainter  painter( &printer );

        painter.drawPixmap( mapPrintRect, mapPixmap, mapPixmap.rect() );
    }
}

void MainWindow::openFile()
{
    QString fileName;
    fileName = KFileDialog::getOpenFileName( KUrl(),
                                    i18n("*.gpx|GPS Data\n*.kml"),
                                            this, i18n("Open File")
                                           );/*
    fileName = QFileDialog::getOpenFileName(this, tr("Open File"),
                                            QString(),
                            tr("GPS Data(*.gpx);;KML(*.kml)"));*/

    if ( ! fileName.isNull() ) {
        QString extension = fileName.section( '.', -1 );

        if ( extension.compare( "gpx", Qt::CaseInsensitive ) == 0 ) {
            m_controlView->marbleWidget()->openGpxFile( fileName );
        }
        else if ( extension.compare( "kml", Qt::CaseInsensitive ) == 0 ) {
            m_controlView->marbleWidget()->addPlaceMarkFile( fileName );
        }
    }
}

#include "KdeMainWindow.moc"
<|endoftext|>


<commit_before>#include "filedownloader.hpp"

using namespace player;

#define BITRATE 800.0 //kbits
#define DATA_SIZE 4096.0 //byte

FileDownloader::FileDownloader(int interest_lifetime) : m_face(m_ioService)
{
  this->interest_lifetime = interest_lifetime;
}

shared_ptr<itec::Buffer> FileDownloader::getFile(string name){
  this->buffer.clear();
  this->buffer.resize (20,chunk());
  this->state = process_state::running;
  this->requestRate = 1000000/(BITRATE*1000/DATA_SIZE*8); //microseconds
  this->file = shared_ptr<itec::Buffer>(new itec::Buffer());
  this->file_name = name;

  boost::asio::deadline_timer timer(m_ioService, boost::posix_time::microseconds(requestRate));
  sendNextInterest(&timer); // starts the download

  // processEvents will block until the requested data received or timeout occurs#

  boost::posix_time::ptime startTime = boost::posix_time::ptime(boost::posix_time::microsec_clock::local_time());
  m_face.processEvents();
  boost::posix_time::ptime endTime = boost::posix_time::ptime(boost::posix_time::microsec_clock::local_time());
  boost::posix_time::time_duration downloadDuration = endTime-startTime;

  double dwrate = 0.0;
  for(int i = 0; i < buffer.size (); i++)
  {
    if(buffer.at(i).state == chunk_state::received)
     dwrate+=buffer.at(i).data->getSize();
  }
  if(downloadDuration.total_milliseconds () > 0)
  {
    dwrate = (dwrate * 8) / downloadDuration.total_milliseconds (); //bits/ms
    dwrate *= 1000; //bits/s
  }
  else
    dwrate = 0.0;

  fprintf(stderr, "dwrate = %f\n", dwrate);

  return file;
}

// send next pending interest, returns success-indicator
void FileDownloader::sendNextInterest(boost::asio::deadline_timer* timer)
{

  if(allChunksReceived ())// all chunks / file has been downloaded
  {
    //TODO Cleanup;
    onFileReceived();
    return;
  }

  // check if caller cancelled
  if(this->state == process_state::cancelled)
  {
    m_face.shutdown(); // dangerous?
    return;
  }

  for(uint index = 0; index < buffer.size(); index++)
  {
    if(buffer[index].state == chunk_state::unavailable)
    {
      expressInterest(index);
      buffer[index].state = chunk_state::requested;

      timer->expires_at (timer->expires_at ()+ boost::posix_time::microseconds(requestRate));
      timer->async_wait(bind(&FileDownloader::sendNextInterest, this, timer));
      return;
    }
  }
  timer->expires_at (timer->expires_at ()+ boost::posix_time::microseconds(requestRate));
  timer->async_wait(bind(&FileDownloader::sendNextInterest, this, timer));
}

void FileDownloader::expressInterest(int seq_nr)
{
   Interest interest(Name(file_name).appendSequenceNumber(seq_nr));  // e.g. "/example/testApp/randomData"
  // appendSequenceNumber
  interest.setInterestLifetime(time::milliseconds(this->interest_lifetime));   // time::milliseconds(1000)
  interest.setMustBeFresh(true);

  m_face.expressInterest(interest,
                         bind(&FileDownloader::onData, this,  _1, _2),
                         bind(&FileDownloader::onTimeout, this, _1));

  //cout << "Expressing interest #" << seq_nr << " " << interest << endl;
}

// private methods
// react to the reception of a reply from a Producer
void FileDownloader::onData(const Interest& interest, const Data& data)
{
  if(!boost::starts_with(data.getName().toUri (), file_name))
    return; // data packet for previous requsted file(s)

  if(state == process_state::cancelled || state == process_state::finished)
  {
    //cout << "onData after cancel" << endl;
    return;
  }

  // get sequence number
  int seq_nr = interest.getName().at(-1).toSequenceNumber();
  //cout << "data-packet #" << seq_nr <<  " received: " << endl;

  const Block& block = data.getContent();

  // first data-packet arrived, allocate space
  this->finalBockId = boost::lexical_cast<int>(data.getFinalBlockId().toUri());

  if(! ((int)buffer.size () == finalBockId+1)) // we assume producer always transmitts a valid final block id
  {
    this->buffer.resize(finalBockId+1,chunk());
  }

  // store received data in buffer
  shared_ptr<itec::Buffer> b(new itec::Buffer((char*)block.value(), block.value_size()));
  buffer[seq_nr].data = b;
  buffer[seq_nr].state = chunk_state::received;
}

// check if actually all parts have been downloaded
bool FileDownloader::allChunksReceived(){
    for(std::vector<chunk>::iterator it = buffer.begin(); it != buffer.end(); ++it)
    {
        if((*it).state != chunk_state::received)
          return false;
    }
    return true;
}

// react on the request / Interest timing out
void FileDownloader::onTimeout(const Interest& interest)
{
  if(state == process_state::cancelled || state == process_state::finished)
  {
      //cout << "onTimeout after cancel" << endl;
      return;
  }
  //cout << "Timeout " << interest << endl;
  // get sequence number
  int seq_nr = interest.getName().at(-1).toSequenceNumber();
  buffer[seq_nr].state = chunk_state::unavailable; // reset state to pending -> queue for re-request
}

// cancel downloading, returned file will be empty
void FileDownloader::cancel()
{
  this->state = process_state::cancelled;
}

void FileDownloader::onFileReceived ()
{
  for(vector<chunk>::iterator it = buffer.begin (); it != buffer.end (); it++)
  {
    file->append((*it).data->getData(),(*it).data->getSize());
  }

  state = process_state::finished;
  //fprintf(stderr, "File received!\n");
}
<commit_msg>fixed bug for requestRate calculation<commit_after>#include "filedownloader.hpp"

using namespace player;

#define BITRATE 1200.0 //kbits
#define DATA_SIZE 4096.0 //byte

FileDownloader::FileDownloader(int interest_lifetime) : m_face(m_ioService)
{
  this->interest_lifetime = interest_lifetime;
}

shared_ptr<itec::Buffer> FileDownloader::getFile(string name){
  this->buffer.clear();
  this->buffer.resize (20,chunk());
  this->state = process_state::running;
  this->requestRate = 1000000/((BITRATE*1000)/(DATA_SIZE*8.0)); //microseconds
  this->file = shared_ptr<itec::Buffer>(new itec::Buffer());
  this->file_name = name;

  boost::asio::deadline_timer timer(m_ioService, boost::posix_time::microseconds(requestRate));
  sendNextInterest(&timer); // starts the download

  // processEvents will block until the requested data received or timeout occurs#

  boost::posix_time::ptime startTime = boost::posix_time::ptime(boost::posix_time::microsec_clock::local_time());
  m_face.processEvents();
  boost::posix_time::ptime endTime = boost::posix_time::ptime(boost::posix_time::microsec_clock::local_time());
  boost::posix_time::time_duration downloadDuration = endTime-startTime;

  double dwrate = 0.0;
  for(int i = 0; i < buffer.size (); i++)
  {
    if(buffer.at(i).state == chunk_state::received)
     dwrate+=buffer.at(i).data->getSize();
  }
  if(downloadDuration.total_milliseconds () > 0)
  {
    dwrate = (dwrate * 8.0) / downloadDuration.total_milliseconds (); //bits/ms
    dwrate *= 1000; //bits/s
  }
  else
    dwrate = 0.0;

  fprintf(stderr, "dwrate = %f\n", dwrate);

  return file;
}

// send next pending interest, returns success-indicator
void FileDownloader::sendNextInterest(boost::asio::deadline_timer* timer)
{

  if(allChunksReceived ())// all chunks / file has been downloaded
  {
    //TODO Cleanup;
    onFileReceived();
    return;
  }

  // check if caller cancelled
  if(this->state == process_state::cancelled)
  {
    m_face.shutdown(); // dangerous?
    return;
  }

  for(uint index = 0; index < buffer.size(); index++)
  {
    if(buffer[index].state == chunk_state::unavailable)
    {
      expressInterest(index);
      buffer[index].state = chunk_state::requested;

      timer->expires_at (timer->expires_at ()+ boost::posix_time::microseconds(requestRate));
      timer->async_wait(bind(&FileDownloader::sendNextInterest, this, timer));
      return;
    }
  }
  timer->expires_at (timer->expires_at ()+ boost::posix_time::microseconds(requestRate));
  timer->async_wait(bind(&FileDownloader::sendNextInterest, this, timer));
}

void FileDownloader::expressInterest(int seq_nr)
{
   Interest interest(Name(file_name).appendSequenceNumber(seq_nr));  // e.g. "/example/testApp/randomData"
  // appendSequenceNumber
  interest.setInterestLifetime(time::milliseconds(this->interest_lifetime));   // time::milliseconds(1000)
  interest.setMustBeFresh(true);

  m_face.expressInterest(interest,
                         bind(&FileDownloader::onData, this,  _1, _2),
                         bind(&FileDownloader::onTimeout, this, _1));

  //cout << "Expressing interest #" << seq_nr << " " << interest << endl;
}

// private methods
// react to the reception of a reply from a Producer
void FileDownloader::onData(const Interest& interest, const Data& data)
{
  if(!boost::starts_with(data.getName().toUri (), file_name))
    return; // data packet for previous requsted file(s)

  if(state == process_state::cancelled || state == process_state::finished)
  {
    //cout << "onData after cancel" << endl;
    return;
  }

  // get sequence number
  int seq_nr = interest.getName().at(-1).toSequenceNumber();
  //cout << "data-packet #" << seq_nr <<  " received: " << endl;

  const Block& block = data.getContent();

  // first data-packet arrived, allocate space
  this->finalBockId = boost::lexical_cast<int>(data.getFinalBlockId().toUri());

  if(! ((int)buffer.size () == finalBockId+1)) // we assume producer always transmitts a valid final block id
  {
    this->buffer.resize(finalBockId+1,chunk());
  }

  // store received data in buffer
  shared_ptr<itec::Buffer> b(new itec::Buffer((char*)block.value(), block.value_size()));
  buffer[seq_nr].data = b;
  buffer[seq_nr].state = chunk_state::received;
}

// check if actually all parts have been downloaded
bool FileDownloader::allChunksReceived(){
    for(std::vector<chunk>::iterator it = buffer.begin(); it != buffer.end(); ++it)
    {
        if((*it).state != chunk_state::received)
          return false;
    }
    return true;
}

// react on the request / Interest timing out
void FileDownloader::onTimeout(const Interest& interest)
{
  if(state == process_state::cancelled || state == process_state::finished)
  {
      //cout << "onTimeout after cancel" << endl;
      return;
  }
  //cout << "Timeout " << interest << endl;
  // get sequence number
  int seq_nr = interest.getName().at(-1).toSequenceNumber();
  buffer[seq_nr].state = chunk_state::unavailable; // reset state to pending -> queue for re-request
}

// cancel downloading, returned file will be empty
void FileDownloader::cancel()
{
  this->state = process_state::cancelled;
}

void FileDownloader::onFileReceived ()
{
  for(vector<chunk>::iterator it = buffer.begin (); it != buffer.end (); it++)
  {
    file->append((*it).data->getData(),(*it).data->getSize());
  }

  state = process_state::finished;
  //fprintf(stderr, "File received!\n");
}
<|endoftext|>


<commit_before>#include <boost/format.hpp>
#include <boost/make_shared.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/range/adaptor/map.hpp>
#include "KinBodyMarker.h"

using boost::ref;
using boost::format;
using boost::str;
using boost::algorithm::ends_with;
using boost::adaptors::map_values;
using OpenRAVE::EnvironmentBasePtr;
using OpenRAVE::KinBodyPtr;
using OpenRAVE::KinBodyWeakPtr;
using OpenRAVE::RobotBase;
using OpenRAVE::RobotBaseWeakPtr;
using visualization_msgs::InteractiveMarkerFeedbackConstPtr;
using interactive_markers::InteractiveMarkerServer;
using interactive_markers::MenuHandler;

typedef OpenRAVE::KinBody::LinkPtr LinkPtr;
typedef OpenRAVE::RobotBase::ManipulatorPtr ManipulatorPtr;
typedef boost::shared_ptr<InteractiveMarkerServer> InteractiveMarkerServerPtr;
typedef MenuHandler::EntryHandle EntryHandle;

namespace or_interactivemarker {

// TODO: Move this to a helper header.
static MenuHandler::CheckState BoolToCheckState(bool const &flag)
{
    if (flag) {
        return MenuHandler::CHECKED;
    } else {
        return MenuHandler::UNCHECKED;
    }
}

static bool CheckStateToBool(MenuHandler::CheckState const &state)
{
    return state == MenuHandler::CHECKED;
}

KinBodyMarker::KinBodyMarker(InteractiveMarkerServerPtr server,
                             KinBodyPtr kinbody)
    : server_(server)
    , kinbody_(kinbody)
    , robot_(boost::dynamic_pointer_cast<RobotBase>(kinbody))
    , has_joint_controls_(false)
{
    BOOST_ASSERT(server);
    BOOST_ASSERT(kinbody);

#if 0
    if (!IsGhost()) {
        CreateGhost();
    }
#endif
}

KinBodyMarker::~KinBodyMarker()
{
    if (ghost_kinbody_) {
        ghost_kinbody_->GetEnv()->Remove(ghost_kinbody_);
        ghost_kinbody_.reset();
        ghost_robot_.reset();
    }
}

bool KinBodyMarker::IsGhost() const
{
    KinBodyPtr kinbody = kinbody_.lock();
    return ends_with(kinbody->GetName(), ".Ghost");
}

void KinBodyMarker::EnvironmentSync()
{
    typedef OpenRAVE::KinBody::LinkPtr LinkPtr;
    typedef OpenRAVE::KinBody::JointPtr JointPtr;

    KinBodyPtr const kinbody = kinbody_.lock();
    bool const is_ghost = IsGhost();

    // Update links. This includes the geometry of the KinBody.
    for (LinkPtr link : kinbody->GetLinks()) {
        LinkMarkerWrapper &wrapper = link_markers_[link.get()];
        LinkMarkerPtr &link_marker = wrapper.link_marker;
        if (!link_marker) {
            link_marker = boost::make_shared<LinkMarker>(server_, link, is_ghost);
            CreateMenu(wrapper);
            UpdateMenu(wrapper);
        }
        link_marker->EnvironmentSync();
    }

    // Update joints.
    if (has_joint_controls_) {
        for (JointPtr joint : kinbody->GetJoints()) {
            JointMarkerPtr &joint_marker = joint_markers_[joint.get()];
            if (!joint_marker) {
                joint_marker = boost::make_shared<JointMarker>(server_, joint);
            }
            joint_marker->EnvironmentSync();
        }
    } else {
        joint_markers_.clear();
    }

#if 0
    // Also update manipulators if we're a robot.
    if (robot_ && !ManipulatorMarker::IsGhost(kinbody_)) { for (ManipulatorPtr const manipulator : robot_->GetManipulators()) {
            auto const it = manipulator_markers_.find(manipulator.get());
            BOOST_ASSERT(it != manipulator_markers_.end());
            it->second->EnvironmentSync();
        }
    }
#endif
}

void KinBodyMarker::CreateMenu(LinkMarkerWrapper &link_wrapper)
{
    typedef boost::optional<EntryHandle> Opt;

    BOOST_ASSERT(!link_wrapper.has_menu);
    auto const cb = boost::bind(&KinBodyMarker::MenuCallback, this,
                                ref(link_wrapper), _1);

    MenuHandler &menu_handler = link_wrapper.link_marker->menu_handler();
    EntryHandle parent = menu_handler.insert("Body");
    link_wrapper.menu_parent = Opt(parent);
    link_wrapper.menu_enabled = Opt(menu_handler.insert(parent, "Enabled", cb));
    link_wrapper.menu_visible = Opt(menu_handler.insert(parent, "Visible", cb));
    link_wrapper.menu_joints = Opt(menu_handler.insert(parent, "Joint Controls", cb));

    std::vector<ManipulatorPtr> manipulators;
    GetManipulators(link_wrapper.link_marker->link(), &manipulators);
    for (ManipulatorPtr const &manipulator : manipulators) {
        menu_handler.insert("Manipulator: " + manipulator->GetName());
    }

    link_wrapper.has_menu = true;
}

void KinBodyMarker::UpdateMenu()
{
    for (LinkMarkerWrapper &marker_wrapper : link_markers_ | map_values) {
        UpdateMenu(marker_wrapper);
        marker_wrapper.link_marker->UpdateMenu();
        // TODO: How can the link notify us that our menu changed?
    }
}

void KinBodyMarker::UpdateMenu(LinkMarkerWrapper &link_wrapper)
{
    if (!link_wrapper.has_menu) {
        return;
    }

    MenuHandler &menu_handler = link_wrapper.link_marker->menu_handler();
    LinkPtr const link = link_wrapper.link_marker->link();

    menu_handler.setCheckState(*link_wrapper.menu_enabled,
        BoolToCheckState(link->IsEnabled()));
    menu_handler.setCheckState(*link_wrapper.menu_visible,
        BoolToCheckState(link->IsVisible()));
    menu_handler.setCheckState(*link_wrapper.menu_joints,
        BoolToCheckState(has_joint_controls_));
}

void KinBodyMarker::MenuCallback(LinkMarkerWrapper &link_wrapper,
                                 InteractiveMarkerFeedbackConstPtr const &feedback)
{
    MenuHandler &menu_handler = link_wrapper.link_marker->menu_handler();
    KinBodyPtr kinbody = kinbody_.lock();

    // Toggle kinbody collision checking.
    if (feedback->menu_entry_id == *link_wrapper.menu_enabled) {
        MenuHandler::CheckState enabled_state;
        menu_handler.getCheckState(*link_wrapper.menu_enabled, enabled_state);
        bool const is_enabled = !CheckStateToBool(enabled_state);
        kinbody->Enable(is_enabled);
        RAVELOG_DEBUG("Toggled enable to %d for '%s'\n",
            is_enabled, kinbody->GetName().c_str());
    }
    // Toggle kinbody visibility.
    else if (feedback->menu_entry_id == *link_wrapper.menu_visible) {
        MenuHandler::CheckState visible_state;
        menu_handler.getCheckState(*link_wrapper.menu_visible, visible_state);
        bool const is_visible = !CheckStateToBool(visible_state);
        kinbody->SetVisible(is_visible);
        RAVELOG_DEBUG("Toggled visible to %d for '%s'\n",
            is_visible, kinbody->GetName().c_str());
    }
    // Toggle joint controls.
    else if (feedback->menu_entry_id == *link_wrapper.menu_joints) {
        MenuHandler::CheckState joints_state;
        menu_handler.getCheckState(*link_wrapper.menu_joints, joints_state);
        has_joint_controls_ = !CheckStateToBool(joints_state);
        RAVELOG_DEBUG("Toggled joint controls to %d for '%s'\n",
            has_joint_controls_, kinbody->GetName().c_str());
    }

    UpdateMenu();
}

void KinBodyMarker::GetManipulators(
        LinkPtr link, std::vector<ManipulatorPtr> *manipulators) const
{
    BOOST_ASSERT(link);
    BOOST_ASSERT(manipulators);

    // Only robots have manipulators.
    KinBodyPtr const body = link->GetParent();
    auto const robot = boost::dynamic_pointer_cast<RobotBase>(body);
    if (!robot) {
        return;
    }

    for (ManipulatorPtr const &manipulator : robot->GetManipulators()) {
        // Check if this link is in the manipulator chain.
        LinkPtr const base_link = manipulator->GetBase();
        LinkPtr const tip_link = manipulator->GetEndEffector();
        std::vector<LinkPtr> chain_links;
        bool const success = robot->GetChain(
                base_link->GetIndex(), tip_link->GetIndex(), chain_links);
        BOOST_ASSERT(success);

        auto const it = std::find(chain_links.begin(), chain_links.end(), link);
        if (it != chain_links.end()) {
            manipulators->push_back(manipulator);
            continue;
        }

#if 0
        // Check if this link is a child (i.e. part of the end-effector)..
        if (manipulator->IsChildLink(link)) {
            manipulators->push_back(manipulator);
            continue;
        }
#endif
    }
}

void KinBodyMarker::CreateGhost()
{
    KinBodyPtr kinbody = kinbody_.lock();

    EnvironmentBasePtr env = kinbody->GetEnv();
    if (kinbody->IsRobot()) {
        ghost_robot_ = OpenRAVE::RaveCreateRobot(env, "");
        ghost_kinbody_ = ghost_robot_;
    } else {
        ghost_kinbody_ = OpenRAVE::RaveCreateKinBody(env, "");
    }

    ghost_robot_->Clone(kinbody, OpenRAVE::Clone_Bodies);
    ghost_robot_->SetName(kinbody->GetName() + ".Ghost");
    ghost_robot_->Enable(false);
    env->Add(ghost_kinbody_, true);
}

}
<commit_msg>Fixed manipulator child link logic.<commit_after>#include <boost/format.hpp>
#include <boost/make_shared.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/range/adaptor/map.hpp>
#include "KinBodyMarker.h"

using boost::ref;
using boost::format;
using boost::str;
using boost::algorithm::ends_with;
using boost::adaptors::map_values;
using OpenRAVE::EnvironmentBasePtr;
using OpenRAVE::KinBodyPtr;
using OpenRAVE::KinBodyWeakPtr;
using OpenRAVE::RobotBase;
using OpenRAVE::RobotBaseWeakPtr;
using visualization_msgs::InteractiveMarkerFeedbackConstPtr;
using interactive_markers::InteractiveMarkerServer;
using interactive_markers::MenuHandler;

typedef OpenRAVE::KinBody::LinkPtr LinkPtr;
typedef OpenRAVE::RobotBase::ManipulatorPtr ManipulatorPtr;
typedef boost::shared_ptr<InteractiveMarkerServer> InteractiveMarkerServerPtr;
typedef MenuHandler::EntryHandle EntryHandle;

namespace or_interactivemarker {

// TODO: Move this to a helper header.
static MenuHandler::CheckState BoolToCheckState(bool const &flag)
{
    if (flag) {
        return MenuHandler::CHECKED;
    } else {
        return MenuHandler::UNCHECKED;
    }
}

static bool CheckStateToBool(MenuHandler::CheckState const &state)
{
    return state == MenuHandler::CHECKED;
}

KinBodyMarker::KinBodyMarker(InteractiveMarkerServerPtr server,
                             KinBodyPtr kinbody)
    : server_(server)
    , kinbody_(kinbody)
    , robot_(boost::dynamic_pointer_cast<RobotBase>(kinbody))
    , has_joint_controls_(false)
{
    BOOST_ASSERT(server);
    BOOST_ASSERT(kinbody);

#if 0
    if (!IsGhost()) {
        CreateGhost();
    }
#endif
}

KinBodyMarker::~KinBodyMarker()
{
    if (ghost_kinbody_) {
        ghost_kinbody_->GetEnv()->Remove(ghost_kinbody_);
        ghost_kinbody_.reset();
        ghost_robot_.reset();
    }
}

bool KinBodyMarker::IsGhost() const
{
    KinBodyPtr kinbody = kinbody_.lock();
    return ends_with(kinbody->GetName(), ".Ghost");
}

void KinBodyMarker::EnvironmentSync()
{
    typedef OpenRAVE::KinBody::LinkPtr LinkPtr;
    typedef OpenRAVE::KinBody::JointPtr JointPtr;

    KinBodyPtr const kinbody = kinbody_.lock();
    bool const is_ghost = IsGhost();

    // Update links. This includes the geometry of the KinBody.
    for (LinkPtr link : kinbody->GetLinks()) {
        LinkMarkerWrapper &wrapper = link_markers_[link.get()];
        LinkMarkerPtr &link_marker = wrapper.link_marker;
        if (!link_marker) {
            link_marker = boost::make_shared<LinkMarker>(server_, link, is_ghost);
            CreateMenu(wrapper);
            UpdateMenu(wrapper);
        }
        link_marker->EnvironmentSync();
    }

    // Update joints.
    if (has_joint_controls_) {
        for (JointPtr joint : kinbody->GetJoints()) {
            JointMarkerPtr &joint_marker = joint_markers_[joint.get()];
            if (!joint_marker) {
                joint_marker = boost::make_shared<JointMarker>(server_, joint);
            }
            joint_marker->EnvironmentSync();
        }
    } else {
        joint_markers_.clear();
    }

#if 0
    // Also update manipulators if we're a robot.
    if (robot_ && !ManipulatorMarker::IsGhost(kinbody_)) { for (ManipulatorPtr const manipulator : robot_->GetManipulators()) {
            auto const it = manipulator_markers_.find(manipulator.get());
            BOOST_ASSERT(it != manipulator_markers_.end());
            it->second->EnvironmentSync();
        }
    }
#endif
}

void KinBodyMarker::CreateMenu(LinkMarkerWrapper &link_wrapper)
{
    typedef boost::optional<EntryHandle> Opt;

    BOOST_ASSERT(!link_wrapper.has_menu);
    auto const cb = boost::bind(&KinBodyMarker::MenuCallback, this,
                                ref(link_wrapper), _1);

    MenuHandler &menu_handler = link_wrapper.link_marker->menu_handler();
    EntryHandle parent = menu_handler.insert("Body");
    link_wrapper.menu_parent = Opt(parent);
    link_wrapper.menu_enabled = Opt(menu_handler.insert(parent, "Enabled", cb));
    link_wrapper.menu_visible = Opt(menu_handler.insert(parent, "Visible", cb));
    link_wrapper.menu_joints = Opt(menu_handler.insert(parent, "Joint Controls", cb));

    std::vector<ManipulatorPtr> manipulators;
    GetManipulators(link_wrapper.link_marker->link(), &manipulators);
    for (ManipulatorPtr const &manipulator : manipulators) {
        menu_handler.insert("Manipulator: " + manipulator->GetName());
    }

    link_wrapper.has_menu = true;
}

void KinBodyMarker::UpdateMenu()
{
    for (LinkMarkerWrapper &marker_wrapper : link_markers_ | map_values) {
        UpdateMenu(marker_wrapper);
        marker_wrapper.link_marker->UpdateMenu();
        // TODO: How can the link notify us that our menu changed?
    }
}

void KinBodyMarker::UpdateMenu(LinkMarkerWrapper &link_wrapper)
{
    if (!link_wrapper.has_menu) {
        return;
    }

    MenuHandler &menu_handler = link_wrapper.link_marker->menu_handler();
    LinkPtr const link = link_wrapper.link_marker->link();

    menu_handler.setCheckState(*link_wrapper.menu_enabled,
        BoolToCheckState(link->IsEnabled()));
    menu_handler.setCheckState(*link_wrapper.menu_visible,
        BoolToCheckState(link->IsVisible()));
    menu_handler.setCheckState(*link_wrapper.menu_joints,
        BoolToCheckState(has_joint_controls_));
}

void KinBodyMarker::MenuCallback(LinkMarkerWrapper &link_wrapper,
                                 InteractiveMarkerFeedbackConstPtr const &feedback)
{
    MenuHandler &menu_handler = link_wrapper.link_marker->menu_handler();
    KinBodyPtr kinbody = kinbody_.lock();

    // Toggle kinbody collision checking.
    if (feedback->menu_entry_id == *link_wrapper.menu_enabled) {
        MenuHandler::CheckState enabled_state;
        menu_handler.getCheckState(*link_wrapper.menu_enabled, enabled_state);
        bool const is_enabled = !CheckStateToBool(enabled_state);
        kinbody->Enable(is_enabled);
        RAVELOG_DEBUG("Toggled enable to %d for '%s'\n",
            is_enabled, kinbody->GetName().c_str());
    }
    // Toggle kinbody visibility.
    else if (feedback->menu_entry_id == *link_wrapper.menu_visible) {
        MenuHandler::CheckState visible_state;
        menu_handler.getCheckState(*link_wrapper.menu_visible, visible_state);
        bool const is_visible = !CheckStateToBool(visible_state);
        kinbody->SetVisible(is_visible);
        RAVELOG_DEBUG("Toggled visible to %d for '%s'\n",
            is_visible, kinbody->GetName().c_str());
    }
    // Toggle joint controls.
    else if (feedback->menu_entry_id == *link_wrapper.menu_joints) {
        MenuHandler::CheckState joints_state;
        menu_handler.getCheckState(*link_wrapper.menu_joints, joints_state);
        has_joint_controls_ = !CheckStateToBool(joints_state);
        RAVELOG_DEBUG("Toggled joint controls to %d for '%s'\n",
            has_joint_controls_, kinbody->GetName().c_str());
    }

    UpdateMenu();
}

void KinBodyMarker::GetManipulators(
        LinkPtr link, std::vector<ManipulatorPtr> *manipulators) const
{
    BOOST_ASSERT(link);
    BOOST_ASSERT(manipulators);

    // Only robots have manipulators.
    KinBodyPtr const body = link->GetParent();
    auto const robot = boost::dynamic_pointer_cast<RobotBase>(body);
    if (!robot) {
        return;
    }

    for (ManipulatorPtr const &manipulator : robot->GetManipulators()) {
        // Check if this link is in the manipulator chain.
        LinkPtr const base_link = manipulator->GetBase();
        LinkPtr const tip_link = manipulator->GetEndEffector();
        std::vector<LinkPtr> chain_links;
        bool const success = robot->GetChain(
                base_link->GetIndex(), tip_link->GetIndex(), chain_links);
        BOOST_ASSERT(success);

        auto const chain_it = std::find(chain_links.begin(), chain_links.end(), link);
        if (chain_it != chain_links.end()) {
            manipulators->push_back(manipulator);
            continue;
        }

        // Check if this link is a child (i.e. part of the end-effector).
        // TODO: This is necessary because IsChildLink is broken.
        std::vector<LinkPtr> child_links;
        manipulator->GetChildLinks(child_links);

        auto const child_it = std::find(child_links.begin(), child_links.end(), link);
        if (child_it != child_links.end()) {
            manipulators->push_back(manipulator);
            continue;
        }
    }
}

void KinBodyMarker::CreateGhost()
{
    KinBodyPtr kinbody = kinbody_.lock();

    EnvironmentBasePtr env = kinbody->GetEnv();
    if (kinbody->IsRobot()) {
        ghost_robot_ = OpenRAVE::RaveCreateRobot(env, "");
        ghost_kinbody_ = ghost_robot_;
    } else {
        ghost_kinbody_ = OpenRAVE::RaveCreateKinBody(env, "");
    }

    ghost_robot_->Clone(kinbody, OpenRAVE::Clone_Bodies);
    ghost_robot_->SetName(kinbody->GetName() + ".Ghost");
    ghost_robot_->Enable(false);
    env->Add(ghost_kinbody_, true);
}

}
<|endoftext|>


<commit_before>#include <PCU.h>
#include "phPartition.h"
#include "phInput.h"
#include <parma.h>
#include <apfZoltan.h>
#include <apfMDS.h>
#include <apfMesh2.h>

namespace ph {

apf::Migration* getSplitPlan(Input& in, apf::Mesh2* m)
{
  assert(in.recursivePtn <= 1);
  assert(in.splitFactor >= 1);
  apf::Migration* plan;
  if (in.splitFactor != 1) {
    apf::Splitter* splitter;
    if (in.partitionMethod == "rib") { //prefer SCOREC RIB over Zoltan RIB
      splitter = Parma_MakeRibSplitter(m);
    } else {
      std::map<std::string, int> methodMap;
      methodMap["graph"] = apf::GRAPH;
      methodMap["hypergraph"] = apf::HYPERGRAPH;
      int method = methodMap[in.partitionMethod];
      splitter = apf::makeZoltanSplitter(m, method, apf::REPARTITION);
    }
    apf::MeshTag* weights = Parma_WeighByMemory(m);
    plan = splitter->split(weights, 1.03, in.splitFactor);
    apf::removeTagFromDimension(m, weights, m->getDimension());
    m->destroyTag(weights);
    delete splitter;
  } else {
    plan = new apf::Migration(m);
  }
  return plan;
}

void split(Input& in, apf::Mesh2* m, void (*runAfter)(apf::Mesh2*))
{
  apf::splitMdsMesh(m, getSplitPlan(in, m), in.splitFactor, runAfter);
}

apf::Migration* split(Input& in, apf::Mesh2* m)
{
  return getSplitPlan(in,m);
}

bool isMixed(apf::Mesh2* m) {
  int mixed = 0;
  apf::MeshEntity* e;
  apf::MeshIterator* it = m->begin(m->getDimension());
  while ((e = m->iterate(it)))
    if ( m->getType(e) != apf::Mesh::TET ) {
      mixed = 1;
      break;
    }
  m->end(it);
  PCU_Max_Ints(&mixed, 1);
  return mixed;
}

void setWeight(apf::Mesh* m, apf::MeshTag* tag, int dim) {
  double w = 1.0;
  apf::MeshEntity* e;
  apf::MeshIterator* it = m->begin(dim);
  while ((e = m->iterate(it)))
    m->setDoubleTag(e, tag, &w);
  m->end(it);
}

apf::MeshTag* setWeights(apf::Mesh* m) {
  apf::MeshTag* tag = m->createDoubleTag("parma_weight", 1);
  setWeight(m, tag, 0);
  setWeight(m, tag, m->getDimension());
  return tag;
}

void clearTags(apf::Mesh* m, apf::MeshTag* t) {
  apf::removeTagFromDimension(m, t, 0);
  apf::removeTagFromDimension(m, t, m->getDimension());
}

void balance(apf::Mesh2* m)
{
  bool fineStats=false; // set to true for per part stats
  Parma_PrintPtnStats(m, "preRefine", fineStats);
  if ( isMixed(m) ) {

    apf::MeshTag* weights = Parma_WeighByMemory(m);
    double tolerance = 1.05;
    const double step = 0.2;
    const int verbose = 0;
    apf::Balancer* balancer = Parma_MakeElmBalancer(m, step, verbose);
    balancer->balance(weights, tolerance);
    delete balancer;
    apf::removeTagFromDimension(m, weights, m->getDimension());
    m->destroyTag(weights);

  } else {
    apf::MeshTag* weights = setWeights(m);
    const double vtxImbTol = 1.03;
    const double step = 0.3;
    const int verbose = 1;  // set to 2 for per iteration stats
    const double ignored = 42.42;

    Parma_ProcessDisconnectedParts(m);
    Parma_PrintPtnStats(m, "post ProcessDisconnectedParts", fineStats);

    apf::Balancer* balancer = Parma_MakeHpsBalancer(m,verbose);
    balancer->balance(weights, ignored);
    delete balancer;
    Parma_PrintPtnStats(m, "post HPS", fineStats);

    for(int i=0; i<3; i++) {
      balancer = Parma_MakeVtxElmBalancer(m, step, verbose);
      balancer->balance(weights, vtxImbTol);
      Parma_PrintPtnStats(m, "post Parma_MakeVtxElmBalancer", fineStats);
      delete balancer;
      double vtxImb = Parma_GetWeightedEntImbalance(m, weights, 0);
      if( vtxImb <= vtxImbTol ) {
        if( !PCU_Comm_Self() )
          fprintf(stdout, "STATUS vtx imbalance target %.3f reached\n",
            vtxImbTol);
        break;
      }
    }
    clearTags(m, weights);
    m->destroyTag(weights);
  }
}

}
<commit_msg>remove hps and disconnected part fixing<commit_after>#include <PCU.h>
#include "phPartition.h"
#include "phInput.h"
#include <parma.h>
#include <apfZoltan.h>
#include <apfMDS.h>
#include <apfMesh2.h>

namespace ph {

apf::Migration* getSplitPlan(Input& in, apf::Mesh2* m)
{
  assert(in.recursivePtn <= 1);
  assert(in.splitFactor >= 1);
  apf::Migration* plan;
  if (in.splitFactor != 1) {
    apf::Splitter* splitter;
    if (in.partitionMethod == "rib") { //prefer SCOREC RIB over Zoltan RIB
      splitter = Parma_MakeRibSplitter(m);
    } else {
      std::map<std::string, int> methodMap;
      methodMap["graph"] = apf::GRAPH;
      methodMap["hypergraph"] = apf::HYPERGRAPH;
      int method = methodMap[in.partitionMethod];
      splitter = apf::makeZoltanSplitter(m, method, apf::REPARTITION);
    }
    apf::MeshTag* weights = Parma_WeighByMemory(m);
    plan = splitter->split(weights, 1.03, in.splitFactor);
    apf::removeTagFromDimension(m, weights, m->getDimension());
    m->destroyTag(weights);
    delete splitter;
  } else {
    plan = new apf::Migration(m);
  }
  return plan;
}

void split(Input& in, apf::Mesh2* m, void (*runAfter)(apf::Mesh2*))
{
  apf::splitMdsMesh(m, getSplitPlan(in, m), in.splitFactor, runAfter);
}

apf::Migration* split(Input& in, apf::Mesh2* m)
{
  return getSplitPlan(in,m);
}

bool isMixed(apf::Mesh2* m) {
  int mixed = 0;
  apf::MeshEntity* e;
  apf::MeshIterator* it = m->begin(m->getDimension());
  while ((e = m->iterate(it)))
    if ( m->getType(e) != apf::Mesh::TET ) {
      mixed = 1;
      break;
    }
  m->end(it);
  PCU_Max_Ints(&mixed, 1);
  return mixed;
}

void setWeight(apf::Mesh* m, apf::MeshTag* tag, int dim) {
  double w = 1.0;
  apf::MeshEntity* e;
  apf::MeshIterator* it = m->begin(dim);
  while ((e = m->iterate(it)))
    m->setDoubleTag(e, tag, &w);
  m->end(it);
}

apf::MeshTag* setWeights(apf::Mesh* m) {
  apf::MeshTag* tag = m->createDoubleTag("parma_weight", 1);
  setWeight(m, tag, 0);
  setWeight(m, tag, m->getDimension());
  return tag;
}

void clearTags(apf::Mesh* m, apf::MeshTag* t) {
  apf::removeTagFromDimension(m, t, 0);
  apf::removeTagFromDimension(m, t, m->getDimension());
}

void balance(apf::Mesh2* m)
{
  bool fineStats=false; // set to true for per part stats
  Parma_PrintPtnStats(m, "preRefine", fineStats);
  if ( isMixed(m) ) {

    apf::MeshTag* weights = Parma_WeighByMemory(m);
    double tolerance = 1.05;
    const double step = 0.2;
    const int verbose = 0;
    apf::Balancer* balancer = Parma_MakeElmBalancer(m, step, verbose);
    balancer->balance(weights, tolerance);
    delete balancer;
    apf::removeTagFromDimension(m, weights, m->getDimension());
    m->destroyTag(weights);

  } else {
    apf::MeshTag* weights = setWeights(m);
    const double vtxImbTol = 1.03;
    const double step = 0.3;
    const int verbose = 1;  // set to 2 for per iteration stats

    for(int i=0; i<3; i++) {
      apf::Balancer* balancer = Parma_MakeVtxElmBalancer(m, step, verbose);
      balancer->balance(weights, vtxImbTol);
      Parma_PrintPtnStats(m, "post Parma_MakeVtxElmBalancer", fineStats);
      delete balancer;
      double vtxImb = Parma_GetWeightedEntImbalance(m, weights, 0);
      if( vtxImb <= vtxImbTol ) {
        if( !PCU_Comm_Self() )
          fprintf(stdout, "STATUS vtx imbalance target %.3f reached\n",
            vtxImbTol);
        break;
      }
    }
    clearTags(m, weights);
    m->destroyTag(weights);
  }
}

}
<|endoftext|>