<commit_before>#include "slang-byte-encode-util.h"

namespace Slang {

// Descriptions of algorithms here...
// https://github.com/stoklund/varint

#if SLANG_LITTLE_ENDIAN && SLANG_UNALIGNED_ACCESS
// Testing on i7, unaligned access is around 40% faster
#   define SLANG_BYTE_ENCODE_USE_UNALIGNED_ACCESS 1
#endif

#ifndef SLANG_BYTE_ENCODE_USE_UNALIGNED_ACCESS
#   define SLANG_BYTE_ENCODE_USE_UNALIGNED_ACCESS 0
#endif

#define SLANG_REPEAT_2(n) n, n
#define SLANG_REPEAT_4(n) SLANG_REPEAT_2(n), SLANG_REPEAT_2(n)
#define SLANG_REPEAT_8(n) SLANG_REPEAT_4(n), SLANG_REPEAT_4(n)
#define SLANG_REPEAT_16(n) SLANG_REPEAT_8(n), SLANG_REPEAT_8(n)
#define SLANG_REPEAT_32(n) SLANG_REPEAT_16(n), SLANG_REPEAT_16(n)
#define SLANG_REPEAT_64(n) SLANG_REPEAT_32(n), SLANG_REPEAT_32(n)
#define SLANG_REPEAT_128(n) SLANG_REPEAT_64(n), SLANG_REPEAT_64(n)

/* static */const int8_t ByteEncodeUtil::s_msb8[256] =
{
    - 1,
    0,
    SLANG_REPEAT_2(1),
    SLANG_REPEAT_4(2),
    SLANG_REPEAT_8(3),
    SLANG_REPEAT_16(4),
    SLANG_REPEAT_32(5),
    SLANG_REPEAT_64(6),
    SLANG_REPEAT_128(7),
};

/* static */size_t ByteEncodeUtil::calcEncodeLiteSizeUInt32(const uint32_t* in, size_t num)
{
    size_t totalNumEncodeBytes = 0;

    for (size_t i = 0; i < num; i++)
    {
        const uint32_t v = in[i];

        if (v < kLiteCut1)
        {
            totalNumEncodeBytes += 1;
        }
        else if (v <= kLiteCut1 + 255 * (kLiteCut2 - 1 - kLiteCut1))
        {
            totalNumEncodeBytes += 2;
        }
        else
        {
            totalNumEncodeBytes += calcNonZeroMsByte32(v) + 2;
        }
    }
    return totalNumEncodeBytes;
}

/* static */size_t ByteEncodeUtil::encodeLiteUInt32(const uint32_t* in, size_t num, uint8_t* encodeOut)
{
    uint8_t* encodeStart = encodeOut;

    for (size_t i = 0; i < num; ++i)
    {
        uint32_t v = in[i];

        if(v < kLiteCut1)
        {
            *encodeOut++ = uint8_t(v);
        }
        else if (v <= kLiteCut1 + 255 * (kLiteCut2 - 1 - kLiteCut1))
        {
            v -= kLiteCut1;

            encodeOut[0] = uint8_t(kLiteCut1 + (v >> 8));
            encodeOut[1] = uint8_t(v);
            encodeOut += 2;
        }
        else
        {
            uint8_t* encodeOutStart = encodeOut++;
            while (v)
            {
                *encodeOut++ = uint8_t(v);
                v >>= 8;
            }
            // Finally write the size to the start
            const int numBytes = int(encodeOut - encodeOutStart);
            encodeOutStart[0] = uint8_t(kLiteCut2 + (numBytes - 2));
        }
    }
    return size_t(encodeOut - encodeStart);
}

/* static */void ByteEncodeUtil::encodeLiteUInt32(const uint32_t* in, size_t num, List<uint8_t>& encodeArrayOut)
{
    // Make sure there is at least enough space for all bytes
    encodeArrayOut.setCount(num);

    uint8_t* encodeOut = encodeArrayOut.begin();
    uint8_t* encodeOutEnd = encodeArrayOut.end();

    for (size_t i = 0; i < num; ++i)
    {
        // Check if we need some more space
        if (encodeOut + kMaxLiteEncodeUInt32 > encodeOutEnd)
        {
            const size_t offset = size_t(encodeOut - encodeArrayOut.begin());

            const UInt oldCapacity = encodeArrayOut.getCapacity();

            // Make some more space
            encodeArrayOut.reserve(oldCapacity + (oldCapacity >> 1) + kMaxLiteEncodeUInt32);
            // Make the size the capacity
            const UInt capacity = encodeArrayOut.getCapacity();
            encodeArrayOut.setCount(capacity);

            encodeOut = encodeArrayOut.begin() + offset;
            encodeOutEnd = encodeArrayOut.end();
        }

        uint32_t v = in[i];

        if (v < kLiteCut1)
        {
            *encodeOut++ = uint8_t(v);
        }
        else if (v <= kLiteCut1 + 255 * (kLiteCut2 - 1 - kLiteCut1))
        {
            v -= kLiteCut1;

            encodeOut[0] = uint8_t(kLiteCut1 + (v >> 8));
            encodeOut[1] = uint8_t(v);
            encodeOut += 2;
        }
        else
        {
            uint8_t* encodeOutStart = encodeOut++;
            while (v)
            {
                *encodeOut++ = uint8_t(v);
                v >>= 8;
            }
            // Finally write the size to the start
            const int numBytes = int(encodeOut - encodeOutStart);
            encodeOutStart[0] = uint8_t(kLiteCut2 + (numBytes - 2));
        }
    }

    encodeArrayOut.setCount(UInt(encodeOut - encodeArrayOut.begin()));
    encodeArrayOut.compress();
}

/* static */int ByteEncodeUtil::encodeLiteUInt32(uint32_t in, uint8_t out[kMaxLiteEncodeUInt32])
{
    // 0-184        1 byte    value = B0
    // 185 - 248    2 bytes   value = 185 + 256 * (B0 - 185) + B1
    // 249 - 255    3 - 9 bytes value = (B0 - 249 + 2) little - endian bytes following B0.

    if (in < kLiteCut1)
    {
        out[0] = uint8_t(in);
        return 1;
    }
    else if (in <= kLiteCut1 + 255 * (kLiteCut2 - 1 - kLiteCut1))
    {
        in -= kLiteCut1;

        out[0] = uint8_t(kLiteCut1 + (in >> 8));
        out[1] = uint8_t(in);
        return 2;
    }
    else
    {
        int numBytes = 1;
        while (in)
        {
            out[numBytes++] = uint8_t(in);
            in >>= 8;
        }
        // Finally write the size
        out[0] = uint8_t(kLiteCut2 + (numBytes - 2));
        return numBytes;
    }
}

static const uint32_t s_unalignedUInt32Mask[5] =
{
    0x00000000,
    0x000000ff,
    0x0000ffff,
    0x00ffffff,
    0xffffffff,
};

/* static */int ByteEncodeUtil::decodeLiteUInt32(const uint8_t* in, uint32_t* out)
{
    uint8_t b0 = *in++;
    if (b0 < kLiteCut1)
    {
        *out = uint32_t(b0);
        return 1;
    }
    else if (b0 < kLiteCut2)
    {
        uint8_t b1 = *in++;
        *out = kLiteCut1 + b1 + (uint32_t(b0 - kLiteCut1) << 8);
        return 2;
    }
    else
    {
        int numBytesRemaining = b0 - kLiteCut2 + 2 - 1;

#if SLANG_BYTE_ENCODE_USE_UNALIGNED_ACCESS
        //const uint32_t mask = s_unalignedUInt32Mask[numBytesRemaining];
        const uint32_t mask = ~(uint32_t(0xffffff00) << ((numBytesRemaining - 1) * 8));
        const uint32_t value = (*(const uint32_t*)in) & mask;
#else
        // This works on all cpus although slower
        uint32_t value = in[0];

        switch (numBytesRemaining)
        {
            case 4: value |= uint32_t(in[3]) << 24;         /* fall thru */
            case 3: value |= uint32_t(in[2]) << 16;         /* fall thru */
            case 2: value |= uint32_t(in[1]) << 8;          /* fall thru */
            case 1: break;
        }
#endif
        *out = value;
        return numBytesRemaining + 1;
    }
}

/* static */size_t ByteEncodeUtil::decodeLiteUInt32(const uint8_t* encodeIn, size_t numValues, uint32_t* valuesOut)
{
    const uint8_t* encodeStart = encodeIn;

    for (size_t i = 0; i < numValues; ++i)
    {
        uint8_t b0 = *encodeIn++;
        if (b0 < kLiteCut1)
        {
            valuesOut[i] = uint32_t(b0);
        }
        else if (b0 < kLiteCut2)
        {
            uint8_t b1 = *encodeIn++;
            valuesOut[i] = kLiteCut1 + b1 + (uint32_t(b0 - kLiteCut1) << 8);
        }
        else
        {
            int numBytesRemaining = b0 - kLiteCut2 + 2 - 1;

#if SLANG_BYTE_ENCODE_USE_UNALIGNED_ACCESS
            uint32_t value = 0;
            // Do not use unaligned access for the last two values,
            // (3rd last is safe because this value will have at least 2 bytes, followed by at worst two 1-byte values)
            // otherwise we can access outside the bounds of the encoded array
            // This prevents memory validation tools from causing an exception here
            if (i < numValues - 2)
            {
                const uint32_t mask = s_unalignedUInt32Mask[numBytesRemaining];
                //const uint32_t mask = ~(uint32_t(0xffffff00) << ((numBytesRemaining - 1) * 8));
                value = (*(const uint32_t*)encodeIn) & mask;
            }
            else
#endif
            {
                // This works on all cpus although slower
                value = encodeIn[0];
                switch (numBytesRemaining)
                {
                case 4: value |= uint32_t(encodeIn[3]) << 24;         /* fall thru */
                case 3: value |= uint32_t(encodeIn[2]) << 16;         /* fall thru */
                case 2: value |= uint32_t(encodeIn[1]) << 8;          /* fall thru */
                case 1: break;
                }
            }
            valuesOut[i] = value;
            encodeIn += numBytesRemaining;
        }
    }

    return size_t(encodeIn - encodeStart);
}

} // namespace Slang
<commit_msg>Fixes around byte decode lite  (#2438)<commit_after>#include "slang-byte-encode-util.h"

namespace Slang {

// Descriptions of algorithms here...
// https://github.com/stoklund/varint

#if SLANG_LITTLE_ENDIAN && SLANG_UNALIGNED_ACCESS
// Testing on i7, unaligned access is around 40% faster
#   define SLANG_BYTE_ENCODE_USE_UNALIGNED_ACCESS 1
#endif

#ifndef SLANG_BYTE_ENCODE_USE_UNALIGNED_ACCESS
#   define SLANG_BYTE_ENCODE_USE_UNALIGNED_ACCESS 0
#endif

#define SLANG_REPEAT_2(n) n, n
#define SLANG_REPEAT_4(n) SLANG_REPEAT_2(n), SLANG_REPEAT_2(n)
#define SLANG_REPEAT_8(n) SLANG_REPEAT_4(n), SLANG_REPEAT_4(n)
#define SLANG_REPEAT_16(n) SLANG_REPEAT_8(n), SLANG_REPEAT_8(n)
#define SLANG_REPEAT_32(n) SLANG_REPEAT_16(n), SLANG_REPEAT_16(n)
#define SLANG_REPEAT_64(n) SLANG_REPEAT_32(n), SLANG_REPEAT_32(n)
#define SLANG_REPEAT_128(n) SLANG_REPEAT_64(n), SLANG_REPEAT_64(n)

/* static */const int8_t ByteEncodeUtil::s_msb8[256] =
{
    - 1,
    0,
    SLANG_REPEAT_2(1),
    SLANG_REPEAT_4(2),
    SLANG_REPEAT_8(3),
    SLANG_REPEAT_16(4),
    SLANG_REPEAT_32(5),
    SLANG_REPEAT_64(6),
    SLANG_REPEAT_128(7),
};

/* static */size_t ByteEncodeUtil::calcEncodeLiteSizeUInt32(const uint32_t* in, size_t num)
{
    size_t totalNumEncodeBytes = 0;

    for (size_t i = 0; i < num; i++)
    {
        const uint32_t v = in[i];

        if (v < kLiteCut1)
        {
            totalNumEncodeBytes += 1;
        }
        else if (v <= kLiteCut1 + 255 * (kLiteCut2 - 1 - kLiteCut1))
        {
            totalNumEncodeBytes += 2;
        }
        else
        {
            totalNumEncodeBytes += calcNonZeroMsByte32(v) + 2;
        }
    }
    return totalNumEncodeBytes;
}

/* static */size_t ByteEncodeUtil::encodeLiteUInt32(const uint32_t* in, size_t num, uint8_t* encodeOut)
{
    uint8_t* encodeStart = encodeOut;

    for (size_t i = 0; i < num; ++i)
    {
        uint32_t v = in[i];

        if(v < kLiteCut1)
        {
            *encodeOut++ = uint8_t(v);
        }
        else if (v <= kLiteCut1 + 255 * (kLiteCut2 - 1 - kLiteCut1))
        {
            v -= kLiteCut1;

            encodeOut[0] = uint8_t(kLiteCut1 + (v >> 8));
            encodeOut[1] = uint8_t(v);
            encodeOut += 2;
        }
        else
        {
            uint8_t* encodeOutStart = encodeOut++;
            while (v)
            {
                *encodeOut++ = uint8_t(v);
                v >>= 8;
            }
            // Finally write the size to the start
            const int numBytes = int(encodeOut - encodeOutStart);
            encodeOutStart[0] = uint8_t(kLiteCut2 + (numBytes - 2));
        }
    }
    return size_t(encodeOut - encodeStart);
}

/* static */void ByteEncodeUtil::encodeLiteUInt32(const uint32_t* in, size_t num, List<uint8_t>& encodeArrayOut)
{
    // Make sure there is at least enough space for all bytes
    encodeArrayOut.setCount(num);

    uint8_t* encodeOut = encodeArrayOut.begin();
    uint8_t* encodeOutEnd = encodeArrayOut.end();

    for (size_t i = 0; i < num; ++i)
    {
        // Check if we need some more space
        if (encodeOut + kMaxLiteEncodeUInt32 > encodeOutEnd)
        {
            const size_t offset = size_t(encodeOut - encodeArrayOut.begin());

            const UInt oldCapacity = encodeArrayOut.getCapacity();

            // Make some more space
            encodeArrayOut.reserve(oldCapacity + (oldCapacity >> 1) + kMaxLiteEncodeUInt32);
            // Make the size the capacity
            const UInt capacity = encodeArrayOut.getCapacity();
            encodeArrayOut.setCount(capacity);

            encodeOut = encodeArrayOut.begin() + offset;
            encodeOutEnd = encodeArrayOut.end();
        }

        uint32_t v = in[i];

        if (v < kLiteCut1)
        {
            *encodeOut++ = uint8_t(v);
        }
        else if (v <= kLiteCut1 + 255 * (kLiteCut2 - 1 - kLiteCut1))
        {
            v -= kLiteCut1;

            encodeOut[0] = uint8_t(kLiteCut1 + (v >> 8));
            encodeOut[1] = uint8_t(v);
            encodeOut += 2;
        }
        else
        {
            uint8_t* encodeOutStart = encodeOut++;
            while (v)
            {
                *encodeOut++ = uint8_t(v);
                v >>= 8;
            }
            // Finally write the size to the start
            const int numBytes = int(encodeOut - encodeOutStart);
            encodeOutStart[0] = uint8_t(kLiteCut2 + (numBytes - 2));
        }
    }

    encodeArrayOut.setCount(UInt(encodeOut - encodeArrayOut.begin()));
    encodeArrayOut.compress();
}

/* static */int ByteEncodeUtil::encodeLiteUInt32(uint32_t in, uint8_t out[kMaxLiteEncodeUInt32])
{
    // 0-184        1 byte    value = B0
    // 185 - 248    2 bytes   value = 185 + 256 * (B0 - 185) + B1
    // 249 - 255    3 - 9 bytes value = (B0 - 249 + 2) little - endian bytes following B0.

    if (in < kLiteCut1)
    {
        out[0] = uint8_t(in);
        return 1;
    }
    else if (in <= kLiteCut1 + 255 * (kLiteCut2 - 1 - kLiteCut1))
    {
        in -= kLiteCut1;

        out[0] = uint8_t(kLiteCut1 + (in >> 8));
        out[1] = uint8_t(in);
        return 2;
    }
    else
    {
        int numBytes = 1;
        while (in)
        {
            out[numBytes++] = uint8_t(in);
            in >>= 8;
        }
        // Finally write the size
        out[0] = uint8_t(kLiteCut2 + (numBytes - 2));
        return numBytes;
    }
}

static const uint32_t s_unalignedUInt32Mask[5] =
{
    0x00000000,
    0x000000ff,
    0x0000ffff,
    0x00ffffff,
    0xffffffff,
};

// Decode the >= kLiteCut2.
// in is pointing past the first byte.
// Only valid numBytesRemaining is 2, 3, or 4
SLANG_FORCE_INLINE static uint32_t _decodeLiteCut2UInt32(const uint8_t* in, int numBytesRemaining)
{
    uint32_t value = 0;
#if SLANG_BYTE_ENCODE_USE_UNALIGNED_ACCESS
    switch (numBytesRemaining)
    {
        case 2:     value = *(const uint16_t*)in; break;
        case 3:     value = (uint32_t(in[2]) << 16) | (uint32_t(in[1]) << 8) | uint32_t(in[0]); break;
        case 4:     value = *(const uint32_t*)in; break;
        default: break;
    }
#else
    // This works on all cpus although slower
    value = in[0];
    switch (numBytesRemaining)
    {
        case 4: value |= uint32_t(in[3]) << 24;         /* fall thru */
        case 3: value |= uint32_t(in[2]) << 16;         /* fall thru */
        case 2: value |= uint32_t(in[1]) << 8;          /* fall thru */
        case 1: break;
    }
#endif
    return value;
}

/* static */int ByteEncodeUtil::decodeLiteUInt32(const uint8_t* in, uint32_t* out)
{
    uint8_t b0 = *in++;
    if (b0 < kLiteCut1)
    {
        *out = uint32_t(b0);
        return 1;
    }
    else if (b0 < kLiteCut2)
    {
        uint8_t b1 = *in++;
        *out = kLiteCut1 + b1 + (uint32_t(b0 - kLiteCut1) << 8);
        return 2;
    }
    else
    {
        const int numBytesRemaining = b0 - kLiteCut2 + 2 - 1;
        *out = _decodeLiteCut2UInt32(in, numBytesRemaining);
        return numBytesRemaining + 1;
    }
}

/* static */size_t ByteEncodeUtil::decodeLiteUInt32(const uint8_t* encodeIn, size_t numValues, uint32_t* valuesOut)
{
    const uint8_t* encodeStart = encodeIn;

    for (size_t i = 0; i < numValues; ++i)
    {
        uint8_t b0 = *encodeIn++;
        if (b0 < kLiteCut1)
        {
            valuesOut[i] = uint32_t(b0);
        }
        else if (b0 < kLiteCut2)
        {
            uint8_t b1 = *encodeIn++;
            valuesOut[i] = kLiteCut1 + b1 + (uint32_t(b0 - kLiteCut1) << 8);
        }
        else
        {
            const int numBytesRemaining = b0 - kLiteCut2 + 2 - 1;

            // For unaligned access, do not use unaligned access for the last two values,
            // (3rd last is safe because this value will have at least 2 bytes, followed by at worst two 1-byte values)
            // otherwise we can access outside the bounds of the encoded array
            // This prevents memory validation tools from causing an exception here
            if (SLANG_BYTE_ENCODE_USE_UNALIGNED_ACCESS && i < numValues - 2)
            {
                const uint32_t mask = s_unalignedUInt32Mask[numBytesRemaining];
                //const uint32_t mask = ~(uint32_t(0xffffff00) << ((numBytesRemaining - 1) * 8));
                valuesOut[i] = (*(const uint32_t*)encodeIn) & mask;
            }
            else
            {
                valuesOut[i] = _decodeLiteCut2UInt32(encodeIn, numBytesRemaining);
            }

            encodeIn += numBytesRemaining;
        }
    }

    return size_t(encodeIn - encodeStart);
}

} // namespace Slang
<|endoftext|>


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

#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>

#include "base/Log.h"
#include "base/util/utils.h"
#include "base/globalsdef.h"

BEGIN_NAMESPACE

bool saveFile(const char *filename, const char *buffer, size_t len, bool binary)
{
    FILE *f = fopen(filename, "w");

    if(!f)
        return false;

    if (fwrite(buffer, sizeof(char), len, f) != len) {
        fclose(f);
        return false;
    }
    fclose(f);

    return true;
}

bool readFile(const char* path, char **message, size_t *len, bool binary)
{
    FILE *f = NULL;
    size_t msglen=0;
    char *msg=0;
    const char *mode = binary ? "rb" : "r" ;
    struct stat buf;
    bool res = false;

    f = fopen(path, mode);
    if ( !f ) {
        goto done;
    }
    if ( fstat(fileno(f), &buf) ) {
        goto done;
    }

    msglen = buf.st_size;
    msg = new char[msglen+1];
    msg[msglen] = 0;

    *len=fread(msg, sizeof(char), msglen, f);
    if ( ferror(f) || *len < msglen ){
        goto done;
    }

    // Set return parameters
    *message=msg;
    msg = 0;
    res = true;

  done:
    if (f) {
        fclose(f);
    }
    if (msg) {
        delete [] msg;
    }

    return res;
}

char** readDir(char* name, int *count, bool onlyCount) {
    char **entries = NULL;
    *count = 0;

    // count entries
    int total = 0;
    DIR *dir = opendir(name);
    if (dir) {
        struct dirent *entry = readdir(dir);
        while (entry) {
            if (strcmp(entry->d_name, ".") &&
                strcmp(entry->d_name, "..")) {
                total++;
            }
            entry = readdir(dir);
        }

        if (!onlyCount && total) {
            entries = new char *[total];

            rewinddir(dir);
            entry = readdir(dir);
            while (entry && *count < total) {
                if (strcmp(entry->d_name, ".") &&
                    strcmp(entry->d_name, "..")) {
                    entries[*count] = stringdup(entry->d_name);
                    ++*count;
                }
                entry = readdir(dir);
            }
        }
        closedir(dir);
    }

    return entries;
}

unsigned long getFileModTime(const char* name)
{
    struct stat buf;

    return stat(name, &buf) ? 0 :
        buf.st_ctime > buf.st_mtime ? buf.st_ctime :
        buf.st_mtime;
}

bool removeFileInDir(const char* d, const char* fname) {

    char toFind    [512];
    bool ret = false;
    char** totalFiles = NULL;
    int numFiles = 0;

    if (fname) {
        sprintf(toFind, "%s/%s", d, fname);
        if (remove(toFind) != 0) {
            LOG.error("Error deleting the %s file", toFind); ret = true;
        } else {
            LOG.debug("File %s deleted succesfully", toFind);
        }
    }
    else {
        totalFiles = readDir((char*)d, &numFiles, false);
        if (totalFiles && numFiles > 0) {
            for (int i = 0; i < numFiles; i++) {
                sprintf(toFind, "%s/%s", d, totalFiles[i]);
                remove(toFind);
            }
        }
        ret = true;
    }
    if (totalFiles) {
        for (int i = 0; i < numFiles; i++) {
            delete [] totalFiles[i];
        }
        delete [] totalFiles; totalFiles = NULL;
    }

    return ret;
}

/**
 * Creates a folder. TODO: move it to SDK utils
 * @return 0 on success, -1 otherwise.
 */
int createFolder(const char *path) {
    DIR* d = opendir(path);
    int res = 0;
    if (!d) {
        res = mkdir(path, 0777);
    } else {
        closedir(d);
    }
    return res;
}

// TODO: convert to the specified encoding, assuming wc is UTF-8
char* toMultibyte(const WCHAR *wc, const char *encoding)
{
#ifdef USE_WCHAR
    size_t length = wcstombs(NULL, wc, 0) + 1;
    if(length == -1) {
        LOG.error("toMultibyte: invalid string.");
        return strdup("");
    }
    char* ret = new char[length];
    wcstombs(ret, wc, length);

    return ret;
#else
    return stringdup(wc);
#endif
}

// TODO: convert to UTF-8 from the specified encoding
WCHAR* toWideChar(const char *mb, const char *encoding)
{
#ifdef USE_WCHAR
    size_t length = mbstowcs(NULL, mb, 0) + 1;
    if(length == -1) {
        LOG.error("toWideChar: invalid string.");
        return wstrdup(TEXT(""));
    }
    WCHAR* ret = new WCHAR[length];
    mbstowcs(ret, mb, length);

    return ret;
#else
    return stringdup(mb);
#endif
}

#ifdef USE_WCHAR
// FIXME-----------------------------------------------------------------------
//Overloading thread-safe version of wcstok (defined in Linux) to make it
//work like the non-thread safe version available on Windows (same as strtok).
// FIXME: adjust VOCL code to NOT use this but String::split and remove it!!
//-----------------------------------------------------------------------------
WCHAR *wcstok(WCHAR *s, const WCHAR *delim)
{
    static WCHAR *state = 0;
    return ::wcstok(s, delim, &state);
}
#endif

// Implemented using mkstemp() with a template hard-coded
// to /tmp. Because the API of mkTempFileName() cannot return
// an open file, the file has to be closed. This exposes
// the possibility for an attacker to replace the file
// before it is opened again if /tmp has incorrect permissions.
char *mkTempFileName(const char *name)
{
    char *filename = new char[strlen("/tmp/") + strlen(name) + strlen(".XXXXXX") + 1];
    int fd;

    sprintf(filename, "/tmp/%s.XXXXXX", name );
    fd = mkstemp(filename);
    if (fd == -1) {
        delete [] filename;
        return NULL;
    } else {
        close(fd);
        return filename;
    }
}

END_NAMESPACE

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

#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>

#include "base/Log.h"
#include "base/util/utils.h"
#include "base/globalsdef.h"

BEGIN_NAMESPACE

bool saveFile(const char *filename, const char *buffer, size_t len, bool binary)
{
    FILE *f = fopen(filename, "w");

    if(!f)
        return false;

    if (fwrite(buffer, sizeof(char), len, f) != len) {
        fclose(f);
        return false;
    }
    fclose(f);

    return true;
}

bool readFile(const char* path, char **message, size_t *len, bool binary)
{
    FILE *f = NULL;
    size_t msglen=0;
    char *msg=0;
    const char *mode = binary ? "rb" : "r" ;
    struct stat buf;
    bool res = false;

    f = fopen(path, mode);
    if ( !f ) {
        goto done;
    }
    if ( fstat(fileno(f), &buf) ) {
        goto done;
    }

    msglen = buf.st_size;
    msg = new char[msglen+1];
    msg[msglen] = 0;

    *len=fread(msg, sizeof(char), msglen, f);
    if ( ferror(f) || *len < msglen ){
        goto done;
    }

    // Set return parameters
    *message=msg;
    msg = 0;
    res = true;

  done:
    if (f) {
        fclose(f);
    }
    if (msg) {
        delete [] msg;
    }

    return res;
}

char** readDir(char* name, int *count, bool onlyCount) {
    char **entries = NULL;
    *count = 0;

    // count entries
    int total = 0;
    DIR *dir = opendir(name);
    if (dir) {
        struct dirent *entry = readdir(dir);
        while (entry) {
            if (strcmp(entry->d_name, ".") &&
                strcmp(entry->d_name, "..")) {
                total++;
            }
            entry = readdir(dir);
        }

        if (!onlyCount && total) {
            entries = new char *[total];

            rewinddir(dir);
            entry = readdir(dir);
            while (entry && *count < total) {
                if (strcmp(entry->d_name, ".") &&
                    strcmp(entry->d_name, "..")) {
                    entries[*count] = stringdup(entry->d_name);
                    ++*count;
                }
                entry = readdir(dir);
            }
        }
        closedir(dir);
    }

    return entries;
}

unsigned long getFileModTime(const char* name)
{
    struct stat buf;

    return stat(name, &buf) ? 0 :
        buf.st_ctime > buf.st_mtime ? buf.st_ctime :
        buf.st_mtime;
}

bool removeFileInDir(const char* d, const char* fname) {

    char toFind    [512];
    bool ret = false;
    char** totalFiles = NULL;
    int numFiles = 0;

    if (fname) {
        sprintf(toFind, "%s/%s", d, fname);
        if (remove(toFind) != 0) {
            LOG.error("Error deleting the %s file", toFind); ret = true;
        } else {
            LOG.debug("File %s deleted succesfully", toFind);
        }
    }
    else {
        totalFiles = readDir((char*)d, &numFiles, false);
        if (totalFiles && numFiles > 0) {
            for (int i = 0; i < numFiles; i++) {
                sprintf(toFind, "%s/%s", d, totalFiles[i]);
                remove(toFind);
            }
        }
        ret = true;
    }
    if (totalFiles) {
        for (int i = 0; i < numFiles; i++) {
            delete [] totalFiles[i];
        }
        delete [] totalFiles; totalFiles = NULL;
    }

    return ret;
}

/**
 * Creates a folder. TODO: move it to SDK utils
 * @return 0 on success, -1 otherwise.
 */
int createFolder(const char *path) {
    DIR* d = opendir(path);
    int res = 0;
    if (!d) {
        res = mkdir(path, 0777);
    } else {
        closedir(d);
    }
    return res;
}

// TODO: convert to the specified encoding, assuming wc is UTF-8
char* toMultibyte(const WCHAR *wc, const char *encoding)
{
#ifdef USE_WCHAR
    size_t length = wcstombs(NULL, wc, 0) + 1;
    if(length == -1) {
        LOG.error("toMultibyte: invalid string.");
        return strdup("");
    }
    char* ret = new char[length];
    wcstombs(ret, wc, length);

    return ret;
#else
    return stringdup(wc);
#endif
}

// TODO: convert to UTF-8 from the specified encoding
WCHAR* toWideChar(const char *mb, const char *encoding)
{
#ifdef USE_WCHAR
    size_t length = mbstowcs(NULL, mb, 0) + 1;
    if(length == -1) {
        LOG.error("toWideChar: invalid string.");
        return wstrdup(TEXT(""));
    }
    WCHAR* ret = new WCHAR[length];
    mbstowcs(ret, mb, length);

    return ret;
#else
    return stringdup(mb);
#endif
}

#ifdef USE_WCHAR
// FIXME-----------------------------------------------------------------------
//Overloading thread-safe version of wcstok (defined in Linux) to make it
//work like the non-thread safe version available on Windows (same as strtok).
// FIXME: adjust VOCL code to NOT use this but String::split and remove it!!
//-----------------------------------------------------------------------------
WCHAR *wcstok(WCHAR *s, const WCHAR *delim)
{
    static WCHAR *state = 0;
    return ::wcstok(s, delim, &state);
}
#endif

// Implemented using mkstemp() with a template hard-coded
// to /tmp. Because the API of mkTempFileName() cannot return
// an open file, the file has to be closed. This exposes
// the possibility for an attacker to replace the file
// before it is opened again if /tmp has incorrect permissions.
char *mkTempFileName(const char *name)
{
    char *filename = new char[strlen("/tmp/") + strlen(name) + strlen(".XXXXXX") + 1];
    int fd;

    sprintf(filename, "/tmp/%s.XXXXXX", name );
    fd = mkstemp(filename);
    if (fd == -1) {
        delete [] filename;
        return NULL;
    } else {
        close(fd);
        return filename;
    }
}

// check the presence of a file
bool fileExists(const char *pathname) {
    if (pathname) {
        struct stat st;

        memset(&st, 0, sizeof(struct stat));

        if (stat(pathname, &st) < 0) {
            return false;
        }

        return true;
    }

    return false;
}
END_NAMESPACE

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: XMLNumberStylesExport.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 13:41:19 $
 *
 *  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 _XMLOFF_NUMBERSTYLESEXPORT_HXX
#define _XMLOFF_NUMBERSTYLESEXPORT_HXX

#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif

#ifndef _RTL_USTRING_
#include <rtl/ustring>
#endif

class SdXMLExport;

const sal_Int16 SdXMLDateFormatCount = 8;
const sal_Int16 SdXMLTimeFormatCount = 7;

class SdXMLNumberStylesExporter
{
public:
    static void exportTimeStyle( SdXMLExport& rExport, sal_Int32 nStyle );
    static void exportDateStyle( SdXMLExport& rExport, sal_Int32 nStyle );

    static sal_Int32 getDateStyleCount() { return SdXMLDateFormatCount; }
    static sal_Int32 getTimeStyleCount() { return SdXMLTimeFormatCount; }

    static rtl::OUString getTimeStyleName(const sal_Int32 nTimeFormat );
    static rtl::OUString getDateStyleName(const sal_Int32 nDateFormat );
};

#endif  //  _XMLOFF_NUMBERSTYLESEXPORT_HXX

<commit_msg>INTEGRATION: CWS warnings01 (1.2.34); FILE MERGED 2005/11/02 14:57:48 cl 1.2.34.1: warning free code changes<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: XMLNumberStylesExport.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-19 18:08:20 $
 *
 *  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 _XMLOFF_NUMBERSTYLESEXPORT_HXX
#define _XMLOFF_NUMBERSTYLESEXPORT_HXX

#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif

#ifndef _RTL_USTRING_
#include <rtl/ustring.hxx>
#endif

class SdXMLExport;

const sal_Int16 SdXMLDateFormatCount = 8;
const sal_Int16 SdXMLTimeFormatCount = 7;

class SdXMLNumberStylesExporter
{
public:
    static void exportTimeStyle( SdXMLExport& rExport, sal_Int32 nStyle );
    static void exportDateStyle( SdXMLExport& rExport, sal_Int32 nStyle );

    static sal_Int32 getDateStyleCount() { return SdXMLDateFormatCount; }
    static sal_Int32 getTimeStyleCount() { return SdXMLTimeFormatCount; }

    static rtl::OUString getTimeStyleName(const sal_Int32 nTimeFormat );
    static rtl::OUString getDateStyleName(const sal_Int32 nDateFormat );
};

#endif  //  _XMLOFF_NUMBERSTYLESEXPORT_HXX

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: PageMasterPropMapper.cxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: mib $ $Date: 2000-11-07 13:33:06 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _XMLOFF_PAGEMASTERPROPMAPPER_HXX
#include "PageMasterPropMapper.hxx"
#endif

#ifndef _XMLOFF_PAGEMASTERSTYLEMAP_HXX
#include "PageMasterStyleMap.hxx"
#endif
#ifndef _XMLOFF_PAGEMASTERPROPHDLFACTORY_HXX
#include "PageMasterPropHdlFactory.hxx"
#endif

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;

//______________________________________________________________________________

XMLPageMasterPropSetMapper::XMLPageMasterPropSetMapper():
    XMLPropertySetMapper( aXMLPageMasterStyleMap, new XMLPageMasterPropHdlFactory())
{
}

XMLPageMasterPropSetMapper::XMLPageMasterPropSetMapper(
        const XMLPropertyMapEntry* pEntries,
        const UniReference< XMLPropertyHandlerFactory >& rFactory ) :
    XMLPropertySetMapper( pEntries, rFactory )
{
}

XMLPageMasterPropSetMapper::~XMLPageMasterPropSetMapper()
{
}

<commit_msg>INTEGRATION: CWS ooo19126 (1.10.650); FILE MERGED 2005/09/05 14:39:14 rt 1.10.650.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: PageMasterPropMapper.cxx,v $
 *
 *  $Revision: 1.11 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 14:28:28 $
 *
 *  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 _XMLOFF_PAGEMASTERPROPMAPPER_HXX
#include "PageMasterPropMapper.hxx"
#endif

#ifndef _XMLOFF_PAGEMASTERSTYLEMAP_HXX
#include "PageMasterStyleMap.hxx"
#endif
#ifndef _XMLOFF_PAGEMASTERPROPHDLFACTORY_HXX
#include "PageMasterPropHdlFactory.hxx"
#endif

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;

//______________________________________________________________________________

XMLPageMasterPropSetMapper::XMLPageMasterPropSetMapper():
    XMLPropertySetMapper( aXMLPageMasterStyleMap, new XMLPageMasterPropHdlFactory())
{
}

XMLPageMasterPropSetMapper::XMLPageMasterPropSetMapper(
        const XMLPropertyMapEntry* pEntries,
        const UniReference< XMLPropertyHandlerFactory >& rFactory ) :
    XMLPropertySetMapper( pEntries, rFactory )
{
}

XMLPageMasterPropSetMapper::~XMLPageMasterPropSetMapper()
{
}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: XMLFontAutoStylePool.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: dvo $ $Date: 2001-06-29 21:07:17 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _CNTRSRT_HXX
#include <svtools/cntnrsrt.hxx>
#endif
#ifndef _VCL_VCLENUM_HXX
#include <vcl/vclenum.hxx>
#endif

#ifndef _XMLOFF_XMLNMSPE_HXX
#include "xmlnmspe.hxx"
#endif
#ifndef _XMLOFF_XMLTOKEN_HXX
#include "xmltoken.hxx"
#endif
#ifndef _XMLOFF_XMLUCONV_HXX
#include "xmluconv.hxx"
#endif
#ifndef _XMLOFF_PROPERTYHANDLER_FONTTYPES_HXX
#include "fonthdl.hxx"
#endif

#ifndef _XMLOFF_XMLEXP_HXX
#include "xmlexp.hxx"
#endif
#ifndef _XMLOFF_XMLFONTAUTOSTYLEPOOL_HXX
#include "XMLFontAutoStylePool.hxx"
#endif

using namespace ::rtl;
using namespace ::com::sun::star::uno;
using namespace ::xmloff::token;

int XMLFontAutoStylePoolNameCmp_Impl( const OUString& r1,
                                      const OUString& r2 )
{
    return (int)r1.compareTo( r2 );
}

DECLARE_CONTAINER_SORT_DEL( XMLFontAutoStylePoolNames_Impl,
                            OUString )
IMPL_CONTAINER_SORT( XMLFontAutoStylePoolNames_Impl,
                     OUString,
                     XMLFontAutoStylePoolNameCmp_Impl )

class XMLFontAutoStylePoolEntry_Impl
{
    OUString    sName;
    OUString    sFamilyName;
    OUString    sStyleName;
    sal_Int16   nFamily;
    sal_Int16   nPitch;
    rtl_TextEncoding eEnc;

public:

    inline XMLFontAutoStylePoolEntry_Impl(
            const ::rtl::OUString& rName,
            const ::rtl::OUString& rFamilyName,
            const ::rtl::OUString& rStyleName,
            sal_Int16 nFamily,
            sal_Int16 nPitch,
            rtl_TextEncoding eEnc );

    inline XMLFontAutoStylePoolEntry_Impl(
            const ::rtl::OUString& rFamilyName,
            const ::rtl::OUString& rStyleName,
            sal_Int16 nFamily,
            sal_Int16 nPitch,
            rtl_TextEncoding eEnc );

    const OUString& GetName() const { return sName; }
    const OUString& GetFamilyName() const { return sFamilyName; }
    const OUString& GetStyleName() const { return sStyleName; }
    sal_Int16 GetFamily() const {   return nFamily; }
    sal_Int16 GetPitch() const { return nPitch; }
    rtl_TextEncoding GetEncoding() const { return eEnc; }
};

inline XMLFontAutoStylePoolEntry_Impl::XMLFontAutoStylePoolEntry_Impl(
        const ::rtl::OUString& rName,
        const ::rtl::OUString& rFamilyName,
        const ::rtl::OUString& rStyleName,
        sal_Int16 nFam,
        sal_Int16 nP,
        rtl_TextEncoding eE ) :
    sName( rName ),
    sFamilyName( rFamilyName ),
    sStyleName( rStyleName ),
    nFamily( nFam ),
    nPitch( nP ),
    eEnc( eE )
{
}

inline XMLFontAutoStylePoolEntry_Impl::XMLFontAutoStylePoolEntry_Impl(
        const ::rtl::OUString& rFamilyName,
        const ::rtl::OUString& rStyleName,
        sal_Int16 nFam,
        sal_Int16 nP,
        rtl_TextEncoding eE ) :
    sFamilyName( rFamilyName ),
    sStyleName( rStyleName ),
    nFamily( nFam ),
    nPitch( nP ),
    eEnc( eE )
{
}
int XMLFontAutoStylePoolEntryCmp_Impl(
        const XMLFontAutoStylePoolEntry_Impl& r1,
        const XMLFontAutoStylePoolEntry_Impl& r2 )
{
    sal_Int8 nEnc1(r1.GetEncoding() != RTL_TEXTENCODING_SYMBOL);
    sal_Int8 nEnc2(r2.GetEncoding() != RTL_TEXTENCODING_SYMBOL);
    if( nEnc1 != nEnc2 )
        return nEnc1 - nEnc2;
    else if( r1.GetPitch() != r2.GetPitch() )
        return (int)r1.GetPitch() - (int)r2.GetPitch();
    else if( r1.GetFamily() != r2.GetFamily() )
        return (int)r1.GetFamily() - (int)r2.GetFamily();
    else
    {
        sal_Int32 nCmp = r1.GetFamilyName().compareTo( r2.GetFamilyName() );
        if( 0 == nCmp )
            return (int)r1.GetStyleName().compareTo( r2.GetStyleName() );
        else
            return (int)nCmp;
    }
}

typedef XMLFontAutoStylePoolEntry_Impl *XMLFontAutoStylePoolEntryPtr;
DECLARE_CONTAINER_SORT_DEL( XMLFontAutoStylePool_Impl,
                            XMLFontAutoStylePoolEntry_Impl )
IMPL_CONTAINER_SORT( XMLFontAutoStylePool_Impl,
                     XMLFontAutoStylePoolEntry_Impl,
                     XMLFontAutoStylePoolEntryCmp_Impl )

XMLFontAutoStylePool::XMLFontAutoStylePool( SvXMLExport& rExp ) :
    rExport( rExp ),
    pPool( new XMLFontAutoStylePool_Impl( 5, 5 ) ),
    pNames( new XMLFontAutoStylePoolNames_Impl( 5, 5 ) )
{
}

XMLFontAutoStylePool::~XMLFontAutoStylePool()
{
    delete pPool;
    delete pNames;
}

OUString XMLFontAutoStylePool::Add(
            const OUString& rFamilyName,
            const OUString& rStyleName,
            sal_Int16 nFamily,
            sal_Int16 nPitch,
            rtl_TextEncoding eEnc )
{
    OUString sName;
    XMLFontAutoStylePoolEntry_Impl aTmp( rFamilyName, rStyleName, nFamily,
                                          nPitch, eEnc );
    sal_uInt32 nPos;
    if( pPool->Seek_Entry( &aTmp, &nPos ) )
    {
        sName = pPool->GetObject( nPos )->GetName();
    }
    else
    {
        OUString sName;
        sal_Int32 nLen = rFamilyName.indexOf( sal_Unicode(';'), 0 );
        if( -1 == nLen )
        {
            sName = rFamilyName;
        }
        else if( nLen > 0 )
        {
            sName = rFamilyName.copy( 0, nLen );
            sName.trim();
        }

        if( !sName.getLength() )
            sName = OUString::valueOf( sal_Unicode( 'F' ) );

        if( pNames->Seek_Entry( &sName, 0 ) )
        {
            sal_Int32 nCount = 1;
            OUString sPrefix( sName );
            sName += OUString::valueOf( nCount );
            while( pNames->Seek_Entry( &sName, 0 ) )
            {
                sName = sPrefix;
                sName += OUString::valueOf( ++nCount );
            }
        }

        XMLFontAutoStylePoolEntry_Impl *pEntry =
            new XMLFontAutoStylePoolEntry_Impl( sName, rFamilyName, rStyleName,
                                                nFamily, nPitch, eEnc );
        pPool->Insert( pEntry );
        pNames->Insert( new OUString( sName ) );
    }

    return sName;
}

::rtl::OUString XMLFontAutoStylePool::Find(
            const OUString& rFamilyName,
            const OUString& rStyleName,
            sal_Int16 nFamily,
            sal_Int16 nPitch,
            rtl_TextEncoding eEnc ) const
{
    OUString sName;
    XMLFontAutoStylePoolEntry_Impl aTmp( rFamilyName, rStyleName, nFamily,
                                          nPitch, eEnc );
    sal_uInt32 nPos;
    if( pPool->Seek_Entry( &aTmp, &nPos ) )
    {
        sName = pPool->GetObject( nPos )->GetName();
    }

    return sName;
}

void XMLFontAutoStylePool::exportXML()
{
    SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_OFFICE,
                              XML_FONT_DECLS,
                              sal_True, sal_True );
    Any aAny;
    OUString sTmp;
    XMLFontFamilyNamePropHdl aFamilyNameHdl;
    XMLFontFamilyPropHdl aFamilyHdl;
    XMLFontPitchPropHdl aPitchHdl;
    XMLFontEncodingPropHdl aEncHdl;
    const SvXMLUnitConverter& rUnitConv = GetExport().GetMM100UnitConverter();

    sal_uInt32 nCount = pPool->Count();
    for( sal_uInt32 i=0; i<nCount; i++ )
    {
        const XMLFontAutoStylePoolEntry_Impl *pEntry = pPool->GetObject( i );

        GetExport().AddAttribute( XML_NAMESPACE_STYLE,
                                  XML_NAME, pEntry->GetName() );

        aAny <<= pEntry->GetFamilyName();
        if( aFamilyNameHdl.exportXML( sTmp, aAny, rUnitConv ) )
            GetExport().AddAttribute( XML_NAMESPACE_FO,
                                      XML_FONT_FAMILY, sTmp );

        const OUString& rStyleName = pEntry->GetStyleName();
        if( rStyleName.getLength() )
            GetExport().AddAttribute( XML_NAMESPACE_STYLE,
                                      XML_FONT_STYLE_NAME,
                                      rStyleName );

        aAny <<= (sal_Int16)pEntry->GetFamily();
        if( aFamilyHdl.exportXML( sTmp, aAny, rUnitConv  ) )
            GetExport().AddAttribute( XML_NAMESPACE_STYLE,
                                      XML_FONT_FAMILY_GENERIC, sTmp );

        aAny <<= (sal_Int16)pEntry->GetPitch();
        if( aPitchHdl.exportXML( sTmp, aAny, rUnitConv  ) )
            GetExport().AddAttribute( XML_NAMESPACE_STYLE,
                                      XML_FONT_PITCH, sTmp );

        aAny <<= (sal_Int16)pEntry->GetEncoding();
        if( aEncHdl.exportXML( sTmp, aAny, rUnitConv  ) )
            GetExport().AddAttribute( XML_NAMESPACE_STYLE,
                                      XML_FONT_CHARSET, sTmp );

        SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_STYLE,
                                  XML_FONT_DECL,
                                  sal_True, sal_True );
    }
}

