<commit_before>// This file may be redistributed and modified only under the terms of
// the GNU Lesser General Public License (See COPYING for details).
// Copyright (C) 2000-2001 <NAME>, <NAME>

#ifndef ATLAS_FILTER_H
#define ATLAS_FILTER_H

#include "config.h"

#include <string>

#ifdef HAVE_STREAMBUF
#include <streambuf>
#else
#include <streambuf.h>
#endif

#include <cstring>
// for memcpy

namespace Atlas {

/** Atlas stream filter

Filters are used by Codec to transform the byte stream before transmission.
The transform must be invertible; that is to say, encoding a string and then
decoding it must result in the original string. Filters can be used for
compression, encryption or performing checksums and other forms of
transmission error detection. A compound filter can be created that acts like
a single filter, allowing various filters to be chained together in useful
ways such as compressing and then encrypting.

@see Codec
@see Negotiate
*/

class Filter
{
    public:
   
    Filter(Filter* = 0);
    virtual ~Filter();

    virtual void begin() = 0;
    virtual void end() = 0;

    virtual std::string encode(const std::string&) = 0;
    virtual std::string decode(const std::string&) = 0;

    enum Type
    {
	CHECKSUM,
	COMPRESSION,
	ENCRYPTION,
    };

    protected:

    Filter* next;
};

#ifdef HAVE_STREAMBUF
class filterbuf : public std::streambuf {
#else
typedef int int_type;

class filterbuf : public streambuf {
#endif
public:

  filterbuf(std::streambuf& buffer,
            Filter& filter)
   : m_streamBuffer(buffer), m_filter(filter)
  {
    setp(m_outBuffer, m_outBuffer + (m_outBufferSize - 1));
    setg(m_inBuffer + m_inPutback, m_inBuffer + m_inPutback,
         m_inBuffer + m_inPutback);
  }
  
  virtual ~filterbuf()
  {
    sync();
  }
  
protected:
  static const int m_outBufferSize = 10;
  char m_outBuffer[m_outBufferSize];

  static const int m_inBufferSize = 10;
  static const int m_inPutback = 4;
  char m_inBuffer[m_inBufferSize];

  int flushOutBuffer()
  {
    int num = pptr() - pbase();
    std::string encoded = m_filter.encode(std::string(pbase(), pptr()));
    m_streamBuffer.sputn(encoded.c_str(), encoded.size());
    pbump(-num);
    return num;
  }  
  
  virtual int_type overflow(int_type c)
  {
    if (c != EOF) {
      *pptr() = c;
      pbump(1);
    }
    if (flushOutBuffer() == EOF) return EOF;
    return c;
  }

