<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 "UUID.h"
#include <stdio.h>
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#include <decaf/lang/Pointer.h>
#include <decaf/lang/Long.h>
#include <decaf/internal/util/StringUtils.h>
#include <decaf/lang/exceptions/RuntimeException.h>
#include <decaf/lang/exceptions/UnsupportedOperationException.h>
#include <decaf/lang/exceptions/IllegalArgumentException.h>
#include <decaf/security/SecureRandom.h>
#include <decaf/security/MessageDigest.h>
#include <decaf/security/NoSuchAlgorithmException.h>

using namespace std;
using namespace decaf;
using namespace decaf::util;
using namespace decaf::internal::util;
using namespace decaf::lang;
using namespace decaf::lang::exceptions;
using namespace decaf::security;

////////////////////////////////////////////////////////////////////////////////
namespace decaf {
namespace util {

    class UUIDImpl {
    private:

        UUIDImpl(const UUIDImpl&);
        UUIDImpl& operator= (const UUIDImpl&);

    public:

        unsigned long long mostSigBits;
        unsigned long long leastSigBits;

        int variant;
        int version;
        long long timestamp;
        int clockSequence;
        long long node;
        int hash;

        UUIDImpl() : mostSigBits(0), leastSigBits(0), variant(0),
                     version(0), timestamp(0), clockSequence(0), node(0), hash(0) {
        }

        UUIDImpl(long long mostSigBits, long long leastSigBits) :
            mostSigBits(mostSigBits), leastSigBits(leastSigBits), variant(0),
            version(0), timestamp(0), clockSequence(0), node(0), hash(0) {

            init();
        }

    private:

        void init() {

            // setup hash field
            int msbHash = (int) (mostSigBits ^ (mostSigBits >> 32));
            int lsbHash = (int) (leastSigBits ^ (leastSigBits >> 32));
            hash = msbHash ^ lsbHash;

            // setup variant field
            if ((leastSigBits & 0x8000000000000000ULL) == 0) {
                // MSB0 not set, NCS backwards compatibility variant
                variant = 0;
            } else if ((leastSigBits & 0x4000000000000000ULL) != 0) {
                // MSB1 set, either MS reserved or future reserved
                variant = (int) ((leastSigBits & 0xE000000000000000ULL) >> 61);
            } else {
                // MSB1 not set, RFC 4122 variant
                variant = 2;
            }

            // setup version field
            version = (int) ((mostSigBits & 0x000000000000F000ULL) >> 12);

            if (variant != 2 && version != 1) {
                return;
            }

            // setup timestamp field
            long long timeLow = (mostSigBits & 0xFFFFFFFF00000000ULL) >> 32;
            long long timeMid = (mostSigBits & 0x00000000FFFF0000ULL) << 16;
            long long timeHigh = (mostSigBits & 0x0000000000000FFFULL) << 48;
            timestamp = timeLow | timeMid | timeHigh;

            // setup clock sequence field
            clockSequence = (int) ((leastSigBits & 0x3FFF000000000000ULL) >> 48);

            // setup node field
            node = (leastSigBits & 0x0000FFFFFFFFFFFFL);
        }

    public:

        std::string toString() const {
            std::string builder;
            std::string msbStr = Long::toHexString(mostSigBits);
            if (msbStr.length() < 16) {
                int diff = 16 - (int)msbStr.length();
                for (int i = 0; i < diff; i++) {
                    builder.append("0");
                }
            }
            builder.append(msbStr);
            builder.insert(8, "-");
            builder.insert(13, "-");
            builder.append("-");
            std::string lsbStr = Long::toHexString(leastSigBits);
            if (lsbStr.length() < 16) {
                int diff = 16 - (int)lsbStr.length();
                for (int i = 0; i < diff; i++) {
                    builder.append("0");
                }
            }
            builder.append(lsbStr);
            builder.insert(23, "-");
            return builder;
        }
    };

}}

////////////////////////////////////////////////////////////////////////////////
UUID::UUID(long long mostSigBits, long long leastSigBits) : uuid(new UUIDImpl(mostSigBits, leastSigBits)) {

}

////////////////////////////////////////////////////////////////////////////////
UUID::UUID(const UUID& source) :
    uuid(new UUIDImpl(source.getMostSignificantBits(), source.getLeastSignificantBits())) {
}

////////////////////////////////////////////////////////////////////////////////
UUID& UUID::operator= (const UUID& source) {
    delete this->uuid;
    this->uuid = new UUIDImpl(source.getMostSignificantBits(), source.getLeastSignificantBits());
    return *this;
}

////////////////////////////////////////////////////////////////////////////////
UUID::~UUID() {
    delete this->uuid;
}

////////////////////////////////////////////////////////////////////////////////
int UUID::compareTo(const UUID& value) const {
    return StringUtils::compare(this->toString().c_str(), value.toString().c_str());
}

////////////////////////////////////////////////////////////////////////////////
bool UUID::equals(const UUID& value) const {
    return this->getMostSignificantBits() == value.getMostSignificantBits() &&
           this->getLeastSignificantBits() == value.getLeastSignificantBits();
}

////////////////////////////////////////////////////////////////////////////////
int UUID::hashCode() const {
    return this->uuid->hash;
}

////////////////////////////////////////////////////////////////////////////////
bool UUID::operator==(const UUID& value) const {
    return this->equals(value);
}

////////////////////////////////////////////////////////////////////////////////
bool UUID::operator<(const UUID& value) const {
    return this->compareTo(value) == -1 ? true : false;
}

////////////////////////////////////////////////////////////////////////////////
std::string UUID::toString() const {
    return this->uuid->toString();
}

////////////////////////////////////////////////////////////////////////////////
long long UUID::getLeastSignificantBits() const {
    return this->uuid->leastSigBits;
}

////////////////////////////////////////////////////////////////////////////////
long long UUID::getMostSignificantBits() const {
    return this->uuid->mostSigBits;
}

////////////////////////////////////////////////////////////////////////////////
long long UUID::node() {

    if (this->version() != 1) {
        throw exceptions::UnsupportedOperationException(
            __FILE__, __LINE__, "UUID::node - Only a Version 1 UUID supports this operation.");
    }

    return (this->uuid->leastSigBits & 0x0000FFFFFFFFFFFFULL);
}

////////////////////////////////////////////////////////////////////////////////
long long UUID::timestamp() {

    if (this->version() != 1) {
        throw exceptions::UnsupportedOperationException(
            __FILE__, __LINE__, "UUID::node - Only a Version 1 UUID supports this operation.");
    }

    // Mask out the version and shift values around to make time.
    long long timeLow = (uuid->mostSigBits & 0xFFFFFFFF00000000ULL) >> 32;
    long long timeMid = (uuid->mostSigBits & 0x00000000FFFF0000ULL) << 16;
    long long timeHigh = (uuid->mostSigBits & 0x0000000000000FFFULL) << 48;

    return timeLow | timeMid | timeHigh;
}

////////////////////////////////////////////////////////////////////////////////
int UUID::clockSequence() {

    if (this->version() != 1) {
        throw exceptions::UnsupportedOperationException(
            __FILE__, __LINE__, "UUID::node - Only a Version 1 UUID supports this operation.");
    }

    return (int) ((this->uuid->leastSigBits & 0x3FFF000000000000ULL) >> 48);
}

////////////////////////////////////////////////////////////////////////////////
int UUID::variant() {

    // determine variant field
    if ((this->uuid->leastSigBits & 0x8000000000000000ULL) == 0) {
        // MSB0 not set, NCS backwards compatibility variant
        return 0;
    } else if ((this->uuid->leastSigBits & 0x4000000000000000ULL) != 0) {
        // MSB1 set, either MS reserved or future reserved
        return (int) ((this->uuid->leastSigBits & 0xE000000000000000ULL) >> 61);
    }

    // MSB1 not set, RFC 4122 variant
    return 2;
}

////////////////////////////////////////////////////////////////////////////////
int UUID::version() {
    return this->uuid->version;
}

////////////////////////////////////////////////////////////////////////////////
UUID UUID::randomUUID() {

    unsigned char data[16];
    SecureRandom secRand;
    secRand.nextBytes(data, 16);

    long long msb = 0;
    long long lsb = 0;

    msb = (data[0] & 0xFFLL) << 56;
    msb |= (data[1] & 0xFFLL) << 48;
    msb |= (data[2] & 0xFFLL) << 40;
    msb |= (data[3] & 0xFFLL) << 32;
    msb |= (data[4] & 0xFFLL) << 24;
    msb |= (data[5] & 0xFFLL) << 16;
    msb |= (data[6] & 0x0FLL) << 8;
    msb |= (0x4LL << 12); // set the version to 4
    msb |= (data[7] & 0xFFLL);

    lsb = (data[8] & 0x3FLL) << 56;
    lsb |= (0x2LL << 62); // set the variant to bits 01
    lsb |= (data[9] & 0xFFLL) << 48;
    lsb |= (data[10] & 0xFFLL) << 40;
    lsb |= (data[11] & 0xFFLL) << 32;
    lsb |= (data[12] & 0xFFLL) << 24;
    lsb |= (data[13] & 0xFFLL) << 16;
    lsb |= (data[14] & 0xFFLL) << 8;
    lsb |= (data[15] & 0xFFLL);

    return UUID(msb, lsb);
}

////////////////////////////////////////////////////////////////////////////////
UUID UUID::nameUUIDFromBytes(const std::vector<char>& name) {
    return UUID::nameUUIDFromBytes(&name[0], (int)name.size());
}

////////////////////////////////////////////////////////////////////////////////
UUID UUID::nameUUIDFromBytes(const char* name, int size) {

    if (name == NULL && size > 0) {
        throw NullPointerException(__FILE__, __LINE__, "UUID name buffer was NULL");
    }

    std::vector<unsigned char> hash;

    try {
        Pointer<MessageDigest> digest(MessageDigest::getInstance("MD5"));
        hash = digest->digest((unsigned char*)name, size);
    } catch (NoSuchAlgorithmException& ex) {
        throw exceptions::RuntimeException(
            __FILE__, __LINE__, "UUID::nameUUIDFromBytes - Failed to run MD5 encoder.");
    }

    long long msb = 0;
    long long lsb = 0;

    msb = (hash[0] & 0xFFLL) << 56;
    msb |= (hash[1] & 0xFFLL) << 48;
    msb |= (hash[2] & 0xFFLL) << 40;
    msb |= (hash[3] & 0xFFLL) << 32;
    msb |= (hash[4] & 0xFFLL) << 24;
    msb |= (hash[5] & 0xFFLL) << 16;
    msb |= (hash[6] & 0x0FLL) << 8;
    msb |= (0x3LL << 12); // set the version to 3
    msb |= (hash[7] & 0xFFLL);

    lsb = (hash[8] & 0x3FLL) << 56;
    lsb |= (0x2LL << 62); // set the variant to bits 01
    lsb |= (hash[9] & 0xFFLL) << 48;
    lsb |= (hash[10] & 0xFFLL) << 40;
    lsb |= (hash[11] & 0xFFLL) << 32;
    lsb |= (hash[12] & 0xFFLL) << 24;
    lsb |= (hash[13] & 0xFFLL) << 16;
    lsb |= (hash[14] & 0xFFLL) << 8;
    lsb |= (hash[15] & 0xFFLL);

    return UUID(msb, lsb);
}