<commit_msg>INTEGRATION: CWS oasis (1.3.276); FILE MERGED 2004/04/19 12:34:26 mib 1.3.276.1: - changed "graphics" style family to "graphic" (#i20153#) - replaced "inch" with "in" (#i18170#)<commit_after>/*************************************************************************
 *
 *  $RCSfile: XMLFontAutoStylePool.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2004-07-13 08:22:31 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _CNTRSRT_HXX
#include <svtools/cntnrsrt.hxx>
#endif
#ifndef _VCL_VCLENUM_HXX
#include <vcl/vclenum.hxx>
#endif

#ifndef _XMLOFF_XMLNMSPE_HXX
#include "xmlnmspe.hxx"
#endif
#ifndef _XMLOFF_XMLTOKEN_HXX
#include "xmltoken.hxx"
#endif
#ifndef _XMLOFF_XMLUCONV_HXX
#include "xmluconv.hxx"
#endif
#ifndef _XMLOFF_PROPERTYHANDLER_FONTTYPES_HXX
#include "fonthdl.hxx"
#endif

#ifndef _XMLOFF_XMLEXP_HXX
#include "xmlexp.hxx"
#endif
#ifndef _XMLOFF_XMLFONTAUTOSTYLEPOOL_HXX
#include "XMLFontAutoStylePool.hxx"
#endif

using namespace ::rtl;
using namespace ::com::sun::star::uno;
using namespace ::xmloff::token;

int XMLFontAutoStylePoolNameCmp_Impl( const OUString& r1,
                                      const OUString& r2 )
{
    return (int)r1.compareTo( r2 );
}

DECLARE_CONTAINER_SORT_DEL( XMLFontAutoStylePoolNames_Impl,
                            OUString )
IMPL_CONTAINER_SORT( XMLFontAutoStylePoolNames_Impl,
                     OUString,
                     XMLFontAutoStylePoolNameCmp_Impl )

class XMLFontAutoStylePoolEntry_Impl
{
    OUString    sName;
    OUString    sFamilyName;
    OUString    sStyleName;
    sal_Int16   nFamily;
    sal_Int16   nPitch;
    rtl_TextEncoding eEnc;

public:

    inline XMLFontAutoStylePoolEntry_Impl(
            const ::rtl::OUString& rName,
            const ::rtl::OUString& rFamilyName,
            const ::rtl::OUString& rStyleName,
            sal_Int16 nFamily,
            sal_Int16 nPitch,
            rtl_TextEncoding eEnc );

    inline XMLFontAutoStylePoolEntry_Impl(
            const ::rtl::OUString& rFamilyName,
            const ::rtl::OUString& rStyleName,
            sal_Int16 nFamily,
            sal_Int16 nPitch,
            rtl_TextEncoding eEnc );

    const OUString& GetName() const { return sName; }
    const OUString& GetFamilyName() const { return sFamilyName; }
    const OUString& GetStyleName() const { return sStyleName; }
    sal_Int16 GetFamily() const {   return nFamily; }
    sal_Int16 GetPitch() const { return nPitch; }
    rtl_TextEncoding GetEncoding() const { return eEnc; }
};

inline XMLFontAutoStylePoolEntry_Impl::XMLFontAutoStylePoolEntry_Impl(
        const ::rtl::OUString& rName,
        const ::rtl::OUString& rFamilyName,
        const ::rtl::OUString& rStyleName,
        sal_Int16 nFam,
        sal_Int16 nP,
        rtl_TextEncoding eE ) :
    sName( rName ),
    sFamilyName( rFamilyName ),
    sStyleName( rStyleName ),
    nFamily( nFam ),
    nPitch( nP ),
    eEnc( eE )
{
}

inline XMLFontAutoStylePoolEntry_Impl::XMLFontAutoStylePoolEntry_Impl(
        const ::rtl::OUString& rFamilyName,
        const ::rtl::OUString& rStyleName,
        sal_Int16 nFam,
        sal_Int16 nP,
        rtl_TextEncoding eE ) :
    sFamilyName( rFamilyName ),
    sStyleName( rStyleName ),
    nFamily( nFam ),
    nPitch( nP ),
    eEnc( eE )
{
}
int XMLFontAutoStylePoolEntryCmp_Impl(
        const XMLFontAutoStylePoolEntry_Impl& r1,
        const XMLFontAutoStylePoolEntry_Impl& r2 )
{
    sal_Int8 nEnc1(r1.GetEncoding() != RTL_TEXTENCODING_SYMBOL);
    sal_Int8 nEnc2(r2.GetEncoding() != RTL_TEXTENCODING_SYMBOL);
    if( nEnc1 != nEnc2 )
        return nEnc1 - nEnc2;
    else if( r1.GetPitch() != r2.GetPitch() )
        return (int)r1.GetPitch() - (int)r2.GetPitch();
    else if( r1.GetFamily() != r2.GetFamily() )
        return (int)r1.GetFamily() - (int)r2.GetFamily();
    else
    {
        sal_Int32 nCmp = r1.GetFamilyName().compareTo( r2.GetFamilyName() );
        if( 0 == nCmp )
            return (int)r1.GetStyleName().compareTo( r2.GetStyleName() );
        else
            return (int)nCmp;
    }
}

typedef XMLFontAutoStylePoolEntry_Impl *XMLFontAutoStylePoolEntryPtr;
DECLARE_CONTAINER_SORT_DEL( XMLFontAutoStylePool_Impl,
                            XMLFontAutoStylePoolEntry_Impl )
IMPL_CONTAINER_SORT( XMLFontAutoStylePool_Impl,
                     XMLFontAutoStylePoolEntry_Impl,
                     XMLFontAutoStylePoolEntryCmp_Impl )

XMLFontAutoStylePool::XMLFontAutoStylePool( SvXMLExport& rExp ) :
    rExport( rExp ),
    pPool( new XMLFontAutoStylePool_Impl( 5, 5 ) ),
    pNames( new XMLFontAutoStylePoolNames_Impl( 5, 5 ) )
{
}

XMLFontAutoStylePool::~XMLFontAutoStylePool()
{
    delete pPool;
    delete pNames;
}

OUString XMLFontAutoStylePool::Add(
            const OUString& rFamilyName,
            const OUString& rStyleName,
            sal_Int16 nFamily,
            sal_Int16 nPitch,
            rtl_TextEncoding eEnc )
{
    OUString sName;
    XMLFontAutoStylePoolEntry_Impl aTmp( rFamilyName, rStyleName, nFamily,
                                          nPitch, eEnc );
    sal_uInt32 nPos;
    if( pPool->Seek_Entry( &aTmp, &nPos ) )
    {
        sName = pPool->GetObject( nPos )->GetName();
    }
    else
    {
        OUString sName;
        sal_Int32 nLen = rFamilyName.indexOf( sal_Unicode(';'), 0 );
        if( -1 == nLen )
        {
            sName = rFamilyName;
        }
        else if( nLen > 0 )
        {
            sName = rFamilyName.copy( 0, nLen );
            sName.trim();
        }

        if( !sName.getLength() )
            sName = OUString::valueOf( sal_Unicode( 'F' ) );

        if( pNames->Seek_Entry( &sName, 0 ) )
        {
            sal_Int32 nCount = 1;
            OUString sPrefix( sName );
            sName += OUString::valueOf( nCount );
            while( pNames->Seek_Entry( &sName, 0 ) )
            {
                sName = sPrefix;
                sName += OUString::valueOf( ++nCount );
            }
        }

        XMLFontAutoStylePoolEntry_Impl *pEntry =
            new XMLFontAutoStylePoolEntry_Impl( sName, rFamilyName, rStyleName,
                                                nFamily, nPitch, eEnc );
        pPool->Insert( pEntry );
        pNames->Insert( new OUString( sName ) );
    }

    return sName;
}

::rtl::OUString XMLFontAutoStylePool::Find(
            const OUString& rFamilyName,
            const OUString& rStyleName,
            sal_Int16 nFamily,
            sal_Int16 nPitch,
            rtl_TextEncoding eEnc ) const
{
    OUString sName;
    XMLFontAutoStylePoolEntry_Impl aTmp( rFamilyName, rStyleName, nFamily,
                                          nPitch, eEnc );
    sal_uInt32 nPos;
    if( pPool->Seek_Entry( &aTmp, &nPos ) )
    {
        sName = pPool->GetObject( nPos )->GetName();
    }

    return sName;
}

void XMLFontAutoStylePool::exportXML()
{
    SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_OFFICE,
                              XML_FONT_FACE_DECLS,
                              sal_True, sal_True );
    Any aAny;
    OUString sTmp;
    XMLFontFamilyNamePropHdl aFamilyNameHdl;
    XMLFontFamilyPropHdl aFamilyHdl;
    XMLFontPitchPropHdl aPitchHdl;
    XMLFontEncodingPropHdl aEncHdl;
    const SvXMLUnitConverter& rUnitConv = GetExport().GetMM100UnitConverter();

    sal_uInt32 nCount = pPool->Count();
    for( sal_uInt32 i=0; i<nCount; i++ )
    {
        const XMLFontAutoStylePoolEntry_Impl *pEntry = pPool->GetObject( i );

        GetExport().AddAttribute( XML_NAMESPACE_STYLE,
                                  XML_NAME, pEntry->GetName() );

        aAny <<= pEntry->GetFamilyName();
        if( aFamilyNameHdl.exportXML( sTmp, aAny, rUnitConv ) )
            GetExport().AddAttribute( XML_NAMESPACE_SVG,
                                      XML_FONT_FAMILY, sTmp );

        const OUString& rStyleName = pEntry->GetStyleName();
        if( rStyleName.getLength() )
            GetExport().AddAttribute( XML_NAMESPACE_STYLE,
                                      XML_FONT_ADORNMENTS,
                                      rStyleName );

        aAny <<= (sal_Int16)pEntry->GetFamily();
        if( aFamilyHdl.exportXML( sTmp, aAny, rUnitConv  ) )
            GetExport().AddAttribute( XML_NAMESPACE_STYLE,
                                      XML_FONT_FAMILY_GENERIC, sTmp );

        aAny <<= (sal_Int16)pEntry->GetPitch();
        if( aPitchHdl.exportXML( sTmp, aAny, rUnitConv  ) )
            GetExport().AddAttribute( XML_NAMESPACE_STYLE,
                                      XML_FONT_PITCH, sTmp );

        aAny <<= (sal_Int16)pEntry->GetEncoding();
        if( aEncHdl.exportXML( sTmp, aAny, rUnitConv  ) )
            GetExport().AddAttribute( XML_NAMESPACE_STYLE,
                                      XML_FONT_CHARSET, sTmp );

        SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_STYLE,
                                  XML_FONT_FACE,
                                  sal_True, sal_True );
    }
}

