<commit_before>/*! \file ucommandqueue.cc
 *******************************************************************************

 File: ucommandqueue.cc\n
 Implementation of the UCommandQueue class.

 This file is part of
 %URBI Kernel, version __kernelversion__\n
 (c) <NAME>, 2004-2005.

 Permission to use, copy, modify, and redistribute this software for
 non-commercial use is hereby granted.

 This software is provided "as is" without warranty of any kind,
 either expressed or implied, including but not limited to the
 implied warranties of fitness for a particular purpose.

 For more information, comments, bug reports: http://www.urbiforge.net

 **************************************************************************** */

#include <cstdlib>
#include "libport/cstring"

#include "uqueue.hh"
#include "ucommandqueue.hh"
#include "userver.hh"

//! UCommandQueue constructor.
/*! UCommandQueue constructor simply calls the UQueue constructor with the same
    behavior.
*/
UCommandQueue::UCommandQueue  (int minBufferSize,
			       int maxBufferSize,
			       int adaptive)
  : UQueue (minBufferSize, maxBufferSize, adaptive),
    cursor_         (0),
    bracketlevel_   (0),
    sbracketlevel_  (0),
    parenlevel_     (0),
    discard_        (false),
    closechar_      (' '),
    closechar2_     (' ')
{
  ADDOBJ(UCommandQueue);
  FREEOBJ(UQueue); // A tester.
}

//! UCommandQueue destructor.
UCommandQueue::~UCommandQueue()
{
  ADDOBJ(UQueue);
  FREEOBJ(UCommandQueue);
}


