⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 charsetdecoder.cpp

📁 log4cxx 0.10 unix下编译包
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
 * 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 <log4cxx/logstring.h>
#include <log4cxx/helpers/charsetdecoder.h>
#include <log4cxx/helpers/bytebuffer.h>
#include <log4cxx/helpers/exception.h>
#include <log4cxx/helpers/mutex.h>
#include <log4cxx/helpers/synchronized.h>
#include <log4cxx/helpers/pool.h>
#include <apr_xlate.h>
#if !defined(LOG4CXX)
#define LOG4CXX 1
#endif
#include <log4cxx/private/log4cxx_private.h>
#include <locale.h>
#include <apr_portable.h>
#include <log4cxx/helpers/stringhelper.h>
#include <log4cxx/helpers/transcoder.h>

using namespace log4cxx;
using namespace log4cxx::helpers;

IMPLEMENT_LOG4CXX_OBJECT(CharsetDecoder)


namespace log4cxx
{
        namespace helpers {

#if APR_HAS_XLATE
          /**
           *  Converts from an arbitrary encoding to LogString
           *    using apr_xlate.  Requires real iconv implementation,
         *    apr-iconv will crash in use.
           */
          class APRCharsetDecoder : public CharsetDecoder
          {
          public:
           /**
            *  Creates a new instance.
            *  @param frompage name of source encoding.
            */
              APRCharsetDecoder(const LogString& frompage) : pool(), mutex(pool) {
#if LOG4CXX_LOGCHAR_IS_WCHAR
                const char* topage = "WCHAR_T";
#endif
#if LOG4CXX_LOGCHAR_IS_UTF8
                const char* topage = "UTF-8";
#endif
#if LOG4CXX_LOGCHAR_IS_UNICHAR
                const char* topage = "UTF-16";
#endif
                std::string fpage(Transcoder::encodeCharsetName(frompage));
                apr_status_t stat = apr_xlate_open(&convset,
                    topage,
                    fpage.c_str(),
                    pool.getAPRPool());
                if (stat != APR_SUCCESS) {
                    throw IllegalArgumentException(frompage);
                }
              }

           /**
            *  Destructor.
            */
              virtual ~APRCharsetDecoder() {
              }

              virtual log4cxx_status_t decode(ByteBuffer& in,
                  LogString& out) {
                  enum { BUFSIZE = 256 };
                  logchar buf[BUFSIZE];
                  const apr_size_t initial_outbytes_left = BUFSIZE * sizeof(logchar);
                  apr_status_t stat = APR_SUCCESS;
                  if (in.remaining() == 0) {
                    size_t outbytes_left = initial_outbytes_left;
                    {
                      synchronized sync(mutex);
                      stat = apr_xlate_conv_buffer((apr_xlate_t*) convset,
                        NULL, NULL, (char*) buf, &outbytes_left);
                    }
                    out.append(buf, (initial_outbytes_left - outbytes_left)/sizeof(logchar));
                  } else {
                    while(in.remaining() > 0 && stat == APR_SUCCESS) {
                      size_t inbytes_left = in.remaining();
                      size_t initial_inbytes_left = inbytes_left;
                      size_t pos = in.position();
                      apr_size_t outbytes_left = initial_outbytes_left;
                      {
                        synchronized sync(mutex);
                        stat = apr_xlate_conv_buffer((apr_xlate_t*) convset,
                           in.data() + pos,
                           &inbytes_left,
                           (char*) buf,
                           &outbytes_left);
                      }
                      out.append(buf, (initial_outbytes_left - outbytes_left)/sizeof(logchar));
                      in.position(pos + (initial_inbytes_left - inbytes_left));
                    }
                  }
                  return stat;
              }

          private:
                  APRCharsetDecoder(const APRCharsetDecoder&);
                  APRCharsetDecoder& operator=(const APRCharsetDecoder&);
                  log4cxx::helpers::Pool pool;
                  Mutex mutex;
                  apr_xlate_t *convset;
          };
          
#endif

#if LOG4CXX_LOGCHAR_IS_WCHAR && LOG4CXX_HAS_MBSRTOWCS
          /**
          *    Converts from the default multi-byte string to
          *        LogString using mbstowcs.
          *
          */
          class MbstowcsCharsetDecoder : public CharsetDecoder
          {
          public:
              MbstowcsCharsetDecoder() {
              }

              virtual ~MbstowcsCharsetDecoder() {
              }

          private:
              inline log4cxx_status_t append(LogString& out, const wchar_t* buf) {
                  out.append(buf);
                  return APR_SUCCESS;
              }

              virtual log4cxx_status_t decode(ByteBuffer& in,
                  LogString& out) {
                  log4cxx_status_t stat = APR_SUCCESS;
                  enum { BUFSIZE = 256 };
                  wchar_t buf[BUFSIZE];

                  mbstate_t mbstate;
                  memset(&mbstate, 0, sizeof(mbstate));

                  while(in.remaining() > 0) {
                      size_t requested = in.remaining();
                      if (requested > BUFSIZE - 1) {
                          requested = BUFSIZE - 1;
                      }

                      memset(buf, 0, BUFSIZE*sizeof(wchar_t));
                      const char* src = in.current();
                      if(*src == 0) {
                           out.append(1, (logchar) 0);
                           in.position(in.position() + 1);
                      } else {
                           size_t converted = mbsrtowcs(buf,
                               &src,
                               requested,
                               &mbstate);
                           if (converted == (size_t) -1) {
                               stat = APR_BADARG;
                               in.position(src - in.data());
                               break;
                           } else {
                               stat = append(out, buf);
                               in.position(in.position() + converted);
                           }
                      }
                  }
                  return stat;
              }



          private:
                  MbstowcsCharsetDecoder(const MbstowcsCharsetDecoder&);
                  MbstowcsCharsetDecoder& operator=(const MbstowcsCharsetDecoder&);
          };
#endif


          /**
          *    Decoder used when the external and internal charsets
          *    are the same.
          *
          */
          class TrivialCharsetDecoder : public CharsetDecoder
          {
          public:
              TrivialCharsetDecoder() {
              }

              virtual ~TrivialCharsetDecoder() {
              }

              virtual log4cxx_status_t decode(ByteBuffer& in,
                  LogString& out) {
                  size_t remaining = in.remaining();
              if( remaining > 0) {
               const logchar* src = (const logchar*) (in.data() + in.position());
               size_t count = remaining / sizeof(logchar);
               out.append(src, count);
               in.position(in.position() + remaining);
              }
                  return APR_SUCCESS;
              }



          private:
                  TrivialCharsetDecoder(const TrivialCharsetDecoder&);
                  TrivialCharsetDecoder& operator=(const TrivialCharsetDecoder&);
          };


#if LOG4CXX_LOGCHAR_IS_UTF8
typedef TrivialCharsetDecoder UTF8CharsetDecoder;
#else
/**
*    Converts from UTF-8 to std::wstring
*
*/
class UTF8CharsetDecoder : public CharsetDecoder
{
public:
    UTF8CharsetDecoder() {
    }

    virtual ~UTF8CharsetDecoder() {
    }

private:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -