<commit_before>#include "Srl/Srl.h"
#include "Srl/Internal.h"

#include <limits>
#include <math.h>

using namespace std;
using namespace Srl;
using namespace Lib;
using namespace Tools;

namespace {

    const char str_true[]  = "true";
    const char str_false[] = "false";
    const char str_null[]  = "null";

    tuple<double, bool> string_to_double(const uint8_t* str, size_t str_len)
    {
        const size_t buffer_size = 64;
        char buffer[buffer_size];

        double val;

        const auto apply = [&val, str, str_len](char* ptr_mem) -> bool {
            char* end = nullptr;
            memcpy(ptr_mem, str, str_len);
            ptr_mem[str_len] = '\0';
            val = strtod(ptr_mem, &end);

            return end == ptr_mem + str_len;
        };

        if(str_len + 1 < buffer_size) {
            return make_tuple(val, apply(buffer));

        } else {
            vector<char> vec_buffer(str_len + 1);
            return make_tuple(val, apply(vec_buffer.data()));
        }
    }

    tuple<uint64_t, bool, bool> string_to_int(const uint8_t* str, size_t str_len)
    {
        size_t   idx = 0;
        uint64_t val = 0;
        bool is_signed = false;

        if(str_len > 0 && *str == '-') {
            if(str_len < 2) {
                /* invalid string */
                return make_tuple(val, false, false);
            }
            is_signed = true;
            idx = 1;
            str++;

        }

        uint64_t tmp = 0;
        for(char c = *str; idx < str_len;
            c = *++str, idx++) {

            if(c >= '0' && c <= '9') {
                tmp = val * 10 + c - '0';
                if(tmp < val) {
                    /* overflow */
                    break;
                }
                val = tmp;
            } else {
                break;
            }
        }

        bool success = idx >= str_len && (!is_signed || val <= numeric_limits<int64_t>::max());

        return make_tuple(val, is_signed, success);
    }

    template<typename TCharAr>
    bool compare_strings(const uint8_t* str, size_t str_len, const TCharAr& to_compare, size_t offset = 0)
    {
        assert(str_len >= offset);

        return str_len == sizeof(TCharAr) - 1 &&
            memcmp(to_compare + offset, str + offset, str_len - offset) == 0;
    }

    template<Type TP>
    typename enable_if<TpTools::is_num(TP) && !TpTools::is_fp(TP), size_t>::type
    conv_type(const Value& value, vector<uint8_t>& out)
    {
        typedef typename TpTools::Real<TP>::type T;
        const auto buffer_size = size_t(numeric_limits<T>::digits10) + 1 + TpTools::is_signed(TP);

        uint8_t buffer[buffer_size];

        bool negative = TpTools::is_signed(TP) && value.pblock().i64 < 0;

        uint64_t val = negative ? -value.pblock().i64 : value.pblock().ui64;

        if(val == 0) {
            if(out.size() < 1) out.resize(1);
            out[0] = '0';
            return 1;
        }

        size_t str_len = 0;
        auto* ptr = buffer + buffer_size - 1;

        for(; val > 0U;
            val /= 10U, ptr--, str_len++) {

            *ptr = '0' + val % 10;
        }

        if(negative) {
            *(ptr) = '-';
            str_len++;
        } else {
            ptr++;
        }

        Aux::copy_to_vec(out, ptr, str_len);

        return str_len;
    }

    template<Type type> typename enable_if<TpTools::is_fp(type), size_t>::type
    conv_type(const Value& value, vector<uint8_t>& out)
    {
        double val = type == Type::FP64 ? value.pblock().fp64 : value.pblock().fp32;

        if(floor(val) == val && val <= numeric_limits<int64_t>::max() && val >= numeric_limits<int64_t>::min()) {

            return conv_type<Type::I64>((int64_t)val, out);
        }

        int sz_buf = out.size();
        int sz = 64;

        do {
            if(sz_buf < sz + 1) /* string terminator */ {
                sz_buf = sz + 1;
                out.resize(sz_buf);
            }

            sz = snprintf((char*)out.data(), sz_buf, "%f", val);

            if(sz < 0) {
                throw Exception("Error occurred on converting floating point value to string.");
            }

            if(sz > sz_buf)
                printf("%i ", sz);

        } while(sz > sz_buf);

        while(sz > 1 && *(out.data() + sz - 1) == '0') {
            sz--;
        }

        return sz;
    }

    template<Type type> typename enable_if<type == Type::Bool, size_t>::type
    conv_type(const Value& value, vector<uint8_t>& out)
    {
        const char* str = value.pblock().ui64 ? str_true : str_false;
        size_t size = (value.pblock().ui64 ? sizeof(str_true) : sizeof(str_false)) - 1;

        Aux::copy_to_vec(out, (const uint8_t*)str, size);

        return size;
    }

    template<Type type>
    typename enable_if<type == Type::Null, size_t>::type
    conv_type(const Value&, vector<uint8_t>& out)
    {
        Aux::copy_to_vec(out, (const uint8_t*)str_null, sizeof(str_null) - 1);
        return sizeof(str_null) - 1;
    }
}

void Tools::trim_space(Lib::MemBlock& block)
{
    return trim_space(block.ptr, block.size);
}

void Tools::trim_space(const uint8_t*& str, size_t& str_len)
{
    if(str == nullptr) {
        return;
    }

    while(str_len > 0 && is_space(*str)) {
        str++;
        str_len--;
    }

    while(str_len > 0 && is_space(*(str + str_len - 1))) {
        str_len--;
    }
}

pair<bool, Value> Tools::string_to_type(const uint8_t* str, size_t str_len, Type hint)
{
    Tools::trim_space(str, str_len);

    if(str_len < 1) {
        return { false, Value(Type::Null) };
    }

    if(str_len >= 4 && str[0] >= 'f') {

        if((str[0] == 't' || str[0] == 'T') && compare_strings(str, str_len, str_true, 1)) {
            return { true, true };
        }

        if((str[0] == 'f' || str[0] == 'F') && compare_strings(str, str_len, str_false, 1)) {
            return { true, false };
        }

        if((str[0] == 'n' || str[0] == 'N') && compare_strings(str, str_len, str_null, 1)) {
            return { true, Value(Type::Null) };
        }
    }

    bool success = false;

    if(!TpTools::is_fp(hint)) {
        bool is_signed;
        uint64_t i;

        tie(i, is_signed, success) = string_to_int(str, str_len);

        if(success) {
            return is_signed ? make_pair(true, Value(-(int64_t)i)) : make_pair(true, Value(i));
        }
    }

    double fp;
    tie(fp, success) = string_to_double(str, str_len);

    return success ? make_pair(true, Value(fp)) : make_pair(false, Value(Type::Null));
}

pair<bool, Value> Tools::string_to_type(const String& string_wrap, Type hint)
{
    if(string_wrap.encoding() == Encoding::UTF8) {
        return string_to_type(string_wrap.data(), string_wrap.size(), hint);

    } else {
        auto vec = Tools::convert_charset(Encoding::UTF8, string_wrap, false);
        if(vec.size() < 1) {
            return make_pair(false, Value(Type::Null));
        }

        return string_to_type(vec.data(), vec.size(), hint);
    }
}

#define SRL_TYPE_TO_STR(id, idx, real, size) \
    case Type::id : return conv_type<Type::id>(value, out);

size_t Tools::type_to_string(const Value& value, vector<uint8_t>& out)
{
    switch(value.type()) {
        /* defined in Type.h */
        SRL_TYPES_SCALAR(SRL_TYPE_TO_STR)

        default : return 0;
    }
}

#undef SRL_TYPE_TO_STR

string Tools::type_to_string(const Value& value)
{
    vector<uint8_t> buffer;
    auto size = Tools::type_to_string(value, buffer);

    return size > 0 ? string((const char*)buffer.data(), size) : string();
}

vector<uint8_t> Tools::convert_charset(Encoding target_encoding, const String& string_wrap, bool throw_error)
{
    vector<uint8_t> buffer;
    auto converted_total = convert_charset(target_encoding, string_wrap, buffer, throw_error);
    buffer.resize(converted_total);

    return move(buffer);
}

/* At time of writing standard code conversion facets aren't implemented in libstdc++, so:
 * TODO convert with codecvt */
#include <iconv.h>
namespace {

    const char* get_charset_string(Encoding encoding)
    {
        static const char str_utf8[] = "UTF-8", str_utf16[] = "UTF-16LE", str_utf32[] = "UTF-32LE";

        const char* rslt = nullptr;

        switch(encoding) {
            case Encoding::UTF8    : rslt = str_utf8;  break;
            case Encoding::UTF16   : rslt = str_utf16; break;
            case Encoding::UTF32   : rslt = str_utf32; break;
            case Encoding::Unknown : rslt = nullptr;   break;
        }

        return rslt;
    }
}