////////////////////////////////////////////////////////////////////////////////
UUID UUID::fromString(const std::string& uuid) {

    static const int POS_SIZE = 5;

    int position[5];
    int lastPosition = 1;
    int startPosition = 0;

    int i = 0;
    for (; i < POS_SIZE && lastPosition > 0; i++) {
        position[i] = (int)uuid.find("-", startPosition);
        lastPosition = position[i];
        startPosition = position[i] + 1;
    }

    // should have and only can have four "-" in UUID
    if (i != POS_SIZE || lastPosition != -1) {
        throw IllegalArgumentException(__FILE__, __LINE__,
            "Invalid UUID string %s", uuid.c_str());
    }

    if (position[0] == 0) {
        throw IllegalArgumentException(__FILE__, __LINE__,
            "Invalid UUID string %s", uuid.c_str());
    } else if (((position[1] - position[0]) - 1) <= 0) {
        throw IllegalArgumentException(__FILE__, __LINE__,
            "Invalid UUID string %s", uuid.c_str());
    } else if (((position[2] - position[1]) - 1) <= 0) {
        throw IllegalArgumentException(__FILE__, __LINE__,
            "Invalid UUID string %s", uuid.c_str());
    } else if ((position[3] + 1) >= (int)uuid.length()) {
        throw IllegalArgumentException(__FILE__, __LINE__,
            "Invalid UUID string %s", uuid.c_str());
    }

    long long m1 = Long::parseLong(uuid.substr(0, position[0]), 16);
    long long m2 = Long::parseLong(uuid.substr(position[0] + 1, (position[1] - position[0]) - 1), 16);
    long long m3 = Long::parseLong(uuid.substr(position[1] + 1, (position[2] - position[1]) - 1), 16);

    long long lsb1 = Long::parseLong(uuid.substr(position[2] + 1, (position[3] - position[2]) - 1), 16);
    long long lsb2 = Long::parseLong(uuid.substr(position[3] + 1), 16);

    long long msb = (m1 << 32) | (m2 << 16) | m3;
    long long lsb = (lsb1 << 48) | lsb2;

    return UUID(msb, lsb);
}
<commit_msg>Fix issue found on windows<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 "UUID.h"
#include <stdio.h>
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#include <decaf/lang/Pointer.h>
#include <decaf/lang/Long.h>
#include <decaf/internal/util/StringUtils.h>
#include <decaf/lang/exceptions/RuntimeException.h>
#include <decaf/lang/exceptions/UnsupportedOperationException.h>
#include <decaf/lang/exceptions/IllegalArgumentException.h>
#include <decaf/security/SecureRandom.h>
#include <decaf/security/MessageDigest.h>
#include <decaf/security/NoSuchAlgorithmException.h>

using namespace std;
using namespace decaf;
using namespace decaf::util;
using namespace decaf::internal::util;
using namespace decaf::lang;
using namespace decaf::lang::exceptions;
using namespace decaf::security;

////////////////////////////////////////////////////////////////////////////////
namespace decaf {
namespace util {

    class UUIDImpl {
    private:

        UUIDImpl(const UUIDImpl&);
        UUIDImpl& operator= (const UUIDImpl&);

    public:

        unsigned long long mostSigBits;
        unsigned long long leastSigBits;

        int variant;
        int version;
        long long timestamp;
        int clockSequence;
        long long node;
        int hash;

        UUIDImpl() : mostSigBits(0), leastSigBits(0), variant(0),
                     version(0), timestamp(0), clockSequence(0), node(0), hash(0) {
        }

        UUIDImpl(long long mostSigBits, long long leastSigBits) :
            mostSigBits(mostSigBits), leastSigBits(leastSigBits), variant(0),
            version(0), timestamp(0), clockSequence(0), node(0), hash(0) {

            init();
        }

    private:

        void init() {

            // setup hash field
            int msbHash = (int) (mostSigBits ^ (mostSigBits >> 32));
            int lsbHash = (int) (leastSigBits ^ (leastSigBits >> 32));
            hash = msbHash ^ lsbHash;

            // setup variant field
            if ((leastSigBits & 0x8000000000000000ULL) == 0) {
                // MSB0 not set, NCS backwards compatibility variant
                variant = 0;
            } else if ((leastSigBits & 0x4000000000000000ULL) != 0) {
                // MSB1 set, either MS reserved or future reserved
                variant = (int) ((leastSigBits & 0xE000000000000000ULL) >> 61);
            } else {
                // MSB1 not set, RFC 4122 variant
                variant = 2;
            }

            // setup version field
            version = (int) ((mostSigBits & 0x000000000000F000ULL) >> 12);

            if (variant != 2 && version != 1) {
                return;
            }

            // setup timestamp field
            long long timeLow = (mostSigBits & 0xFFFFFFFF00000000ULL) >> 32;
            long long timeMid = (mostSigBits & 0x00000000FFFF0000ULL) << 16;
            long long timeHigh = (mostSigBits & 0x0000000000000FFFULL) << 48;
            timestamp = timeLow | timeMid | timeHigh;

            // setup clock sequence field
            clockSequence = (int) ((leastSigBits & 0x3FFF000000000000ULL) >> 48);

            // setup node field
            node = (leastSigBits & 0x0000FFFFFFFFFFFFL);
        }

    public:

        std::string toString() const {
            std::string builder;
            std::string msbStr = Long::toHexString(mostSigBits);
            if (msbStr.length() < 16) {
                int diff = 16 - (int)msbStr.length();
                for (int i = 0; i < diff; i++) {
                    builder.append("0");
                }
            }
            builder.append(msbStr);
            builder.insert(8, "-");
            builder.insert(13, "-");
            builder.append("-");
            std::string lsbStr = Long::toHexString(leastSigBits);
            if (lsbStr.length() < 16) {
                int diff = 16 - (int)lsbStr.length();
                for (int i = 0; i < diff; i++) {
                    builder.append("0");
                }
            }
            builder.append(lsbStr);
            builder.insert(23, "-");
            return builder;
        }
    };

}}

////////////////////////////////////////////////////////////////////////////////
UUID::UUID(long long mostSigBits, long long leastSigBits) : uuid(new UUIDImpl(mostSigBits, leastSigBits)) {

}

////////////////////////////////////////////////////////////////////////////////
UUID::UUID(const UUID& source) :
    uuid(new UUIDImpl(source.getMostSignificantBits(), source.getLeastSignificantBits())) {
}

////////////////////////////////////////////////////////////////////////////////
UUID& UUID::operator= (const UUID& source) {
    delete this->uuid;
    this->uuid = new UUIDImpl(source.getMostSignificantBits(), source.getLeastSignificantBits());
    return *this;
}

////////////////////////////////////////////////////////////////////////////////
UUID::~UUID() {
    delete this->uuid;
}

////////////////////////////////////////////////////////////////////////////////
int UUID::compareTo(const UUID& value) const {
    return StringUtils::compare(this->toString().c_str(), value.toString().c_str());
}

////////////////////////////////////////////////////////////////////////////////
bool UUID::equals(const UUID& value) const {
    return this->getMostSignificantBits() == value.getMostSignificantBits() &&
           this->getLeastSignificantBits() == value.getLeastSignificantBits();
}

////////////////////////////////////////////////////////////////////////////////
int UUID::hashCode() const {
    return this->uuid->hash;
}

////////////////////////////////////////////////////////////////////////////////
bool UUID::operator==(const UUID& value) const {
    return this->equals(value);
}

////////////////////////////////////////////////////////////////////////////////
bool UUID::operator<(const UUID& value) const {
    return this->compareTo(value) == -1 ? true : false;
}

////////////////////////////////////////////////////////////////////////////////
std::string UUID::toString() const {
    return this->uuid->toString();
}

////////////////////////////////////////////////////////////////////////////////
long long UUID::getLeastSignificantBits() const {
    return this->uuid->leastSigBits;
}

////////////////////////////////////////////////////////////////////////////////
long long UUID::getMostSignificantBits() const {
    return this->uuid->mostSigBits;
}

////////////////////////////////////////////////////////////////////////////////
long long UUID::node() {

    if (this->version() != 1) {
        throw exceptions::UnsupportedOperationException(
            __FILE__, __LINE__, "UUID::node - Only a Version 1 UUID supports this operation.");
    }

    return (this->uuid->leastSigBits & 0x0000FFFFFFFFFFFFULL);
}

////////////////////////////////////////////////////////////////////////////////
long long UUID::timestamp() {

    if (this->version() != 1) {
        throw exceptions::UnsupportedOperationException(
            __FILE__, __LINE__, "UUID::node - Only a Version 1 UUID supports this operation.");
    }

    // Mask out the version and shift values around to make time.
    long long timeLow = (uuid->mostSigBits & 0xFFFFFFFF00000000ULL) >> 32;
    long long timeMid = (uuid->mostSigBits & 0x00000000FFFF0000ULL) << 16;
    long long timeHigh = (uuid->mostSigBits & 0x0000000000000FFFULL) << 48;

    return timeLow | timeMid | timeHigh;
}

////////////////////////////////////////////////////////////////////////////////
int UUID::clockSequence() {

    if (this->version() != 1) {
        throw exceptions::UnsupportedOperationException(
            __FILE__, __LINE__, "UUID::node - Only a Version 1 UUID supports this operation.");
    }

    return (int) ((this->uuid->leastSigBits & 0x3FFF000000000000ULL) >> 48);
}

////////////////////////////////////////////////////////////////////////////////
int UUID::variant() {

    // determine variant field
    if ((this->uuid->leastSigBits & 0x8000000000000000ULL) == 0) {
        // MSB0 not set, NCS backwards compatibility variant
        return 0;
    } else if ((this->uuid->leastSigBits & 0x4000000000000000ULL) != 0) {
        // MSB1 set, either MS reserved or future reserved
        return (int) ((this->uuid->leastSigBits & 0xE000000000000000ULL) >> 61);
    }

    // MSB1 not set, RFC 4122 variant
    return 2;
}

////////////////////////////////////////////////////////////////////////////////
int UUID::version() {
    return this->uuid->version;
}

////////////////////////////////////////////////////////////////////////////////
UUID UUID::randomUUID() {

    unsigned char data[16];
    SecureRandom secRand;
    secRand.nextBytes(data, 16);

    long long msb = 0;
    long long lsb = 0;

    msb = (data[0] & 0xFFLL) << 56;
    msb |= (data[1] & 0xFFLL) << 48;
    msb |= (data[2] & 0xFFLL) << 40;
    msb |= (data[3] & 0xFFLL) << 32;
    msb |= (data[4] & 0xFFLL) << 24;
    msb |= (data[5] & 0xFFLL) << 16;
    msb |= (data[6] & 0x0FLL) << 8;
    msb |= (0x4LL << 12); // set the version to 4
    msb |= (data[7] & 0xFFLL);

    lsb = (data[8] & 0x3FLL) << 56;
    lsb |= (0x2LL << 62); // set the variant to bits 01
    lsb |= (data[9] & 0xFFLL) << 48;
    lsb |= (data[10] & 0xFFLL) << 40;
    lsb |= (data[11] & 0xFFLL) << 32;
    lsb |= (data[12] & 0xFFLL) << 24;
    lsb |= (data[13] & 0xFFLL) << 16;
    lsb |= (data[14] & 0xFFLL) << 8;
    lsb |= (data[15] & 0xFFLL);

    return UUID(msb, lsb);
}

////////////////////////////////////////////////////////////////////////////////
UUID UUID::nameUUIDFromBytes(const std::vector<char>& name) {
    if (!name.empty()) {
        return UUID::nameUUIDFromBytes(&name[0], (int)name.size());
    } else {
        return UUID::nameUUIDFromBytes(NULL, 0);
    }
}