//! Pops the next command in the queue.
/*! popCommand scan the buffer to a terminating ',' or ';' symbol by removing
    any text between:

    - { and }
    - [ and ]
    - / * and * /
    - // and \\n
    - # and \\n
    - (and )

    This function is interruptible which means that is does not rescan the
    entire buffer from the start each time it is called, but it stores it's
    internal state before quitting and starts again where it left. This
    is important when the buffer comes from a TCP/IP entry connection where
    instructions typically arrive in several shots.

    The final ',' or ';' is the last character of the popped data.

    \param length the length of the extracted command. zero means "no command
	   is available yet".
    \return a pointer to the the data popped or 0 in case of error.
*/
ubyte*
UCommandQueue::popCommand (int &length)
{
  if (dataSize_ == 0)
  {
    length = 0;
    return buffer_;
  }

  // Scanning
  int position = start_ + cursor_;
  if (position >= bufferSize_)
    position = position - bufferSize_;

  int nextposition = position + 1;
  if (nextposition >= bufferSize_)
    nextposition = nextposition - bufferSize_;

  int previousposition = position - 1;
  if (previousposition < 0)
    previousposition = previousposition + bufferSize_;
  char p0 = (char) buffer_[previousposition]; // extract the previous char.
  if (cursor_ == 0)
    // no previous char at start
    p0 = ' ';

  bool found = false;
  while (cursor_ < dataSize_ && !found)
  {
    char p_1 = p0;
    p0 = (char) buffer_[position];
    char p1 = (cursor_ < dataSize_ - 1) ? (char) buffer_[nextposition] : '-';

    if (discard_)
    {
      // One char close sequence
      if (p0 == closechar_ && closechar2_ == ' ')
	discard_ = closechar_ == '"' && p_1 == '\\'

      // Two chars close sequence
      if (p_1 == closechar_ && p0  == closechar2_ && closechar2_ != ' ')
	discard_ = false;
    }
    else
    {
      switch (p0)
      {
	case '{':
	  ++bracketlevel_;
	  break;
	case '}':
	  --bracketlevel_;
	  if (bracketlevel_ < 0)
	    bracketlevel_ = 0;
	  break;
	case '[':
	  ++sbracketlevel_;
	  break;
	case ']':
	  --sbracketlevel_;
	  if (sbracketlevel_ < 0)
	    sbracketlevel_ = 0;
	  break;
	case '(':
	  ++parenlevel_;
	  break;
	case ')':
	  --parenlevel_;
	  if (parenlevel_ < 0)<commit_msg>Fix typo in previous patch.<commit_after>/*! \file ucommandqueue.cc
 *******************************************************************************

 File: ucommandqueue.cc\n
 Implementation of the UCommandQueue class.

 This file is part of
 %URBI Kernel, version __kernelversion__\n
 (c) <NAME>, 2004-2005.

 Permission to use, copy, modify, and redistribute this software for
 non-commercial use is hereby granted.

 This software is provided "as is" without warranty of any kind,
 either expressed or implied, including but not limited to the
 implied warranties of fitness for a particular purpose.

 For more information, comments, bug reports: http://www.urbiforge.net

 **************************************************************************** */

#include <cstdlib>
#include "libport/cstring"

#include "uqueue.hh"
#include "ucommandqueue.hh"
#include "userver.hh"

//! UCommandQueue constructor.
/*! UCommandQueue constructor simply calls the UQueue constructor with the same
    behavior.
*/
UCommandQueue::UCommandQueue  (int minBufferSize,
			       int maxBufferSize,
			       int adaptive)
  : UQueue (minBufferSize, maxBufferSize, adaptive),
    cursor_         (0),
    bracketlevel_   (0),
    sbracketlevel_  (0),
    parenlevel_     (0),
    discard_        (false),
    closechar_      (' '),
    closechar2_     (' ')
{
  ADDOBJ(UCommandQueue);
  FREEOBJ(UQueue); // A tester.
}

//! UCommandQueue destructor.
UCommandQueue::~UCommandQueue()
{
  ADDOBJ(UQueue);
  FREEOBJ(UCommandQueue);
}


//! Pops the next command in the queue.
/*! popCommand scan the buffer to a terminating ',' or ';' symbol by removing
    any text between:

    - { and }
    - [ and ]
    - / * and * /
    - // and \\n
    - # and \\n
    - (and )

    This function is interruptible which means that is does not rescan the
    entire buffer from the start each time it is called, but it stores it's
    internal state before quitting and starts again where it left. This
    is important when the buffer comes from a TCP/IP entry connection where
    instructions typically arrive in several shots.

    The final ',' or ';' is the last character of the popped data.

    \param length the length of the extracted command. zero means "no command
	   is available yet".
    \return a pointer to the the data popped or 0 in case of error.
*/
ubyte*
UCommandQueue::popCommand (int &length)
{
  if (dataSize_ == 0)
  {
    length = 0;
    return buffer_;
  }

  // Scanning
  int position = start_ + cursor_;
  if (position >= bufferSize_)
    position = position - bufferSize_;

  int nextposition = position + 1;
  if (nextposition >= bufferSize_)
    nextposition = nextposition - bufferSize_;

  int previousposition = position - 1;
  if (previousposition < 0)
    previousposition = previousposition + bufferSize_;
  char p0 = (char) buffer_[previousposition]; // extract the previous char.
  if (cursor_ == 0)
    // no previous char at start
    p0 = ' ';

  bool found = false;
  while (cursor_ < dataSize_ && !found)
  {
    char p_1 = p0;
    p0 = (char) buffer_[position];
    char p1 = (cursor_ < dataSize_ - 1) ? (char) buffer_[nextposition] : '-';

    if (discard_)
    {
      // One char close sequence
      if (p0 == closechar_ && closechar2_ == ' ')
	discard_ = closechar_ == '"' && p_1 == '\\';

      // Two chars close sequence
      if (p_1 == closechar_ && p0  == closechar2_ && closechar2_ != ' ')
	discard_ = false;
    }
    else
    {
      switch (p0)
      {
	case '{':
	  ++bracketlevel_;
	  break;
	case '}':
	  --bracketlevel_;
	  if (bracketlevel_ < 0)
	    bracketlevel_ = 0;
	  break;
	case '[':
	  ++sbracketlevel_;
	  break;
	case ']':
	  --sbracketlevel_;
	  if (sbracketlevel_ < 0)
	    sbracketlevel_ = 0;
	  break;
	case '(':
	  ++parenlevel_;
	  break;
	case ')':
	  --parenlevel_;
	  if (parenlevel_ < 0)
{'fraction_non_alphanumeric': 0.14547820429407937, 'fraction_numerical': 0.01040988939492518, 'mean_word_length': 2.949640287769784, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 11, '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': '4471936', 'n_tokens_mistral': 2470, 'n_tokens_neox': 2276, 'n_words': 781}