<|endoftext|>


<commit_before>

#include <cassert>
#include <sstream>
#include <iomanip>

#include <reflectionzeug/Color.h>
#include <reflectionzeug/util.h>

namespace reflectionzeug
{

Color::Color()
{
	v = 0;
}

Color::Color(const Color & color)
{
	v = color.rgba();
}

Color::Color(unsigned int rgba)
{
    v = rgba;
}

Color::Color(int red, int green, int blue, int alpha)
{
    m_rgba.a = static_cast<unsigned char>(alpha);
    m_rgba.r = static_cast<unsigned char>(red);
    m_rgba.g = static_cast<unsigned char>(green);
    m_rgba.b = static_cast<unsigned char>(blue);
}

Color::~Color()
{
}

Color Color::fromString(const std::string & string, bool * ok)
{
    *ok = util::matchesRegex(string, "#[0-9A-F]{8}");

    if (!(*ok))
        return Color();

    std::stringstream stream(string.substr(1, string.length()));
    unsigned int colorHex;
    stream >> std::hex >> std::uppercase;
    stream >> colorHex;

    return Color(colorHex);
}

int Color::red() const
{
    return m_rgba.r;
}

void Color::setRed(int value)
{
    assert(0 <= value && value <= 255);
    m_rgba.r = static_cast<unsigned char>(value);
}

int Color::green() const
{
    return m_rgba.g;
}

void Color::setGreen(int value)
{
    assert(0 <= value && value <= 255);
    m_rgba.g = static_cast<unsigned char>(value);
}

int Color::blue() const
{
    return m_rgba.b;
}

void Color::setBlue(int value)
{
    assert(0 <= value && value <= 255);
    m_rgba.b = static_cast<unsigned char>(value);
}

int Color::alpha() const
{
    return m_rgba.a;
}

void Color::setAlpha(int value)
{
    assert(0 <= value && value <= 255);
    m_rgba.a = static_cast<unsigned char>(value);
}

unsigned int Color::rgba() const
{
    return v;
}

void Color::setRgba(unsigned int rgba)
{
    v = rgba;
}

std::string Color::asHex() const
{
    std::stringstream stream;
    stream << "#";
    stream << std::hex << std::uppercase << std::setw(8) << std::setfill('0');
    stream << this->rgba();
    return stream.str();
}

std::string Color::toString() const
{
    return asHex();
}

} // namespace reflectionzeug
<commit_msg>Allow for color codes with lower-case letters<commit_after>

