<commit_before>#include "io_arch.h"
#include "io_bzip.h"
#include "io_gzip.h"
#include "logger.h"
#include <archive.h>
#include <archive_entry.h>
#include <boost/algorithm/string.hpp>

namespace ncv
{
        enum class archive_type : int
        {
                tar,
                tar_gz,
                tar_bz2,
                gz,
                bz2,
                unknown
        };

        static archive_type decode_archive_type(const std::string& path)
        {

                if (    boost::algorithm::iends_with(path, ".tar.gz") ||
                        boost::algorithm::iends_with(path, ".tgz"))
                {
                        return archive_type::tar_gz;
                }

                else if (boost::algorithm::iends_with(path, ".tar.bz2") ||
                         boost::algorithm::iends_with(path, ".tbz") ||
                         boost::algorithm::iends_with(path, ".tbz2") ||
                         boost::algorithm::iends_with(path, ".tb2"))
                {
                        return archive_type::tar_bz2;
                }

                else if (boost::algorithm::iends_with(path, ".tar"))
                {
                        return archive_type::tar;
                }

                else if (boost::algorithm::iends_with(path, ".gz"))
                {
                        return archive_type::gz;
                }

                else
                {
                        return archive_type::unknown;
                }
        }

//        static bool io_decode(const io::data_t& orig_data, const std::string& path, io::data_t& data)
//        {
//                const archive_type type = decode_archive_type(path);

//                switch (type)
//                {
//                case archive_type::tar_gz:
//                case archive_type::gz:
//                        return io::uncompress_gzip(orig_data, data);

//                case archive_type::tar_bz2:
//                case archive_type::bz2:
//                        return io::uncompress_bzip2(orig_data, data);

//                case archive_type::tar:
//                default:
//                        return !(data = orig_data).empty();
//                }
//        }

//        static bool io_decode(std::istream& istream, const std::string& path, io::data_t& data)
//        {
//                const archive_type type = decode_archive_type(path);

//                switch (type)
//                {
//                case archive_type::tar_gz:
//                case archive_type::gz:
//                        return io::uncompress_gzip(istream, data);

//                case archive_type::tar_bz2:
//                case archive_type::bz2:
//                        return io::uncompress_bzip2(istream, data);

//                case archive_type::tar:
//                default:
//                        return io::load_binary(istream, data);
//                }
//        }

//        static bool io_untar(const io::data_t& data, const std::string& log_header, const io::data_callback_t& callback)
//        {
//                char zeroBlock[512];
//                memset(zeroBlock, 0, 512);

//                bool nextEntryHasLongName = false;

//                for (size_t pos = 0; pos < data.size(); )
//                {
//                        TARFileHeader header;
//                        if (!io::load_struct(data, header, pos))
//                        {
//                                log_error() << log_header << "failed to read TAR header!";
//                                return false;
//                        }
//                        if (memcmp(&header, zeroBlock, 512) == 0)
//                        {
//                                log_info() << log_header << "found TAR end.";
//                                break;
//                        }

//                        // compose the filename
//                        std::string filename(header.filename, std::min((size_t)100, strlen(header.filename)));
//                        const size_t prefixLength = strlen(header.filenamePrefix);
//                        if (prefixLength > 0)
//                        {
//                                filename =
//                                std::string(header.filenamePrefix, std::min((size_t)155, prefixLength)) +
//                                "/" +
//                                filename;
//                        }

//                        if (header.typeFlag == '0' || header.typeFlag == 0)
//                        {
//                                // handle GNU TAR long filenames
//                                if (nextEntryHasLongName)
//                                {
//                                        filename = std::string(header.filename);
//                                        if (!io::load_struct(data, header, pos))
//                                        {
//                                                log_error() << log_header << "failed to read TAR header!";
//                                                return false;
//                                        }
//                                        nextEntryHasLongName = false;
//                                }

//                                const size_t filesize = header.filesize();
//                                log_info() << log_header << "found file <" << filename << "> (" << filesize << " bytes).";

//                                // read the file into memory
//                                io::data_t orig_filedata;
//                                if (!io::load_data(data, filesize, orig_filedata, pos))
//                                {
//                                        log_error() << log_header << "failed to read TAR data!";
//                                        return false;
//                                }

//                                io::data_t filedata;
//                                if (!io_decode(orig_filedata, filename, filedata))
//                                {
//                                        log_error() << log_header << "failed to decode TAR data!";
//                                        return false;
//                                }

//                                callback(filename, filedata);

//                                // ignore padding
//                                const size_t paddingBytes = (512 - (filesize % 512)) % 512;
//                                if (!io::load_skip(data, paddingBytes, pos))
//                                {
//                                        log_error() << log_header << "failed to skip TAR padding!";
//                                        return false;
//                                }
//                        }

//                        else if (header.typeFlag == '5')
//                        {
//                                log_info() << log_header << "found directory <" << filename << ">.";
//                        }

//                        else if(header.typeFlag == 'L')
//                        {
//                                nextEntryHasLongName = true;
//                        }

//                        else
//                        {
//                                log_info() << log_header << "found unhandled TAR entry type <" << header.typeFlag << ">.";
//                        }
//                }

//                // OK
//                return true;
//        }

        bool copy(archive* ar, io::data_t& data)
        {
                while (true)
                {
                        const void* buff;
                        size_t size;
                        off_t offset;

                        const int r = archive_read_data_block(ar, &buff, &size, &offset);
                        if (r == ARCHIVE_EOF)
                                return true;
                        if (r != ARCHIVE_OK)
                                return false;

                        data.insert(data.end(), (const char*)buff, (const char*)buff + size);
                }

                return true;
        }

        bool io::decode(const std::string& path, const std::string& log_header, const data_callback_t& callback)
        {
                int r;

                archive* ar = archive_read_new();

                archive_read_support_filter_all(ar);
                archive_read_support_format_all(ar);
                archive_read_support_format_raw(ar);

                if ((r = archive_read_open_filename(ar, path.c_str(), 10240)))
                {
                        log_error() << log_header << "failed to open archive <" << path << ">!";
                        log_error() << log_header << "error <" << archive_error_string(ar) << ">!";
                        return false;
                }

                bool ok = true;
                while (ok)
                {
                        archive_entry* entry;
                        r = archive_read_next_header(ar, &entry);

                        if (r == ARCHIVE_EOF)
                                break;
                        if (r != ARCHIVE_OK)
                        {
                                log_error() << log_header << "failed to read archive!";
                                log_error() << log_header << "error <" << archive_error_string(ar) << ">!";
                                ok = false;
                                break;
                        }

                        const std::string filename = archive_entry_pathname(entry);
                        const archive_type filetype = decode_archive_type(filename);
                        const int64_t filesize = archive_entry_size(entry);

                        log_info() << log_header << "filename = <" << filename << ">, filesize = <" << filesize << ">";

                        switch (filetype)
                        {
                        case archive_type::tar:
                        case archive_type::tar_gz:
                        case archive_type::tar_bz2:
                        case archive_type::gz:
                        case archive_type::bz2:
                                // todo
                                break;

                        default:
                                {
                                        data_t data;
                                        if (copy(ar, data))
                                        {
                                                log_info() << log_header
                                                           << "filename = <" << filename
                                                           << ">, filesize = <" << data.size()
                                                           << "/" << filesize << ">";
                                                callback(filename, data);
                                        }
                                        else
                                        {
                                                log_error() << log_header << "failed to read entry!";
                                                log_error() << log_header << "error <" << archive_error_string(ar) << ">!";
                                                ok = false;
                                        }
                                }
                                break;
                        }
                }

                archive_read_close(ar);
                archive_read_free(ar);

                // OK
                return ok;
        }
}
<commit_msg>cleanup<commit_after>#include "io_arch.h"
#include "io_bzip.h"
#include "io_gzip.h"
#include "logger.h"
#include <archive.h>
#include <archive_entry.h>
#include <boost/algorithm/string.hpp>

namespace ncv
{
        namespace detail
        {
                enum class archive_type : int
                {
                        tar,
                        tar_gz,
                        tar_bz2,
                        gz,
                        bz2,
                        unknown
                };

                archive_type decode_archive_type(const std::string& path)
                {

                        if (    boost::algorithm::iends_with(path, ".tar.gz") ||
                                boost::algorithm::iends_with(path, ".tgz"))
                        {
                                return archive_type::tar_gz;
                        }

                        else if (boost::algorithm::iends_with(path, ".tar.bz2") ||
                                 boost::algorithm::iends_with(path, ".tbz") ||
                                 boost::algorithm::iends_with(path, ".tbz2") ||
                                 boost::algorithm::iends_with(path, ".tb2"))
                        {
                                return archive_type::tar_bz2;
                        }

                        else if (boost::algorithm::iends_with(path, ".tar"))
                        {
                                return archive_type::tar;
                        }

                        else if (boost::algorithm::iends_with(path, ".gz"))
                        {
                                return archive_type::gz;
                        }

                        else
                        {
                                return archive_type::unknown;
                        }
                }