////////////////////////////////////////////////////////////////////////////////
UUID UUID::nameUUIDFromBytes(const char* name, int size) {

    if (name == NULL && size > 0) {
        throw NullPointerException(__FILE__, __LINE__, "UUID name buffer was NULL");
    }

    std::vector<unsigned char> hash;

    try {
        Pointer<MessageDigest> digest(MessageDigest::getInstance("MD5"));
        hash = digest->digest((unsigned char*)name, size);
    } catch (NoSuchAlgorithmException& ex) {
        throw exceptions::RuntimeException(
            __FILE__, __LINE__, "UUID::nameUUIDFromBytes - Failed to run MD5 encoder.");
    }

    long long msb = 0;
    long long lsb = 0;

    msb = (hash[0] & 0xFFLL) << 56;
    msb |= (hash[1] & 0xFFLL) << 48;
    msb |= (hash[2] & 0xFFLL) << 40;
    msb |= (hash[3] & 0xFFLL) << 32;
    msb |= (hash[4] & 0xFFLL) << 24;
    msb |= (hash[5] & 0xFFLL) << 16;
    msb |= (hash[6] & 0x0FLL) << 8;
    msb |= (0x3LL << 12); // set the version to 3
    msb |= (hash[7] & 0xFFLL);

    lsb = (hash[8] & 0x3FLL) << 56;
    lsb |= (0x2LL << 62); // set the variant to bits 01
    lsb |= (hash[9] & 0xFFLL) << 48;
    lsb |= (hash[10] & 0xFFLL) << 40;
    lsb |= (hash[11] & 0xFFLL) << 32;
    lsb |= (hash[12] & 0xFFLL) << 24;
    lsb |= (hash[13] & 0xFFLL) << 16;
    lsb |= (hash[14] & 0xFFLL) << 8;
    lsb |= (hash[15] & 0xFFLL);

    return UUID(msb, lsb);
}