#include <cassert>
#include <sstream>
#include <iomanip>

#include <reflectionzeug/Color.h>
#include <reflectionzeug/util.h>

namespace reflectionzeug
{

Color::Color()
{
	v = 0;
}

Color::Color(const Color & color)
{
	v = color.rgba();
}

Color::Color(unsigned int rgba)
{
    v = rgba;
}

Color::Color(int red, int green, int blue, int alpha)
{
    m_rgba.a = static_cast<unsigned char>(alpha);
    m_rgba.r = static_cast<unsigned char>(red);
    m_rgba.g = static_cast<unsigned char>(green);
    m_rgba.b = static_cast<unsigned char>(blue);
}

Color::~Color()
{
}

Color Color::fromString(const std::string & string, bool * ok)
{
    *ok = util::matchesRegex(string, "#[0-9A-Fa-f]{8}");

    if (!(*ok))
        return Color();

    std::stringstream stream(string.substr(1, string.length()));
    unsigned int colorHex;
    stream >> std::hex >> std::uppercase;
    stream >> colorHex;

    return Color(colorHex);
}

int Color::red() const
{
    return m_rgba.r;
}

void Color::setRed(int value)
{
    assert(0 <= value && value <= 255);
    m_rgba.r = static_cast<unsigned char>(value);
}

int Color::green() const
{
    return m_rgba.g;
}

void Color::setGreen(int value)
{
    assert(0 <= value && value <= 255);
    m_rgba.g = static_cast<unsigned char>(value);
}

int Color::blue() const
{
    return m_rgba.b;
}

void Color::setBlue(int value)
{
    assert(0 <= value && value <= 255);
    m_rgba.b = static_cast<unsigned char>(value);
}

int Color::alpha() const
{
    return m_rgba.a;
}

void Color::setAlpha(int value)
{
    assert(0 <= value && value <= 255);
    m_rgba.a = static_cast<unsigned char>(value);
}

unsigned int Color::rgba() const
{
    return v;
}

void Color::setRgba(unsigned int rgba)
{
    v = rgba;
}

std::string Color::asHex() const
{
    std::stringstream stream;
    stream << "#";
    stream << std::hex << std::uppercase << std::setw(8) << std::setfill('0');
    stream << this->rgba();
    return stream.str();
}

std::string Color::toString() const
{
    return asHex();
}

} // namespace reflectionzeug
<|endoftext|>