                bool copy(archive* ar, io::data_t& data)
                {
                        while (true)
                        {
                                const void* buff;
                                size_t size;
                                off_t offset;

                                const int r = archive_read_data_block(ar, &buff, &size, &offset);
                                if (r == ARCHIVE_EOF)
                                        return true;
                                if (r != ARCHIVE_OK)
                                        return false;

                                data.insert(data.end(), (const char*)buff, (const char*)buff + size);
                        }

                        return true;
                }

        }

//        bool _decode(archive* ar_, const std::string& path, const std::string& log_header, const io::data_callback_t& callback)
//        {
//                archive* ar = archive_read_new();

//                archive_read_support_filter_all(ar);
//                archive_read_support_format_all(ar);
//                archive_read_support_format_raw(ar);

//                int r;
//                if ((r = archive_read_open_filename(ar_, path.c_str(), 10240)))
//                {
//                        log_error() << log_header << "failed to open archive <" << path << ">!";
//                        log_error() << log_header << "error <" << archive_error_string(ar) << ">!";
//                        return false;
//                }

//                bool ok = true;
//                while (ok)
//                {
//                        archive_entry* entry;
//                        r = archive_read_next_header(ar, &entry);

//                        if (r == ARCHIVE_EOF)
//                                break;
//                        if (r != ARCHIVE_OK)
//                        {
//                                log_error() << log_header << "failed to read archive!";
//                                log_error() << log_header << "error <" << archive_error_string(ar) << ">!";
//                                ok = false;
//                                break;
//                        }

//                        const std::string filename = archive_entry_pathname(entry);
//                        const archive_type filetype = decode_archive_type(filename);
//                        const int64_t filesize = archive_entry_size(entry);

//                        log_info() << log_header << "filename = <" << filename << ">, filesize = <" << filesize << ">";

//                        switch (filetype)
//                        {
//                        case archive_type::tar:
//                        case archive_type::tar_gz:
//                        case archive_type::tar_bz2:
//                        case archive_type::gz:
//                        case archive_type::bz2:
//                                _decode(ar, filename, log_header, callback);
//                                break;

//                        default:
//                                {
//                                        io::data_t data;
//                                        if (copy(ar, data))
//                                        {
//                                                log_info() << log_header
//                                                           << "filename = <" << filename
//                                                           << ">, filesize = <" << data.size()
//                                                           << "/" << filesize << ">";
//                                                callback(filename, data);
//                                        }
//                                        else
//                                        {
//                                                log_error() << log_header << "failed to read entry!";
//                                                log_error() << log_header << "error <" << archive_error_string(ar) << ">!";
//                                                ok = false;
//                                        }
//                                }
//                                break;
//                        }
//                }

//                archive_read_close(ar);
//                archive_read_free(ar);

//                // OK
//                return ok;
//        }

        bool io::decode(const std::string& path, const std::string& log_header, const data_callback_t& callback)
        {
                archive* ar = archive_read_new();

                archive_read_support_filter_all(ar);
                archive_read_support_format_all(ar);
                archive_read_support_format_raw(ar);

                int r;
                if ((r = archive_read_open_filename(ar, path.c_str(), 10240)))
                {
                        log_error() << log_header << "failed to open archive <" << path << ">!";
                        log_error() << log_header << "error <" << archive_error_string(ar) << ">!";
                        return false;
                }

                bool ok = true;
                while (ok)
                {
                        archive_entry* entry;
                        r = archive_read_next_header(ar, &entry);

                        if (r == ARCHIVE_EOF)
                                break;
                        if (r != ARCHIVE_OK)
                        {
                                log_error() << log_header << "failed to read archive!";
                                log_error() << log_header << "error <" << archive_error_string(ar) << ">!";
                                ok = false;
                                break;
                        }

                        const std::string filename = archive_entry_pathname(entry);
                        const detail::archive_type filetype = detail::decode_archive_type(filename);
                        const int64_t filesize = archive_entry_size(entry);

                        log_info() << log_header << "filename = <" << filename << ">, filesize = <" << filesize << ">";

                        switch (filetype)
                        {
                        case detail::archive_type::tar:
                        case detail::archive_type::tar_gz:
                        case detail::archive_type::tar_bz2:
                        case detail::archive_type::gz:
                        case detail::archive_type::bz2:
                                // todo
                                break;

                        default:
                                {
                                        io::data_t data;
                                        if (detail::copy(ar, data))
                                        {
                                                log_info() << log_header
                                                           << "filename = <" << filename
                                                           << ">, filesize = <" << data.size()
                                                           << "/" << filesize << ">";
                                                callback(filename, data);
                                        }
                                        else
                                        {

                                                ok = false;
                                        }
                                }
                                break;
                        }
                }

                archive_read_close(ar);
                archive_read_free(ar);

                // OK
                return ok;
        }
}
<|endoftext|>


<commit_before>// Copyright (c) 2010 Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>

// language.cc: Subclasses and singletons for google_breakpad::Language.
// See language.h for details.

#include "common/language.h"

namespace google_breakpad {

// C++ language-specific operations.
class CPPLanguage: public Language {
 public:
  string MakeQualifiedName(const string &parent_name,
                           const string &name) const {
    if (parent_name.empty())
      return name;
    else
      return parent_name + "::" + name;
  }
};

const CPPLanguage CPPLanguageSingleton;

// Java language-specific operations.
class JavaLanguage: public Language {
 public:
  string MakeQualifiedName(const string &parent_name,
                           const string &name) const {
    if (parent_name.empty())
      return name;
    else
      return parent_name + "." + name;
  }
};

JavaLanguage JavaLanguageSingleton;

// Assembler language-specific operations.
class AssemblerLanguage: public Language {
  bool HasFunctions() const { return false; }
  string MakeQualifiedName(const string &parent_name,
                           const string &name) const {
    return name;
  }
};

AssemblerLanguage AssemblerLanguageSingleton;

const Language * const Language::CPlusPlus = &CPPLanguageSingleton;
const Language * const Language::Java = &JavaLanguageSingleton;
const Language * const Language::Assembler = &AssemblerLanguageSingleton;

} // namespace google_breakpad
<commit_msg>Add missing constructor to CPPLanguage class to make it compile with CLang. P=rafael.espindola R=jimb at https://bugzilla.mozilla.org/show_bug.cgi?id=623121<commit_after>// Copyright (c) 2010 Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>

// language.cc: Subclasses and singletons for google_breakpad::Language.
// See language.h for details.

#include "common/language.h"

namespace google_breakpad {

// C++ language-specific operations.
class CPPLanguage: public Language {
 public:
  CPPLanguage() {}
  string MakeQualifiedName(const string &parent_name,
                           const string &name) const {
    if (parent_name.empty())
      return name;
    else
      return parent_name + "::" + name;
  }
};

const CPPLanguage CPPLanguageSingleton;

// Java language-specific operations.
class JavaLanguage: public Language {
 public:
  string MakeQualifiedName(const string &parent_name,
                           const string &name) const {
    if (parent_name.empty())
      return name;
    else
      return parent_name + "." + name;
  }
};

JavaLanguage JavaLanguageSingleton;

// Assembler language-specific operations.
class AssemblerLanguage: public Language {
  bool HasFunctions() const { return false; }
  string MakeQualifiedName(const string &parent_name,
                           const string &name) const {
    return name;
  }
};

AssemblerLanguage AssemblerLanguageSingleton;

const Language * const Language::CPlusPlus = &CPPLanguageSingleton;
const Language * const Language::Java = &JavaLanguageSingleton;
const Language * const Language::Assembler = &AssemblerLanguageSingleton;

} // namespace google_breakpad
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: basscript.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: rt $ $Date: 2005-01-27 14:24:11 $
 *
 *  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 SCRIPTING_BASSCRIPT_HXX
#include "basscript.hxx"
#endif

#ifndef _VOS_MUTEX_HXX_
#include <vos/mutex.hxx>
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif
#ifndef _SBXCLASS_HXX
#include <svtools/sbx.hxx>
#endif
#ifndef _SB_SBSTAR_HXX
#include <basic/sbstar.hxx>
#endif
#ifndef _SB_SBMOD_HXX
#include <basic/sbmod.hxx>
#endif
#ifndef _SB_SBMETH_HXX
#include <basic/sbmeth.hxx>
#endif
#ifndef _COM_SUN_STAR_SCRIPT_PROVIDER_SCRIPTFRAMEWORKERRORTYPE_HPP_
#include <com/sun/star/script/provider/ScriptFrameworkErrorType.hpp>
#endif
#include <map>

using namespace ::com::sun::star;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::script;

extern ::com::sun::star::uno::Any sbxToUnoValue( SbxVariable* pVar );
extern void unoToSbxValue( SbxVariable* pVar, const ::com::sun::star::uno::Any& aValue );

//.........................................................................
namespace basprov
{
//.........................................................................

    typedef ::std::map< sal_Int16, Any, ::std::less< sal_Int16 > > OutParamMap;

    // =============================================================================
    // BasicScriptImpl
    // =============================================================================

    BasicScriptImpl::BasicScriptImpl( const ::rtl::OUString& funcName,  SbMethod* pMethod )
        :m_pMethod( pMethod ), m_funcName( funcName )
    {
    }

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

    BasicScriptImpl::~BasicScriptImpl()
    {
    }

    // -----------------------------------------------------------------------------
    // XScript
    // -----------------------------------------------------------------------------