size_t Tools::convert_charset(Encoding target_encoding, const String& str_wrap,
                              vector<uint8_t>& buffer,  bool throw_error, size_t buffer_index)
{
    if(str_wrap.size() < 1) {
        return 0;
    }

    auto src_encoding = str_wrap.encoding();

    auto* cs_from = get_charset_string(src_encoding);
    auto* cs_to   = get_charset_string(target_encoding);

    if(cs_from == cs_to) {
        auto seg = str_wrap.size() + buffer_index;
        if(buffer.size() < seg) {
            buffer.resize(seg);
        }
        memcpy(&buffer[buffer_index], str_wrap.data(), str_wrap.size());

        return str_wrap.size();
    }

    if(cs_from == nullptr || cs_to == nullptr) {
        if(throw_error) {
            throw Exception("Unable to convert charset. Unknown encoding.");
        }
        return 0;
    }

    iconv_t desc = iconv_open(cs_to, cs_from);

    if(desc == (iconv_t)(-1)) {
        if(throw_error) {
            throw Exception("Unable to convert charset. Failed to open iconv descriptor.");
        }
        return 0;
    }

    size_t left_in = str_wrap.size();
    size_t reserve = left_in * (
        target_encoding < src_encoding ? 1 : src_encoding == Encoding::UTF16 ? 2 : 4
    );

    if(buffer_index + reserve > buffer.size()) {
        buffer.resize(buffer_index + reserve);
    }
    size_t left_out = buffer.size() - buffer_index;

    auto* src = (char*)str_wrap.data();
    size_t converted = 0;

    while(true) {
        auto* dst = (char*)&buffer[buffer_index + converted];
        converted = iconv(desc, &src, &left_in, &dst, &left_out);

        if(converted == 0) {
            /* all characters converted */
            break;
        }

        if(errno == EINVAL) {
            /* incomplete byte-sequence encountered, not exception-worthy */
            break;
        }

        if(errno == EILSEQ) {
            iconv_close(desc);
            if(throw_error) {
                throw Exception("Unable to convert charset. Invalid byte sequence.");
            }
            return 0;
        }

        if (errno == E2BIG) {
            /* output buffer not big enough */
            auto current = buffer.size();
            auto new_size = buffer.size() + left_in * 4;
            buffer.resize(new_size);
            converted = current - left_out;
            left_out = new_size - converted;
        }
    }

    iconv_close(desc);

    return buffer.size() - buffer_index - left_out;
}
<commit_msg>Update ToolsStrConv.cpp<commit_after>#include "Srl/Srl.h"
#include "Srl/Internal.h"

#include <limits>
#include <math.h>

using namespace std;
using namespace Srl;
using namespace Lib;
using namespace Tools;

namespace {

    const char str_true[]  = "true";
    const char str_false[] = "false";
    const char str_null[]  = "null";

    tuple<double, bool> string_to_double(const uint8_t* str, size_t str_len)
    {
        const size_t buffer_size = 64;
        char buffer[buffer_size];

        double val;

        const auto apply = [&val, str, str_len](char* ptr_mem) -> bool {
            char* end = nullptr;
            memcpy(ptr_mem, str, str_len);
            ptr_mem[str_len] = '\0';
            val = strtod(ptr_mem, &end);

            return end == ptr_mem + str_len;
        };

        if(str_len + 1 < buffer_size) {
            return make_tuple(val, apply(buffer));

        } else {
            vector<char> vec_buffer(str_len + 1);
            return make_tuple(val, apply(vec_buffer.data()));
        }
    }

    tuple<uint64_t, bool, bool> string_to_int(const uint8_t* str, size_t str_len)
    {
        size_t   idx = 0;
        uint64_t val = 0;
        bool is_signed = false;

        if(str_len > 0 && *str == '-') {
            if(str_len < 2) {
                /* invalid string */
                return make_tuple(val, false, false);
            }
            is_signed = true;
            idx = 1;
            str++;

        }

        uint64_t tmp = 0;
        for(char c = *str; idx < str_len;
            c = *++str, idx++) {

            if(c >= '0' && c <= '9') {
                tmp = val * 10 + c - '0';
                if(tmp < val) {
                    /* overflow */
                    break;
                }
                val = tmp;
            } else {
                break;
            }
        }

        bool success = idx >= str_len && (!is_signed || val <= numeric_limits<int64_t>::max());

        return make_tuple(val, is_signed, success);
    }

    template<typename TCharAr>
    bool compare_strings(const uint8_t* str, size_t str_len, const TCharAr& to_compare, size_t offset = 0)
    {
        assert(str_len >= offset);

        return str_len == sizeof(TCharAr) - 1 &&
            memcmp(to_compare + offset, str + offset, str_len - offset) == 0;
    }

    template<Type TP>
    typename enable_if<TpTools::is_num(TP) && !TpTools::is_fp(TP), size_t>::type
    conv_type(const Value& value, vector<uint8_t>& out)
    {
        typedef typename TpTools::Real<TP>::type T;
        const auto buffer_size = size_t(numeric_limits<T>::digits10) + 1 + TpTools::is_signed(TP);

        uint8_t buffer[buffer_size];

        bool negative = TpTools::is_signed(TP) && value.pblock().i64 < 0;

        uint64_t val = negative ? -value.pblock().i64 : value.pblock().ui64;

        if(val == 0) {
            if(out.size() < 1) out.resize(1);
            out[0] = '0';
            return 1;
        }

        size_t str_len = 0;
        auto* ptr = buffer + buffer_size - 1;

        for(; val > 0U;
            val /= 10U, ptr--, str_len++) {

            *ptr = '0' + val % 10;
        }

        if(negative) {
            *(ptr) = '-';
            str_len++;
        } else {
            ptr++;
        }

        Aux::copy_to_vec(out, ptr, str_len);

        return str_len;
    }

    template<Type type> typename enable_if<TpTools::is_fp(type), size_t>::type
    conv_type(const Value& value, vector<uint8_t>& out)
    {
        double val = type == Type::FP64 ? value.pblock().fp64 : value.pblock().fp32;

        if(floor(val) == val && val <= numeric_limits<int64_t>::max() && val >= numeric_limits<int64_t>::min()) {

            return conv_type<Type::I64>((int64_t)val, out);
        }

        int sz_buf = out.size();
        int sz = 64;

        do {
            if(sz_buf < sz + 1) /* string terminator */ {
                sz_buf = sz + 1;
                out.resize(sz_buf);
            }

            sz = snprintf((char*)out.data(), sz_buf, "%f", val);

            if(sz < 0) {
                throw Exception("Error occurred on converting floating point value to string.");
            }

        } while(sz > sz_buf);

        while(sz > 1 && *(out.data() + sz - 1) == '0') {
            sz--;
        }

        return sz;
    }

    template<Type type> typename enable_if<type == Type::Bool, size_t>::type
    conv_type(const Value& value, vector<uint8_t>& out)
    {
        const char* str = value.pblock().ui64 ? str_true : str_false;
        size_t size = (value.pblock().ui64 ? sizeof(str_true) : sizeof(str_false)) - 1;

        Aux::copy_to_vec(out, (const uint8_t*)str, size);

        return size;
    }

    template<Type type>
    typename enable_if<type == Type::Null, size_t>::type
    conv_type(const Value&, vector<uint8_t>& out)
    {
        Aux::copy_to_vec(out, (const uint8_t*)str_null, sizeof(str_null) - 1);
        return sizeof(str_null) - 1;
    }
}

void Tools::trim_space(Lib::MemBlock& block)
{
    return trim_space(block.ptr, block.size);
}

void Tools::trim_space(const uint8_t*& str, size_t& str_len)
{
    if(str == nullptr) {
        return;
    }

    while(str_len > 0 && is_space(*str)) {
        str++;
        str_len--;
    }

    while(str_len > 0 && is_space(*(str + str_len - 1))) {
        str_len--;
    }
}

pair<bool, Value> Tools::string_to_type(const uint8_t* str, size_t str_len, Type hint)
{
    Tools::trim_space(str, str_len);

    if(str_len < 1) {
        return { false, Value(Type::Null) };
    }

    if(str_len >= 4 && str[0] >= 'f') {

        if((str[0] == 't' || str[0] == 'T') && compare_strings(str, str_len, str_true, 1)) {
            return { true, true };
        }

        if((str[0] == 'f' || str[0] == 'F') && compare_strings(str, str_len, str_false, 1)) {
            return { true, false };
        }

        if((str[0] == 'n' || str[0] == 'N') && compare_strings(str, str_len, str_null, 1)) {
            return { true, Value(Type::Null) };
        }
    }

    bool success = false;

    if(!TpTools::is_fp(hint)) {
        bool is_signed;
        uint64_t i;

        tie(i, is_signed, success) = string_to_int(str, str_len);

        if(success) {
            return is_signed ? make_pair(true, Value(-(int64_t)i)) : make_pair(true, Value(i));
        }
    }

    double fp;
    tie(fp, success) = string_to_double(str, str_len);

    return success ? make_pair(true, Value(fp)) : make_pair(false, Value(Type::Null));
}

pair<bool, Value> Tools::string_to_type(const String& string_wrap, Type hint)
{
    if(string_wrap.encoding() == Encoding::UTF8) {
        return string_to_type(string_wrap.data(), string_wrap.size(), hint);

    } else {
        auto vec = Tools::convert_charset(Encoding::UTF8, string_wrap, false);
        if(vec.size() < 1) {
            return make_pair(false, Value(Type::Null));
        }

        return string_to_type(vec.data(), vec.size(), hint);
    }
}

#define SRL_TYPE_TO_STR(id, idx, real, size) \
    case Type::id : return conv_type<Type::id>(value, out);

size_t Tools::type_to_string(const Value& value, vector<uint8_t>& out)
{
    switch(value.type()) {
        /* defined in Type.h */
        SRL_TYPES_SCALAR(SRL_TYPE_TO_STR)

        default : return 0;
    }
}

#undef SRL_TYPE_TO_STR