<commit_before>//===- unittest/AST/SourceLocationTest.cpp - AST source loc unit tests ----===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains tests for SourceLocation and SourceRange fields
// in AST nodes.
//
// FIXME: In the long-term, when we test more than source locations, we may
// want to have a unit test file for an AST node (or group of related nodes),
// rather than a unit test file for source locations for all AST nodes.
//
//===----------------------------------------------------------------------===//

#include "clang/AST/ASTContext.h"
#include "MatchVerifier.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/Tooling/Tooling.h"
#include "gtest/gtest.h"

namespace clang {
namespace ast_matchers {

// FIXME: Pull the *Verifier tests into their own test file.

TEST(MatchVerifier, ParseError) {
  LocationVerifier<VarDecl> Verifier;
  Verifier.expectLocation(1, 1);
  EXPECT_FALSE(Verifier.match("int i", varDecl()));
}

TEST(MatchVerifier, NoMatch) {
  LocationVerifier<VarDecl> Verifier;
  Verifier.expectLocation(1, 1);
  EXPECT_FALSE(Verifier.match("int i;", recordDecl()));
}

TEST(MatchVerifier, WrongType) {
  LocationVerifier<RecordDecl> Verifier;
  Verifier.expectLocation(1, 1);
  EXPECT_FALSE(Verifier.match("int i;", varDecl()));
}

TEST(LocationVerifier, WrongLocation) {
  LocationVerifier<VarDecl> Verifier;
  Verifier.expectLocation(1, 1);
  EXPECT_FALSE(Verifier.match("int i;", varDecl()));
}

TEST(RangeVerifier, WrongRange) {
  RangeVerifier<VarDecl> Verifier;
  Verifier.expectRange(1, 1, 1, 1);
  EXPECT_FALSE(Verifier.match("int i;", varDecl()));
}

class LabelDeclRangeVerifier : public RangeVerifier<LabelStmt> {
protected:
  virtual SourceRange getRange(const LabelStmt &Node) {
    return Node.getDecl()->getSourceRange();
  }
};

TEST(LabelDecl, Range) {
  LabelDeclRangeVerifier Verifier;
  Verifier.expectRange(1, 12, 1, 12);
  EXPECT_TRUE(Verifier.match("void f() { l: return; }", labelStmt()));
}

TEST(LabelStmt, Range) {
  RangeVerifier<LabelStmt> Verifier;
  Verifier.expectRange(1, 12, 1, 15);
  EXPECT_TRUE(Verifier.match("void f() { l: return; }", labelStmt()));
}

TEST(ParmVarDecl, KNRLocation) {
  LocationVerifier<ParmVarDecl> Verifier;
  Verifier.expectLocation(1, 8);
  EXPECT_TRUE(Verifier.match("void f(i) {}", varDecl(), Lang_C));
}

TEST(ParmVarDecl, KNRRange) {
  RangeVerifier<ParmVarDecl> Verifier;
  Verifier.expectRange(1, 8, 1, 8);
  EXPECT_TRUE(Verifier.match("void f(i) {}", varDecl(), Lang_C));
}

TEST(CXXNewExpr, ArrayRange) {
  RangeVerifier<CXXNewExpr> Verifier;
  Verifier.expectRange(1, 12, 1, 22);
  EXPECT_TRUE(Verifier.match("void f() { new int[10]; }", newExpr()));
}

TEST(CXXNewExpr, ParenRange) {
  RangeVerifier<CXXNewExpr> Verifier;
  Verifier.expectRange(1, 12, 1, 20);
  EXPECT_TRUE(Verifier.match("void f() { new int(); }", newExpr()));
}

TEST(MemberExpr, ImplicitMemberRange) {
  RangeVerifier<MemberExpr> Verifier;
  Verifier.expectRange(2, 30, 2, 30);
  EXPECT_TRUE(Verifier.match("struct S { operator int() const; };\n"
                             "int foo(const S& s) { return s; }",
                             memberExpr()));
}

TEST(VarDecl, VMTypeFixedVarDeclRange) {
  RangeVerifier<VarDecl> Verifier;
  Verifier.expectRange(1, 1, 1, 23);
  EXPECT_TRUE(Verifier.match("int a[(int)(void*)1234];",
                             varDecl(), Lang_C89));
}

TEST(CXXConstructorDecl, NoRetFunTypeLocRange) {
  RangeVerifier<CXXConstructorDecl> Verifier;
  Verifier.expectRange(1, 11, 1, 13);
  EXPECT_TRUE(Verifier.match("class C { C(); };", functionDecl()));
}

TEST(CompoundLiteralExpr, CompoundVectorLiteralRange) {
  RangeVerifier<CompoundLiteralExpr> Verifier;
  Verifier.expectRange(2, 11, 2, 22);
  EXPECT_TRUE(Verifier.match(
                  "typedef int int2 __attribute__((ext_vector_type(2)));\n"
                  "int2 i2 = (int2){1, 2};", compoundLiteralExpr()));
}

TEST(CompoundLiteralExpr, ParensCompoundVectorLiteralRange) {
  RangeVerifier<CompoundLiteralExpr> Verifier;
  Verifier.expectRange(2, 20, 2, 31);
  EXPECT_TRUE(Verifier.match(
                  "typedef int int2 __attribute__((ext_vector_type(2)));\n"
                  "constant int2 i2 = (int2)(1, 2);",
                  compoundLiteralExpr(), Lang_OpenCL));
}

TEST(InitListExpr, VectorLiteralListBraceRange) {
  RangeVerifier<InitListExpr> Verifier;
  Verifier.expectRange(2, 17, 2, 22);
  EXPECT_TRUE(Verifier.match(
                  "typedef int int2 __attribute__((ext_vector_type(2)));\n"
                  "int2 i2 = (int2){1, 2};", initListExpr()));
}

TEST(InitListExpr, VectorLiteralInitListParens) {
  RangeVerifier<InitListExpr> Verifier;
  Verifier.expectRange(2, 26, 2, 31);
  EXPECT_TRUE(Verifier.match(
                  "typedef int int2 __attribute__((ext_vector_type(2)));\n"
                  "constant int2 i2 = (int2)(1, 2);", initListExpr(), Lang_OpenCL));
}

class TemplateAngleBracketLocRangeVerifier : public RangeVerifier<TypeLoc> {
protected:
  virtual SourceRange getRange(const TypeLoc &Node) {
    TemplateSpecializationTypeLoc T =
        Node.getUnqualifiedLoc().castAs<TemplateSpecializationTypeLoc>();
    assert(!T.isNull());
    return SourceRange(T.getLAngleLoc(), T.getRAngleLoc());
  }
};

TEST(TemplateSpecializationTypeLoc, AngleBracketLocations) {
  TemplateAngleBracketLocRangeVerifier Verifier;
  Verifier.expectRange(2, 8, 2, 10);
  EXPECT_TRUE(Verifier.match(
      "template<typename T> struct A {}; struct B{}; void f(\n"
      "const A<B>&);",
      loc(templateSpecializationType())));
}

TEST(CXXNewExpr, TypeParenRange) {
  RangeVerifier<CXXNewExpr> Verifier;
  Verifier.expectRange(1, 10, 1, 18);
  EXPECT_TRUE(Verifier.match("int* a = new (int);", newExpr()));
}

class UnaryTransformTypeLocParensRangeVerifier : public RangeVerifier<TypeLoc> {
protected:
  virtual SourceRange getRange(const TypeLoc &Node) {
    UnaryTransformTypeLoc T =
        Node.getUnqualifiedLoc().castAs<UnaryTransformTypeLoc>();
    assert(!T.isNull());
    return SourceRange(T.getLParenLoc(), T.getRParenLoc());
  }
};

TEST(UnaryTransformTypeLoc, ParensRange) {
  UnaryTransformTypeLocParensRangeVerifier Verifier;
  Verifier.expectRange(3, 26, 3, 28);
  EXPECT_TRUE(Verifier.match(
      "template <typename T>\n"
      "struct S {\n"
      "typedef __underlying_type(T) type;\n"
      "};",
      loc(unaryTransformType())));
}

TEST(CXXFunctionalCastExpr, SourceRange) {
  RangeVerifier<CXXFunctionalCastExpr> Verifier;
  Verifier.expectRange(2, 10, 2, 14);
  EXPECT_TRUE(Verifier.match(
      "int foo() {\n"
      "  return int{};\n"
      "}",
      functionalCastExpr(), Lang_CXX11));
}

TEST(CXXConstructExpr, SourceRange) {
  RangeVerifier<CXXConstructExpr> Verifier;
  Verifier.expectRange(3, 14, 3, 19);
  EXPECT_TRUE(Verifier.match(
      "struct A { A(int, int); };\n"
      "void f(A a);\n"
      "void g() { f({0, 0}); }",
      constructExpr(), Lang_CXX11));
}

TEST(CXXTemporaryObjectExpr, SourceRange) {
  RangeVerifier<CXXTemporaryObjectExpr> Verifier;
  Verifier.expectRange(2, 6, 2, 12);
  EXPECT_TRUE(Verifier.match(
      "struct A { A(int, int); };\n"
      "A a( A{0, 0} );",
      temporaryObjectExpr(), Lang_CXX11));
}

TEST(CXXUnresolvedConstructExpr, SourceRange) {
  RangeVerifier<CXXUnresolvedConstructExpr> Verifier;
  Verifier.expectRange(3, 10, 3, 12);
  std::vector<std::string> Args;
  Args.push_back("-fno-delayed-template-parsing");
  EXPECT_TRUE(Verifier.match(
      "template <typename U>\n"
      "U foo() {\n"
      "  return U{};\n"
      "}",
      unresolvedConstructExpr(), Args, Lang_CXX11));
}

TEST(UsingDecl, SourceRange) {
  RangeVerifier<UsingDecl> Verifier;
  Verifier.expectRange(2, 22, 2, 25);
  EXPECT_TRUE(Verifier.match(
      "class B { protected: int i; };\n"
      "class D : public B { B::i; };",
      usingDecl()));
}

TEST(UnresolvedUsingValueDecl, SourceRange) {
  RangeVerifier<UnresolvedUsingValueDecl> Verifier;
  Verifier.expectRange(3, 3, 3, 6);
  EXPECT_TRUE(Verifier.match(
      "template <typename B>\n"
      "class D : public B {\n"
      "  B::i;\n"
      "};",
      unresolvedUsingValueDecl()));
}

TEST(FriendDecl, InstantiationSourceRange) {
  RangeVerifier<FriendDecl> Verifier;
  Verifier.expectRange(4, 3, 4, 35);
  EXPECT_TRUE(Verifier.match(
      "template <typename T> class S;\n"
      "template<class T> void operator+(S<T> x);\n"
      "template<class T> struct S {\n"
      "  friend void operator+<>(S<T> src);\n"
      "};\n"
      "void test(S<double> s) { +s; }",
      friendDecl(hasParent(recordDecl(isTemplateInstantiation())))));
}

} // end namespace ast_matchers
} // end namespace clang
<commit_msg>Add first set of tests for FriendDecl source range and location.<commit_after>//===- unittest/AST/SourceLocationTest.cpp - AST source loc unit tests ----===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains tests for SourceLocation and SourceRange fields
// in AST nodes.
//
// FIXME: In the long-term, when we test more than source locations, we may
// want to have a unit test file for an AST node (or group of related nodes),
// rather than a unit test file for source locations for all AST nodes.
//
//===----------------------------------------------------------------------===//

