<commit_before>/*
 * Copyright 2006-2008 The FLWOR Foundation.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ZORBA_TRANSCODE_STREAMBUF_API_H
#define ZORBA_TRANSCODE_STREAMBUF_API_H

#include <stdexcept>
#include <streambuf>
#include <string>

#include <zorba/config.h>
#include <zorba/internal/proxy.h>
#include <zorba/internal/unique_ptr.h>

namespace zorba {

typedef internal::ztd::proxy<std::streambuf> proxy_streambuf;

///////////////////////////////////////////////////////////////////////////////

/**
 * A %transcode_streambuf is-a std::streambuf for transcoding character
 * encodings from/to UTF-8 on-the-fly.
 *
 * To use it, replace a stream's streambuf:
 * \code
 *  istream is;
 *  // ...
 *  transcode_streambuf tbuf( "ISO-8859-1", is.rdbuf() );
 *  is.ios::rdbuf( &tbuf );
 * \endcode
 * Note that the %transcode_streambuf must exist for as long as it's being used
 * by the stream.  If you are replacing the streabuf for a stream you did not
 * create, you should set it back to the original streambuf:
 * \code
 *  void f( ostream &os ) {
 *    transcode_streambuf tbuf( "ISO-8859-1", os.rdbuf() );
 *    try {
 *      os.ios::rdbuf( &tbuf );
 *      // ...
 *    }
 *    catch ( ... ) {
 *      os.ios::rdbuf( tbuf.orig_streambuf() );
 *      throw;
 *    }
 *  }
 * \endcode
 *
 * While %transcode_streambuf does support seeking, the positions are relative
 * to the original byte stream.
 */
class ZORBA_DLL_PUBLIC transcode_streambuf : public std::streambuf {
public:
  /**
   * Base %exception class.
   */
  class exception : public std::exception {
  public:
    exception( std::string const &message );
    ~exception() throw();
    char const* what() const throw();
  private:
    std::string message_;
  };

  /**
   * Constructs a %transcode_streambuf.
   *
   * @param charset The name of the character encoding to convert from/to.
   * @param orig The original streambuf to read/write from/to.
   */
  transcode_streambuf( char const *charset, std::streambuf *orig );

  /**
   * Destructs a %transcode_streambuf.
   */
  ~transcode_streambuf();

  /**
   * Gets the original streambuf.
   *
   * @return Returns said streambuf.
   */
  std::streambuf* orig_streambuf() const {
    return intern_buf_->original();
  }

protected:
  void imbue( std::locale const& );
  pos_type seekoff( off_type, std::ios_base::seekdir, std::ios_base::openmode );
  pos_type seekpos( pos_type, std::ios_base::openmode );
  std::streambuf* setbuf( char_type*, std::streamsize );
  std::streamsize showmanyc();
  int sync();
  int_type overflow( int_type );
  int_type pbackfail( int_type );
  int_type uflow();
  int_type underflow();<commit_msg>Doxygen update.<commit_after>/*
 * Copyright 2006-2008 The FLWOR Foundation.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ZORBA_TRANSCODE_STREAMBUF_API_H
#define ZORBA_TRANSCODE_STREAMBUF_API_H

#include <stdexcept>
#include <streambuf>
#include <string>

#include <zorba/config.h>
#include <zorba/internal/proxy.h>
#include <zorba/internal/unique_ptr.h>

namespace zorba {

typedef internal::ztd::proxy<std::streambuf> proxy_streambuf;

///////////////////////////////////////////////////////////////////////////////

/**
 * A %transcode_streambuf is-a std::streambuf for transcoding character
 * encodings from/to UTF-8 on-the-fly.
 *
 * To use it, replace a stream's streambuf:
 * \code
 *  istream is;
 *  // ...
 *  transcode_streambuf tbuf( "ISO-8859-1", is.rdbuf() );
 *  is.ios::rdbuf( &tbuf );
 * \endcode
 * Note that the %transcode_streambuf must exist for as long as it's being used
 * by the stream.  If you are replacing the streabuf for a stream you did not
 * create, you should set it back to the original streambuf:
 * \code
 *  void f( ostream &os ) {
 *    transcode_streambuf tbuf( "ISO-8859-1", os.rdbuf() );
 *    try {
 *      os.ios::rdbuf( &tbuf );
 *      // ...
 *    }
 *    catch ( ... ) {
 *      os.ios::rdbuf( tbuf.orig_streambuf() );
 *      throw;
 *    }
 *  }
 * \endcode
 *
 * While %transcode_streambuf does support seeking, the positions are relative
 * to the original byte stream.
 */
class ZORBA_DLL_PUBLIC transcode_streambuf : public std::streambuf {
public:
  /**
   * Base %exception class.
   */
  class exception : public std::exception {
  public:
    exception( std::string const &message );
    ~exception() throw();
    char const* what() const throw();
  private:
    std::string message_;
  };

  /**
   * Constructs a %transcode_streambuf.
   *
   * @param charset The name of the character encoding to convert from/to.
   * @param orig The original streambuf to read/write from/to.
   * @throws std::invalid_argument if either \a charset is not supported or
   * \a orig is null.
   */
  transcode_streambuf( char const *charset, std::streambuf *orig );

  /**
   * Destructs a %transcode_streambuf.
   */
  ~transcode_streambuf();

  /**
   * Gets the original streambuf.
   *
   * @return Returns said streambuf.
   */
  std::streambuf* orig_streambuf() const {
    return intern_buf_->original();
  }

protected:
  void imbue( std::locale const& );
  pos_type seekoff( off_type, std::ios_base::seekdir, std::ios_base::openmode );
  pos_type seekpos( pos_type, std::ios_base::openmode );
  std::streambuf* setbuf( char_type*, std::streamsize );
  std::streamsize showmanyc();
  int sync();
  int_type overflow( int_type );
  int_type pbackfail( int_type );
  int_type uflow();
  int_type underflow();
{'fraction_non_alphanumeric': 0.1414656771799629, 'fraction_numerical': 0.007111935683364255, 'mean_word_length': 3.1467948717948717, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1990877', 'n_tokens_mistral': 2075, 'n_tokens_neox': 2084, 'n_words': 628}