string Tools::type_to_string(const Value& value)
{
    vector<uint8_t> buffer;
    auto size = Tools::type_to_string(value, buffer);

    return size > 0 ? string((const char*)buffer.data(), size) : string();
}

vector<uint8_t> Tools::convert_charset(Encoding target_encoding, const String& string_wrap, bool throw_error)
{
    vector<uint8_t> buffer;
    auto converted_total = convert_charset(target_encoding, string_wrap, buffer, throw_error);
    buffer.resize(converted_total);

    return move(buffer);
}

/* At time of writing standard code conversion facets aren't implemented in libstdc++, so:
 * TODO convert with codecvt */
#include <iconv.h>
namespace {

    const char* get_charset_string(Encoding encoding)
    {
        static const char str_utf8[] = "UTF-8", str_utf16[] = "UTF-16LE", str_utf32[] = "UTF-32LE";

        const char* rslt = nullptr;

        switch(encoding) {
            case Encoding::UTF8    : rslt = str_utf8;  break;
            case Encoding::UTF16   : rslt = str_utf16; break;
            case Encoding::UTF32   : rslt = str_utf32; break;
            case Encoding::Unknown : rslt = nullptr;   break;
        }

        return rslt;
    }
}

size_t Tools::convert_charset(Encoding target_encoding, const String& str_wrap,
                              vector<uint8_t>& buffer,  bool throw_error, size_t buffer_index)
{
    if(str_wrap.size() < 1) {
        return 0;
    }

    auto src_encoding = str_wrap.encoding();

    auto* cs_from = get_charset_string(src_encoding);
    auto* cs_to   = get_charset_string(target_encoding);

    if(cs_from == cs_to) {
        auto seg = str_wrap.size() + buffer_index;
        if(buffer.size() < seg) {
            buffer.resize(seg);
        }
        memcpy(&buffer[buffer_index], str_wrap.data(), str_wrap.size());

        return str_wrap.size();
    }

    if(cs_from == nullptr || cs_to == nullptr) {
        if(throw_error) {
            throw Exception("Unable to convert charset. Unknown encoding.");
        }
        return 0;
    }

    iconv_t desc = iconv_open(cs_to, cs_from);

    if(desc == (iconv_t)(-1)) {
        if(throw_error) {
            throw Exception("Unable to convert charset. Failed to open iconv descriptor.");
        }
        return 0;
    }

    size_t left_in = str_wrap.size();
    size_t reserve = left_in * (
        target_encoding < src_encoding ? 1 : src_encoding == Encoding::UTF16 ? 2 : 4
    );

    if(buffer_index + reserve > buffer.size()) {
        buffer.resize(buffer_index + reserve);
    }
    size_t left_out = buffer.size() - buffer_index;

    auto* src = (char*)str_wrap.data();
    size_t converted = 0;

    while(true) {
        auto* dst = (char*)&buffer[buffer_index + converted];
        converted = iconv(desc, &src, &left_in, &dst, &left_out);

        if(converted == 0) {
            /* all characters converted */
            break;
        }

        if(errno == EINVAL) {
            /* incomplete byte-sequence encountered, not exception-worthy */
            break;
        }

        if(errno == EILSEQ) {
            iconv_close(desc);
            if(throw_error) {
                throw Exception("Unable to convert charset. Invalid byte sequence.");
            }
            return 0;
        }

        if (errno == E2BIG) {
            /* output buffer not big enough */
            auto current = buffer.size();
            auto new_size = buffer.size() + left_in * 4;
            buffer.resize(new_size);
            converted = current - left_out;
            left_out = new_size - converted;
        }
    }

    iconv_close(desc);

    return buffer.size() - buffer_index - left_out;
}
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
///     http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Dr. Oreste Costa-Panaia
////////////////////////////////////////////////////////////////////////////////

#include "memory-map.h"

#ifdef TRI_HAVE_POSIX_MMAP

#include "Logger/Logger.h"
#include "Basics/tri-strings.h"

#include <sys/mman.h>

using namespace arangodb;

////////////////////////////////////////////////////////////////////////////////
// @brief flush memory mapped file to disk
////////////////////////////////////////////////////////////////////////////////

int TRI_FlushMMFile(int fileDescriptor, void* startingAddress,
                    size_t numOfBytesToFlush, int flags) {
  // ...........................................................................
  // Possible flags to send are (based upon the Ubuntu Linux ASM include files:
  // #define MS_ASYNC        1             /* sync memory asynchronously */
  // #define MS_INVALIDATE   2               /* invalidate the caches */
  // #define MS_SYNC         4               /* synchronous memory sync */
  // Note: under windows all flushes are achieved synchronously
  // ...........................................................................

  int res = msync(startingAddress, numOfBytesToFlush, flags);

#ifdef __APPLE__
  if (res == 0) {
    res = fcntl(fileDescriptor, F_FULLFSYNC, 0);
  }
#endif

  if (res == 0) {
    // msync was successful
    return TRI_ERROR_NO_ERROR;
  }

  if (errno == ENOMEM) {
    // we have synced a region that was not mapped

    // set a special error. ENOMEM (out of memory) is not appropriate
    LOG_TOPIC(ERR, Logger::MMAP) << "msync failed for range " << startingAddress << " - " << (void*)(((char*)startingAddress) + numOfBytesToFlush);

    return TRI_ERROR_ARANGO_MSYNC_FAILED;
  }

  return TRI_ERROR_SYS_ERROR;
}

////////////////////////////////////////////////////////////////////////////////
// @brief memory map a file
////////////////////////////////////////////////////////////////////////////////

int TRI_MMFile(void* memoryAddress, size_t numOfBytesToInitialize,
               int memoryProtection, int flags, int fileDescriptor,
               void** mmHandle, int64_t offset, void** result) {
  TRI_ASSERT(memoryAddress == nullptr);
  off_t offsetRetyped = (off_t)offset;
  TRI_ASSERT(offsetRetyped == 0);

  *mmHandle = nullptr;  // only useful for Windows

  *result = mmap(memoryAddress, numOfBytesToInitialize, memoryProtection, flags,
                 fileDescriptor, offsetRetyped);

  if (*result != MAP_FAILED) {
    LOG_TOPIC(DEBUG, Logger::MMAP) << "memory-mapped range " << Logger::RANGE(*result, numOfBytesToInitialize) << ", file-descriptor " << fileDescriptor;

    return TRI_ERROR_NO_ERROR;
  }

  if (errno == ENOMEM) {
    LOG_TOPIC(DEBUG, Logger::MMAP) << "out of memory in mmap";

    return TRI_ERROR_OUT_OF_MEMORY_MMAP;
  }

  return TRI_ERROR_SYS_ERROR;
}

////////////////////////////////////////////////////////////////////////////////
// @brief unmap a memory-mapped file
////////////////////////////////////////////////////////////////////////////////

int TRI_UNMMFile(void* memoryAddress, size_t numOfBytesToUnMap,
                 int fileDescriptor, void** mmHandle) {
  TRI_ASSERT(*mmHandle == nullptr);  // only useful for Windows

  int res = munmap(memoryAddress, numOfBytesToUnMap);

  if (res == 0) {
    LOG_TOPIC(DEBUG, Logger::MMAP) << "memory-unmapped range " << Logger::RANGE(memoryAddress, numOfBytesToUnMap) << ", file-descriptor " << fileDescriptor;

    return TRI_ERROR_NO_ERROR;
  }

  // error

  if (errno == ENOSPC) {
    return TRI_ERROR_ARANGO_FILESYSTEM_FULL;
  }
  if (errno == ENOMEM) {
    return TRI_ERROR_OUT_OF_MEMORY_MMAP;
  }

  return TRI_ERROR_SYS_ERROR;
}

////////////////////////////////////////////////////////////////////////////////
// @brief protect a region in a memory-mapped file
////////////////////////////////////////////////////////////////////////////////

