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

📄 esc_seq.cpp

📁 使用BorlandC++4.5编译的一个MUD客户端程序
💻 CPP
字号:
// esc_seq.cpp - escape sequence parser methods

#include <stdio.h>
#include <string.h>

#include "debug.hpp"
#include "esc_seq.hpp"

// These will need some adjustment to parse out the position code

static const char   ESCAPE = 27; // VT102 command prefix - escape

// ------------------------------------------------------------------------
// constructor
//
//   buf - null-terminated string
//
// The sense of the parser is that a function returns nonzero if it
// successfully parsed part of an escape sequence.
// -  Functions internally set the _isComplete to true if they
//    complete a sequence, and set _type appropriately.
// -  Functions that increment the buffer pointer are responsible for
//    checking for end of string.

EscapeSequence::EscapeSequence(char * buf)
: _type(NONE),
  _isComplete(0),
  _isEscapeSequence(1),
  _nParameters(0)
{
    ASSERT(NULL != buf, "Null pointer forbidden");
    
    if (_EndOfString(buf))       // Empty string?
        _isEscapeSequence = 0;
    else if (0 == _ParseEscapeSequence(buf))
        _isEscapeSequence = 0;
}

// ------------------------------------------------------------------------
// _SetType - sets the type for this, and assumes that it is now complete!
void EscapeSequence::_SetType(_Type type)
{
    _type = type;
    _isComplete = 1;
}

int EscapeSequence::_ParseEscapeSequence(char * buf)
{
    if (*buf == ESCAPE)
    {
        ++ buf; // Great!  Parsed a character
        if (_EndOfString(buf))
            return 1;           // Valid, but end of string

        return (_ScrollReverse(buf)
                || _LeftSquareBracket(buf));
    };
    return 0; // Not escape sequence
}

// ------------------------------------------------------------------------
// _ScrollReverse -- This is actually the reverse-newline sequence
//
int EscapeSequence::_ScrollReverse(char * buf)
{
    if (*buf == 'M')       // Reverse scroll code?
    {
        _SetType(REV_NEWLINE);
        return 1;
    };
    return 0;
}

// ------------------------------------------------------------------------
// Most escape sequences are prefixed by "Esc-["
//
int EscapeSequence::_LeftSquareBracket(char * buf)
{
    int ret_val = 0;       // Default is to assume that this is invalid
    
    if (*buf != '\[')
        ret_val = 0;
    else
    {    
        ++ buf;
        if (_EndOfString(buf))         // No more string
            ret_val = 1;
        else if (0 == _GetParameters(&buf)) // Not a valid sequence?
            ret_val = 0;
        else if (_EndOfString(buf)) // No terminator, not finished
            ret_val = 1;
        else
        {
            switch (*buf)          // Get type from terminator
            {
              case 'J':            // Might be a clear screen if parameter = 2
                if (1 == ParameterCount() && Parameter(0) == 2)
                {
                    _SetType(CLRSCR);
                    ret_val = 1;
                };
                break;
                
              case 'K':                // CLREOL
                if (0 == _nParameters) // Must have no parameters
                {
                    _SetType(CLREOL);
                    ret_val = 1;
                };
                break;
                
              case 'H':                        // Cursor move
                if (2 == ParameterCount())     // Exactly two parameters?
                {
                    _SetType(CMOVE);
                    ret_val = 1;
                };
                break;
                
              case 'r':                    // Set scroll region 
                if (2 == ParameterCount()) // Exactly two parameters?
                {
                    _SetType(SCROLL);
                    ret_val = 1;
                };
                break;
                
              case 'm':            // Ansi screen color/attribute sequence
                _SetType(ANSI_COLOR);
                ret_val = 1; 
                break;
                
              default:             // Not escape sequence
                break;
            };
        };
    };
    return ret_val; // No match
}
        
// ------------------------------------------------------------------------
// _GetParameters - Count the parameters.
//
// Leaves the pointer buf pointing at the first character after the
// parameters, which may be end-of-string.
//
// Returns:
//   zero if for some reason this can't be an escape sequence
//
int EscapeSequence::_GetParameters(char ** buf)
{
    ASSERT(NULL != buf, "Invalid pointer?");
    ASSERT(NULL != *buf, "Invalid string?");
    
    int ret_val = 1; // So far, this is an escape sequence

    int value;           // Scanned numeric value
    int chars_read;      // Number of characters scanned from string
    int fields_scanned;  // Number of fields matched
    while (1)          // Loop forever
    {
        // Check for integer value first
        
        fields_scanned = sscanf(*buf, "%d%n", &value, &chars_read);
        if (0 == fields_scanned) // Nothing scanned
            break;
        else if (1 == fields_scanned)
        {
            if (_nParameters >= 20)
            {
                // Give up on this escape sequence--too many parameters.
                ret_val = 0; 
                break;
            };
            _parameters[_nParameters] = value;
            ++ _nParameters;
            *buf += chars_read; // Move to next parameter
        };

        // Check for semicolon or terminator
        if (_EndOfString(*buf))          // End of string, not finished
            break;
        else if (**buf == ';')           // Another parameter?
            ++ *buf;                     // Keep going
        else
            break;                       // No more parameters, exit
    };
    return ret_val; 
}

// EOF //

⌨️ 快捷键说明

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