    Any BasicScriptImpl::invoke( const Sequence< Any >& aParams, Sequence< sal_Int16 >& aOutParamIndex, Sequence< Any >& aOutParam )
        throw ( provider::ScriptFrameworkErrorException, reflection::InvocationTargetException, uno::RuntimeException)
    {
        // TODO: throw CannotConvertException
        // TODO: check length of aOutParamIndex, aOutParam

        ::vos::OGuard aGuard( Application::GetSolarMutex() );

        Any aReturn;

        if ( m_pMethod )
        {
            // check if compiled
            SbModule* pModule = static_cast< SbModule* >( m_pMethod->GetParent() );
            if ( pModule && !pModule->IsCompiled() )
                pModule->Compile();

            // check number of parameters
            sal_Int32 nParamsCount = aParams.getLength();
            SbxInfo* pInfo = m_pMethod->GetInfo();
            if ( pInfo )
            {
                sal_Int32 nSbxOptional = 0;
                USHORT n = 1;
                for ( const SbxParamInfo* pParamInfo = pInfo->GetParam( n ); pParamInfo; pParamInfo = pInfo->GetParam( ++n ) )
                {
                    if ( ( pParamInfo->nFlags & SBX_OPTIONAL ) != 0 )
                        ++nSbxOptional;
                    else
                        nSbxOptional = 0;
                }
                sal_Int32 nSbxCount = n - 1;
                if ( nParamsCount < nSbxCount - nSbxOptional )
                {
                    throw provider::ScriptFrameworkErrorException(
                        ::rtl::OUString(
                            RTL_CONSTASCII_USTRINGPARAM(
                                "wrong number of paramters!" ) ),
                         Reference< XInterface >(),
                         m_funcName,
                         ::rtl::OUString(
                             RTL_CONSTASCII_USTRINGPARAM( "Basic" ) ),
                        provider::ScriptFrameworkErrorType::UNKNOWN  );
                }
            }

            // set parameters
            SbxArrayRef xSbxParams;
            if ( nParamsCount > 0 )
            {
                xSbxParams = new SbxArray;
                const Any* pParams = aParams.getConstArray();
                for ( sal_Int32 i = 0; i < nParamsCount; ++i )
                {
                    SbxVariableRef xSbxVar = new SbxVariable( SbxVARIANT );
                    unoToSbxValue( static_cast< SbxVariable* >( xSbxVar ), pParams[i] );
                    xSbxParams->Put( xSbxVar, static_cast< USHORT >( i ) + 1 );
                }
            }
            if ( xSbxParams.Is() )
                m_pMethod->SetParameters( xSbxParams );

            // call method
            SbxVariableRef xReturn = new SbxVariable;
            ErrCode nErr = m_pMethod->Call( xReturn );
            if ( nErr != SbxERR_OK )
            {
                // TODO: throw InvocationTargetException ?
            }

            // get output parameters
            if ( xSbxParams.Is() )
            {
                SbxInfo* pInfo = m_pMethod->GetInfo();
                if ( pInfo )
                {
                    OutParamMap aOutParamMap;
                    for ( USHORT n = 1, nCount = xSbxParams->Count(); n < nCount; ++n )
                    {
                        const SbxParamInfo* pParamInfo = pInfo->GetParam( n );
                        if ( pParamInfo && ( pParamInfo->eType & SbxBYREF ) != 0 )
                        {
                            SbxVariable* pVar = xSbxParams->Get( n );
                            if ( pVar )
                            {
                                SbxVariableRef xVar = pVar;
                                aOutParamMap.insert( OutParamMap::value_type( n - 1, sbxToUnoValue( xVar ) ) );
                            }
                        }
                    }
                    sal_Int32 nOutParamCount = aOutParamMap.size();
                    aOutParamIndex.realloc( nOutParamCount );
                    aOutParam.realloc( nOutParamCount );
                    sal_Int16* pOutParamIndex = aOutParamIndex.getArray();
                    Any* pOutParam = aOutParam.getArray();
                    for ( OutParamMap::iterator aIt = aOutParamMap.begin(); aIt != aOutParamMap.end(); ++aIt, ++pOutParamIndex, ++pOutParam )
                    {
                        *pOutParamIndex = aIt->first;
                        *pOutParam = aIt->second;
                    }
                }
            }

            // get return value
            aReturn = sbxToUnoValue( xReturn );

            // reset parameters
            m_pMethod->SetParameters( NULL );
        }

        return aReturn;
    }

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

//.........................................................................
}   // namespace basprov
//.........................................................................
<commit_msg>INTEGRATION: CWS visibility03 (1.8.10); FILE MERGED 2005/04/01 16:55:43 mhu 1.8.10.1: #i45006# Replaced includes svtools/sbx*.hxx with basic/sbx*.hxx<commit_after>/*************************************************************************
 *
 *  $RCSfile: basscript.cxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: obo $ $Date: 2005-04-13 08:14:07 $
 *
 *  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 SCRIPTING_BASSCRIPT_HXX
#include "basscript.hxx"
#endif

#ifndef _VOS_MUTEX_HXX_
#include <vos/mutex.hxx>
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif
#ifndef _SBXCLASS_HXX
#include <basic/sbx.hxx>
#endif
#ifndef _SB_SBSTAR_HXX
#include <basic/sbstar.hxx>
#endif
#ifndef _SB_SBMOD_HXX
#include <basic/sbmod.hxx>
#endif
#ifndef _SB_SBMETH_HXX
#include <basic/sbmeth.hxx>
#endif
#ifndef _COM_SUN_STAR_SCRIPT_PROVIDER_SCRIPTFRAMEWORKERRORTYPE_HPP_
#include <com/sun/star/script/provider/ScriptFrameworkErrorType.hpp>
#endif
#include <map>

using namespace ::com::sun::star;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::script;

extern ::com::sun::star::uno::Any sbxToUnoValue( SbxVariable* pVar );
extern void unoToSbxValue( SbxVariable* pVar, const ::com::sun::star::uno::Any& aValue );

//.........................................................................
namespace basprov
{
//.........................................................................

    typedef ::std::map< sal_Int16, Any, ::std::less< sal_Int16 > > OutParamMap;

    // =============================================================================
    // BasicScriptImpl
    // =============================================================================

    BasicScriptImpl::BasicScriptImpl( const ::rtl::OUString& funcName,  SbMethod* pMethod )
        :m_pMethod( pMethod ), m_funcName( funcName )
    {
    }

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

    BasicScriptImpl::~BasicScriptImpl()
    {
    }

    // -----------------------------------------------------------------------------
    // XScript
    // -----------------------------------------------------------------------------

    Any BasicScriptImpl::invoke( const Sequence< Any >& aParams, Sequence< sal_Int16 >& aOutParamIndex, Sequence< Any >& aOutParam )
        throw ( provider::ScriptFrameworkErrorException, reflection::InvocationTargetException, uno::RuntimeException)
    {
        // TODO: throw CannotConvertException
        // TODO: check length of aOutParamIndex, aOutParam

        ::vos::OGuard aGuard( Application::GetSolarMutex() );

        Any aReturn;

        if ( m_pMethod )
        {
            // check if compiled
            SbModule* pModule = static_cast< SbModule* >( m_pMethod->GetParent() );
            if ( pModule && !pModule->IsCompiled() )
                pModule->Compile();

            // check number of parameters
            sal_Int32 nParamsCount = aParams.getLength();
            SbxInfo* pInfo = m_pMethod->GetInfo();
            if ( pInfo )
            {
                sal_Int32 nSbxOptional = 0;
                USHORT n = 1;
                for ( const SbxParamInfo* pParamInfo = pInfo->GetParam( n ); pParamInfo; pParamInfo = pInfo->GetParam( ++n ) )
                {
                    if ( ( pParamInfo->nFlags & SBX_OPTIONAL ) != 0 )
                        ++nSbxOptional;
                    else
                        nSbxOptional = 0;
                }
                sal_Int32 nSbxCount = n - 1;
                if ( nParamsCount < nSbxCount - nSbxOptional )
                {
                    throw provider::ScriptFrameworkErrorException(
                        ::rtl::OUString(
                            RTL_CONSTASCII_USTRINGPARAM(
                                "wrong number of paramters!" ) ),
                         Reference< XInterface >(),
                         m_funcName,
                         ::rtl::OUString(
                             RTL_CONSTASCII_USTRINGPARAM( "Basic" ) ),
                        provider::ScriptFrameworkErrorType::UNKNOWN  );
                }
            }

            // set parameters
            SbxArrayRef xSbxParams;
            if ( nParamsCount > 0 )
            {
                xSbxParams = new SbxArray;
                const Any* pParams = aParams.getConstArray();
                for ( sal_Int32 i = 0; i < nParamsCount; ++i )
                {
                    SbxVariableRef xSbxVar = new SbxVariable( SbxVARIANT );
                    unoToSbxValue( static_cast< SbxVariable* >( xSbxVar ), pParams[i] );
                    xSbxParams->Put( xSbxVar, static_cast< USHORT >( i ) + 1 );
                }
            }
            if ( xSbxParams.Is() )
                m_pMethod->SetParameters( xSbxParams );

            // call method
            SbxVariableRef xReturn = new SbxVariable;
            ErrCode nErr = m_pMethod->Call( xReturn );
            if ( nErr != SbxERR_OK )
            {
                // TODO: throw InvocationTargetException ?
            }

            // get output parameters
            if ( xSbxParams.Is() )
            {
                SbxInfo* pInfo = m_pMethod->GetInfo();
                if ( pInfo )
                {
                    OutParamMap aOutParamMap;
                    for ( USHORT n = 1, nCount = xSbxParams->Count(); n < nCount; ++n )
                    {
                        const SbxParamInfo* pParamInfo = pInfo->GetParam( n );
                        if ( pParamInfo && ( pParamInfo->eType & SbxBYREF ) != 0 )
                        {
                            SbxVariable* pVar = xSbxParams->Get( n );
                            if ( pVar )
                            {
                                SbxVariableRef xVar = pVar;
                                aOutParamMap.insert( OutParamMap::value_type( n - 1, sbxToUnoValue( xVar ) ) );
                            }
                        }
                    }
                    sal_Int32 nOutParamCount = aOutParamMap.size();
                    aOutParamIndex.realloc( nOutParamCount );
                    aOutParam.realloc( nOutParamCount );
                    sal_Int16* pOutParamIndex = aOutParamIndex.getArray();
                    Any* pOutParam = aOutParam.getArray();
                    for ( OutParamMap::iterator aIt = aOutParamMap.begin(); aIt != aOutParamMap.end(); ++aIt, ++pOutParamIndex, ++pOutParam )
                    {
                        *pOutParamIndex = aIt->first;
                        *pOutParam = aIt->second;
                    }
                }
            }

            // get return value
            aReturn = sbxToUnoValue( xReturn );

            // reset parameters
            m_pMethod->SetParameters( NULL );
        }

        return aReturn;
    }

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

//.........................................................................
}   // namespace basprov
//.........................................................................
<|endoftext|>