int TRI_ProtectMMFile(void* memoryAddress, size_t numOfBytesToProtect,
                      int flags, int fileDescriptor, void** mmHandle) {
  TRI_ASSERT(*mmHandle == nullptr);  // only useful for Windows

  int res = mprotect(memoryAddress, numOfBytesToProtect, flags);

  if (res == 0) {
    LOG_TOPIC(TRACE, Logger::MMAP) << "memory-protecting range " << Logger::RANGE(memoryAddress, numOfBytesToProtect) << ", file-descriptor " << fileDescriptor;

    return TRI_ERROR_NO_ERROR;
  }

  return TRI_ERROR_SYS_ERROR;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief gives hints about upcoming sequential memory usage
////////////////////////////////////////////////////////////////////////////////

int TRI_MMFileAdvise(void* memoryAddress, size_t numOfBytes, int advice) {
#ifdef __linux__
  LOG_TOPIC(TRACE, Logger::MMAP) << "madvise " << advice << " for range " << Logger::RANGE(memoryAddress, numOfBytes);

  int res = madvise(memoryAddress, numOfBytes, advice);

  if (res == 0) {
    return TRI_ERROR_NO_ERROR;
  }

  char buffer[256];
  char* p = strerror_r(errno, buffer, 256);
  LOG_TOPIC(ERR, Logger::MMAP) << "madvise " << advice << " for range " << Logger::RANGE(memoryAddress, numOfBytes) << " failed with: " << p << " ";
  return TRI_ERROR_INTERNAL;
#else
  return TRI_ERROR_NO_ERROR;
#endif
}

#endif
<commit_msg>more diagnoses<commit_after>////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
///     http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Dr. Oreste Costa-Panaia
////////////////////////////////////////////////////////////////////////////////

#include "memory-map.h"

#ifdef TRI_HAVE_POSIX_MMAP

#include "Logger/Logger.h"
#include "Basics/tri-strings.h"

#include <sys/mman.h>

using namespace arangodb;

////////////////////////////////////////////////////////////////////////////////
// @brief flush memory mapped file to disk
////////////////////////////////////////////////////////////////////////////////

int TRI_FlushMMFile(int fileDescriptor, void* startingAddress,
                    size_t numOfBytesToFlush, int flags) {
  // ...........................................................................
  // Possible flags to send are (based upon the Ubuntu Linux ASM include files:
  // #define MS_ASYNC        1             /* sync memory asynchronously */
  // #define MS_INVALIDATE   2               /* invalidate the caches */
  // #define MS_SYNC         4               /* synchronous memory sync */
  // Note: under windows all flushes are achieved synchronously
  // ...........................................................................

  int res = msync(startingAddress, numOfBytesToFlush, flags);

#ifdef __APPLE__
  if (res == 0) {
    res = fcntl(fileDescriptor, F_FULLFSYNC, 0);
  }
#endif

  if (res == 0) {
    // msync was successful
    LOG_TOPIC(TRACE, Logger::MMAP) << "msync succeeded for range " << Logger::RANGE(startingAddress, numOfBytesToFlush) << ", file-descriptor " << fileDescriptor;
    return TRI_ERROR_NO_ERROR;
  }

  if (errno == ENOMEM) {
    // we have synced a region that was not mapped

    // set a special error. ENOMEM (out of memory) is not appropriate
    LOG_TOPIC(ERR, Logger::MMAP) << "msync failed for range " << Logger::RANGE(startingAddress, numOfBytesToFlush) << ", file-descriptor " << fileDescriptor;

    return TRI_ERROR_ARANGO_MSYNC_FAILED;
  }

  return TRI_ERROR_SYS_ERROR;
}

////////////////////////////////////////////////////////////////////////////////
// @brief memory map a file
////////////////////////////////////////////////////////////////////////////////

int TRI_MMFile(void* memoryAddress, size_t numOfBytesToInitialize,
               int memoryProtection, int flags, int fileDescriptor,
               void** mmHandle, int64_t offset, void** result) {
  TRI_ASSERT(memoryAddress == nullptr);
  off_t offsetRetyped = (off_t)offset;
  TRI_ASSERT(offsetRetyped == 0);

  *mmHandle = nullptr;  // only useful for Windows

  *result = mmap(memoryAddress, numOfBytesToInitialize, memoryProtection, flags,
                 fileDescriptor, offsetRetyped);

  if (*result != MAP_FAILED) {
    LOG_TOPIC(DEBUG, Logger::MMAP) << "memory-mapped range " << Logger::RANGE(*result, numOfBytesToInitialize) << ", file-descriptor " << fileDescriptor;

    return TRI_ERROR_NO_ERROR;
  }

  if (errno == ENOMEM) {
    LOG_TOPIC(DEBUG, Logger::MMAP) << "out of memory in mmap";

    return TRI_ERROR_OUT_OF_MEMORY_MMAP;
  }

  return TRI_ERROR_SYS_ERROR;
}

////////////////////////////////////////////////////////////////////////////////
// @brief unmap a memory-mapped file
////////////////////////////////////////////////////////////////////////////////

int TRI_UNMMFile(void* memoryAddress, size_t numOfBytesToUnMap,
                 int fileDescriptor, void** mmHandle) {
  TRI_ASSERT(*mmHandle == nullptr);  // only useful for Windows

  int res = munmap(memoryAddress, numOfBytesToUnMap);

  if (res == 0) {
    LOG_TOPIC(DEBUG, Logger::MMAP) << "memory-unmapped range " << Logger::RANGE(memoryAddress, numOfBytesToUnMap) << ", file-descriptor " << fileDescriptor;

    return TRI_ERROR_NO_ERROR;
  }

  // error

  if (errno == ENOSPC) {
    return TRI_ERROR_ARANGO_FILESYSTEM_FULL;
  }
  if (errno == ENOMEM) {
    return TRI_ERROR_OUT_OF_MEMORY_MMAP;
  }

  return TRI_ERROR_SYS_ERROR;
}

////////////////////////////////////////////////////////////////////////////////
// @brief protect a region in a memory-mapped file
////////////////////////////////////////////////////////////////////////////////

int TRI_ProtectMMFile(void* memoryAddress, size_t numOfBytesToProtect,
                      int flags, int fileDescriptor, void** mmHandle) {
  TRI_ASSERT(*mmHandle == nullptr);  // only useful for Windows

  int res = mprotect(memoryAddress, numOfBytesToProtect, flags);

  if (res == 0) {
    LOG_TOPIC(TRACE, Logger::MMAP) << "memory-protecting range " << Logger::RANGE(memoryAddress, numOfBytesToProtect) << ", file-descriptor " << fileDescriptor;

    return TRI_ERROR_NO_ERROR;
  }

  return TRI_ERROR_SYS_ERROR;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief gives hints about upcoming sequential memory usage
////////////////////////////////////////////////////////////////////////////////

int TRI_MMFileAdvise(void* memoryAddress, size_t numOfBytes, int advice) {
#ifdef __linux__
  LOG_TOPIC(TRACE, Logger::MMAP) << "madvise " << advice << " for range " << Logger::RANGE(memoryAddress, numOfBytes);

  int res = madvise(memoryAddress, numOfBytes, advice);

  if (res == 0) {
    return TRI_ERROR_NO_ERROR;
  }

  char buffer[256];
  char* p = strerror_r(errno, buffer, 256);
  LOG_TOPIC(ERR, Logger::MMAP) << "madvise " << advice << " for range " << Logger::RANGE(memoryAddress, numOfBytes) << " failed with: " << p << " ";
  return TRI_ERROR_INTERNAL;
#else
  return TRI_ERROR_NO_ERROR;
#endif
}

#endif
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: epbm.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: hjs $ $Date: 2004-06-25 12:31: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): _______________________________________
 *
 *
 ************************************************************************/

#include <vcl/svapp.hxx>
#include <vcl/graph.hxx>
#include <vcl/bmpacc.hxx>
#include <vcl/msgbox.hxx>
#include <svtools/solar.hrc>
#include <svtools/fltcall.hxx>
#include <svtools/FilterConfigItem.hxx>
#include "strings.hrc"
#include "dlgepbm.hrc"
#include "dlgepbm.hxx"

//============================ PBMWriter ==================================

class PBMWriter {

private:

    PFilterCallback     mpCallback;
    void *              mpCallerData;

    SvStream*           mpOStm;             // Die auszugebende PBM-Datei
    USHORT              mpOStmOldModus;

    BOOL                mbStatus;
    sal_Int32           mnMode;             // 0 -> raw, 1-> ascii
    BitmapReadAccess*   mpAcc;
    ULONG               mnWidth, mnHeight;  // Bildausmass in Pixeln

    BOOL                ImplCallback( USHORT nPercent );
    BOOL                ImplWriteHeader();
    void                ImplWriteBody();
    void                ImplWriteNumber( sal_Int32 );

public:
                        PBMWriter();
                        ~PBMWriter();

    BOOL                WritePBM( const Graphic& rGraphic, SvStream& rPBM,
                                  PFilterCallback pCallback, void* pCallerdata,
                                  FilterConfigItem* pConfigItem );
};

//=================== Methoden von PBMWriter ==============================

PBMWriter::PBMWriter() :
    mpAcc       ( NULL ),
    mbStatus    ( TRUE )
{
}

// ------------------------------------------------------------------------

PBMWriter::~PBMWriter()
{
}

// ------------------------------------------------------------------------

BOOL PBMWriter::ImplCallback( USHORT nPercent )
{
    if ( mpCallback != NULL )
    {
        if ( ( (*mpCallback)( mpCallerData, nPercent ) ) == TRUE )
        {
            mpOStm->SetError( SVSTREAM_FILEFORMAT_ERROR );
            return TRUE;
        }
    }
    return FALSE;
}

// ------------------------------------------------------------------------

BOOL PBMWriter::WritePBM( const Graphic& rGraphic, SvStream& rPBM,
                          PFilterCallback pCallback, void* pCallerdata,
                          FilterConfigItem* pConfigItem )
{

    mpOStm = &rPBM;
    mpCallback = pCallback;
    mpCallerData = pCallerdata;

    if ( pConfigItem )
        mnMode = pConfigItem->ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "FileFormat" ) ), 0 );

    BitmapEx    aBmpEx( rGraphic.GetBitmapEx() );
    Bitmap      aBmp = aBmpEx.GetBitmap();
    aBmp.Convert( BMP_CONVERSION_1BIT_THRESHOLD );

    mpOStmOldModus = mpOStm->GetNumberFormatInt();
    mpOStm->SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );

    mpAcc = aBmp.AcquireReadAccess();
    if( mpAcc )
    {
        if ( ImplWriteHeader() )
            ImplWriteBody();

        aBmp.ReleaseAccess( mpAcc );
    }
    else
        mbStatus = FALSE;

    mpOStm->SetNumberFormatInt( mpOStmOldModus );

    return mbStatus;
}

// ------------------------------------------------------------------------

