c: chain Of Responsibility

发布时间 2023-10-28 06:00:05作者: ®Geovin Du Dream Park™

 

/**
 * @file chainOfResponsibility.h
 * @author your name (geovindu)
 * @brief  chain Of Responsibility 职责链模式
 * @version 0.1
 * @date 2023-10-28
 *  IDE: VSCODE C11 C17
 * @copyright Copyright (c) 2023
 * 
 */


#ifndef  _CHAINOFRESPONSIBILITY_H_
#define _CHAINOFRESPONSIBILITY_H_

#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief 检验处理链
 * 
 */
typedef struct ChainDuValidator {
    bool (* const chainDuValidator)
    (struct ChainDuValidator *pThis, int val);
} ChainDuValidator;

/**
 * @brief 
 * 
 */
typedef struct {
    ChainDuValidator base;
    const int min;
    const int max;
} ChainDuRangeValidator;

/**
 * @brief 
 * 
 */
typedef struct {
    ChainDuValidator base;
    int previousValue;
} ChainDuPreviousValueValidator;

/**
 * @brief 
 * 
 */
typedef struct ChainedValidator {
    ChainDuValidator base;
    ChainDuValidator *pWrapped;
    ChainDuValidator *pNext;
} ChainedValidator;

/**
 * @brief 
 * 
 */
typedef struct {
    int top;
    const size_t size;
    int * const pBuf;
    ChainDuValidator * const pValidator;
} Stack;

/**
 * @brief 
 * 
 * @param p 
 * @param val 
 * @return true 
 * @return false 
 */
bool ChainDuvalidateRange(ChainDuValidator *p, int val);

/**
 * @brief 
 * 
 * @param p 
 * @param val 
 * @return true 
 * @return false 
 */
bool ChainDuvalidatePrevious(ChainDuValidator *p, int val);

/**
 * @brief 
 * 
 * @param p 
 * @param val 
 * @return true 
 * @return false 
 */
bool ChainDuvalidateChain(ChainDuValidator *p, int val);

/**
 * @brief 
 * 
 * @param p 
 * @param val 
 * @return true 
 * @return false 
 */
bool ChainDupush(Stack *p, int val);

/**
 * @brief 
 * 
 * @param p 
 * @param pRet 
 * @return true 
 * @return false 
 */
bool ChainDupop(Stack *p, int *pRet);


/**
 * @brief 
 * 
 */
#define DunewRangeValidator(min, max) \
    {{ChainDuvalidateRange}, (min), (max)}

/**
 * @brief 
 * 
 */
#define DunewPreviousValueValidator \
    {{ChainDuvalidatePrevious}, 0}


/**
 * @brief 
 * 
 */
#define DunewChainedValidator(wrapped, next)       \
    {{ChainDuvalidateChain}, (wrapped), (next)}



/**
 * @brief 
 * 
 */
#define newStack(buf) {                  \
    0, sizeof(buf) / sizeof(int), (buf), \
    NULL                                 \
} 

/**
 * @brief 
 * 
 */
#define DunewStackWithValidator(buf, pValidator) { \
    0, sizeof(buf) / sizeof(int), (buf),         \
    pValidator                                   \
}

#ifdef __cplusplus
}
#endif

#endif

  

/**
 * @file chainOfResponsibility.C
 * @author your name (geovindu)
 * @brief  chain Of Responsibility 职责链模式
 * @version 0.1
 * @date 2023-10-28
 * IDE: VSCODE C11 C17
 * @copyright Copyright (c) 2023
 * 
 */

#include "include/chainOfResponsibility.h"
#include <stdbool.h>

/**
 * @brief 
 * 
 * @param p 
 * @return true 
 * @return false 
 */
static bool isStackFull(const Stack *p) {
    return p->top == p->size;
}

/**
 * @brief 
 * 
 * @param p 
 * @return true 
 * @return false 
 */
static bool isStackEmpty(const Stack *p) {
    return p->top == 0;
}

/**
 * @brief 
 * 
 * @param p 
 * @param val 
 * @return true 
 * @return false 
 */
bool ChainDuvalidateRange(ChainDuValidator *p, int val) {
    ChainDuRangeValidator *pThis = (ChainDuRangeValidator *)p;
    return pThis->min <= val && val <= pThis->max;
}

/**
 * @brief 
 * 
 * @param p 
 * @param val 
 * @return true 
 * @return false 
 */
bool ChainDuvalidatePrevious(ChainDuValidator *p, int val) {
    ChainDuPreviousValueValidator *pThis = (ChainDuPreviousValueValidator *)p;
    if (val < pThis->previousValue) return false;
    pThis->previousValue = val;
    return true;
}

/**
 * @brief 
 * 
 * @param p 
 * @param val 
 * @return true 
 * @return false 
 */
bool ChainDuvalidate(ChainDuValidator *p, int val) {
    if (! p) return true;
    return p->chainDuValidator(p, val);
}

// true: 成功, false: 失敗
/**
 * @brief 
 * 
 * @param p 
 * @param val 
 * @return true 
 * @return false 
 */
bool ChainDupush(Stack *p, int val) {
    if (! ChainDuvalidate(p->pValidator, val) || isStackFull(p)) return false;
    p->pBuf[p->top++] = val;
    return true;
}

// true: 成功, false: 失敗

/**
 * @brief 
 * 
 * @param p 
 * @param pRet 
 * @return true 
 * @return false 
 */
bool ChainDupop(Stack *p, int *pRet) {
    if (isStackEmpty(p)) return false;
    *pRet = p->pBuf[--p->top];
    return true;
}

/**
 * @brief 
 * 
 * @param p 
 * @param val 
 * @return true 
 * @return false 
 */
bool ChainDuvalidateChain(ChainDuValidator *p, int val) {
    ChainedValidator *pThis = (ChainedValidator *)p;

    p = pThis->pWrapped;
    if (! p->chainDuValidator(p, val)) return false;

    p = pThis->pNext;
    return !p || p->chainDuValidator(p, val);
}

  

typedef struct TestValidator {
    Validator base;
    bool result;
} TestValidator;


static bool validateTest(Validator *p, int val) {
        TestValidator *pThis = (TestValidator *)p;
        return pThis->result;
}


static TestValidator trueValidator = {{validateTest}, true};
static TestValidator falseValidator = {{validateTest}, false};



int main(void)
{
    printf("hello c world, \n");
    printf("你好,中国\n");



    RangeValidator rangeValidator = DunewRangeValidator(0, 9);
    PreviousValueValidator prevValidator = DunewPreviousValueValidator;

    ChainedValidator prevChain = DunewChainedValidator(&prevValidator.base, NULL);
    ChainedValidator rangeChain = DunewChainedValidator(&rangeValidator.base, &prevChain.base);

    //int buf[16]={1,2,4,3,5,7,8};
    //Stack stack = DunewStackWithValidator(buf, &rangeChain.base);
    //false, ChainDupush(&stack, -1)
    //ChainDupush(&stack, -1); 
   return 0:
}