<commit_before>/*********************************************************************************************************
* MUIController.cpp
* Note: iBurnMgr MUIController
* E-mail:<forcemz@outlook.com>
* Data: @2015.03
* Copyright (C) 2015 The ForceStudio All Rights Reserved.
**********************************************************************************************************/
#include "Precompiled.h"
#include "APIController.h"
#include "MUIController.h"
#include <stdio.h>
#include <stdlib.h>
#include <locale>
#include <fstream>

NAMESPACEMETRO
MUI::LocaleInfo localeinfo = {L"0",0};
namespace MUI{
	MUIController muiController;
	static LocnameBase localbase[] = {
		{ "chs", 2052 },
		{"cht", 1028},
		{"enu",1033}
	};
	const char *getLocaleName(DWORD lcid)
	{
		for (auto i : localbase)
		{
			if (i.id == lcid)
				return i.name;
		}
		return "english";
	}

	MUIController::MUIController()
	{

	}
	DWORD MUIController::Init()
	{
		UILcId = GetSystemDefaultLCID();
		WCHAR szLocal[LOCALE_NAME_MAX_LENGTH] = { 0 };
		WCHAR szlangFile[MAX_UNC_PATH] = {0};
		DWORD eror = ERROR_SUCCESS;
		std::wstring initfile;
		std::wstring langFile;
		GetModuleFileNameW(GetModuleHandleW(NULL), szlangFile, MAX_UNC_PATH);
		initfile = szlangFile;
		initfile+=L".ini";
		if (_waccess_s(initfile.c_str(), 4) == 0){
			int x=GetPrivateProfileStringW(L"iBurnMgr.Config", L"LocaleName", NULL, szLocal, LOCALE_NAME_MAX_LENGTH, initfile.c_str());
			localeinfo.lcid = GetPrivateProfileIntW(L"iBurnMgr.Config", L"LCID", NULL, initfile.c_str());
		}
		if (localeinfo.lcid == 0)
			localeinfo.lcid = UILcId;
		if (!wcslen(szLocal))
		{
			if (LCIDToLocaleName(UILcId, szLocal, LOCALE_NAME_MAX_LENGTH, LOCALE_ALLOW_NEUTRAL_NAMES) == 0)
			{
				eror = GetLastError();
			}
		}
		localeinfo.localename = szLocal;
		(wcsrchr(szlangFile, L'\\'))[1]=0;
		langFile = szlangFile;
		langFile += szLocal;
		langFile += L".lang";
		if (!_waccess_s(langFile.c_str(), 0) == 0)
		{
			langFile = szlangFile;
			langFile+=L"en.lang";
			localeinfo.localename = L"en-US";
		}
		this->ifilename = langFile;
		if (!MUIResourceLoader())
		{
			return 1;
		}
		//for (auto x : m_langTree)
		//{
		//	MessageBoxW(nullptr, x.second.c_str(), x.first.c_str(), MB_OK);
		//}
		return 0;
	}
	std::wstring MUIController::atString(std::wstring &key, std::wstring &value)
	{
		auto iter = m_langTree.find(key);
		if (iter == m_langTree.end())
			return value;
		return m_langTree.at(key);
	}
	std::wstring MUIController::atString(const wchar_t *key, const wchar_t *value)
	{
		std::wstring k = key;
		std::wstring v = value;
		return atString(k, v);
	}
	bool MUIController::MUIResourceLoader()
	{
		wchar_t szBuffer[4096];
		std::wstring newLineStr = L"\\n";
		std::wstring newLine = L"\n";
		std::wstring bufferString;
		std::wifstream file(this->ifilename);
		file.imbue(std::locale(getLocaleName(UILcId)));
		if (!file.is_open())
			return false;
		while (!file.eof())
		{
			file.getline(szBuffer,4096);
			bufferString = szBuffer;
			if (bufferString[0] != '#'&&bufferString[0] != '/'&&bufferString[0]!='[')
			{
				auto np = bufferString.find('=');
				if (np != bufferString.npos)
				{
					std::wstring value = bufferString.substr(np + 1);
					size_t index=0;
					while ((index = value.find(L"\\n")) != value.npos)
					{
						value.replace(index, 2, L"\n");
					}
					m_langTree.insert(std::pair<std::wstring, std::wstring>(bufferString.substr(0, np),value));
				}
			}
		}
		return true;
	}
}
ENDNAMESPACE
<commit_msg>Update MUIController.cpp<commit_after>/*********************************************************************************************************
* MUIController.cpp
* Note: iBurnMgr MUIController
* E-mail:<forcemz@outlook.com>
* Date: @2015.03
* Copyright (C) 2015 The ForceStudio All Rights Reserved.
**********************************************************************************************************/
#include "Precompiled.h"
#include "APIController.h"
#include "MUIController.h"
#include <stdio.h>
#include <stdlib.h>
#include <locale>
#include <fstream>

NAMESPACEMETRO
MUI::LocaleInfo localeinfo = {L"0",0};
namespace MUI{
	MUIController muiController;
	static LocnameBase localbase[] = {
		{ "chs", 2052 },
		{"cht", 1028},
		{"enu",1033}
	};
	const char *getLocaleName(DWORD lcid)
	{
		for (auto i : localbase)
		{
			if (i.id == lcid)
				return i.name;
		}
		return "english";
	}

	MUIController::MUIController()
	{

	}
	DWORD MUIController::Init()
	{
		UILcId = GetSystemDefaultLCID();
		WCHAR szLocal[LOCALE_NAME_MAX_LENGTH] = { 0 };
		WCHAR szlangFile[MAX_UNC_PATH] = {0};
		DWORD eror = ERROR_SUCCESS;
		std::wstring initfile;
		std::wstring langFile;
		GetModuleFileNameW(GetModuleHandleW(NULL), szlangFile, MAX_UNC_PATH);
		initfile = szlangFile;
		initfile+=L".ini";
		if (_waccess_s(initfile.c_str(), 4) == 0){
			int x=GetPrivateProfileStringW(L"iBurnMgr.Config", L"LocaleName", NULL, szLocal, LOCALE_NAME_MAX_LENGTH, initfile.c_str());
			localeinfo.lcid = GetPrivateProfileIntW(L"iBurnMgr.Config", L"LCID", NULL, initfile.c_str());
		}
		if (localeinfo.lcid == 0)
			localeinfo.lcid = UILcId;
		if (!wcslen(szLocal))
		{
			if (LCIDToLocaleName(UILcId, szLocal, LOCALE_NAME_MAX_LENGTH, LOCALE_ALLOW_NEUTRAL_NAMES) == 0)
			{
				eror = GetLastError();
			}
		}
		localeinfo.localename = szLocal;
		(wcsrchr(szlangFile, L'\\'))[1]=0;
		langFile = szlangFile;
		langFile += szLocal;
		langFile += L".lang";
		if (!_waccess_s(langFile.c_str(), 0) == 0)
		{
			langFile = szlangFile;
			langFile+=L"en.lang";
			localeinfo.localename = L"en-US";
		}
		this->ifilename = langFile;
		if (!MUIResourceLoader())
		{
			return 1;
		}
		//for (auto x : m_langTree)
		//{
		//	MessageBoxW(nullptr, x.second.c_str(), x.first.c_str(), MB_OK);
		//}
		return 0;
	}
	std::wstring MUIController::atString(std::wstring &key, std::wstring &value)
	{
		auto iter = m_langTree.find(key);
		if (iter == m_langTree.end())
			return value;
		return m_langTree.at(key);
	}
	std::wstring MUIController::atString(const wchar_t *key, const wchar_t *value)
	{
		std::wstring k = key;
		std::wstring v = value;
		return atString(k, v);
	}
	bool MUIController::MUIResourceLoader()
	{
		wchar_t szBuffer[4096];
		std::wstring newLineStr = L"\\n";
		std::wstring newLine = L"\n";
		std::wstring bufferString;
		std::wifstream file(this->ifilename);
		file.imbue(std::locale(getLocaleName(UILcId)));
		if (!file.is_open())
			return false;
		while (!file.eof())
		{
			file.getline(szBuffer,4096);
			bufferString = szBuffer;
			if (bufferString[0] != '#'&&bufferString[0] != '/'&&bufferString[0]!='[')
			{
				auto np = bufferString.find('=');
				if (np != bufferString.npos)
				{
					std::wstring value = bufferString.substr(np + 1);
					size_t index=0;
					while ((index = value.find(L"\\n")) != value.npos)
					{
						value.replace(index, 2, L"\n");
					}
					m_langTree.insert(std::pair<std::wstring, std::wstring>(bufferString.substr(0, np),value));
				}
			}
		}
		return true;
	}
}
ENDNAMESPACE
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/
// $Id$