BOOL PBMWriter::ImplWriteHeader()
{
    mnWidth = mpAcc->Width();
    mnHeight = mpAcc->Height();
    if ( mnWidth && mnHeight )
    {
        if ( mnMode == 0 )
            *mpOStm << "P4\x0a";
        else
            *mpOStm << "P1\x0a";

        ImplWriteNumber( mnWidth );
        *mpOStm << (BYTE)32;
        ImplWriteNumber( mnHeight );
        *mpOStm << (BYTE)10;
    }
    else mbStatus = FALSE;
    return mbStatus;
}

// ------------------------------------------------------------------------

void PBMWriter::ImplWriteBody()
{
    if ( mnMode == 0 )
    {
        BYTE    nBYTE;
        for ( ULONG y = 0; y < mnHeight; y++ )
        {
            ULONG x;
            for ( x = 0; x < mnWidth; x++ )
            {
                nBYTE <<= 1;
                if (!(mpAcc->GetPixel( y, x ) & 1 ) )
                    nBYTE++;
                if ( ( x & 7 ) == 7 )
                    *mpOStm << nBYTE;
            }
            if ( ( x & 7 ) != 0 )
                *mpOStm << (BYTE)( nBYTE << ( ( x ^ 7 ) + 1 ) );
        }
    }
    else
    {
        int nxCount;
        for ( ULONG y = 0; y < mnHeight; y++ )
        {
            nxCount = 70;
            for ( ULONG x = 0; x < mnWidth; x++ )
            {
                if (!( --nxCount ) )
                {
                    nxCount = 69;
                    *mpOStm << (BYTE)10;
                }
                *mpOStm << (BYTE)( ( mpAcc->GetPixel( y, x ) ^ 1 ) + '0' ) ;
            }
            *mpOStm << (BYTE)10;
        }
    }
}

// ------------------------------------------------------------------------
// eine Dezimalzahl im ASCII format wird in den Stream geschrieben

void PBMWriter::ImplWriteNumber( sal_Int32 nNumber )
{
    const ByteString aNum( ByteString::CreateFromInt32( nNumber ) );

    for( sal_Int16 n = 0, nLen = aNum.Len(); n < nLen; n++ )
        *mpOStm << aNum.GetChar( n );

}

// ------------------------------------------------------------------------

// ---------------------
// - exported function -
// ---------------------

extern "C" BOOL __LOADONCALLAPI GraphicExport( SvStream& rStream, Graphic& rGraphic,
                                               PFilterCallback pCallback, void* pCallerData,
                                               FilterConfigItem* pConfigItem, BOOL )
{
    PBMWriter aPBMWriter;

    return aPBMWriter.WritePBM( rGraphic, rStream, pCallback, pCallerData, pConfigItem );
}

// ------------------------------------------------------------------------

extern "C" BOOL __LOADONCALLAPI DoExportDialog( FltCallDialogParameter& rPara )
{
    BOOL bRet = FALSE;

    if ( rPara.pWindow )
    {
        ByteString  aResMgrName( "epb" );
        ResMgr* pResMgr;

        aResMgrName.Append( ByteString::CreateFromInt32( SOLARUPD ) );
        pResMgr = ResMgr::CreateResMgr( aResMgrName.GetBuffer(), Application::GetSettings().GetUILocale() );

        if( pResMgr )
        {
            rPara.pResMgr = pResMgr;
            bRet = ( DlgExportEPBM( rPara ).Execute() == RET_OK );
            delete pResMgr;
        }
        else
            bRet = TRUE;
    }

    return bRet;
}

// ------------------------------------------------------------------------

#pragma hdrstop

// ---------------
// - Win16 trash -
// ---------------

#ifdef WIN

static HINSTANCE hDLLInst = 0;

extern "C" int CALLBACK LibMain( HINSTANCE hDLL, WORD, WORD nHeap, LPSTR )
{
    if ( nHeap )
        UnlockData( 0 );

    hDLLInst = hDLL;

    return TRUE;
}

// ------------------------------------------------------------------------

extern "C" int CALLBACK WEP( int )
{
    return 1;
}

#endif
<commit_msg>INTEGRATION: CWS ooo20040815 (1.5.18); FILE MERGED 2004/08/04 13:21:41 waratah 1.5.18.1: #i32569# remove pragmas from gcc build initialise variable reorder definitions to match class definition<commit_after>/*************************************************************************
 *
 *  $RCSfile: epbm.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: hr $ $Date: 2004-09-09 11:27:38 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/

#include <vcl/svapp.hxx>
#include <vcl/graph.hxx>
#include <vcl/bmpacc.hxx>
#include <vcl/msgbox.hxx>
#include <svtools/solar.hrc>
#include <svtools/fltcall.hxx>
#include <svtools/FilterConfigItem.hxx>
#include "strings.hrc"
#include "dlgepbm.hrc"
#include "dlgepbm.hxx"

//============================ PBMWriter ==================================

class PBMWriter {

private:

    PFilterCallback     mpCallback;
    void *              mpCallerData;

    SvStream*           mpOStm;             // Die auszugebende PBM-Datei
    USHORT              mpOStmOldModus;

    BOOL                mbStatus;
    sal_Int32           mnMode;             // 0 -> raw, 1-> ascii
    BitmapReadAccess*   mpAcc;
    ULONG               mnWidth, mnHeight;  // Bildausmass in Pixeln

    BOOL                ImplCallback( USHORT nPercent );
    BOOL                ImplWriteHeader();
    void                ImplWriteBody();
    void                ImplWriteNumber( sal_Int32 );

public:
                        PBMWriter();
                        ~PBMWriter();

    BOOL                WritePBM( const Graphic& rGraphic, SvStream& rPBM,
                                  PFilterCallback pCallback, void* pCallerdata,
                                  FilterConfigItem* pConfigItem );
};

//=================== Methoden von PBMWriter ==============================

PBMWriter::PBMWriter() :
    mbStatus    ( TRUE ),
    mpAcc       ( NULL )
{
}

// ------------------------------------------------------------------------

PBMWriter::~PBMWriter()
{
}

// ------------------------------------------------------------------------

BOOL PBMWriter::ImplCallback( USHORT nPercent )
{
    if ( mpCallback != NULL )
    {
        if ( ( (*mpCallback)( mpCallerData, nPercent ) ) == TRUE )
        {
            mpOStm->SetError( SVSTREAM_FILEFORMAT_ERROR );
            return TRUE;
        }
    }
    return FALSE;
}

// ------------------------------------------------------------------------

BOOL PBMWriter::WritePBM( const Graphic& rGraphic, SvStream& rPBM,
                          PFilterCallback pCallback, void* pCallerdata,
                          FilterConfigItem* pConfigItem )
{

    mpOStm = &rPBM;
    mpCallback = pCallback;
    mpCallerData = pCallerdata;

    if ( pConfigItem )
        mnMode = pConfigItem->ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "FileFormat" ) ), 0 );

    BitmapEx    aBmpEx( rGraphic.GetBitmapEx() );
    Bitmap      aBmp = aBmpEx.GetBitmap();
    aBmp.Convert( BMP_CONVERSION_1BIT_THRESHOLD );

    mpOStmOldModus = mpOStm->GetNumberFormatInt();
    mpOStm->SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );

    mpAcc = aBmp.AcquireReadAccess();
    if( mpAcc )
    {
        if ( ImplWriteHeader() )
            ImplWriteBody();

        aBmp.ReleaseAccess( mpAcc );
    }
    else
        mbStatus = FALSE;

    mpOStm->SetNumberFormatInt( mpOStmOldModus );

    return mbStatus;
}

// ------------------------------------------------------------------------

BOOL PBMWriter::ImplWriteHeader()
{
    mnWidth = mpAcc->Width();
    mnHeight = mpAcc->Height();
    if ( mnWidth && mnHeight )
    {
        if ( mnMode == 0 )
            *mpOStm << "P4\x0a";
        else
            *mpOStm << "P1\x0a";

        ImplWriteNumber( mnWidth );
        *mpOStm << (BYTE)32;
        ImplWriteNumber( mnHeight );
        *mpOStm << (BYTE)10;
    }
    else mbStatus = FALSE;
    return mbStatus;
}

// ------------------------------------------------------------------------

void PBMWriter::ImplWriteBody()
{
    if ( mnMode == 0 )
    {
        BYTE    nBYTE = 0;
        for ( ULONG y = 0; y < mnHeight; y++ )
        {
            ULONG x;
            for ( x = 0; x < mnWidth; x++ )
            {
                nBYTE <<= 1;
                if (!(mpAcc->GetPixel( y, x ) & 1 ) )
                    nBYTE++;
                if ( ( x & 7 ) == 7 )
                    *mpOStm << nBYTE;
            }
            if ( ( x & 7 ) != 0 )
                *mpOStm << (BYTE)( nBYTE << ( ( x ^ 7 ) + 1 ) );
        }
    }
    else
    {
        int nxCount;
        for ( ULONG y = 0; y < mnHeight; y++ )
        {
            nxCount = 70;
            for ( ULONG x = 0; x < mnWidth; x++ )
            {
                if (!( --nxCount ) )
                {
                    nxCount = 69;
                    *mpOStm << (BYTE)10;
                }
                *mpOStm << (BYTE)( ( mpAcc->GetPixel( y, x ) ^ 1 ) + '0' ) ;
            }
            *mpOStm << (BYTE)10;
        }
    }
}

// ------------------------------------------------------------------------
// eine Dezimalzahl im ASCII format wird in den Stream geschrieben