////////////////////////////////////////////////////////////////////////////////
UUID UUID::fromString(const std::string& uuid) {

    static const int POS_SIZE = 5;

    int position[5];
    int lastPosition = 1;
    int startPosition = 0;

    int i = 0;
    for (; i < POS_SIZE && lastPosition > 0; i++) {
        position[i] = (int)uuid.find("-", startPosition);
        lastPosition = position[i];
        startPosition = position[i] + 1;
    }

    // should have and only can have four "-" in UUID
    if (i != POS_SIZE || lastPosition != -1) {
        throw IllegalArgumentException(__FILE__, __LINE__,
            "Invalid UUID string %s", uuid.c_str());
    }

    if (position[0] == 0) {
        throw IllegalArgumentException(__FILE__, __LINE__,
            "Invalid UUID string %s", uuid.c_str());
    } else if (((position[1] - position[0]) - 1) <= 0) {
        throw IllegalArgumentException(__FILE__, __LINE__,
            "Invalid UUID string %s", uuid.c_str());
    } else if (((position[2] - position[1]) - 1) <= 0) {
        throw IllegalArgumentException(__FILE__, __LINE__,
            "Invalid UUID string %s", uuid.c_str());
    } else if ((position[3] + 1) >= (int)uuid.length()) {
        throw IllegalArgumentException(__FILE__, __LINE__,
            "Invalid UUID string %s", uuid.c_str());
    }

    long long m1 = Long::parseLong(uuid.substr(0, position[0]), 16);
    long long m2 = Long::parseLong(uuid.substr(position[0] + 1, (position[1] - position[0]) - 1), 16);
    long long m3 = Long::parseLong(uuid.substr(position[1] + 1, (position[2] - position[1]) - 1), 16);

    long long lsb1 = Long::parseLong(uuid.substr(position[2] + 1, (position[3] - position[2]) - 1), 16);
    long long lsb2 = Long::parseLong(uuid.substr(position[3] + 1), 16);

    long long msb = (m1 << 32) | (m2 << 16) | m3;
    long long lsb = (lsb1 << 48) | lsb2;

    return UUID(msb, lsb);
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: accessibleeventnotifier.hxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 02:25:18 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef COMPHELPER_ACCESSIBLE_EVENT_NOTIFIER
#define COMPHELPER_ACCESSIBLE_EVENT_NOTIFIER

#ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLEEVENTOBJECT_HPP_
#include <com/sun/star/accessibility/AccessibleEventObject.hpp>
#endif
#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLEEVENTLISTENER_HPP_
#include <com/sun/star/accessibility/XAccessibleEventListener.hpp>
#endif

#ifndef _THREAD_HXX_
#include <osl/thread.hxx>
#endif
#ifndef _OSL_CONDITN_HXX_
#include <osl/conditn.hxx>
#endif
#ifndef _CPPUHELPER_INTERFACECONTAINER_H_
#include <cppuhelper/interfacecontainer.h>
#endif
#ifndef INCLUDED_COMPHELPERDLLAPI_H
#include "comphelper/comphelperdllapi.h"
#endif

#include <map>
#include <list>

//.........................................................................
namespace comphelper
{
//.........................................................................

    //=====================================================================
    //= AccessibleEventNotifier
    //=====================================================================
    class COMPHELPER_DLLPUBLIC AccessibleEventNotifier
    {
    // typedefs
    public:
        typedef sal_uInt32  TClientId;

        typedef ::std::pair< TClientId, ::com::sun::star::accessibility::AccessibleEventObject >
                                                                                ClientEvent;

        typedef ::cppu::OInterfaceContainerHelper                                   EventListeners;
        typedef ::std::map< TClientId, EventListeners*, ::std::less< TClientId > >  ClientMap;

    protected:
        AccessibleEventNotifier( );     // never implemented
        ~AccessibleEventNotifier( );    // never implemented

    private:
        COMPHELPER_DLLPRIVATE AccessibleEventNotifier( const AccessibleEventNotifier& );                // never implemented!
        COMPHELPER_DLLPRIVATE AccessibleEventNotifier& operator=( const AccessibleEventNotifier& ); // never implemented!

    public:
        /** registers a client of this class, means a broadcaster of AccessibleEvents

No precaution is taken to care for disposal of this component. When the component
            dies, it must call <member>revokeClient</member> or <member>revokeClientNotifyDisposing</member>
            explicitly itself.

        */
        static  TClientId   registerClient( );

        /** revokes a broadcaster of AccessibleEvents

Note that no disposing event is fired when you use this method, the client is simply revoked.
            You can for instance revoke a client if the last listener for it is revoked, but the client
            itself is not disposed.

            When the client is disposed, you should prefer <member>revokeClientNotifyDisposing</member>

Any possibly pending events for this client are removed from the queue.

            @seealso revokeClientNotifyDisposing
        */
        static  void        revokeClient( const TClientId _nClient );

        /** revokes a client, with additionally notifying a disposing event to all listeners registered for
            this client

Any other possibly pending events for this client are removed from the queue

            @param _nClient
                the id of the client which should be revoked
            @param _rxEventSource
                the source to be notified together with the <member scope="com.sun.star.lang">XComponent::disposing</member>
                call.
        */
        static  void        revokeClientNotifyDisposing(
                        const TClientId _nClient,
                        const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxEventSource
                    ) SAL_THROW( ( ) );

        /** registers a listener for the given client

            @param _nClient
                the id of the client for which a listener should be registered
            @return
                the number of event listeners currently registered for this client
        */
        static sal_Int32 addEventListener(
                        const TClientId _nClient,
                        const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& _rxListener
                    ) SAL_THROW( ( ) );

        /** revokes a listener for the given client

            @param _nClient
                the id of the client for which a listener should be revoked
            @return
                the number of event listeners currently registered for this client
        */
        static sal_Int32 removeEventListener(
                        const TClientId _nClient,
                        const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& _rxListener
                    ) SAL_THROW( ( ) );

        /** retrieves the set of listeners registered for a given client
        */
        static ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > >
                        getEventListeners( const TClientId _nClient ) SAL_THROW( ( ) );

        /** adds an event, which is to be braodcasted, to the queue

            @param _nClient
                the id of the client which needs to broadcast the event
        */
        static void addEvent(
                        const TClientId _nClient,
                        const ::com::sun::star::accessibility::AccessibleEventObject& _rEvent
                    ) SAL_THROW( ( ) );

    private:
        /// generates a new client id
        COMPHELPER_DLLPRIVATE static    TClientId   generateId();

        /** looks up a client in our client map, asserts if it cannot find it or no event thread is present

            @precond
                to be called with our mutex locked

            @param _nClient
                the id of the client to loopup
            @param _rPos
                out-parameter for the position of the client in the client map

            @return
                <TRUE/> if and only if the client could be found and <arg>_rPos</arg> has been filled with
                it's position
        */
        COMPHELPER_DLLPRIVATE static    sal_Bool    implLookupClient( const TClientId _nClient, ClientMap::iterator& _rPos );
    };

//.........................................................................
}   // namespace comphelper
//.........................................................................

#endif // COMPHELPER_ACCESSIBLE_EVENT_NOTIFIER

<commit_msg>INTEGRATION: CWS changefileheader (1.7.246); FILE MERGED 2008/04/01 15:05:17 thb 1.7.246.3: #i85898# Stripping all external header guards 2008/04/01 12:26:23 thb 1.7.246.2: #i85898# Stripping all external header guards 2008/03/31 12:19:26 rt 1.7.246.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: accessibleeventnotifier.hxx,v $
 * $Revision: 1.8 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef COMPHELPER_ACCESSIBLE_EVENT_NOTIFIER
#define COMPHELPER_ACCESSIBLE_EVENT_NOTIFIER

#include <com/sun/star/accessibility/AccessibleEventObject.hpp>
#include <com/sun/star/accessibility/XAccessibleEventListener.hpp>
#include <osl/thread.hxx>
#include <osl/conditn.hxx>
#include <cppuhelper/interfacecontainer.h>
#include "comphelper/comphelperdllapi.h"

#include <map>
#include <list>

//.........................................................................
namespace comphelper
{
//.........................................................................

    //=====================================================================
    //= AccessibleEventNotifier
    //=====================================================================
    class COMPHELPER_DLLPUBLIC AccessibleEventNotifier
    {
    // typedefs
    public:
        typedef sal_uInt32  TClientId;

        typedef ::std::pair< TClientId, ::com::sun::star::accessibility::AccessibleEventObject >
                                                                                ClientEvent;

        typedef ::cppu::OInterfaceContainerHelper                                   EventListeners;
        typedef ::std::map< TClientId, EventListeners*, ::std::less< TClientId > >  ClientMap;

    protected:
        AccessibleEventNotifier( );     // never implemented
        ~AccessibleEventNotifier( );    // never implemented

    private:
        COMPHELPER_DLLPRIVATE AccessibleEventNotifier( const AccessibleEventNotifier& );                // never implemented!
        COMPHELPER_DLLPRIVATE AccessibleEventNotifier& operator=( const AccessibleEventNotifier& ); // never implemented!

    public:
        /** registers a client of this class, means a broadcaster of AccessibleEvents

No precaution is taken to care for disposal of this component. When the component
            dies, it must call <member>revokeClient</member> or <member>revokeClientNotifyDisposing</member>
            explicitly itself.

        */
        static  TClientId   registerClient( );

        /** revokes a broadcaster of AccessibleEvents

Note that no disposing event is fired when you use this method, the client is simply revoked.
            You can for instance revoke a client if the last listener for it is revoked, but the client
            itself is not disposed.

            When the client is disposed, you should prefer <member>revokeClientNotifyDisposing</member>

Any possibly pending events for this client are removed from the queue.

            @seealso revokeClientNotifyDisposing
        */
        static  void        revokeClient( const TClientId _nClient );

        /** revokes a client, with additionally notifying a disposing event to all listeners registered for
            this client

Any other possibly pending events for this client are removed from the queue

            @param _nClient
                the id of the client which should be revoked
            @param _rxEventSource
                the source to be notified together with the <member scope="com.sun.star.lang">XComponent::disposing</member>
                call.
        */
        static  void        revokeClientNotifyDisposing(
                        const TClientId _nClient,
                        const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxEventSource
                    ) SAL_THROW( ( ) );

        /** registers a listener for the given client

            @param _nClient
                the id of the client for which a listener should be registered
            @return
                the number of event listeners currently registered for this client
        */
        static sal_Int32 addEventListener(
                        const TClientId _nClient,
                        const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& _rxListener
                    ) SAL_THROW( ( ) );

        /** revokes a listener for the given client

            @param _nClient
                the id of the client for which a listener should be revoked
            @return
                the number of event listeners currently registered for this client
        */
        static sal_Int32 removeEventListener(
                        const TClientId _nClient,
                        const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& _rxListener
                    ) SAL_THROW( ( ) );

        /** retrieves the set of listeners registered for a given client
        */
        static ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > >
                        getEventListeners( const TClientId _nClient ) SAL_THROW( ( ) );

        /** adds an event, which is to be braodcasted, to the queue

            @param _nClient
                the id of the client which needs to broadcast the event
        */
        static void addEvent(
                        const TClientId _nClient,
                        const ::com::sun::star::accessibility::AccessibleEventObject& _rEvent
                    ) SAL_THROW( ( ) );

    private:
        /// generates a new client id
        COMPHELPER_DLLPRIVATE static    TClientId   generateId();

        /** looks up a client in our client map, asserts if it cannot find it or no event thread is present

            @precond
                to be called with our mutex locked

            @param _nClient
                the id of the client to loopup
            @param _rPos
                out-parameter for the position of the client in the client map

            @return
                <TRUE/> if and only if the client could be found and <arg>_rPos</arg> has been filled with
                it's position
        */
        COMPHELPER_DLLPRIVATE static    sal_Bool    implLookupClient( const TClientId _nClient, ClientMap::iterator& _rPos );
    };

//.........................................................................
}   // namespace comphelper
//.........................................................................

#endif // COMPHELPER_ACCESSIBLE_EVENT_NOTIFIER

<|endoftext|>


<commit_before>#include "videoin.hpp"

using namespace cv;
using namespace std;

VideoIn::VideoIn(const char *path)
{
   if (strstr(path, ".png") || strstr(path, ".jpg"))
   {
      _frame = imread(path);
      _video = false;
   }
   else
   {
      _cap = VideoCapture(path);
      _video = true;
   }
   _frameCounter = 0;
}
VideoIn::VideoIn(int stream)
{
   _cap = VideoCapture(stream);
   _video = true;
   _frameCounter = 0;
}

bool VideoIn::getNextFrame(bool pause, Mat &frame)
{
   if (!pause && _video)
   {
      _cap >> _frame;
      if( _frame.empty() )
	 return false;
      if (_frame.rows > 800)
	 pyrDown(_frame, _frame);
      _frameCounter += 1;
   }
   frame = _frame.clone();

   return true;
}
int VideoIn::frameCounter(void)
{
   return _frameCounter;
}

VideoCapture *VideoIn::VideoCap(void)
{
   if (_video)
      return &_cap;
   return NULL;
}
void VideoIn::frameCounter(int frameCount)
{
   if (_video)
      _cap.set(CV_CAP_PROP_POS_FRAMES, frameCount);
   _frameCounter = frameCount;
}

<commit_msg>Updated videoin.cpp<commit_after>#include "videoin.hpp"
#include <iostream>

using namespace cv;
using namespace std;

VideoIn::VideoIn(const char *path)
{
   if (strstr(path, ".png") || strstr(path, ".jpg"))
   {
      _frame = imread(path);
      _video = false;
   }
   else
   {
      _cap = VideoCapture(path);
      _video = true;
   }
   _frameCounter = 0;
}
VideoIn::VideoIn(int stream)
{
   _cap = VideoCapture(stream);
   _video = true;
   _frameCounter = 0;
}

bool VideoIn::getNextFrame(bool pause, Mat &frame)
{
   if (!pause && _video)
   {
      _cap >> _frame;
      if( _frame.empty() )
	 return false;
      if (_frame.rows > 800)
	 pyrDown(_frame, _frame);
      _frameCounter += 1;
   }
   frame = _frame.clone();

   return true;
}
int VideoIn::frameCounter(void)
{
   return _frameCounter;
}

VideoCapture *VideoIn::VideoCap(void)
{
   if (_video)
      return &_cap;
   return NULL;
}
void VideoIn::frameCounter(int frameCount)
{
   if (_video)
      _cap.set(CV_CAP_PROP_POS_FRAMES, frameCount);
   _frameCounter = frameCount;
}

<|endoftext|>


<commit_before>#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <chrono>

#include "dogbot/Coms.hh"
#include "dogbot/DogBotAPI.hh"
#include "dogbot/LegKinematics.hh"
#include "dogbot/SplineGaitController.hh"

#include "ServoTable.hh"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
  Q_OBJECT

public:
  explicit MainWindow(QWidget *parent = 0);
  ~MainWindow();

protected:
  void timerEvent(QTimerEvent *event) override;

private slots:
  void on_pushButtonConnect_clicked();

  void on_pushButtonPWMReport_clicked();

  void on_pushButtonPing_clicked();

  void on_comboBoxMotorControlMode_activated(const QString &arg1);

  void on_sliderPosition_sliderMoved(int position);

  void on_sliderTorque_sliderMoved(int torque);

  void on_pushButtonQueryId_clicked();

  void on_pushButtonGetVersion_clicked();

  void on_pushButtonState_clicked();

  void on_pushButtonQueryDevices_clicked();

  void on_pushButtonPing1_clicked();

  void on_pushButtonOpenLog_clicked();

  void on_pushButtonQueryState_clicked();

  void on_pushButtonDrv8305_2_clicked();

  void on_pushButtonDrv8305_3_clicked();

  void on_pushButtonDrv8305_5_clicked();

  void on_pushButtonDrv8305_4_clicked();

  void on_pushButtonTim1_clicked();

  void on_spinDeviceId_valueChanged(int arg1);

  void on_comboBoxCalibration_activated(const QString &arg1);

  void on_comboBoxControlState_activated(const QString &arg1);

  void on_checkBoxIndicator_toggled(bool checked);

  void on_spinOtherJointId_valueChanged(int arg1);

  void on_comboBox_activated(const QString &arg1);

  void on_comboBoxPositionRef_activated(const QString &arg1);

  void on_pushButton_2_clicked();

  void on_pushButtonCalZero_clicked();

  void on_doubleSpinBoxJointRelGain_valueChanged(double arg1);

  void on_doubleSpinBoxJointRelOffset_valueChanged(double arg1);

  void on_doubleSpinBoxDemandPosition_editingFinished();

  void on_doubleSpinBoxTorqueLimit_editingFinished();

  void on_doubleSpinBoxDemandPosition_valueChanged(double arg1);

  void on_doubleSpinBoxCalibrationOffset_editingFinished();

  void on_pushButton_3_clicked();

  void on_pushButton_4_clicked();

  void on_doubleSpinBoxIGain_valueChanged(double arg1);

  void updateIGain(double arg1);
  void on_sliderPosition_valueChanged(int value);

  void on_doubleSpinBoxVelocityGain_valueChanged(double arg1);

  void on_doubleSpinBoxVelocityIGain_valueChanged(double arg1);

  void on_doubleSpinBoxVelocityLimit_valueChanged(double arg1);

  void on_doubleSpinBoxPositionGain_valueChanged(double arg1);

  void on_pushButton_5_clicked();

  void on_pushButtonEmergencyStop_clicked();

  void on_doubleSpinBoxHomeIndexOffset_valueChanged(double arg1);

  void on_pushButtonQueryHomed_clicked();

  void on_pushButtonOff_clicked();

  void on_pushButtonHold_clicked();

  void on_pushButtonBrake_clicked();

  void on_comboBoxServoName_activated(const QString &arg1);

  void on_actionSaveConfig_triggered();

  void on_actionLoadConfig_triggered();

  void on_actionSave_Config_As_triggered();

  void on_pushButtonResetAll_clicked();

  void on_pushButtonRefresh_clicked();

  void on_actionExit_triggered();

  void on_comboBoxFanState_activated(int index);

  void on_checkBoxJointRelative_stateChanged(int arg1);

  void on_lineEditFanTempThreshold_editingFinished();

  void on_comboBoxFanState_currentIndexChanged(const QString &arg1);

  void on_updatePosition(double angle);

  void on_doubleSpinBoxEndStopStart_valueChanged(double arg1);

  void on_doubleSpinBoxEndStopEnd_valueChanged(double arg1);

  void on_checkBoxEndStopEnable_toggled(bool checked);

  void on_doubleSpinBoxJointInertia_valueChanged(double arg1);

  void LocalProcessParam(PacketParam8ByteC psp);

  void on_pushButtonSetEndStopStart_clicked();

  void on_pushButtonSetEndStopEnd_clicked();

  void on_pushButtonSaveConfig_clicked();

  void on_comboBoxSafetyMode_activated(const QString &arg1);

  void on_pushButtonLowPower_clicked();

  void on_comboBoxGotoJoint_activated(const QString &arg1);

  void on_pushButtonHomeJoint_clicked();

  void on_pushButtonHomeAll_clicked();

  void on_pushButtonPhaseEndStops_clicked();

  void on_doubleSpinBoxEndStopForce_valueChanged(double arg1);

  void on_lineEditServoReportFrequency_textEdited(const QString &arg1);

  void on_checkBoxRunAnimation_stateChanged(int arg1);

  void on_dialAnimationOmega_valueChanged(int value);

  void on_doubleSpinBoxAnimationTorque_valueChanged(double arg1);

  void on_doubleSpinBoxAnimationSpeedLimit_valueChanged(double arg1);

  void on_comboBoxAmimationStyle_activated(const QString &arg1);

signals:
  void setLogText(const QString &str);
  void setControlState(const QString &str);
  void setControlMode(const QString &str);
  void setFault(const QString &str);
  void setCalibrationState(int index);
  void setCalibrationAngle(double value);
  void setOtherJoint(int jointId);
  void setPositionRef(const QString &str);
  void setIndicator(bool state);
  void setOtherJointGain(double gain);
  void setOtherJointOffset(double offset);
  void setSupplyVoltage(QString str);
  void setDriveTemperature(QString str);
  void setMotorTemperature(QString str);
  void setFanTemperatureThreshold(QString str);
  void setMotorIGain(double offset);
  void setMotorVelocity(double offset);
  void setVelocityPGain(double offset);
  void setVelocityIGain(double offset);
  void setDemandPhaseVelocity(double offset);
  void setVelocityLimit(double offset);
  void setPositionGain(double offset);
  void setHomeIndexOffset(double offset);
  void setHallSensors(const QString &str);
  void setUSBErrors(const QString &str);
  void setUSBDrops(const QString &str);
  void setCANErrors(const QString &str);
  void setCANDrops(const QString &str);
  void setMainLoopTimeout(const QString &str);
  void setFaultMap(const QString &str);
  void setIndexSensor(bool state);
  void setJointRelativeEnabled(bool state);
  void setFanMode(const QString &str);
  void updatePosition(double angle);

  void callLocalProcessParam(struct PacketParam8ByteC psp);

private:
  void SetupComs();

  void QueryAll();

  bool ProcessParam(struct PacketParam8ByteC *psp, std::string &displayStr);

  //! Close current connection
  void CloseConnection();

  //! Get the current position and set the given parameter to it.
  void SetValueToCurrentPosition(ComsParameterIndexT param);

  //! Run the current animation
  void RunAnimation();

  //! Stop current animation
  void StopAnimation();

  int m_toQuery = 0;
  std::vector<ComsParameterIndexT> m_displayQuery;

  bool m_updatePositionFromController = false;

  Ui::MainWindow *ui;
  std::shared_ptr<DogBotN::ComsC> m_coms;
  std::shared_ptr<DogBotN::DogBotAPIC> m_dogBotAPI;
  bool m_PWMReportRequested = false;

  std::vector<PacketDeviceIdC> m_devices;
  float m_position = 0;
  float m_torque = 3.0;
  std::shared_ptr<std::ostream> m_logStrm;
  int m_targetDeviceId = 0;
  enum PositionReferenceT g_positionReference = PR_Relative;

  float m_servoAngle = 0;
  float m_servoTorque = 0;
  float m_maxCurrent = 20.0;
  enum PositionReferenceT m_servoRef = PR_Relative;
  enum PWMControlDynamicT m_controlMode = CM_Off;
  ServoTable *m_servoTable = 0;
  std::string m_configFilename;

  DogBotN::SplineGaitControllerC m_gaitController;
  bool m_runAnimation = false;
  std::thread m_animationThread;
  float m_animationOmega = 1.0;
  float m_animationTorque = 6.0;
  float g_animationVelocityLimit = 2000.0;
  std::mutex m_accessGait;
};