// define before any includes
#define BOOST_SPIRIT_THREADSAFE

#include <mapnik/map.hpp>
#include <mapnik/datasource_cache.hpp>
#include <mapnik/font_engine_freetype.hpp>
#include <mapnik/agg_renderer.hpp>
#include <mapnik/filter_factory.hpp>
#include <mapnik/color_factory.hpp>
#include <mapnik/image_util.hpp>
#include <mapnik/config_error.hpp>

#include <iostream>

int main ( int argc , char** argv)
{
    if (argc != 2)
    {
        std::cout << "usage: ./rundemo <mapnik_install_dir>\n";
        return EXIT_SUCCESS;
    }

    using namespace mapnik;
    try {
        std::cout << " running demo ... \n";
        std::string mapnik_dir(argv[1]);
        datasource_cache::instance()->register_datasources(mapnik_dir + "/lib/mapnik/input/");
        freetype_engine::register_font(mapnik_dir + "/lib/mapnik/fonts/DejaVuSans.ttf");

        Map m(800,600);
        m.set_background(color_factory::from_string("white"));

        // create styles

        // Provinces (polygon)
        feature_type_style provpoly_style;

        rule_type provpoly_rule_on;
        provpoly_rule_on.set_filter(create_filter("[NAME_EN] = 'Ontario'"));
        provpoly_rule_on.append(polygon_symbolizer(Color(250, 190, 183)));
        provpoly_style.add_rule(provpoly_rule_on);

        rule_type provpoly_rule_qc;
        provpoly_rule_qc.set_filter(create_filter("[NAME_EN] = 'Quebec'"));
        provpoly_rule_qc.append(polygon_symbolizer(Color(217, 235, 203)));
        provpoly_style.add_rule(provpoly_rule_qc);

        m.insert_style("provinces",provpoly_style);

        // Provinces (polyline)
        feature_type_style provlines_style;

        stroke provlines_stk (Color(0,0,0),1.0);
        provlines_stk.add_dash(8, 4);
        provlines_stk.add_dash(2, 2);
        provlines_stk.add_dash(2, 2);

        rule_type provlines_rule;
        provlines_rule.append(line_symbolizer(provlines_stk));
        provlines_style.add_rule(provlines_rule);

        m.insert_style("provlines",provlines_style);

        // Drainage
        feature_type_style qcdrain_style;

        rule_type qcdrain_rule;
        qcdrain_rule.set_filter(create_filter("[HYC] = 8"));
        qcdrain_rule.append(polygon_symbolizer(Color(153, 204, 255)));
        qcdrain_style.add_rule(qcdrain_rule);

        m.insert_style("drainage",qcdrain_style);

        // Roads 3 and 4 (The "grey" roads)
        feature_type_style roads34_style;
        rule_type roads34_rule;
        roads34_rule.set_filter(create_filter("[CLASS] = 3 or [CLASS] = 4"));
        stroke roads34_rule_stk(Color(171,158,137),2.0);
        roads34_rule_stk.set_line_cap(ROUND_CAP);
        roads34_rule_stk.set_line_join(ROUND_JOIN);
        roads34_rule.append(line_symbolizer(roads34_rule_stk));
        roads34_style.add_rule(roads34_rule);

        m.insert_style("smallroads",roads34_style);

        // Roads 2 (The thin yellow ones)
        feature_type_style roads2_style_1;
        rule_type roads2_rule_1;
        roads2_rule_1.set_filter(create_filter("[CLASS] = 2"));
        stroke roads2_rule_stk_1(Color(171,158,137),4.0);
        roads2_rule_stk_1.set_line_cap(ROUND_CAP);
        roads2_rule_stk_1.set_line_join(ROUND_JOIN);
        roads2_rule_1.append(line_symbolizer(roads2_rule_stk_1));
        roads2_style_1.add_rule(roads2_rule_1);

        m.insert_style("road-border", roads2_style_1);

        feature_type_style roads2_style_2;
        rule_type roads2_rule_2;
        roads2_rule_2.set_filter(create_filter("[CLASS] = 2"));
        stroke roads2_rule_stk_2(Color(255,250,115),2.0);
        roads2_rule_stk_2.set_line_cap(ROUND_CAP);
        roads2_rule_stk_2.set_line_join(ROUND_JOIN);
        roads2_rule_2.append(line_symbolizer(roads2_rule_stk_2));
        roads2_style_2.add_rule(roads2_rule_2);

        m.insert_style("road-fill", roads2_style_2);

        // Roads 1 (The big orange ones, the highways)
        feature_type_style roads1_style_1;
        rule_type roads1_rule_1;
        roads1_rule_1.set_filter(create_filter("[CLASS] = 1"));
        stroke roads1_rule_stk_1(Color(188,149,28),7.0);
        roads1_rule_stk_1.set_line_cap(ROUND_CAP);
        roads1_rule_stk_1.set_line_join(ROUND_JOIN);
        roads1_rule_1.append(line_symbolizer(roads1_rule_stk_1));
        roads1_style_1.add_rule(roads1_rule_1);
        m.insert_style("highway-border", roads1_style_1);

        feature_type_style roads1_style_2;
        rule_type roads1_rule_2;
        roads1_rule_2.set_filter(create_filter("[CLASS] = 1"));
        stroke roads1_rule_stk_2(Color(242,191,36),5.0);
        roads1_rule_stk_2.set_line_cap(ROUND_CAP);
        roads1_rule_stk_2.set_line_join(ROUND_JOIN);
        roads1_rule_2.append(line_symbolizer(roads1_rule_stk_2));
        roads1_style_2.add_rule(roads1_rule_2);
        m.insert_style("highway-fill", roads1_style_2);

        // Populated Places

        feature_type_style popplaces_style;
        rule_type popplaces_rule;
        text_symbolizer popplaces_text_symbolizer("GEONAME","DejaVu Sans Book",10,Color(0,0,0));
        popplaces_text_symbolizer.set_halo_fill(Color(255,255,200));
        popplaces_text_symbolizer.set_halo_radius(1);
        popplaces_rule.append(popplaces_text_symbolizer);
        popplaces_style.add_rule(popplaces_rule);

        m.insert_style("popplaces",popplaces_style );

        // Layers
        // Provincial  polygons
        {
            parameters p;
            p["type"]="shape";
            p["file"]="../data/boundaries";

            Layer lyr("Provinces");
            lyr.set_datasource(datasource_cache::instance()->create(p));
            lyr.add_style("provinces");
            m.addLayer(lyr);
        }

        // Drainage
        {
            parameters p;
            p["type"]="shape";
            p["file"]="../data/qcdrainage";
            Layer lyr("Quebec Hydrography");
            lyr.set_datasource(datasource_cache::instance()->create(p));
            lyr.add_style("drainage");
            m.addLayer(lyr);
        }

        {
            parameters p;
            p["type"]="shape";
            p["file"]="../data/ontdrainage";

            Layer lyr("Ontario Hydrography");
            lyr.set_datasource(datasource_cache::instance()->create(p));
            lyr.add_style("drainage");
            m.addLayer(lyr);
        }

        // Provincial boundaries
        {
            parameters p;
            p["type"]="shape";
            p["file"]="../data/boundaries_l";
            Layer lyr("Provincial borders");
            lyr.set_datasource(datasource_cache::instance()->create(p));
            lyr.add_style("provlines");
            m.addLayer(lyr);
        }

        // Roads
        {
            parameters p;
            p["type"]="shape";
            p["file"]="../data/roads";
            Layer lyr("Roads");
            lyr.set_datasource(datasource_cache::instance()->create(p));
            lyr.add_style("smallroads");
            lyr.add_style("road-border");
            lyr.add_style("road-fill");
            lyr.add_style("highway-border");
            lyr.add_style("highway-fill");

            m.addLayer(lyr);
        }
        // popplaces
        {
            parameters p;
            p["type"]="shape";
            p["file"]="../data/popplaces";
            p["encoding"] = "latin1";
            Layer lyr("Populated Places");
            lyr.set_datasource(datasource_cache::instance()->create(p));
            lyr.add_style("popplaces");
            m.addLayer(lyr);
        }

        m.zoomToBox(Envelope<double>(1405120.04127408,-247003.813399447,
                                     1706357.31328276,-25098.593149577));

        Image32 buf(m.getWidth(),m.getHeight());
        agg_renderer<Image32> ren(m,buf);
        ren.apply();

        save_to_file<ImageData32>("demo.jpg","jpeg",buf.data());
        save_to_file<ImageData32>("demo.png","png",buf.data());
        save_to_file<ImageData32>("demo256.png","png256",buf.data());
        std::cout << "Three maps have been rendered in the current directory:\n"
           "- demo.jpg\n"
           "- demo.png\n"
           "- demo256.png\n"
           "Have a look!\n";
    }
    catch ( const mapnik::config_error & ex )
    {
        std::cerr << "### Configuration error: " << ex.what();
        return EXIT_FAILURE;
    }
    catch ( const std::exception & ex )
    {
        std::cerr << "### std::exception: " << ex.what();
        return EXIT_FAILURE;
    }
    catch ( ... )
    {
        std::cerr << "### Unknown exception." << std::endl;
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}
<commit_msg>updated to be compatble with latest trunk<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/
// $Id$

// define before any includes
#define BOOST_SPIRIT_THREADSAFE

#include <mapnik/map.hpp>
#include <mapnik/datasource_cache.hpp>
#include <mapnik/font_engine_freetype.hpp>
#include <mapnik/agg_renderer.hpp>
#include <mapnik/filter_factory.hpp>
#include <mapnik/color_factory.hpp>
#include <mapnik/image_util.hpp>
#include <mapnik/config_error.hpp>

#include <iostream>

int main ( int argc , char** argv)
{
    if (argc != 2)
    {
        std::cout << "usage: ./rundemo <mapnik_install_dir>\n";
        return EXIT_SUCCESS;
    }

    using namespace mapnik;
    try {
        std::cout << " running demo ... \n";
        std::string mapnik_dir(argv[1]);
        datasource_cache::instance()->register_datasources(mapnik_dir + "/lib/mapnik/input/");
        freetype_engine::register_font(mapnik_dir + "/lib/mapnik/fonts/DejaVuSans.ttf");

        Map m(800,600);
        m.set_background(color_factory::from_string("white"));

        // create styles

        // Provinces (polygon)
        feature_type_style provpoly_style;

        rule_type provpoly_rule_on;
        provpoly_rule_on.set_filter(create_filter("[NAME_EN] = 'Ontario'"));
        provpoly_rule_on.append(polygon_symbolizer(Color(250, 190, 183)));
        provpoly_style.add_rule(provpoly_rule_on);

        rule_type provpoly_rule_qc;
        provpoly_rule_qc.set_filter(create_filter("[NAME_EN] = 'Quebec'"));
        provpoly_rule_qc.append(polygon_symbolizer(Color(217, 235, 203)));
        provpoly_style.add_rule(provpoly_rule_qc);

        m.insert_style("provinces",provpoly_style);

        // Provinces (polyline)
        feature_type_style provlines_style;

        stroke provlines_stk (Color(0,0,0),1.0);
        provlines_stk.add_dash(8, 4);
        provlines_stk.add_dash(2, 2);
        provlines_stk.add_dash(2, 2);

        rule_type provlines_rule;
        provlines_rule.append(line_symbolizer(provlines_stk));
        provlines_style.add_rule(provlines_rule);

        m.insert_style("provlines",provlines_style);

        // Drainage
        feature_type_style qcdrain_style;

        rule_type qcdrain_rule;
        qcdrain_rule.set_filter(create_filter("[HYC] = 8"));
        qcdrain_rule.append(polygon_symbolizer(Color(153, 204, 255)));
        qcdrain_style.add_rule(qcdrain_rule);

        m.insert_style("drainage",qcdrain_style);

        // Roads 3 and 4 (The "grey" roads)
        feature_type_style roads34_style;
        rule_type roads34_rule;
        roads34_rule.set_filter(create_filter("[CLASS] = 3 or [CLASS] = 4"));
        stroke roads34_rule_stk(Color(171,158,137),2.0);
        roads34_rule_stk.set_line_cap(ROUND_CAP);
        roads34_rule_stk.set_line_join(ROUND_JOIN);
        roads34_rule.append(line_symbolizer(roads34_rule_stk));
        roads34_style.add_rule(roads34_rule);

        m.insert_style("smallroads",roads34_style);

        // Roads 2 (The thin yellow ones)
        feature_type_style roads2_style_1;
        rule_type roads2_rule_1;
        roads2_rule_1.set_filter(create_filter("[CLASS] = 2"));
        stroke roads2_rule_stk_1(Color(171,158,137),4.0);
        roads2_rule_stk_1.set_line_cap(ROUND_CAP);
        roads2_rule_stk_1.set_line_join(ROUND_JOIN);
        roads2_rule_1.append(line_symbolizer(roads2_rule_stk_1));
        roads2_style_1.add_rule(roads2_rule_1);

        m.insert_style("road-border", roads2_style_1);

        feature_type_style roads2_style_2;
        rule_type roads2_rule_2;
        roads2_rule_2.set_filter(create_filter("[CLASS] = 2"));
        stroke roads2_rule_stk_2(Color(255,250,115),2.0);
        roads2_rule_stk_2.set_line_cap(ROUND_CAP);
        roads2_rule_stk_2.set_line_join(ROUND_JOIN);
        roads2_rule_2.append(line_symbolizer(roads2_rule_stk_2));
        roads2_style_2.add_rule(roads2_rule_2);

        m.insert_style("road-fill", roads2_style_2);

        // Roads 1 (The big orange ones, the highways)
        feature_type_style roads1_style_1;
        rule_type roads1_rule_1;
        roads1_rule_1.set_filter(create_filter("[CLASS] = 1"));
        stroke roads1_rule_stk_1(Color(188,149,28),7.0);
        roads1_rule_stk_1.set_line_cap(ROUND_CAP);
        roads1_rule_stk_1.set_line_join(ROUND_JOIN);
        roads1_rule_1.append(line_symbolizer(roads1_rule_stk_1));
        roads1_style_1.add_rule(roads1_rule_1);
        m.insert_style("highway-border", roads1_style_1);

        feature_type_style roads1_style_2;
        rule_type roads1_rule_2;
        roads1_rule_2.set_filter(create_filter("[CLASS] = 1"));
        stroke roads1_rule_stk_2(Color(242,191,36),5.0);
        roads1_rule_stk_2.set_line_cap(ROUND_CAP);
        roads1_rule_stk_2.set_line_join(ROUND_JOIN);
        roads1_rule_2.append(line_symbolizer(roads1_rule_stk_2));
        roads1_style_2.add_rule(roads1_rule_2);
        m.insert_style("highway-fill", roads1_style_2);

        // Populated Places

        feature_type_style popplaces_style;
        rule_type popplaces_rule;
        text_symbolizer popplaces_text_symbolizer("GEONAME","DejaVu Sans Book",10,Color(0,0,0));
        popplaces_text_symbolizer.set_halo_fill(Color(255,255,200));
        popplaces_text_symbolizer.set_halo_radius(1);
        popplaces_rule.append(popplaces_text_symbolizer);
        popplaces_style.add_rule(popplaces_rule);

        m.insert_style("popplaces",popplaces_style );

        // Layers
        // Provincial  polygons
        {
            parameters p;
            p["type"]="shape";
            p["file"]="../data/boundaries";

            Layer lyr("Provinces");
            lyr.set_datasource(datasource_cache::instance()->create(p));
            lyr.add_style("provinces");
            m.addLayer(lyr);
        }

        // Drainage
        {
            parameters p;
            p["type"]="shape";
            p["file"]="../data/qcdrainage";
            Layer lyr("Quebec Hydrography");
            lyr.set_datasource(datasource_cache::instance()->create(p));
            lyr.add_style("drainage");
            m.addLayer(lyr);
        }

        {
            parameters p;
            p["type"]="shape";
            p["file"]="../data/ontdrainage";

            Layer lyr("Ontario Hydrography");
            lyr.set_datasource(datasource_cache::instance()->create(p));
            lyr.add_style("drainage");
            m.addLayer(lyr);
        }

        // Provincial boundaries
        {
            parameters p;
            p["type"]="shape";
            p["file"]="../data/boundaries_l";
            Layer lyr("Provincial borders");
            lyr.set_datasource(datasource_cache::instance()->create(p));
            lyr.add_style("provlines");
            m.addLayer(lyr);
        }

        // Roads
        {
            parameters p;
            p["type"]="shape";
            p["file"]="../data/roads";
            Layer lyr("Roads");
            lyr.set_datasource(datasource_cache::instance()->create(p));
            lyr.add_style("smallroads");
            lyr.add_style("road-border");
            lyr.add_style("road-fill");
            lyr.add_style("highway-border");
            lyr.add_style("highway-fill");

            m.addLayer(lyr);
        }
        // popplaces
        {
            parameters p;
            p["type"]="shape";
            p["file"]="../data/popplaces";
            p["encoding"] = "latin1";
            Layer lyr("Populated Places");
            lyr.set_datasource(datasource_cache::instance()->create(p));
            lyr.add_style("popplaces");
            m.addLayer(lyr);
        }

        m.zoomToBox(Envelope<double>(1405120.04127408,-247003.813399447,
                                     1706357.31328276,-25098.593149577));

        Image32 buf(m.getWidth(),m.getHeight());
        agg_renderer<Image32> ren(m,buf);
        ren.apply();

        save_to_file<ImageData32>(buf.data(),"demo.jpg","jpeg");
        save_to_file<ImageData32>(buf.data(),"demo.png","png");
        save_to_file<ImageData32>(buf.data(),"demo256.png","png256");
        std::cout << "Three maps have been rendered in the current directory:\n"
           "- demo.jpg\n"
           "- demo.png\n"
           "- demo256.png\n"
           "Have a look!\n";
    }
    catch ( const mapnik::config_error & ex )
    {
        std::cerr << "### Configuration error: " << ex.what();
        return EXIT_FAILURE;
    }
    catch ( const std::exception & ex )
    {
        std::cerr << "### std::exception: " << ex.what();
        return EXIT_FAILURE;
    }
    catch ( ... )
    {
        std::cerr << "### Unknown exception." << std::endl;
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/** @file

  Parse the records.config configuration file.

  @section license License

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
 */

#include "ts/ink_platform.h"
#include "ts/ink_memory.h"

#include "ts/TextBuffer.h"
#include "ts/Tokenizer.h"
#include "ts/ink_defs.h"
#include "ts/ink_string.h"

#include "P_RecFile.h"
#include "P_RecUtils.h"
#include "P_RecMessage.h"
#include "P_RecCore.h"
#include "ts/I_Layout.h"

const char *g_rec_config_fpath         = nullptr;
LLQ *g_rec_config_contents_llq         = nullptr;
InkHashTable *g_rec_config_contents_ht = nullptr;
ink_mutex g_rec_config_lock;

//-------------------------------------------------------------------------
// RecConfigFileInit
//-------------------------------------------------------------------------
void
RecConfigFileInit()
{
  ink_mutex_init(&g_rec_config_lock);
  g_rec_config_contents_llq = create_queue();
  g_rec_config_contents_ht  = ink_hash_table_create(InkHashTableKeyType_String);
}

//-------------------------------------------------------------------------
// RecFileImport_Xmalloc
//-------------------------------------------------------------------------
static int
RecFileImport_Xmalloc(const char *file, char **file_buf, int *file_size)
{
  int err = REC_ERR_FAIL;
  RecHandle h_file;
  int bytes_read;

  if (file && file_buf && file_size) {
    *file_buf  = nullptr;
    *file_size = 0;
    if ((h_file = RecFileOpenR(file)) != REC_HANDLE_INVALID) {
      *file_size = RecFileGetSize(h_file);
      *file_buf  = (char *)ats_malloc(*file_size + 1);
      if (RecFileRead(h_file, *file_buf, *file_size, &bytes_read) != REC_ERR_FAIL && bytes_read == *file_size) {
        (*file_buf)[*file_size] = '\0';
        err                     = REC_ERR_OKAY;
      } else {
        ats_free(*file_buf);
        *file_buf  = nullptr;
        *file_size = 0;
      }
      RecFileClose(h_file);
    }
  }

  return err;
}

//-------------------------------------------------------------------------
// RecConfigOverrideFromEnvironment
//-------------------------------------------------------------------------
const char *
RecConfigOverrideFromEnvironment(const char *name, const char *value)
{
  ats_scoped_str envname(ats_strdup(name));
  const char *envval = nullptr;

  // Munge foo.bar.config into FOO_BAR_CONFIG.
  for (char *c = envname; *c != '\0'; ++c) {
    switch (*c) {
    case '.':
      *c = '_';
      break;
    default:
      *c = ParseRules::ink_toupper(*c);
      break;
    }
  }

  envval = getenv((const char *)envname);
  if (envval) {
    return envval;
  }

  return value;
}

//-------------------------------------------------------------------------
// RecParseConfigFile
//-------------------------------------------------------------------------
int
RecConfigFileParse(const char *path, RecConfigEntryCallback handler, bool inc_version)
{
  char *fbuf;
  int fsize;

  const char *line;
  int line_num;

  char *rec_type_str, *name_str, *data_type_str, *data_str;
  const char *value_str;
  RecT rec_type;
  RecDataT data_type;

  Tokenizer line_tok("\r\n");
  tok_iter_state line_tok_state;

  RecConfigFileEntry *cfe;

  RecDebug(DL_Note, "Reading '%s'", path);

  // watch out, we're altering our g_rec_config_xxx structures
  ink_mutex_acquire(&g_rec_config_lock);

  if (RecFileImport_Xmalloc(path, &fbuf, &fsize) == REC_ERR_FAIL) {
    RecLog(DL_Warning, "Could not import '%s'", path);
    ink_mutex_release(&g_rec_config_lock);
    return REC_ERR_FAIL;
  }
  // clear our g_rec_config_contents_xxx structures
  while (!queue_is_empty(g_rec_config_contents_llq)) {
    cfe = (RecConfigFileEntry *)dequeue(g_rec_config_contents_llq);
    ats_free(cfe->entry);
    ats_free(cfe);
  }
  ink_hash_table_destroy(g_rec_config_contents_ht);
  g_rec_config_contents_ht = ink_hash_table_create(InkHashTableKeyType_String);

  line_tok.Initialize(fbuf, SHARE_TOKS);
  line     = line_tok.iterFirst(&line_tok_state);
  line_num = 1;
  while (line) {
    char *lc = ats_strdup(line);
    char *lt = lc;
    char *ln;

    while (isspace(*lt)) {
      lt++;
    }
    rec_type_str = strtok_r(lt, " \t", &ln);

    // check for blank lines and comments
    if ((!rec_type_str) || (rec_type_str && (*rec_type_str == '#'))) {
      goto L_next_line;
    }

    name_str      = strtok_r(nullptr, " \t", &ln);
    data_type_str = strtok_r(nullptr, " \t", &ln);

    // extract the string data (a little bit tricker since it can have spaces)
    if (ln) {
      // 'ln' will point to either the next token or a bunch of spaces
      // if the user didn't supply a value (e.g. 'STRING   ').  First
      // scan past all of the spaces.  If we hit a '\0', then we we
      // know we didn't have a valid value.  If not, set 'data_str' to
      // the start of the token and scan until we find the end.  Once
      // the end is found, back-peddle to remove any trailing spaces.
      while (isspace(*ln)) {
        ln++;
      }
      if (*ln == '\0') {
        data_str = nullptr;
      } else {
        data_str = ln;
        while (*ln != '\0') {
          ln++;
        }
        ln--;
        while (isspace(*ln) && (ln > data_str)) {
          ln--;
        }
        ln++;
        *ln = '\0';
      }
    } else {
      data_str = nullptr;
    }

    // check for errors
    if (!(rec_type_str && name_str && data_type_str && data_str)) {
      RecLog(DL_Warning, "Could not parse line at '%s:%d' -- skipping line: '%s'", path, line_num, line);
      goto L_next_line;
    }

    // record type
    if (strcmp(rec_type_str, "CONFIG") == 0) {
      rec_type = RECT_CONFIG;
    } else if (strcmp(rec_type_str, "PROCESS") == 0) {
      rec_type = RECT_PROCESS;
    } else if (strcmp(rec_type_str, "NODE") == 0) {
      rec_type = RECT_NODE;
    } else if (strcmp(rec_type_str, "LOCAL") == 0) {
      rec_type = RECT_LOCAL;
    } else {
      RecLog(DL_Warning, "Unknown record type '%s' at '%s:%d' -- skipping line", rec_type_str, path, line_num);
      goto L_next_line;
    }

    // data_type
    if (strcmp(data_type_str, "INT") == 0) {
      data_type = RECD_INT;
    } else if (strcmp(data_type_str, "FLOAT") == 0) {
      data_type = RECD_FLOAT;
    } else if (strcmp(data_type_str, "STRING") == 0) {
      data_type = RECD_STRING;
    } else if (strcmp(data_type_str, "COUNTER") == 0) {
      data_type = RECD_COUNTER;
    } else {
      RecLog(DL_Warning, "Unknown data type '%s' at '%s:%d' -- skipping line", data_type_str, path, line_num);
      goto L_next_line;
    }

    // OK, we parsed the record, send it to the handler ...
    value_str = RecConfigOverrideFromEnvironment(name_str, data_str);
    handler(rec_type, data_type, name_str, value_str, value_str == data_str ? REC_SOURCE_EXPLICIT : REC_SOURCE_ENV, inc_version);

    // update our g_rec_config_contents_xxx
    cfe             = (RecConfigFileEntry *)ats_malloc(sizeof(RecConfigFileEntry));
    cfe->entry_type = RECE_RECORD;
    cfe->entry      = ats_strdup(name_str);
    enqueue(g_rec_config_contents_llq, (void *)cfe);
    ink_hash_table_insert(g_rec_config_contents_ht, name_str, nullptr);
    goto L_done;

  L_next_line:
    // store this line into g_rec_config_contents_llq so that we can
    // write it out later
    cfe             = (RecConfigFileEntry *)ats_malloc(sizeof(RecConfigFileEntry));
    cfe->entry_type = RECE_COMMENT;
    cfe->entry      = ats_strdup(line);
    enqueue(g_rec_config_contents_llq, (void *)cfe);

  L_done:
    line = line_tok.iterNext(&line_tok_state);
    line_num++;
    ats_free(lc);
  }

  ink_mutex_release(&g_rec_config_lock);
  ats_free(fbuf);

  return REC_ERR_OKAY;
}
<commit_msg>preserve whitespace when reading/writing records.config<commit_after>/** @file

  Parse the records.config configuration file.

  @section license License

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
 */

#include "ts/ink_platform.h"
#include "ts/ink_memory.h"

#include "ts/TextBuffer.h"
#include "ts/Tokenizer.h"
#include "ts/ink_defs.h"
#include "ts/ink_string.h"

#include "P_RecFile.h"
#include "P_RecUtils.h"
#include "P_RecMessage.h"
#include "P_RecCore.h"
#include "ts/I_Layout.h"

const char *g_rec_config_fpath         = nullptr;
LLQ *g_rec_config_contents_llq         = nullptr;
InkHashTable *g_rec_config_contents_ht = nullptr;
ink_mutex g_rec_config_lock;

//-------------------------------------------------------------------------
// RecConfigFileInit
//-------------------------------------------------------------------------
void
RecConfigFileInit()
{
  ink_mutex_init(&g_rec_config_lock);
  g_rec_config_contents_llq = create_queue();
  g_rec_config_contents_ht  = ink_hash_table_create(InkHashTableKeyType_String);
}

//-------------------------------------------------------------------------
// RecFileImport_Xmalloc
//-------------------------------------------------------------------------
static int
RecFileImport_Xmalloc(const char *file, char **file_buf, int *file_size)
{
  int err = REC_ERR_FAIL;
  RecHandle h_file;
  int bytes_read;

  if (file && file_buf && file_size) {
    *file_buf  = nullptr;
    *file_size = 0;
    if ((h_file = RecFileOpenR(file)) != REC_HANDLE_INVALID) {
      *file_size = RecFileGetSize(h_file);
      *file_buf  = (char *)ats_malloc(*file_size + 1);
      if (RecFileRead(h_file, *file_buf, *file_size, &bytes_read) != REC_ERR_FAIL && bytes_read == *file_size) {
        (*file_buf)[*file_size] = '\0';
        err                     = REC_ERR_OKAY;
      } else {
        ats_free(*file_buf);
        *file_buf  = nullptr;
        *file_size = 0;
      }
      RecFileClose(h_file);
    }
  }

  return err;
}

//-------------------------------------------------------------------------
// RecConfigOverrideFromEnvironment
//-------------------------------------------------------------------------
const char *
RecConfigOverrideFromEnvironment(const char *name, const char *value)
{
  ats_scoped_str envname(ats_strdup(name));
  const char *envval = nullptr;

  // Munge foo.bar.config into FOO_BAR_CONFIG.
  for (char *c = envname; *c != '\0'; ++c) {
    switch (*c) {
    case '.':
      *c = '_';
      break;
    default:
      *c = ParseRules::ink_toupper(*c);
      break;
    }
  }

  envval = getenv((const char *)envname);
  if (envval) {
    return envval;
  }

  return value;
}

//-------------------------------------------------------------------------
// RecParseConfigFile
//-------------------------------------------------------------------------
int
RecConfigFileParse(const char *path, RecConfigEntryCallback handler, bool inc_version)
{
  char *fbuf;
  int fsize;

  const char *line;
  int line_num;

  char *rec_type_str, *name_str, *data_type_str, *data_str;
  const char *value_str;
  RecT rec_type;
  RecDataT data_type;

  Tokenizer line_tok("\r\n");
  tok_iter_state line_tok_state;

  RecConfigFileEntry *cfe;

  RecDebug(DL_Note, "Reading '%s'", path);

  // watch out, we're altering our g_rec_config_xxx structures
  ink_mutex_acquire(&g_rec_config_lock);

  if (RecFileImport_Xmalloc(path, &fbuf, &fsize) == REC_ERR_FAIL) {
    RecLog(DL_Warning, "Could not import '%s'", path);
    ink_mutex_release(&g_rec_config_lock);
    return REC_ERR_FAIL;
  }
  // clear our g_rec_config_contents_xxx structures
  while (!queue_is_empty(g_rec_config_contents_llq)) {
    cfe = (RecConfigFileEntry *)dequeue(g_rec_config_contents_llq);
    ats_free(cfe->entry);
    ats_free(cfe);
  }
  ink_hash_table_destroy(g_rec_config_contents_ht);
  g_rec_config_contents_ht = ink_hash_table_create(InkHashTableKeyType_String);

  line_tok.Initialize(fbuf, SHARE_TOKS | ALLOW_EMPTY_TOKS);
  line     = line_tok.iterFirst(&line_tok_state);
  line_num = 1;
  while (line) {
    char *lc = ats_strdup(line);
    char *lt = lc;
    char *ln;

    while (isspace(*lt)) {
      lt++;
    }
    rec_type_str = strtok_r(lt, " \t", &ln);

    // check for blank lines and comments
    if ((!rec_type_str) || (rec_type_str && (*rec_type_str == '#'))) {
      goto L_next_line;
    }

    name_str      = strtok_r(nullptr, " \t", &ln);
    data_type_str = strtok_r(nullptr, " \t", &ln);

    // extract the string data (a little bit tricker since it can have spaces)
    if (ln) {
      // 'ln' will point to either the next token or a bunch of spaces
      // if the user didn't supply a value (e.g. 'STRING   ').  First
      // scan past all of the spaces.  If we hit a '\0', then we we
      // know we didn't have a valid value.  If not, set 'data_str' to
      // the start of the token and scan until we find the end.  Once
      // the end is found, back-peddle to remove any trailing spaces.
      while (isspace(*ln)) {
        ln++;
      }
      if (*ln == '\0') {
        data_str = nullptr;
      } else {
        data_str = ln;
        while (*ln != '\0') {
          ln++;
        }
        ln--;
        while (isspace(*ln) && (ln > data_str)) {
          ln--;
        }
        ln++;
        *ln = '\0';
      }
    } else {
      data_str = nullptr;
    }

    // check for errors
    if (!(rec_type_str && name_str && data_type_str && data_str)) {
      RecLog(DL_Warning, "Could not parse line at '%s:%d' -- skipping line: '%s'", path, line_num, line);
      goto L_next_line;
    }

    // record type
    if (strcmp(rec_type_str, "CONFIG") == 0) {
      rec_type = RECT_CONFIG;
    } else if (strcmp(rec_type_str, "PROCESS") == 0) {
      rec_type = RECT_PROCESS;
    } else if (strcmp(rec_type_str, "NODE") == 0) {
      rec_type = RECT_NODE;
    } else if (strcmp(rec_type_str, "LOCAL") == 0) {
      rec_type = RECT_LOCAL;
    } else {
      RecLog(DL_Warning, "Unknown record type '%s' at '%s:%d' -- skipping line", rec_type_str, path, line_num);
      goto L_next_line;
    }

    // data_type
    if (strcmp(data_type_str, "INT") == 0) {
      data_type = RECD_INT;
    } else if (strcmp(data_type_str, "FLOAT") == 0) {
      data_type = RECD_FLOAT;
    } else if (strcmp(data_type_str, "STRING") == 0) {
      data_type = RECD_STRING;
    } else if (strcmp(data_type_str, "COUNTER") == 0) {
      data_type = RECD_COUNTER;
    } else {
      RecLog(DL_Warning, "Unknown data type '%s' at '%s:%d' -- skipping line", data_type_str, path, line_num);
      goto L_next_line;
    }

    // OK, we parsed the record, send it to the handler ...
    value_str = RecConfigOverrideFromEnvironment(name_str, data_str);
    handler(rec_type, data_type, name_str, value_str, value_str == data_str ? REC_SOURCE_EXPLICIT : REC_SOURCE_ENV, inc_version);

    // update our g_rec_config_contents_xxx
    cfe             = (RecConfigFileEntry *)ats_malloc(sizeof(RecConfigFileEntry));
    cfe->entry_type = RECE_RECORD;
    cfe->entry      = ats_strdup(name_str);
    enqueue(g_rec_config_contents_llq, (void *)cfe);
    ink_hash_table_insert(g_rec_config_contents_ht, name_str, nullptr);
    goto L_done;

  L_next_line:
    // store this line into g_rec_config_contents_llq so that we can
    // write it out later
    cfe             = (RecConfigFileEntry *)ats_malloc(sizeof(RecConfigFileEntry));
    cfe->entry_type = RECE_COMMENT;
    cfe->entry      = ats_strdup(line);
    enqueue(g_rec_config_contents_llq, (void *)cfe);

  L_done:
    line = line_tok.iterNext(&line_tok_state);
    line_num++;
    ats_free(lc);
  }

  ink_mutex_release(&g_rec_config_lock);
  ats_free(fbuf);

  return REC_ERR_OKAY;
}
<|endoftext|>