void PBMWriter::ImplWriteNumber( sal_Int32 nNumber )
{
    const ByteString aNum( ByteString::CreateFromInt32( nNumber ) );

    for( sal_Int16 n = 0, nLen = aNum.Len(); n < nLen; n++ )
        *mpOStm << aNum.GetChar( n );

}

// ------------------------------------------------------------------------

// ---------------------
// - exported function -
// ---------------------

extern "C" BOOL __LOADONCALLAPI GraphicExport( SvStream& rStream, Graphic& rGraphic,
                                               PFilterCallback pCallback, void* pCallerData,
                                               FilterConfigItem* pConfigItem, BOOL )
{
    PBMWriter aPBMWriter;

    return aPBMWriter.WritePBM( rGraphic, rStream, pCallback, pCallerData, pConfigItem );
}

// ------------------------------------------------------------------------

extern "C" BOOL __LOADONCALLAPI DoExportDialog( FltCallDialogParameter& rPara )
{
    BOOL bRet = FALSE;

    if ( rPara.pWindow )
    {
        ByteString  aResMgrName( "epb" );
        ResMgr* pResMgr;

        aResMgrName.Append( ByteString::CreateFromInt32( SOLARUPD ) );
        pResMgr = ResMgr::CreateResMgr( aResMgrName.GetBuffer(), Application::GetSettings().GetUILocale() );

        if( pResMgr )
        {
            rPara.pResMgr = pResMgr;
            bRet = ( DlgExportEPBM( rPara ).Execute() == RET_OK );
            delete pResMgr;
        }
        else
            bRet = TRUE;
    }

    return bRet;
}

// ------------------------------------------------------------------------
#ifndef GCC
#pragma hdrstop
#endif

// ---------------
// - Win16 trash -
// ---------------

#ifdef WIN

static HINSTANCE hDLLInst = 0;

extern "C" int CALLBACK LibMain( HINSTANCE hDLL, WORD, WORD nHeap, LPSTR )
{
    if ( nHeap )
        UnlockData( 0 );

    hDLLInst = hDLL;

    return TRUE;
}

// ------------------------------------------------------------------------

extern "C" int CALLBACK WEP( int )
{
    return 1;
}

#endif
<|endoftext|>


<commit_before>#include "opencv/cv.h"
#include "opencv/highgui.h"

#ifdef OPENCV_2_1
#  include "opencv/highgui.hpp"
#else
#  include "opencv2/highgui/highgui.hpp"
#endif

#include <iostream>
#include <fstream>
#include <string>
using namespace cv;

#define USAGE "USAGE: find-face --cascade=PATH.xml [ --scale=SCALE ] IMAGE"

bool starts_with(std::string &string, const char *comparator) {
  size_t length = string.length();
  return string.compare(0, length, comparator, length) == 0;
}

int main(int argc, const char** argv)
{
  std::string cascade_name;
  std::string input_name;
  CascadeClassifier cascade;
  double scale = 1;

  const std::string help_opt = "--help";
  const std::string scale_opt = "--scale=";
  const std::string cascade_opt = "--cascade=";

  for (int i = 1; i < argc; i++) {
    if (cascade_opt.compare(0, cascade_opt.length(), argv[i], cascade_opt.length()) == 0) {
      cascade_name.assign(argv[i] + cascade_opt.length());
    } else if (scale_opt.compare(0, scale_opt.length(), argv[i], scale_opt.length()) == 0) {
      if (!sscanf(argv[i] + scale_opt.length(), "%lf", &scale) || scale < 1)
        scale = 1;
    } else if (help_opt == argv[i]) {
      std::cout << USAGE << std::endl;
      return 0;
    } else {
      input_name.assign(argv[i]);
    }
  }

  if (cascade_name.empty()) {
    std::cerr << "ERROR: --cascade=PATH argument required" << std::endl;
    return -1;
  }

  if (!cascade.load(cascade_name)) {
    std::cerr << "ERROR: could not load classifier cascade: " << cascade_name << std::endl;
    return -1;
  }

  if (input_name.empty()) {
    std::cerr << "ERROR: image name required" << std::endl;
    return -1;
  }

  std::ifstream file(input_name.c_str());
  if (!file.good()) {
    std::cerr << "file not found or not readable: " << input_name << std::endl;
    return -1;
  }

  Mat image = imread(input_name, 1);
  if (!image.empty()) {
    Mat gray, small_image(cvRound(image.rows/scale), cvRound(image.cols/scale), CV_8UC1);
    cvtColor(image, gray, CV_BGR2GRAY);
    resize(gray, small_image, small_image.size(), 0, 0, INTER_LINEAR);
    equalizeHist(small_image, small_image);

    vector<Rect> faces;
    cascade.detectMultiScale(small_image, faces, 1.1, 2, 0, Size(30, 30));
    if (!faces.empty()) {
      unsigned int max_area = 0;
      const Rect *max_region;
      for (vector<Rect>::const_iterator r = faces.begin(); r != faces.end(); r++) {
        float area = r->width * r->height;
        if (area > max_area) {
          max_area = area;
          max_region = &*r;
        }
      }

      /* Should happen, but guard against all areas being <= 0. */
      if (!max_region)
        return 0;

      float image_width  = static_cast<float>(image.rows);
      float image_height = static_cast<float>(image.cols);
      std::cout
        << max_region->x / image_width << " "
        << max_region->y / image_height << " "
        << max_region->width / image_width << " "
        << max_region->height / image_height << std::endl;
    }
  }

  return 0;
}
<commit_msg>Remove unused function.<commit_after>#include "opencv/cv.h"
#include "opencv/highgui.h"

#ifdef OPENCV_2_1
#  include "opencv/highgui.hpp"
#else
#  include "opencv2/highgui/highgui.hpp"
#endif

#include <iostream>
#include <fstream>
#include <string>
using namespace cv;

#define USAGE "USAGE: find-face --cascade=PATH.xml [ --scale=SCALE ] IMAGE"

int main(int argc, const char** argv)
{
  std::string cascade_name;
  std::string input_name;
  CascadeClassifier cascade;
  double scale = 1;

  const std::string help_opt = "--help";
  const std::string scale_opt = "--scale=";
  const std::string cascade_opt = "--cascade=";

  for (int i = 1; i < argc; i++) {
    if (cascade_opt.compare(0, cascade_opt.length(), argv[i], cascade_opt.length()) == 0) {
      cascade_name.assign(argv[i] + cascade_opt.length());
    } else if (scale_opt.compare(0, scale_opt.length(), argv[i], scale_opt.length()) == 0) {
      if (!sscanf(argv[i] + scale_opt.length(), "%lf", &scale) || scale < 1)
        scale = 1;
    } else if (help_opt == argv[i]) {
      std::cout << USAGE << std::endl;
      return 0;
    } else {
      input_name.assign(argv[i]);
    }
  }

  if (cascade_name.empty()) {
    std::cerr << "ERROR: --cascade=PATH argument required" << std::endl;
    return -1;
  }

  if (!cascade.load(cascade_name)) {
    std::cerr << "ERROR: could not load classifier cascade: " << cascade_name << std::endl;
    return -1;
  }

  if (input_name.empty()) {
    std::cerr << "ERROR: image name required" << std::endl;
    return -1;
  }

  std::ifstream file(input_name.c_str());
  if (!file.good()) {
    std::cerr << "file not found or not readable: " << input_name << std::endl;
    return -1;
  }

  Mat image = imread(input_name, 1);
  if (!image.empty()) {
    Mat gray, small_image(cvRound(image.rows/scale), cvRound(image.cols/scale), CV_8UC1);
    cvtColor(image, gray, CV_BGR2GRAY);
    resize(gray, small_image, small_image.size(), 0, 0, INTER_LINEAR);
    equalizeHist(small_image, small_image);

    vector<Rect> faces;
    cascade.detectMultiScale(small_image, faces, 1.1, 2, 0, Size(30, 30));
    if (!faces.empty()) {
      unsigned int max_area = 0;
      const Rect *max_region;
      for (vector<Rect>::const_iterator r = faces.begin(); r != faces.end(); r++) {
        float area = r->width * r->height;
        if (area > max_area) {
          max_area = area;
          max_region = &*r;
        }
      }

      /* Should happen, but guard against all areas being <= 0. */
      if (!max_region)
        return 0;

      float image_width  = static_cast<float>(image.rows);
      float image_height = static_cast<float>(image.cols);
      std::cout
        << max_region->x / image_width << " "
        << max_region->y / image_height << " "
        << max_region->width / image_width << " "
        << max_region->height / image_height << std::endl;
    }
  }

  return 0;
}
<|endoftext|>


<commit_before>/// \file ROOT/TLine.hxx
/// \ingroup Graf ROOT7
/// \author Olivier Couet <Olivier.Couet@cern.ch>
/// \date 2017-10-16
/// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
/// is welcome!

/*************************************************************************
 * Copyright (C) 1995-2017, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT7_TLine
#define ROOT7_TLine

#include <ROOT/TDrawable.hxx>
#include <ROOT/TDrawingAttr.hxx>
#include <ROOT/TDrawingOptsBase.hxx>
#include <ROOT/TPadPos.hxx>
#include <ROOT/TPad.hxx>
#include <ROOT/TPadPainter.hxx>

#include <initializer_list>
#include <memory>

namespace ROOT {
namespace Experimental {

/** \class ROOT::Experimental::TLine
 A simple line.
 */