#include "clang/AST/ASTContext.h"
#include "MatchVerifier.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/Tooling/Tooling.h"
#include "gtest/gtest.h"

namespace clang {
namespace ast_matchers {

// FIXME: Pull the *Verifier tests into their own test file.

TEST(MatchVerifier, ParseError) {
  LocationVerifier<VarDecl> Verifier;
  Verifier.expectLocation(1, 1);
  EXPECT_FALSE(Verifier.match("int i", varDecl()));
}

TEST(MatchVerifier, NoMatch) {
  LocationVerifier<VarDecl> Verifier;
  Verifier.expectLocation(1, 1);
  EXPECT_FALSE(Verifier.match("int i;", recordDecl()));
}

TEST(MatchVerifier, WrongType) {
  LocationVerifier<RecordDecl> Verifier;
  Verifier.expectLocation(1, 1);
  EXPECT_FALSE(Verifier.match("int i;", varDecl()));
}

TEST(LocationVerifier, WrongLocation) {
  LocationVerifier<VarDecl> Verifier;
  Verifier.expectLocation(1, 1);
  EXPECT_FALSE(Verifier.match("int i;", varDecl()));
}

TEST(RangeVerifier, WrongRange) {
  RangeVerifier<VarDecl> Verifier;
  Verifier.expectRange(1, 1, 1, 1);
  EXPECT_FALSE(Verifier.match("int i;", varDecl()));
}

class LabelDeclRangeVerifier : public RangeVerifier<LabelStmt> {
protected:
  virtual SourceRange getRange(const LabelStmt &Node) {
    return Node.getDecl()->getSourceRange();
  }
};

TEST(LabelDecl, Range) {
  LabelDeclRangeVerifier Verifier;
  Verifier.expectRange(1, 12, 1, 12);
  EXPECT_TRUE(Verifier.match("void f() { l: return; }", labelStmt()));
}

TEST(LabelStmt, Range) {
  RangeVerifier<LabelStmt> Verifier;
  Verifier.expectRange(1, 12, 1, 15);
  EXPECT_TRUE(Verifier.match("void f() { l: return; }", labelStmt()));
}

TEST(ParmVarDecl, KNRLocation) {
  LocationVerifier<ParmVarDecl> Verifier;
  Verifier.expectLocation(1, 8);
  EXPECT_TRUE(Verifier.match("void f(i) {}", varDecl(), Lang_C));
}

TEST(ParmVarDecl, KNRRange) {
  RangeVerifier<ParmVarDecl> Verifier;
  Verifier.expectRange(1, 8, 1, 8);
  EXPECT_TRUE(Verifier.match("void f(i) {}", varDecl(), Lang_C));
}

TEST(CXXNewExpr, ArrayRange) {
  RangeVerifier<CXXNewExpr> Verifier;
  Verifier.expectRange(1, 12, 1, 22);
  EXPECT_TRUE(Verifier.match("void f() { new int[10]; }", newExpr()));
}

TEST(CXXNewExpr, ParenRange) {
  RangeVerifier<CXXNewExpr> Verifier;
  Verifier.expectRange(1, 12, 1, 20);
  EXPECT_TRUE(Verifier.match("void f() { new int(); }", newExpr()));
}

TEST(MemberExpr, ImplicitMemberRange) {
  RangeVerifier<MemberExpr> Verifier;
  Verifier.expectRange(2, 30, 2, 30);
  EXPECT_TRUE(Verifier.match("struct S { operator int() const; };\n"
                             "int foo(const S& s) { return s; }",
                             memberExpr()));
}

TEST(VarDecl, VMTypeFixedVarDeclRange) {
  RangeVerifier<VarDecl> Verifier;
  Verifier.expectRange(1, 1, 1, 23);
  EXPECT_TRUE(Verifier.match("int a[(int)(void*)1234];",
                             varDecl(), Lang_C89));
}

TEST(CXXConstructorDecl, NoRetFunTypeLocRange) {
  RangeVerifier<CXXConstructorDecl> Verifier;
  Verifier.expectRange(1, 11, 1, 13);
  EXPECT_TRUE(Verifier.match("class C { C(); };", functionDecl()));
}

TEST(CompoundLiteralExpr, CompoundVectorLiteralRange) {
  RangeVerifier<CompoundLiteralExpr> Verifier;
  Verifier.expectRange(2, 11, 2, 22);
  EXPECT_TRUE(Verifier.match(
                  "typedef int int2 __attribute__((ext_vector_type(2)));\n"
                  "int2 i2 = (int2){1, 2};", compoundLiteralExpr()));
}

TEST(CompoundLiteralExpr, ParensCompoundVectorLiteralRange) {
  RangeVerifier<CompoundLiteralExpr> Verifier;
  Verifier.expectRange(2, 20, 2, 31);
  EXPECT_TRUE(Verifier.match(
                  "typedef int int2 __attribute__((ext_vector_type(2)));\n"
                  "constant int2 i2 = (int2)(1, 2);",
                  compoundLiteralExpr(), Lang_OpenCL));
}

TEST(InitListExpr, VectorLiteralListBraceRange) {
  RangeVerifier<InitListExpr> Verifier;
  Verifier.expectRange(2, 17, 2, 22);
  EXPECT_TRUE(Verifier.match(
                  "typedef int int2 __attribute__((ext_vector_type(2)));\n"
                  "int2 i2 = (int2){1, 2};", initListExpr()));
}

TEST(InitListExpr, VectorLiteralInitListParens) {
  RangeVerifier<InitListExpr> Verifier;
  Verifier.expectRange(2, 26, 2, 31);
  EXPECT_TRUE(Verifier.match(
                  "typedef int int2 __attribute__((ext_vector_type(2)));\n"
                  "constant int2 i2 = (int2)(1, 2);", initListExpr(), Lang_OpenCL));
}

class TemplateAngleBracketLocRangeVerifier : public RangeVerifier<TypeLoc> {
protected:
  virtual SourceRange getRange(const TypeLoc &Node) {
    TemplateSpecializationTypeLoc T =
        Node.getUnqualifiedLoc().castAs<TemplateSpecializationTypeLoc>();
    assert(!T.isNull());
    return SourceRange(T.getLAngleLoc(), T.getRAngleLoc());
  }
};

TEST(TemplateSpecializationTypeLoc, AngleBracketLocations) {
  TemplateAngleBracketLocRangeVerifier Verifier;
  Verifier.expectRange(2, 8, 2, 10);
  EXPECT_TRUE(Verifier.match(
      "template<typename T> struct A {}; struct B{}; void f(\n"
      "const A<B>&);",
      loc(templateSpecializationType())));
}

TEST(CXXNewExpr, TypeParenRange) {
  RangeVerifier<CXXNewExpr> Verifier;
  Verifier.expectRange(1, 10, 1, 18);
  EXPECT_TRUE(Verifier.match("int* a = new (int);", newExpr()));
}

class UnaryTransformTypeLocParensRangeVerifier : public RangeVerifier<TypeLoc> {
protected:
  virtual SourceRange getRange(const TypeLoc &Node) {
    UnaryTransformTypeLoc T =
        Node.getUnqualifiedLoc().castAs<UnaryTransformTypeLoc>();
    assert(!T.isNull());
    return SourceRange(T.getLParenLoc(), T.getRParenLoc());
  }
};

TEST(UnaryTransformTypeLoc, ParensRange) {
  UnaryTransformTypeLocParensRangeVerifier Verifier;
  Verifier.expectRange(3, 26, 3, 28);
  EXPECT_TRUE(Verifier.match(
      "template <typename T>\n"
      "struct S {\n"
      "typedef __underlying_type(T) type;\n"
      "};",
      loc(unaryTransformType())));
}

TEST(CXXFunctionalCastExpr, SourceRange) {
  RangeVerifier<CXXFunctionalCastExpr> Verifier;
  Verifier.expectRange(2, 10, 2, 14);
  EXPECT_TRUE(Verifier.match(
      "int foo() {\n"
      "  return int{};\n"
      "}",
      functionalCastExpr(), Lang_CXX11));
}

TEST(CXXConstructExpr, SourceRange) {
  RangeVerifier<CXXConstructExpr> Verifier;
  Verifier.expectRange(3, 14, 3, 19);
  EXPECT_TRUE(Verifier.match(
      "struct A { A(int, int); };\n"
      "void f(A a);\n"
      "void g() { f({0, 0}); }",
      constructExpr(), Lang_CXX11));
}

TEST(CXXTemporaryObjectExpr, SourceRange) {
  RangeVerifier<CXXTemporaryObjectExpr> Verifier;
  Verifier.expectRange(2, 6, 2, 12);
  EXPECT_TRUE(Verifier.match(
      "struct A { A(int, int); };\n"
      "A a( A{0, 0} );",
      temporaryObjectExpr(), Lang_CXX11));
}

TEST(CXXUnresolvedConstructExpr, SourceRange) {
  RangeVerifier<CXXUnresolvedConstructExpr> Verifier;
  Verifier.expectRange(3, 10, 3, 12);
  std::vector<std::string> Args;
  Args.push_back("-fno-delayed-template-parsing");
  EXPECT_TRUE(Verifier.match(
      "template <typename U>\n"
      "U foo() {\n"
      "  return U{};\n"
      "}",
      unresolvedConstructExpr(), Args, Lang_CXX11));
}

TEST(UsingDecl, SourceRange) {
  RangeVerifier<UsingDecl> Verifier;
  Verifier.expectRange(2, 22, 2, 25);
  EXPECT_TRUE(Verifier.match(
      "class B { protected: int i; };\n"
      "class D : public B { B::i; };",
      usingDecl()));
}

TEST(UnresolvedUsingValueDecl, SourceRange) {
  RangeVerifier<UnresolvedUsingValueDecl> Verifier;
  Verifier.expectRange(3, 3, 3, 6);
  EXPECT_TRUE(Verifier.match(
      "template <typename B>\n"
      "class D : public B {\n"
      "  B::i;\n"
      "};",
      unresolvedUsingValueDecl()));
}

TEST(FriendDecl, FriendFunctionLocation) {
  LocationVerifier<FriendDecl> Verifier;
  Verifier.expectLocation(2, 13);
  EXPECT_TRUE(Verifier.match("struct A {\n"
                             "friend void f();\n"
                             "};\n",
                             friendDecl()));
}

TEST(FriendDecl, FriendFunctionRange) {
  RangeVerifier<FriendDecl> Verifier;
  Verifier.expectRange(2, 1, 2, 15);
  EXPECT_TRUE(Verifier.match("struct A {\n"
                             "friend void f();\n"
                             "};\n",
                             friendDecl()));
}

TEST(FriendDecl, FriendClassLocation) {
  LocationVerifier<FriendDecl> Verifier;
  Verifier.expectLocation(2, 8);
  EXPECT_TRUE(Verifier.match("struct A {\n"
                             "friend class B;\n"
                             "};\n",
                             friendDecl()));
}

TEST(FriendDecl, FriendClassRange) {
  RangeVerifier<FriendDecl> Verifier;
  Verifier.expectRange(2, 1, 2, 14);
  EXPECT_TRUE(Verifier.match("struct A {\n"
                             "friend class B;\n"
                             "};\n",
                             friendDecl()));
}

TEST(FriendDecl, FriendTemplateParameterLocation) {
  LocationVerifier<FriendDecl> Verifier;
  Verifier.expectLocation(3, 8);
  EXPECT_TRUE(Verifier.match("template <typename T>\n"
                             "struct A {\n"
                             "friend T;\n"
                             "};\n",
                             friendDecl(), Lang_CXX11));
}

TEST(FriendDecl, FriendTemplateParameterRange) {
  RangeVerifier<FriendDecl> Verifier;
  Verifier.expectRange(3, 1, 3, 8);
  EXPECT_TRUE(Verifier.match("template <typename T>\n"
                             "struct A {\n"
                             "friend T;\n"
                             "};\n",
                             friendDecl(), Lang_CXX11));
}

TEST(FriendDecl, FriendDecltypeLocation) {
  LocationVerifier<FriendDecl> Verifier;
  Verifier.expectLocation(4, 8);
  EXPECT_TRUE(Verifier.match("struct A;\n"
                             "A foo();\n"
                             "struct A {\n"
                             "friend decltype(foo());\n"
                             "};\n",
                             friendDecl(), Lang_CXX11));
}

TEST(FriendDecl, FriendDecltypeRange) {
  RangeVerifier<FriendDecl> Verifier;
  Verifier.expectRange(4, 1, 4, 8);
  EXPECT_TRUE(Verifier.match("struct A;\n"
                             "A foo();\n"
                             "struct A {\n"
                             "friend decltype(foo());\n"
                             "};\n",
                             friendDecl(), Lang_CXX11));
}

TEST(FriendDecl, InstantiationSourceRange) {
  RangeVerifier<FriendDecl> Verifier;
  Verifier.expectRange(4, 3, 4, 35);
  EXPECT_TRUE(Verifier.match(
      "template <typename T> class S;\n"
      "template<class T> void operator+(S<T> x);\n"
      "template<class T> struct S {\n"
      "  friend void operator+<>(S<T> src);\n"
      "};\n"
      "void test(S<double> s) { +s; }",
      friendDecl(hasParent(recordDecl(isTemplateInstantiation())))));
}

} // end namespace ast_matchers
} // end namespace clang
<|endoftext|>