#endif // MAINWINDOW_H
<commit_msg>Turn down initial velocity limit.<commit_after>#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <chrono>

#include "dogbot/Coms.hh"
#include "dogbot/DogBotAPI.hh"
#include "dogbot/LegKinematics.hh"
#include "dogbot/SplineGaitController.hh"

#include "ServoTable.hh"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
  Q_OBJECT

public:
  explicit MainWindow(QWidget *parent = 0);
  ~MainWindow();

protected:
  void timerEvent(QTimerEvent *event) override;

private slots:
  void on_pushButtonConnect_clicked();

  void on_pushButtonPWMReport_clicked();

  void on_pushButtonPing_clicked();

  void on_comboBoxMotorControlMode_activated(const QString &arg1);

  void on_sliderPosition_sliderMoved(int position);

  void on_sliderTorque_sliderMoved(int torque);

  void on_pushButtonQueryId_clicked();

  void on_pushButtonGetVersion_clicked();

  void on_pushButtonState_clicked();

  void on_pushButtonQueryDevices_clicked();

  void on_pushButtonPing1_clicked();

  void on_pushButtonOpenLog_clicked();

  void on_pushButtonQueryState_clicked();

  void on_pushButtonDrv8305_2_clicked();

  void on_pushButtonDrv8305_3_clicked();

  void on_pushButtonDrv8305_5_clicked();

  void on_pushButtonDrv8305_4_clicked();

  void on_pushButtonTim1_clicked();

  void on_spinDeviceId_valueChanged(int arg1);

  void on_comboBoxCalibration_activated(const QString &arg1);

  void on_comboBoxControlState_activated(const QString &arg1);

  void on_checkBoxIndicator_toggled(bool checked);

  void on_spinOtherJointId_valueChanged(int arg1);

  void on_comboBox_activated(const QString &arg1);

  void on_comboBoxPositionRef_activated(const QString &arg1);

  void on_pushButton_2_clicked();

  void on_pushButtonCalZero_clicked();

  void on_doubleSpinBoxJointRelGain_valueChanged(double arg1);

  void on_doubleSpinBoxJointRelOffset_valueChanged(double arg1);

  void on_doubleSpinBoxDemandPosition_editingFinished();

  void on_doubleSpinBoxTorqueLimit_editingFinished();

  void on_doubleSpinBoxDemandPosition_valueChanged(double arg1);

  void on_doubleSpinBoxCalibrationOffset_editingFinished();

  void on_pushButton_3_clicked();

  void on_pushButton_4_clicked();

  void on_doubleSpinBoxIGain_valueChanged(double arg1);

  void updateIGain(double arg1);
  void on_sliderPosition_valueChanged(int value);

  void on_doubleSpinBoxVelocityGain_valueChanged(double arg1);

  void on_doubleSpinBoxVelocityIGain_valueChanged(double arg1);

  void on_doubleSpinBoxVelocityLimit_valueChanged(double arg1);

  void on_doubleSpinBoxPositionGain_valueChanged(double arg1);

  void on_pushButton_5_clicked();

  void on_pushButtonEmergencyStop_clicked();

  void on_doubleSpinBoxHomeIndexOffset_valueChanged(double arg1);

  void on_pushButtonQueryHomed_clicked();

  void on_pushButtonOff_clicked();

  void on_pushButtonHold_clicked();

  void on_pushButtonBrake_clicked();

  void on_comboBoxServoName_activated(const QString &arg1);

  void on_actionSaveConfig_triggered();

  void on_actionLoadConfig_triggered();

  void on_actionSave_Config_As_triggered();

  void on_pushButtonResetAll_clicked();

  void on_pushButtonRefresh_clicked();

  void on_actionExit_triggered();

  void on_comboBoxFanState_activated(int index);

  void on_checkBoxJointRelative_stateChanged(int arg1);

  void on_lineEditFanTempThreshold_editingFinished();

  void on_comboBoxFanState_currentIndexChanged(const QString &arg1);

  void on_updatePosition(double angle);

  void on_doubleSpinBoxEndStopStart_valueChanged(double arg1);

  void on_doubleSpinBoxEndStopEnd_valueChanged(double arg1);

  void on_checkBoxEndStopEnable_toggled(bool checked);

  void on_doubleSpinBoxJointInertia_valueChanged(double arg1);

  void LocalProcessParam(PacketParam8ByteC psp);

  void on_pushButtonSetEndStopStart_clicked();

  void on_pushButtonSetEndStopEnd_clicked();

  void on_pushButtonSaveConfig_clicked();

  void on_comboBoxSafetyMode_activated(const QString &arg1);

  void on_pushButtonLowPower_clicked();

  void on_comboBoxGotoJoint_activated(const QString &arg1);

  void on_pushButtonHomeJoint_clicked();

  void on_pushButtonHomeAll_clicked();

  void on_pushButtonPhaseEndStops_clicked();

  void on_doubleSpinBoxEndStopForce_valueChanged(double arg1);

  void on_lineEditServoReportFrequency_textEdited(const QString &arg1);

  void on_checkBoxRunAnimation_stateChanged(int arg1);

  void on_dialAnimationOmega_valueChanged(int value);

  void on_doubleSpinBoxAnimationTorque_valueChanged(double arg1);

  void on_doubleSpinBoxAnimationSpeedLimit_valueChanged(double arg1);

  void on_comboBoxAmimationStyle_activated(const QString &arg1);

signals:
  void setLogText(const QString &str);
  void setControlState(const QString &str);
  void setControlMode(const QString &str);
  void setFault(const QString &str);
  void setCalibrationState(int index);
  void setCalibrationAngle(double value);
  void setOtherJoint(int jointId);
  void setPositionRef(const QString &str);
  void setIndicator(bool state);
  void setOtherJointGain(double gain);
  void setOtherJointOffset(double offset);
  void setSupplyVoltage(QString str);
  void setDriveTemperature(QString str);
  void setMotorTemperature(QString str);
  void setFanTemperatureThreshold(QString str);
  void setMotorIGain(double offset);
  void setMotorVelocity(double offset);
  void setVelocityPGain(double offset);
  void setVelocityIGain(double offset);
  void setDemandPhaseVelocity(double offset);
  void setVelocityLimit(double offset);
  void setPositionGain(double offset);
  void setHomeIndexOffset(double offset);
  void setHallSensors(const QString &str);
  void setUSBErrors(const QString &str);
  void setUSBDrops(const QString &str);
  void setCANErrors(const QString &str);
  void setCANDrops(const QString &str);
  void setMainLoopTimeout(const QString &str);
  void setFaultMap(const QString &str);
  void setIndexSensor(bool state);
  void setJointRelativeEnabled(bool state);
  void setFanMode(const QString &str);
  void updatePosition(double angle);

  void callLocalProcessParam(struct PacketParam8ByteC psp);

private:
  void SetupComs();

  void QueryAll();

  bool ProcessParam(struct PacketParam8ByteC *psp, std::string &displayStr);

  //! Close current connection
  void CloseConnection();

  //! Get the current position and set the given parameter to it.
  void SetValueToCurrentPosition(ComsParameterIndexT param);

  //! Run the current animation
  void RunAnimation();

  //! Stop current animation
  void StopAnimation();

  int m_toQuery = 0;
  std::vector<ComsParameterIndexT> m_displayQuery;

  bool m_updatePositionFromController = false;

  Ui::MainWindow *ui;
  std::shared_ptr<DogBotN::ComsC> m_coms;
  std::shared_ptr<DogBotN::DogBotAPIC> m_dogBotAPI;
  bool m_PWMReportRequested = false;

  std::vector<PacketDeviceIdC> m_devices;
  float m_position = 0;
  float m_torque = 3.0;
  std::shared_ptr<std::ostream> m_logStrm;
  int m_targetDeviceId = 0;
  enum PositionReferenceT g_positionReference = PR_Relative;

  float m_servoAngle = 0;
  float m_servoTorque = 0;
  float m_maxCurrent = 20.0;
  enum PositionReferenceT m_servoRef = PR_Relative;
  enum PWMControlDynamicT m_controlMode = CM_Off;
  ServoTable *m_servoTable = 0;
  std::string m_configFilename;

  DogBotN::SplineGaitControllerC m_gaitController;
  bool m_runAnimation = false;
  std::thread m_animationThread;
  float m_animationOmega = 1.0;
  float m_animationTorque = 6.0;
  float g_animationVelocityLimit = 500.0;
  std::mutex m_accessGait;
};

#endif // MAINWINDOW_H
<|endoftext|>


<commit_before>// Copyright (c) 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 "content/renderer/browser_plugin/browser_plugin_compositing_helper.h"

#include "cc/solid_color_layer.h"
#include "cc/texture_layer.h"
#include "content/common/browser_plugin_messages.h"
#include "content/renderer/browser_plugin/browser_plugin_manager.h"
#include "content/renderer/render_thread_impl.h"
#include "third_party/khronos/GLES2/gl2.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebGraphicsContext3D.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebSharedGraphicsContext3D.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginContainer.h"
#include "webkit/compositor_bindings/web_layer_impl.h"