class TLine : public TDrawableBase<TLine> {
public:

/** class ROOT::Experimental::TLine::DrawingOpts
 Drawing options for TLine.
 */

class DrawingOpts: public TDrawingOptsBase {
   TDrawingAttr<TColor> fLineColor{*this, "Line.Color", TColor::kBlack};   ///< The line color.
   TDrawingAttr<int> fLineWidth{*this, "Line.Width", 1. };                 ///< The line width.
   TDrawingAttr<int> fLineStyle{*this, "Line.Style", 1.};                  ///< The line style.
   TDrawingAttr<float>  fLineOpacity{*this, "Line.Opacity", 1.};           ///< The line opacity.

public:
   /// The color of the line.
   void SetLineColor(const TColor &col) { fLineColor = col; }
   TDrawingAttr<TColor> &GetLineColor() { return fLineColor; }
   const TColor &GetLineColor() const   { return fLineColor.Get(); }

   ///The width of the line.
    void SetLineWidth(int width) { fLineWidth = width; }
    TDrawingAttr<int> &GetLineWidth() { return fLineWidth; }
    int GetLineWidth() const   { return (int)fLineWidth; }

    ///The style of the line.
    void SetLineStyle(int style) { fLineStyle = style; }
    TDrawingAttr<int> &GetLineStyle() { return fLineStyle; }
    int GetLineStyle() const { return (int)fLineStyle; }

    ///The opacity of the line.
    void SetLineColorAlpha(float opacity) { fLineOpacity = opacity; }
    TDrawingAttr<float> &GetLineColorAlpha() { return fLineOpacity; }
    float GetLineColorAlpha() const { return (float)fLineOpacity; }
};

private:

   /// Line's coordinates

   TPadPos fP1;           ///< 1st point
   TPadPos fP2;           ///< 2nd point

   /// Line attributes
   DrawingOpts fOpts;

public:
   TLine() = default;

   TLine(const TPadPos& p1, const TPadPos& p2) : fP1(p1), fP2(p2) {}

   void SetP1(const TPadPos& p1) { fP1 = p1; }
   void SetP2(const TPadPos& p2) { fP2 = p2; }

   const TPadPos& GetP1() const { return fP1; }
   const TPadPos& GetP2() const { return fP2; }

   /// Get the drawing options.
   DrawingOpts &GetOptions() { return fOpts; }
   const DrawingOpts &GetOptions() const { return fOpts; }

   void Paint(Internal::TPadPainter &topPad) final
   {
      topPad.AddDisplayItem(
         std::make_unique<ROOT::Experimental::TOrdinaryDisplayItem<ROOT::Experimental::TLine>>(this));
   }
};

inline std::shared_ptr<ROOT::Experimental::TLine>
GetDrawable(const std::shared_ptr<ROOT::Experimental::TLine> &line)
{
   /// A TLine is a TDrawable itself.
   return line;
}

} // namespace Experimental
} // namespace ROOT

#endif
<commit_msg>Indent.<commit_after>/// \file ROOT/TLine.hxx
/// \ingroup Graf ROOT7
/// \author Olivier Couet <Olivier.Couet@cern.ch>
/// \date 2017-10-16
/// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
/// is welcome!

/*************************************************************************
 * Copyright (C) 1995-2017, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT7_TLine
#define ROOT7_TLine

#include <ROOT/TDrawable.hxx>
#include <ROOT/TDrawingAttr.hxx>
#include <ROOT/TDrawingOptsBase.hxx>
#include <ROOT/TPadPos.hxx>
#include <ROOT/TPad.hxx>
#include <ROOT/TPadPainter.hxx>

#include <initializer_list>
#include <memory>

namespace ROOT {
namespace Experimental {

/** \class ROOT::Experimental::TLine
 A simple line.
 */

class TLine : public TDrawableBase<TLine> {
public:

/** class ROOT::Experimental::TLine::DrawingOpts
 Drawing options for TLine.
 */

class DrawingOpts: public TDrawingOptsBase {
   TDrawingAttr<TColor> fLineColor{*this, "Line.Color", TColor::kBlack};   ///< The line color.
   TDrawingAttr<int> fLineWidth{*this, "Line.Width", 1. };                 ///< The line width.
   TDrawingAttr<int> fLineStyle{*this, "Line.Style", 1.};                  ///< The line style.
   TDrawingAttr<float>  fLineOpacity{*this, "Line.Opacity", 1.};           ///< The line opacity.

public:
   /// The color of the line.
   void SetLineColor(const TColor &col) { fLineColor = col; }
   TDrawingAttr<TColor> &GetLineColor() { return fLineColor; }
   const TColor &GetLineColor() const   { return fLineColor.Get(); }

   ///The width of the line.
   void SetLineWidth(int width) { fLineWidth = width; }
   TDrawingAttr<int> &GetLineWidth() { return fLineWidth; }
   int GetLineWidth() const   { return (int)fLineWidth; }

   ///The style of the line.
   void SetLineStyle(int style) { fLineStyle = style; }
   TDrawingAttr<int> &GetLineStyle() { return fLineStyle; }
   int GetLineStyle() const { return (int)fLineStyle; }

   ///The opacity of the line.
   void SetLineColorAlpha(float opacity) { fLineOpacity = opacity; }
   TDrawingAttr<float> &GetLineColorAlpha() { return fLineOpacity; }
   float GetLineColorAlpha() const { return (float)fLineOpacity; }
};

private:

   /// Line's coordinates

   TPadPos fP1;           ///< 1st point
   TPadPos fP2;           ///< 2nd point

   /// Line attributes
   DrawingOpts fOpts;

public:
   TLine() = default;

   TLine(const TPadPos& p1, const TPadPos& p2) : fP1(p1), fP2(p2) {}

   void SetP1(const TPadPos& p1) { fP1 = p1; }
   void SetP2(const TPadPos& p2) { fP2 = p2; }

   const TPadPos& GetP1() const { return fP1; }
   const TPadPos& GetP2() const { return fP2; }

   /// Get the drawing options.
   DrawingOpts &GetOptions() { return fOpts; }
   const DrawingOpts &GetOptions() const { return fOpts; }

   void Paint(Internal::TPadPainter &topPad) final
   {
      topPad.AddDisplayItem(
         std::make_unique<ROOT::Experimental::TOrdinaryDisplayItem<ROOT::Experimental::TLine>>(this));
   }
};

inline std::shared_ptr<ROOT::Experimental::TLine>
GetDrawable(const std::shared_ptr<ROOT::Experimental::TLine> &line)
{
   /// A TLine is a TDrawable itself.
   return line;
}

} // namespace Experimental
} // namespace ROOT

#endif
<|endoftext|>


<commit_before>// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2015 Intel Corporation. All Rights Reserved.

#include <librealsense/rs.hpp>
#include "example.hpp"

#define _USE_MATH_DEFINES
#include <math.h>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <thread>

gl_font font(20);
texture_buffer buffers[RS_STREAM_COUNT];