  virtual int_type underflow()
  {
    if (gptr() < egptr()) return *gptr();
    
    int numPutback = gptr() - eback();

    if (numPutback > m_inPutback) numPutback = m_inPutback;

    std::memcpy(m_outBuffer + (m_inPutback - numPutback),
                gptr() - numPutback,
                numPutback);

    int num;

    //     FIXME
    // Here we need to actually
    //  * get data from m_streamBuffer
    //  * encode it with m_filter
    //  * put _that_ into the buffer
    //
    // Currently it just fetches it and places it straight in the
    // buffer.
    // The problem is the limited size of the buffer with the
    // Filter::decode operation not having any kind of size
    // limitation.
    num = m_streamBuffer.sgetn(m_inBuffer + m_inPutback,
                               m_inBufferSize - m_inPutback);<commit_msg>Removed an extra comma from the Type declaration. Added some casts. Added a todo comment complaining about the huge inline methods.<commit_after>// This file may be redistributed and modified only under the terms of
// the GNU Lesser General Public License (See COPYING for details).
// Copyright (C) 2000-2001 <NAME>, <NAME>

#ifndef ATLAS_FILTER_H
#define ATLAS_FILTER_H

#include "config.h"

#include <string>

#ifdef HAVE_STREAMBUF
#include <streambuf>
#else
#include <streambuf.h>
#endif

#include <cstring>
// for memcpy

namespace Atlas {

/** Atlas stream filter

Filters are used by Codec to transform the byte stream before transmission.
The transform must be invertible; that is to say, encoding a string and then
decoding it must result in the original string. Filters can be used for
compression, encryption or performing checksums and other forms of
transmission error detection. A compound filter can be created that acts like
a single filter, allowing various filters to be chained together in useful
ways such as compressing and then encrypting.

@see Codec
@see Negotiate
*/

class Filter
{
    public:
   
    Filter(Filter* = 0);
    virtual ~Filter();

    virtual void begin() = 0;
    virtual void end() = 0;

    virtual std::string encode(const std::string&) = 0;
    virtual std::string decode(const std::string&) = 0;

    enum Type
    {
	CHECKSUM,
	COMPRESSION,
	ENCRYPTION
    };

    protected:

    Filter* next;
};

#ifdef HAVE_STREAMBUF
class filterbuf : public std::streambuf {
#else
typedef int int_type;

class filterbuf : public streambuf {
#endif
public:

  filterbuf(std::streambuf& buffer,
            Filter& filter)
   : m_streamBuffer(buffer), m_filter(filter)
  {
    setp(m_outBuffer, m_outBuffer + (m_outBufferSize - 1));
    setg(m_inBuffer + m_inPutback, m_inBuffer + m_inPutback,
         m_inBuffer + m_inPutback);
  }
  
  virtual ~filterbuf()
  {
    sync();
  }
  
protected:
  static const int m_outBufferSize = 10;
  char m_outBuffer[m_outBufferSize];

  static const int m_inBufferSize = 10;
  static const int m_inPutback = 4;
  char m_inBuffer[m_inBufferSize];

  int flushOutBuffer()
  {
    int num = pptr() - pbase();
    std::string encoded = m_filter.encode(std::string(pbase(), pptr()));
    m_streamBuffer.sputn(encoded.c_str(), (long) encoded.size());
    pbump(-num);
    return num;
  }  
  
  virtual int_type overflow(int_type c)
  {
    if (c != EOF) {
      *pptr() = (char) c;
      pbump(1);
    }
    if (flushOutBuffer() == EOF) return EOF;
    return c;
  }

   /*%TODO(Jesse,Atlas,filterbuf)
   * It's bad style to put non-trivial amounts of code inside class declarations. It:
   * 1) Clutters up the declaration. This is bad because the declaration is the place
   * people go to to find out how to use your class.
   * 2) The compiler won't actually inline virtual methods or methods that it decides
   * are too complex. This means that every compilation unit that includes the header
   * will have its own copy of the generated code which slows the compilation and linking
   * down (the linker will strip out the duplicates so it shouldn't affect the exe).
   */
  virtual int_type underflow()
  {
    using namespace std;
    if (gptr() < egptr()) return *gptr();
    
    int numPutback = gptr() - eback();

    if (numPutback > m_inPutback) numPutback = m_inPutback;

    memcpy(m_outBuffer + (m_inPutback - numPutback),
                gptr() - numPutback,
                (unsigned long) numPutback);

    int num;

    //     FIXME
    // Here we need to actually
    //  * get data from m_streamBuffer
    //  * encode it with m_filter
    //  * put _that_ into the buffer
    //
    // Currently it just fetches it and places it straight in the
    // buffer.
    // The problem is the limited size of the buffer with the
    // Filter::decode operation not having any kind of size
    // limitation.
    num = m_streamBuffer.sgetn(m_inBuffer + m_inPutback,
                               m_inBufferSize - m_inPutback);
{'fraction_non_alphanumeric': 0.09286601352283703, 'fraction_numerical': 0.00579550158686353, 'mean_word_length': 3.0177383592017737, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, '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': '6908178', 'n_tokens_mistral': 2339, 'n_tokens_neox': 2246, 'n_words': 794}