namespace content {

BrowserPluginCompositingHelper::BrowserPluginCompositingHelper(
    WebKit::WebPluginContainer* container,
    BrowserPluginManager* manager,
    int instance_id,
    int host_routing_id)
    : instance_id_(instance_id),
      host_routing_id_(host_routing_id),
      last_gpu_route_id_(0),
      last_gpu_host_id_(0),
      last_mailbox_valid_(false),
      ack_pending_(true),
      ack_pending_for_crashed_guest_(false),
      container_(container),
      browser_plugin_manager_(manager) {
}

BrowserPluginCompositingHelper::~BrowserPluginCompositingHelper() {
}

void BrowserPluginCompositingHelper::EnableCompositing(bool enable) {
  if (enable && !texture_layer_) {
    texture_layer_ = cc::TextureLayer::createForMailbox();
    texture_layer_->setIsDrawable(true);
    texture_layer_->setContentsOpaque(true);

    background_layer_ = cc::SolidColorLayer::create();
    background_layer_->setMasksToBounds(true);
    background_layer_->setBackgroundColor(
        SkColorSetARGBInline(255, 255, 255, 255));
    background_layer_->addChild(texture_layer_);
    web_layer_.reset(new WebKit::WebLayerImpl(background_layer_));
  }

  container_->setWebLayer(enable ? web_layer_.get() : NULL);
}

// If we have a mailbox that was freed up from the compositor,
// but we are not expected to return it to the guest renderer
// via an ACK, we should free it because we now own it.
// To free the mailbox memory, we need a context to consume it
// into a texture ID and then delete this texture ID.
// We use a shared graphics context accessible from the main
// thread to do it.
void BrowserPluginCompositingHelper::FreeMailboxMemory(
    const std::string& mailbox_name,
    unsigned sync_point) {
  if (mailbox_name.empty())
    return;

  WebKit::WebGraphicsContext3D *context =
     WebKit::WebSharedGraphicsContext3D::mainThreadContext();
  DCHECK(context);
  // When a buffer is released from the compositor, we also get a
  // sync point that specifies when in the command buffer
  // it's safe to use it again.
  // If the sync point is non-zero, we need to tell our context
  // to wait until this sync point is reached before we can safely
  // delete the buffer.
  if (sync_point)
    context->waitSyncPoint(sync_point);

  unsigned texture_id = context->createTexture();
  context->bindTexture(GL_TEXTURE_2D, texture_id);
  context->consumeTextureCHROMIUM(
      GL_TEXTURE_2D,
      reinterpret_cast<const int8*>(mailbox_name.data()));
  context->deleteTexture(texture_id);
}

void BrowserPluginCompositingHelper::MailboxReleased(
    const std::string& mailbox_name,
    int gpu_route_id,
    int gpu_host_id,
    unsigned sync_point) {
  // This means the GPU process crashed and we have nothing further to do.
  // Nobody is expecting an ACK and the buffer doesn't need to be deleted
  // because it went away with the GPU process.
  if (last_gpu_host_id_ != gpu_host_id)
    return;

  // This means the guest crashed.
  // Either ACK the last buffer, so texture transport could
  // be destroyed of delete the mailbox if nobody wants it back.
  if (last_gpu_route_id_ != gpu_route_id) {
    if (!ack_pending_for_crashed_guest_) {
      FreeMailboxMemory(mailbox_name, sync_point);
    } else {
      ack_pending_for_crashed_guest_ = false;
      browser_plugin_manager_->Send(
          new BrowserPluginHostMsg_BuffersSwappedACK(
              host_routing_id_,
              instance_id_,
              gpu_route_id,
              gpu_host_id,
              mailbox_name,
              sync_point));
    }
    return;
  }

  // We need to send an ACK to TextureImageTransportSurface
  // for every buffer it sends us. However, if a buffer is freed up from
  // the compositor in cases like switching back to SW mode without a new
  // buffer arriving, no ACK is needed and we destroy this buffer.
  if (!ack_pending_) {
    FreeMailboxMemory(mailbox_name, sync_point);
    last_mailbox_valid_ = false;
    return;
  }
  ack_pending_ = false;
  browser_plugin_manager_->Send(
      new BrowserPluginHostMsg_BuffersSwappedACK(
          host_routing_id_,
          instance_id_,
          gpu_route_id,
          gpu_host_id,
          mailbox_name,
          sync_point));
}

void BrowserPluginCompositingHelper::OnContainerDestroy() {
  if (container_)
    container_->setWebLayer(NULL);
  container_ = NULL;

  texture_layer_ = NULL;
  background_layer_ = NULL;
  web_layer_.reset();
}

void BrowserPluginCompositingHelper::OnBuffersSwapped(
    const gfx::Size& size,
    const std::string& mailbox_name,
    int gpu_route_id,
    int gpu_host_id) {
  // If the guest crashed but the GPU process didn't, we may still have
  // a transport surface waiting on an ACK, which we must send to
  // avoid leaking.
  if (last_gpu_route_id_ != gpu_route_id && last_gpu_host_id_ == gpu_host_id)
    ack_pending_for_crashed_guest_ = ack_pending_;

  // If these mismatch, we are either just starting up, GPU process crashed or
  // guest renderer crashed.
  // In this case, we are communicating with a new image transport
  // surface and must ACK with the new ID's and an empty mailbox.
  if (last_gpu_route_id_ != gpu_route_id || last_gpu_host_id_ != gpu_host_id)
    last_mailbox_valid_ = false;

  last_gpu_route_id_ = gpu_route_id;
  last_gpu_host_id_ = gpu_host_id;

  ack_pending_ = true;
  // Browser plugin getting destroyed, do a fast ACK.
  if (!texture_layer_) {
    MailboxReleased(mailbox_name, gpu_route_id, gpu_host_id, 0);
    return;
  }

  // The size of browser plugin container is not always equal to the size
  // of the buffer that arrives here. This could be for a number of reasons,
  // including autosize and a resize in progress.
  // During resize, the container size changes first and then some time
  // later, a new buffer with updated size will arrive. During this process,
  // we need to make sure that things are still displayed pixel perfect.
  // We accomplish this by modifying bounds of the texture layer only
  // when a new buffer arrives.
  // Visually, this will either display a smaller part of the buffer
  // or introduce a gutter around it.
  if (buffer_size_ != size) {
    buffer_size_ = size;
    texture_layer_->setBounds(buffer_size_);
  }

  bool current_mailbox_valid = !mailbox_name.empty();
  if (!last_mailbox_valid_) {
    MailboxReleased(std::string(), gpu_route_id, gpu_host_id, 0);
    if (!current_mailbox_valid)
      return;
  }

  cc::TextureMailbox::ReleaseCallback callback;
  if (current_mailbox_valid) {
    callback = base::Bind(&BrowserPluginCompositingHelper::MailboxReleased,
                          scoped_refptr<BrowserPluginCompositingHelper>(this),
                          mailbox_name,
                          gpu_route_id,
                          gpu_host_id);
  }
  texture_layer_->setTextureMailbox(cc::TextureMailbox(mailbox_name,
                                                       callback));
  last_mailbox_valid_ = current_mailbox_valid;
}

void BrowserPluginCompositingHelper::UpdateVisibility(bool visible) {
  if (texture_layer_)
    texture_layer_->setIsDrawable(visible);
}

}  // namespace content
<commit_msg>Removing DCHECK and returning instead. It's a valid state for context to be NULL, particularly during teardown.<commit_after>// Copyright (c) 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 "content/renderer/browser_plugin/browser_plugin_compositing_helper.h"

#include "cc/solid_color_layer.h"
#include "cc/texture_layer.h"
#include "content/common/browser_plugin_messages.h"
#include "content/renderer/browser_plugin/browser_plugin_manager.h"
#include "content/renderer/render_thread_impl.h"
#include "third_party/khronos/GLES2/gl2.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebGraphicsContext3D.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebSharedGraphicsContext3D.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginContainer.h"
#include "webkit/compositor_bindings/web_layer_impl.h"

namespace content {

BrowserPluginCompositingHelper::BrowserPluginCompositingHelper(
    WebKit::WebPluginContainer* container,
    BrowserPluginManager* manager,
    int instance_id,
    int host_routing_id)
    : instance_id_(instance_id),
      host_routing_id_(host_routing_id),
      last_gpu_route_id_(0),
      last_gpu_host_id_(0),
      last_mailbox_valid_(false),
      ack_pending_(true),
      ack_pending_for_crashed_guest_(false),
      container_(container),
      browser_plugin_manager_(manager) {
}

BrowserPluginCompositingHelper::~BrowserPluginCompositingHelper() {
}

void BrowserPluginCompositingHelper::EnableCompositing(bool enable) {
  if (enable && !texture_layer_) {
    texture_layer_ = cc::TextureLayer::createForMailbox();
    texture_layer_->setIsDrawable(true);
    texture_layer_->setContentsOpaque(true);

    background_layer_ = cc::SolidColorLayer::create();
    background_layer_->setMasksToBounds(true);
    background_layer_->setBackgroundColor(
        SkColorSetARGBInline(255, 255, 255, 255));
    background_layer_->addChild(texture_layer_);
    web_layer_.reset(new WebKit::WebLayerImpl(background_layer_));
  }

  container_->setWebLayer(enable ? web_layer_.get() : NULL);
}

// If we have a mailbox that was freed up from the compositor,
// but we are not expected to return it to the guest renderer
// via an ACK, we should free it because we now own it.
// To free the mailbox memory, we need a context to consume it
// into a texture ID and then delete this texture ID.
// We use a shared graphics context accessible from the main
// thread to do it.
void BrowserPluginCompositingHelper::FreeMailboxMemory(
    const std::string& mailbox_name,
    unsigned sync_point) {
  if (mailbox_name.empty())
    return;

  WebKit::WebGraphicsContext3D *context =
     WebKit::WebSharedGraphicsContext3D::mainThreadContext();
  if (!context)
    return;
  // When a buffer is released from the compositor, we also get a
  // sync point that specifies when in the command buffer
  // it's safe to use it again.
  // If the sync point is non-zero, we need to tell our context
  // to wait until this sync point is reached before we can safely
  // delete the buffer.
  if (sync_point)
    context->waitSyncPoint(sync_point);

  unsigned texture_id = context->createTexture();
  context->bindTexture(GL_TEXTURE_2D, texture_id);
  context->consumeTextureCHROMIUM(
      GL_TEXTURE_2D,
      reinterpret_cast<const int8*>(mailbox_name.data()));
  context->deleteTexture(texture_id);
}

void BrowserPluginCompositingHelper::MailboxReleased(
    const std::string& mailbox_name,
    int gpu_route_id,
    int gpu_host_id,
    unsigned sync_point) {
  // This means the GPU process crashed and we have nothing further to do.
  // Nobody is expecting an ACK and the buffer doesn't need to be deleted
  // because it went away with the GPU process.
  if (last_gpu_host_id_ != gpu_host_id)
    return;

  // This means the guest crashed.
  // Either ACK the last buffer, so texture transport could
  // be destroyed of delete the mailbox if nobody wants it back.
  if (last_gpu_route_id_ != gpu_route_id) {
    if (!ack_pending_for_crashed_guest_) {
      FreeMailboxMemory(mailbox_name, sync_point);
    } else {
      ack_pending_for_crashed_guest_ = false;
      browser_plugin_manager_->Send(
          new BrowserPluginHostMsg_BuffersSwappedACK(
              host_routing_id_,
              instance_id_,
              gpu_route_id,
              gpu_host_id,
              mailbox_name,
              sync_point));
    }
    return;
  }

  // We need to send an ACK to TextureImageTransportSurface
  // for every buffer it sends us. However, if a buffer is freed up from
  // the compositor in cases like switching back to SW mode without a new
  // buffer arriving, no ACK is needed and we destroy this buffer.
  if (!ack_pending_) {
    FreeMailboxMemory(mailbox_name, sync_point);
    last_mailbox_valid_ = false;
    return;
  }
  ack_pending_ = false;
  browser_plugin_manager_->Send(
      new BrowserPluginHostMsg_BuffersSwappedACK(
          host_routing_id_,
          instance_id_,
          gpu_route_id,
          gpu_host_id,
          mailbox_name,
          sync_point));
}

void BrowserPluginCompositingHelper::OnContainerDestroy() {
  if (container_)
    container_->setWebLayer(NULL);
  container_ = NULL;

  texture_layer_ = NULL;
  background_layer_ = NULL;
  web_layer_.reset();
}

void BrowserPluginCompositingHelper::OnBuffersSwapped(
    const gfx::Size& size,
    const std::string& mailbox_name,
    int gpu_route_id,
    int gpu_host_id) {
  // If the guest crashed but the GPU process didn't, we may still have
  // a transport surface waiting on an ACK, which we must send to
  // avoid leaking.
  if (last_gpu_route_id_ != gpu_route_id && last_gpu_host_id_ == gpu_host_id)
    ack_pending_for_crashed_guest_ = ack_pending_;

  // If these mismatch, we are either just starting up, GPU process crashed or
  // guest renderer crashed.
  // In this case, we are communicating with a new image transport
  // surface and must ACK with the new ID's and an empty mailbox.
  if (last_gpu_route_id_ != gpu_route_id || last_gpu_host_id_ != gpu_host_id)
    last_mailbox_valid_ = false;

  last_gpu_route_id_ = gpu_route_id;
  last_gpu_host_id_ = gpu_host_id;

  ack_pending_ = true;
  // Browser plugin getting destroyed, do a fast ACK.
  if (!texture_layer_) {
    MailboxReleased(mailbox_name, gpu_route_id, gpu_host_id, 0);
    return;
  }

  // The size of browser plugin container is not always equal to the size
  // of the buffer that arrives here. This could be for a number of reasons,
  // including autosize and a resize in progress.
  // During resize, the container size changes first and then some time
  // later, a new buffer with updated size will arrive. During this process,
  // we need to make sure that things are still displayed pixel perfect.
  // We accomplish this by modifying bounds of the texture layer only
  // when a new buffer arrives.
  // Visually, this will either display a smaller part of the buffer
  // or introduce a gutter around it.
  if (buffer_size_ != size) {
    buffer_size_ = size;
    texture_layer_->setBounds(buffer_size_);
  }

  bool current_mailbox_valid = !mailbox_name.empty();
  if (!last_mailbox_valid_) {
    MailboxReleased(std::string(), gpu_route_id, gpu_host_id, 0);
    if (!current_mailbox_valid)
      return;
  }

  cc::TextureMailbox::ReleaseCallback callback;
  if (current_mailbox_valid) {
    callback = base::Bind(&BrowserPluginCompositingHelper::MailboxReleased,
                          scoped_refptr<BrowserPluginCompositingHelper>(this),
                          mailbox_name,
                          gpu_route_id,
                          gpu_host_id);
  }
  texture_layer_->setTextureMailbox(cc::TextureMailbox(mailbox_name,
                                                       callback));
  last_mailbox_valid_ = current_mailbox_valid;
}

void BrowserPluginCompositingHelper::UpdateVisibility(bool visible) {
  if (texture_layer_)
    texture_layer_->setIsDrawable(visible);
}

}  // namespace content
<|endoftext|>