int main(int argc, char * argv[]) try
{
    rs::log_to_console(rs::log_severity::warn);
    //rs::log_to_file(rs::log_severity::debug, "librealsense.log");

    rs::context ctx;
    if(ctx.get_device_count() == 0) throw std::runtime_error("No device detected. Is it plugged in?");
    rs::device & dev = *ctx.get_device(0);

    // Open a GLFW window
    glfwInit();
    std::ostringstream ss; ss << "CPP Restart Example (" << dev.get_name() << ")";
    GLFWwindow * win = glfwCreateWindow(1280, 960, ss.str().c_str(), 0, 0);
    glfwMakeContextCurrent(win);

    for(int i=0; i<20; ++i)
    {
        try
        {
            if(dev.is_streaming()) dev.stop();

            std::this_thread::sleep_for(std::chrono::milliseconds(100));

            for(int j=0; j<4; ++j)
            {
                auto s = (rs::stream)j;
                if(dev.is_stream_enabled(s)) dev.disable_stream(s);
            }

            switch(i)
            {
            case 0:
                dev.enable_stream(rs::stream::color, 640, 480, rs::format::yuyv, 60);
                break;
            case 1:
                dev.enable_stream(rs::stream::color, 640, 480, rs::format::rgb8, 60);
                break;
            case 2:
                dev.enable_stream(rs::stream::color, 640, 480, rs::format::bgr8, 60);
                break;
            case 3:
                dev.enable_stream(rs::stream::color, 640, 480, rs::format::rgba8, 60);
                break;
            case 4:
                dev.enable_stream(rs::stream::color, 640, 480, rs::format::bgra8, 60);
                break;
            case 5:
                dev.enable_stream(rs::stream::color, 1920, 1080, rs::format::rgb8, 0);
                break;
            case 6:
                dev.enable_stream(rs::stream::depth, rs::preset::largest_image);
                break;
            case 7:
                dev.enable_stream(rs::stream::depth, 480, 360, rs::format::z16, 60);
                break;
            case 8:
                dev.enable_stream(rs::stream::depth, 320, 240, rs::format::z16, 60);
                break;
            case 9:
                dev.enable_stream(rs::stream::infrared, rs::preset::largest_image);
                break;
            case 10:
                dev.enable_stream(rs::stream::infrared, 492, 372, rs::format::y8, 60);
                break;
            case 11:
                dev.enable_stream(rs::stream::infrared, 320, 240, rs::format::y8, 60);
                break;
            case 12:
                dev.enable_stream(rs::stream::infrared, 0, 0, rs::format::y16, 60);
                break;
            case 13:
                dev.enable_stream(rs::stream::infrared, 0, 0, rs::format::y8, 60);
                dev.enable_stream(rs::stream::infrared2, 0, 0, rs::format::y8, 60);
                break;
            case 14:
                dev.enable_stream(rs::stream::infrared, 0, 0, rs::format::y16, 60);
                dev.enable_stream(rs::stream::infrared2, 0, 0, rs::format::y16, 60);
                break;
            case 15:
                dev.enable_stream(rs::stream::depth, rs::preset::best_quality);
                dev.enable_stream(rs::stream::infrared, 0, 0, rs::format::y8, 0);
                break;
            case 16:
                dev.enable_stream(rs::stream::depth, rs::preset::best_quality);
                dev.enable_stream(rs::stream::infrared, 0, 0, rs::format::y16, 0);
                break;
            case 17:
                dev.enable_stream(rs::stream::depth, rs::preset::best_quality);
                dev.enable_stream(rs::stream::color, rs::preset::best_quality);
                break;
            case 18:
                dev.enable_stream(rs::stream::depth, rs::preset::best_quality);
                dev.enable_stream(rs::stream::color, rs::preset::best_quality);
                dev.enable_stream(rs::stream::infrared, rs::preset::best_quality);
                break;
            case 19:
                dev.enable_stream(rs::stream::depth, rs::preset::best_quality);
                dev.enable_stream(rs::stream::color, rs::preset::best_quality);
                dev.enable_stream(rs::stream::infrared, rs::preset::best_quality);
                dev.enable_stream(rs::stream::infrared2, rs::preset::best_quality);
                break;
            }

            dev.start();
            for(int j=0; j<120; ++j)
            {
                // Wait for new images
                glfwPollEvents();
                if(glfwWindowShouldClose(win)) goto done;
                dev.wait_for_frames();

                // Clear the framebuffer
                int w,h;
                glfwGetWindowSize(win, &w, &h);
                glViewport(0, 0, w, h);
                glClear(GL_COLOR_BUFFER_BIT);

                // Draw the images
                glPushMatrix();
                glfwGetWindowSize(win, &w, &h);
                glOrtho(0, w, h, 0, -1, +1);
                buffers[0].show(dev, rs::stream::color, 0, 0, w/2, h/2, font);
                buffers[1].show(dev, rs::stream::depth, w/2, 0, w-w/2, h/2, font);
                buffers[2].show(dev, rs::stream::infrared, 0, h/2, w/2, h-h/2, font);
                buffers[3].show(dev, rs::stream::infrared2, w/2, h/2, w-w/2, h-h/2, font);
                glPopMatrix();
                glfwSwapBuffers(win);
            }
        }
        catch(const rs::error & e)
        {
            std::cerr << "RealSense error calling " << e.get_failed_function() << "(" << e.get_failed_args() << "):\n    " << e.what() << std::endl;
            std::cout << "Skipping mode " << i << std::endl;
        }
    }
done:
    glfwDestroyWindow(win);
    glfwTerminate();
    return EXIT_SUCCESS;
}
catch(const rs::error & e)
{
    std::cerr << "RealSense error calling " << e.get_failed_function() << "(" << e.get_failed_args() << "):\n    " << e.what() << std::endl;
    return EXIT_FAILURE;
}
catch(const std::exception & e)
{
    std::cerr << e.what() << std::endl;
    return EXIT_FAILURE;
}
<commit_msg>Fix font loading issue in one sample.<commit_after>// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2015 Intel Corporation. All Rights Reserved.

#include <librealsense/rs.hpp>
#include "example.hpp"

#define _USE_MATH_DEFINES
#include <math.h>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <thread>

texture_buffer buffers[RS_STREAM_COUNT];

int main(int argc, char * argv[]) try
{
    rs::log_to_console(rs::log_severity::warn);
    //rs::log_to_file(rs::log_severity::debug, "librealsense.log");

    rs::context ctx;
    if(ctx.get_device_count() == 0) throw std::runtime_error("No device detected. Is it plugged in?");
    rs::device & dev = *ctx.get_device(0);

    // Open a GLFW window
    glfwInit();
    std::ostringstream ss; ss << "CPP Restart Example (" << dev.get_name() << ")";
    GLFWwindow * win = glfwCreateWindow(1280, 960, ss.str().c_str(), 0, 0);
    glfwMakeContextCurrent(win);
    gl_font font(20);

    for(int i=0; i<20; ++i)
    {
        try
        {
            if(dev.is_streaming()) dev.stop();

            std::this_thread::sleep_for(std::chrono::milliseconds(100));

            for(int j=0; j<4; ++j)
            {
                auto s = (rs::stream)j;
                if(dev.is_stream_enabled(s)) dev.disable_stream(s);
            }

            switch(i)
            {
            case 0:
                dev.enable_stream(rs::stream::color, 640, 480, rs::format::yuyv, 60);
                break;
            case 1:
                dev.enable_stream(rs::stream::color, 640, 480, rs::format::rgb8, 60);
                break;
            case 2:
                dev.enable_stream(rs::stream::color, 640, 480, rs::format::bgr8, 60);
                break;
            case 3:
                dev.enable_stream(rs::stream::color, 640, 480, rs::format::rgba8, 60);
                break;
            case 4:
                dev.enable_stream(rs::stream::color, 640, 480, rs::format::bgra8, 60);
                break;
            case 5:
                dev.enable_stream(rs::stream::color, 1920, 1080, rs::format::rgb8, 0);
                break;
            case 6:
                dev.enable_stream(rs::stream::depth, rs::preset::largest_image);
                break;
            case 7:
                dev.enable_stream(rs::stream::depth, 480, 360, rs::format::z16, 60);
                break;
            case 8:
                dev.enable_stream(rs::stream::depth, 320, 240, rs::format::z16, 60);
                break;
            case 9:
                dev.enable_stream(rs::stream::infrared, rs::preset::largest_image);
                break;
            case 10:
                dev.enable_stream(rs::stream::infrared, 492, 372, rs::format::y8, 60);
                break;
            case 11:
                dev.enable_stream(rs::stream::infrared, 320, 240, rs::format::y8, 60);
                break;
            case 12:
                dev.enable_stream(rs::stream::infrared, 0, 0, rs::format::y16, 60);
                break;
            case 13:
                dev.enable_stream(rs::stream::infrared, 0, 0, rs::format::y8, 60);
                dev.enable_stream(rs::stream::infrared2, 0, 0, rs::format::y8, 60);
                break;
            case 14:
                dev.enable_stream(rs::stream::infrared, 0, 0, rs::format::y16, 60);
                dev.enable_stream(rs::stream::infrared2, 0, 0, rs::format::y16, 60);
                break;
            case 15:
                dev.enable_stream(rs::stream::depth, rs::preset::best_quality);
                dev.enable_stream(rs::stream::infrared, 0, 0, rs::format::y8, 0);
                break;
            case 16:
                dev.enable_stream(rs::stream::depth, rs::preset::best_quality);
                dev.enable_stream(rs::stream::infrared, 0, 0, rs::format::y16, 0);
                break;
            case 17:
                dev.enable_stream(rs::stream::depth, rs::preset::best_quality);
                dev.enable_stream(rs::stream::color, rs::preset::best_quality);
                break;
            case 18:
                dev.enable_stream(rs::stream::depth, rs::preset::best_quality);
                dev.enable_stream(rs::stream::color, rs::preset::best_quality);
                dev.enable_stream(rs::stream::infrared, rs::preset::best_quality);
                break;
            case 19:
                dev.enable_stream(rs::stream::depth, rs::preset::best_quality);
                dev.enable_stream(rs::stream::color, rs::preset::best_quality);
                dev.enable_stream(rs::stream::infrared, rs::preset::best_quality);
                dev.enable_stream(rs::stream::infrared2, rs::preset::best_quality);
                break;
            }

            dev.start();
            for(int j=0; j<120; ++j)
            {
                // Wait for new images
                glfwPollEvents();
                if(glfwWindowShouldClose(win)) goto done;
                dev.wait_for_frames();

                // Clear the framebuffer
                int w,h;
                glfwGetWindowSize(win, &w, &h);
                glViewport(0, 0, w, h);
                glClear(GL_COLOR_BUFFER_BIT);

                // Draw the images
                glPushMatrix();
                glfwGetWindowSize(win, &w, &h);
                glOrtho(0, w, h, 0, -1, +1);
                buffers[0].show(dev, rs::stream::color, 0, 0, w/2, h/2, font);
                buffers[1].show(dev, rs::stream::depth, w/2, 0, w-w/2, h/2, font);
                buffers[2].show(dev, rs::stream::infrared, 0, h/2, w/2, h-h/2, font);
                buffers[3].show(dev, rs::stream::infrared2, w/2, h/2, w-w/2, h-h/2, font);
                glPopMatrix();
                glfwSwapBuffers(win);
            }
        }
        catch(const rs::error & e)
        {
            std::cerr << "RealSense error calling " << e.get_failed_function() << "(" << e.get_failed_args() << "):\n    " << e.what() << std::endl;
            std::cout << "Skipping mode " << i << std::endl;
        }
    }
done:
    glfwDestroyWindow(win);
    glfwTerminate();
    return EXIT_SUCCESS;
}
catch(const rs::error & e)
{
    std::cerr << "RealSense error calling " << e.get_failed_function() << "(" << e.get_failed_args() << "):\n    " << e.what() << std::endl;
    return EXIT_FAILURE;
}
catch(const std::exception & e)
{
    std::cerr << e.what() << std::endl;
    return EXIT_FAILURE;
}
<|endoftext|>