/**
* @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:
}