<commit_before>#include "core/memory_tracker.h"
#include "core/log.h"
#include "core/math_utils.h"
#include "core/MT/spin_mutex.h"
#include "core/stack_allocator.h"
#include "core/string.h"

//#include <new>
#include <stdio.h>
#include <vadefs.h>
#include <Windows.h>

#ifdef MEM_TRACK

#undef min

namespace Lumix
{
	void memTrackerLog(const char*, const char* message, ...)
	{
		char tmp[1024];
		va_list args;
		va_start(args, message);
		vsnprintf(tmp, 1021, message, args);
		va_end(args);

		catCString(tmp, sizeof(tmp), "\n");
		OutputDebugString(tmp);
	}

	// struct FILE_LINE_REPORT
	struct FileLineReport
	{
		const char *file;
		int32_t line;

		LUMIX_FORCE_INLINE bool operator == (const FileLineReport &other) const { return file == other.file && line == other.line; }
		LUMIX_FORCE_INLINE bool operator != (const FileLineReport &other) const { return !(*this == other); }

		LUMIX_FORCE_INLINE bool operator < (const FileLineReport &other) const
		{
			if(file == NULL)
				return other.file != NULL;
			if(other.file == NULL)
				return false;
			int cmp = strcmp(file, other.file);
			if(cmp != 0)
				return cmp < 0;
			return line < other.line;
		}

		LUMIX_FORCE_INLINE bool operator > (const FileLineReport &other) const
		{
			if(file == NULL)
				return other.file != NULL;
			if(other.file == NULL)
				return false;
			int cmp = strcmp(file, other.file);
			if(cmp != 0)
				return cmp > 0;
			return line > other.line;
		}
	};

	typedef Map<uint32_t, MemoryTracker::Entry*, MemTrackAllocator> map_alloc_order;
	typedef Map<FileLineReport, intptr_t, MemTrackAllocator> file_line_map;
	typedef Map<const char *, intptr_t, MemTrackAllocator> file_map;
	typedef Map<FileLineReport, uint32_t, MemTrackAllocator> alloc_count_map;

	#pragma init_seg(compiler)
	MemoryTracker MemoryTracker::s_instance;
	uint32_t MemoryTracker::s_alloc_counter = 0;

	MemoryTracker& MemoryTracker::getInstance()
	{
		return s_instance;
	}

	void MemoryTracker::add(void* p, const intptr_t size, const char* file, const int line)
	{
		if(!p) return;

		MT::SpinLock lock(m_spin_mutex);

		m_map.insert(p, Entry(file, line, size));
		m_allocated_memory += size;
	}

	void MemoryTracker::remove(void* p)
	{
		if(!p) return;

		MT::SpinLock lock(m_spin_mutex);

		EntryTable::iterator it = m_map.find(p);
		ASSERT(it != m_map.end() && "Allocated/Dealocataed from different places?");
		if(it != m_map.end())
		{
			m_allocated_memory -= (*it).size();
			m_map.erase(it);
		}
	}

	static void getEntryLog(MemoryTracker::Entry& entry, void* address, base_string<char, StackAllocator<512> >& string)
	{
		if (entry.file() != NULL)
		{
			string.cat(entry.file(), "(", entry.line(), ") : ");
		}
		string.cat("{", entry.allocID(), " } normal block");
		if (address)
		{
			string.cat(" at ", (int64_t)address);
		}
		string.cat(", ", entry.size(), " bytes long.");
	}

	void MemoryTracker::dumpDetailed()
	{
		// Detected memory leaks!
		// Dumping objects ->
		// {147} normal block at 0x003AF7C0, 10 bytes long.
		// Data: <          > CD CD CD CD CD CD CD CD CD CD
		// d:\temp\zmazat\tt\tt\mainfrm.cpp(34) : {145} normal block at 0x003AF760, 30 bytes long.
		// Data: <               > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
		//    Object dump complete.

		MT::SpinLock lock(m_spin_mutex);
		int32_t count = m_map.size();

		if (count)
		{
			memTrackerLog("MemoryTracker", "MemoryTracker Detected memory leaks!");
			memTrackerLog("MemoryTracker", "Dumping objects ->");
		}
		else
		{
			memTrackerLog("MemoryTracker", "MemoryTracker No leaks detected!");
		}

		for (EntryTable::iterator it = m_map.begin(); it != m_map.end(); ++it)
		{
			base_string<char, StackAllocator<512> > string;

			Entry& entry = *it;
			void* adr = it.key();

			getEntryLog(entry, adr, string);
			memTrackerLog("MemoryTracker", "%s", string.c_str());

			int32_t str_len = Math::min(16, (int32_t)entry.size());
			char asci_buf[17];
			memset(asci_buf, 0, 17);
			memcpy(asci_buf, adr, str_len);

			string = "";
			string.cat("Data: <", asci_buf, ">");
			for (int j = 0; j < str_len; j++)
			{
				char hex[4];
				hex[0] = ' ';
				toCStringHex(*((uint8_t*)adr + j), hex+1, 2);
				string.cat(hex);
			}
			memTrackerLog("MemoryTracker", "%s", string.c_str());
		}
		if(count)
		{
			memTrackerLog("MemoryTracker", "	  Object dump complete.");
		}
	}

	void MemoryTracker::dumpSortedByAllocationOrder()
	{
		// Detected memory leaks!
		// Dumping objects ->
		// {147} normal block at 0x003AF7C0, 10 bytes long.
		// Data: <          > CD CD CD CD CD CD CD CD CD CD
		// d:\temp\zmazat\tt\tt\mainfrm.cpp(34) : {145} normal block at 0x003AF760, 30 bytes long.
		// Data: <               > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
		//    Object dump complete.

		MT::SpinLock lock(m_spin_mutex);
		int count = m_map.size();

		if (count)
		{
			memTrackerLog("MemoryTracker", "MemoryTracker Detected memory leaks!");
			memTrackerLog("MemoryTracker", "Dumping objects ->");
		}
		else
		{
			memTrackerLog("MemoryTracker", "MemoryTracker No leaks detected!");
		}

		map_alloc_order alloc_order_map;
		for (EntryTable::iterator it = m_map.begin(); it != m_map.end(); ++it)
		{
			Entry& entry = *it;
			alloc_order_map.insert(entry.allocID(), &entry);
		}

		for (map_alloc_order::iterator it = alloc_order_map.begin(); it != alloc_order_map.end(); ++it)
		{
			base_string<char, StackAllocator<512> > string;
			Entry& entry = *(it.second());
			getEntryLog(entry, NULL, string);

			memTrackerLog("MemoryTracker", string.c_str());
		}

		if(count)
		{
			memTrackerLog("MemoryTracker", "	  Object dump complete.");
		}
	}

	void MemoryTracker::dumpTruncatedPerFileLine()
	{
		memTrackerLog("MemoryTracker", "Dumping objects ->");

		file_line_map report_map;
		{
			MT::SpinLock lock(m_spin_mutex);
			for (EntryTable::iterator it = m_map.begin(); it != m_map.end(); ++it)
			{
				Entry& entry = *it;

				FileLineReport r;
				r.file = entry.file();
				r.line = entry.line();

				file_line_map::iterator rit = report_map.find(r);
				if(rit != report_map.end())
					rit.second() += entry.size();
				else
					report_map.insert(r, entry.size());
			}
		}

		for (file_line_map::iterator it = report_map.begin(); it != report_map.end(); ++it)
		{
			base_string<char, StackAllocator<512> > string;

			const FileLineReport &rep = it.first();
			intptr_t size = it.second();

			const char *file = rep.file ? rep.file : "unknown";

			string = file;
			string += "(";
			string.cat(rep.line);
			string += ") : ";
			string.cat(size);

			memTrackerLog("MemoryTracker", string.c_str());
		}

		memTrackerLog("MemoryTracker", "Object dump complete.");
	}

	void MemoryTracker::dumpTruncatedPerFile()
	{
		memTrackerLog("MemoryTracker", "Dumping objects ->");

		file_map report_map;
		{
			MT::SpinLock lock(m_spin_mutex);
			for (EntryTable::iterator it = m_map.begin(); it != m_map.end(); ++it)
			{
				Entry& entry = *it;

				file_map::iterator rit = report_map.find(entry.file());
				if(rit != report_map.end())
					rit.second() += entry.size();
				else
					report_map.insert(entry.file(), entry.size());
			}
		}

		for (file_map::iterator it = report_map.begin(); it != report_map.end(); ++it)
		{
			base_string<char, StackAllocator<512> > string;

			intptr_t size = it.second();
			const char *file = it.first();

			string = file;
			string += " : ";
			string.cat(size);

			memTrackerLog("MemoryTracker", string.c_str());
		}

		memTrackerLog("MemoryTracker", "Object dump complete.");
	}

	void MemoryTracker::markAll()
	{
		MT::SpinLock lock(m_spin_mutex);

		for (EntryTable::iterator it = m_map.begin(); it != m_map.end(); ++it)
		{
			(*it).mark();
		}
		++m_mark;
	}

	void MemoryTracker::dumpUnmarked()
	{
		// Detected memory leaks!
		// Dumping objects ->
		// {147} normal block at 0x003AF7C0, 10 bytes long.
		// Data: <          > CD CD CD CD CD CD CD CD CD CD
		// d:\temp\zmazat\tt\tt\mainfrm.cpp(34) : {145} normal block at 0x003AF760, 30 bytes long.
		// Data: <               > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
		//    Object dump complete.

		//	Lock lock(m_lock);

		MT::SpinLock lock(m_spin_mutex);

		std::size_t size = 0;

		memTrackerLog("MemoryTracker", "Dumping objects ->");

		for (EntryTable::iterator it = m_map.begin(); it != m_map.end(); ++it)
		{
			base_string<char, StackAllocator<512> > string;

			Entry& entry = *it;
			void* adr = it.key();

			if (0 == entry.getMark() || m_mark == entry.getMark())
				continue;

			size += entry.size();

			getEntryLog(entry, adr, string);

			memTrackerLog("MemoryTracker", "%s", string.c_str());

			int str_len = Math::min(16, (int)entry.size());
			char asci_buf[17];
			memset(asci_buf, 0, 17);
			memcpy(asci_buf, adr, str_len);

			string.cat("Data: <", asci_buf, ">");
			for (int j = 0; j < str_len; j++)
			{
				char hex[4];
				hex[0] = ' ';
				toCStringHex(*((uint8_t*)adr + j), hex + 1, 2);
				string.cat(hex);
			}

			memTrackerLog("MemoryTracker", "%s", string.c_str());
		}

		if (0 < size) {
			memTrackerLog("MemoryTracker", "Size of all objects: %u", size);
		}
	}

	MemoryTracker::MemoryTracker()
		: m_spin_mutex(false)
		, m_mark(0)
		, m_allocated_memory(0)
	{
	}

	MemoryTracker::~MemoryTracker()
	{
		Lumix::MemoryTracker::getInstance().dumpDetailed();
	}
} //~namespace Lumix

#endif //~MEM_TRACK
<commit_msg>memorytracker output fixed<commit_after>#include "core/memory_tracker.h"
#include "core/log.h"
#include "core/math_utils.h"
#include "core/MT/spin_mutex.h"
#include "core/stack_allocator.h"
#include "core/string.h"

//#include <new>
#include <stdio.h>
#include <vadefs.h>
#include <Windows.h>

#ifdef MEM_TRACK

#undef min

namespace Lumix
{
	void memTrackerLog(const char*, const char* message, ...)
	{
		char tmp[1024];
		va_list args;
		va_start(args, message);
		vsnprintf(tmp, 1021, message, args);
		va_end(args);

		catCString(tmp, sizeof(tmp), "\n");
		OutputDebugString(tmp);
	}

	// struct FILE_LINE_REPORT
	struct FileLineReport
	{
		const char *file;
		int32_t line;

		LUMIX_FORCE_INLINE bool operator == (const FileLineReport &other) const { return file == other.file && line == other.line; }
		LUMIX_FORCE_INLINE bool operator != (const FileLineReport &other) const { return !(*this == other); }

		LUMIX_FORCE_INLINE bool operator < (const FileLineReport &other) const
		{
			if(file == NULL)
				return other.file != NULL;
			if(other.file == NULL)
				return false;
			int cmp = strcmp(file, other.file);
			if(cmp != 0)
				return cmp < 0;
			return line < other.line;
		}

		LUMIX_FORCE_INLINE bool operator > (const FileLineReport &other) const
		{
			if(file == NULL)
				return other.file != NULL;
			if(other.file == NULL)
				return false;
			int cmp = strcmp(file, other.file);
			if(cmp != 0)
				return cmp > 0;
			return line > other.line;
		}
	};

	typedef Map<uint32_t, MemoryTracker::Entry*, MemTrackAllocator> map_alloc_order;
	typedef Map<FileLineReport, intptr_t, MemTrackAllocator> file_line_map;
	typedef Map<const char *, intptr_t, MemTrackAllocator> file_map;
	typedef Map<FileLineReport, uint32_t, MemTrackAllocator> alloc_count_map;

	#pragma init_seg(compiler)
	MemoryTracker MemoryTracker::s_instance;
	uint32_t MemoryTracker::s_alloc_counter = 0;

	MemoryTracker& MemoryTracker::getInstance()
	{
		return s_instance;
	}

	void MemoryTracker::add(void* p, const intptr_t size, const char* file, const int line)
	{
		if(!p) return;

		MT::SpinLock lock(m_spin_mutex);

		m_map.insert(p, Entry(file, line, size));
		m_allocated_memory += size;
	}

	void MemoryTracker::remove(void* p)
	{
		if(!p) return;

		MT::SpinLock lock(m_spin_mutex);

		EntryTable::iterator it = m_map.find(p);
		ASSERT(it != m_map.end() && "Allocated/Dealocataed from different places?");
		if(it != m_map.end())
		{
			m_allocated_memory -= (*it).size();
			m_map.erase(it);
		}
	}

	static void getEntryLog(MemoryTracker::Entry& entry, void* address, base_string<char, StackAllocator<512> >& string)
	{
		if (entry.file() != NULL)
		{
			string.cat(entry.file(), "(", entry.line(), ") : ");
		}
		string.cat("{", entry.allocID(), " } normal block");
		if (address)
		{
			string.cat(" at ", (int64_t)address);
		}
		string.cat(", ", entry.size(), " bytes long.");
	}

	void MemoryTracker::dumpDetailed()
	{
		// Detected memory leaks!
		// Dumping objects ->
		// {147} normal block at 0x003AF7C0, 10 bytes long.
		// Data: <          > CD CD CD CD CD CD CD CD CD CD
		// d:\temp\zmazat\tt\tt\mainfrm.cpp(34) : {145} normal block at 0x003AF760, 30 bytes long.
		// Data: <               > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
		//    Object dump complete.

		MT::SpinLock lock(m_spin_mutex);
		int32_t count = m_map.size();

		if (count)
		{
			memTrackerLog("MemoryTracker", "MemoryTracker Detected memory leaks!");
			memTrackerLog("MemoryTracker", "Dumping objects ->");
		}
		else
		{
			memTrackerLog("MemoryTracker", "MemoryTracker No leaks detected!");
		}

		for (EntryTable::iterator it = m_map.begin(); it != m_map.end(); ++it)
		{
			base_string<char, StackAllocator<512> > string;

			Entry& entry = *it;
			void* adr = it.key();

			getEntryLog(entry, adr, string);
			memTrackerLog("MemoryTracker", "%s", string.c_str());

			int32_t str_len = Math::min(16, (int32_t)entry.size());
			char asci_buf[17];
			memset(asci_buf, 0, 17);
			memcpy(asci_buf, adr, str_len);

			string = "";
			string.cat("Data: <", asci_buf, ">");
			for (int j = 0; j < str_len; j++)
			{
				char hex[4];
				hex[0] = ' ';
				toCStringHex(*((uint8_t*)adr + j), hex+1, 2);
				hex[3] = 0;
				string.cat(hex);
			}
			memTrackerLog("MemoryTracker", "%s", string.c_str());
		}
		if(count)
		{
			memTrackerLog("MemoryTracker", "	  Object dump complete.");
		}
	}

	void MemoryTracker::dumpSortedByAllocationOrder()
	{
		// Detected memory leaks!
		// Dumping objects ->
		// {147} normal block at 0x003AF7C0, 10 bytes long.
		// Data: <          > CD CD CD CD CD CD CD CD CD CD
		// d:\temp\zmazat\tt\tt\mainfrm.cpp(34) : {145} normal block at 0x003AF760, 30 bytes long.
		// Data: <               > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
		//    Object dump complete.

		MT::SpinLock lock(m_spin_mutex);
		int count = m_map.size();

		if (count)
		{
			memTrackerLog("MemoryTracker", "MemoryTracker Detected memory leaks!");
			memTrackerLog("MemoryTracker", "Dumping objects ->");
		}
		else
		{
			memTrackerLog("MemoryTracker", "MemoryTracker No leaks detected!");
		}

		map_alloc_order alloc_order_map;
		for (EntryTable::iterator it = m_map.begin(); it != m_map.end(); ++it)
		{
			Entry& entry = *it;
			alloc_order_map.insert(entry.allocID(), &entry);
		}

		for (map_alloc_order::iterator it = alloc_order_map.begin(); it != alloc_order_map.end(); ++it)
		{
			base_string<char, StackAllocator<512> > string;
			Entry& entry = *(it.second());
			getEntryLog(entry, NULL, string);

			memTrackerLog("MemoryTracker", string.c_str());
		}

		if(count)
		{
			memTrackerLog("MemoryTracker", "	  Object dump complete.");
		}
	}

	void MemoryTracker::dumpTruncatedPerFileLine()
	{
		memTrackerLog("MemoryTracker", "Dumping objects ->");

		file_line_map report_map;
		{
			MT::SpinLock lock(m_spin_mutex);
			for (EntryTable::iterator it = m_map.begin(); it != m_map.end(); ++it)
			{
				Entry& entry = *it;

				FileLineReport r;
				r.file = entry.file();
				r.line = entry.line();

				file_line_map::iterator rit = report_map.find(r);
				if(rit != report_map.end())
					rit.second() += entry.size();
				else
					report_map.insert(r, entry.size());
			}
		}

		for (file_line_map::iterator it = report_map.begin(); it != report_map.end(); ++it)
		{
			base_string<char, StackAllocator<512> > string;

			const FileLineReport &rep = it.first();
			intptr_t size = it.second();

			const char *file = rep.file ? rep.file : "unknown";

			string = file;
			string += "(";
			string.cat(rep.line);
			string += ") : ";
			string.cat(size);

			memTrackerLog("MemoryTracker", string.c_str());
		}

		memTrackerLog("MemoryTracker", "Object dump complete.");
	}

	void MemoryTracker::dumpTruncatedPerFile()
	{
		memTrackerLog("MemoryTracker", "Dumping objects ->");

		file_map report_map;
		{
			MT::SpinLock lock(m_spin_mutex);
			for (EntryTable::iterator it = m_map.begin(); it != m_map.end(); ++it)
			{
				Entry& entry = *it;

				file_map::iterator rit = report_map.find(entry.file());
				if(rit != report_map.end())
					rit.second() += entry.size();
				else
					report_map.insert(entry.file(), entry.size());
			}
		}

		for (file_map::iterator it = report_map.begin(); it != report_map.end(); ++it)
		{
			base_string<char, StackAllocator<512> > string;

			intptr_t size = it.second();
			const char *file = it.first();

			string = file;
			string += " : ";
			string.cat(size);

			memTrackerLog("MemoryTracker", string.c_str());
		}

		memTrackerLog("MemoryTracker", "Object dump complete.");
	}

	void MemoryTracker::markAll()
	{
		MT::SpinLock lock(m_spin_mutex);

		for (EntryTable::iterator it = m_map.begin(); it != m_map.end(); ++it)
		{
			(*it).mark();
		}
		++m_mark;
	}

	void MemoryTracker::dumpUnmarked()
	{
		// Detected memory leaks!
		// Dumping objects ->
		// {147} normal block at 0x003AF7C0, 10 bytes long.
		// Data: <          > CD CD CD CD CD CD CD CD CD CD
		// d:\temp\zmazat\tt\tt\mainfrm.cpp(34) : {145} normal block at 0x003AF760, 30 bytes long.
		// Data: <               > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
		//    Object dump complete.

		//	Lock lock(m_lock);

		MT::SpinLock lock(m_spin_mutex);

		std::size_t size = 0;

		memTrackerLog("MemoryTracker", "Dumping objects ->");

		for (EntryTable::iterator it = m_map.begin(); it != m_map.end(); ++it)
		{
			base_string<char, StackAllocator<512> > string;

			Entry& entry = *it;
			void* adr = it.key();

			if (0 == entry.getMark() || m_mark == entry.getMark())
				continue;

			size += entry.size();

			getEntryLog(entry, adr, string);

			memTrackerLog("MemoryTracker", "%s", string.c_str());

			int str_len = Math::min(16, (int)entry.size());
			char asci_buf[17];
			memset(asci_buf, 0, 17);
			memcpy(asci_buf, adr, str_len);

			string.cat("Data: <", asci_buf, ">");
			for (int j = 0; j < str_len; j++)
			{
				char hex[4];
				hex[0] = ' ';
				toCStringHex(*((uint8_t*)adr + j), hex + 1, 2);
				hex[3] = 0;
				string.cat(hex);
			}

			memTrackerLog("MemoryTracker", "%s", string.c_str());
		}

		if (0 < size) {
			memTrackerLog("MemoryTracker", "Size of all objects: %u", size);
		}
	}

	MemoryTracker::MemoryTracker()
		: m_spin_mutex(false)
		, m_mark(0)
		, m_allocated_memory(0)
	{
	}

	MemoryTracker::~MemoryTracker()
	{
		Lumix::MemoryTracker::getInstance().dumpDetailed();
	}
} //~namespace Lumix

#endif //~MEM_TRACK
<|endoftext|>