RedisModule/source/moduleiec.c

250 lines
7.2 KiB
C
Raw Normal View History

2024-08-30 09:53:12 +08:00
/*
** ASDU
**
**
** Key: info_<PubIdx>_<InfoIdx>
** Field: ···
**
**
** PubIdx-->InfoIdx-->Info(bytes)
*/
#include <string.h>
#include "../include/redismodule.h"
#include "../include/moduleiec.h"
Info ***Idx2Infos;
int updateInfos(const char * str);
int IECSetVar(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
// 校验参数
if (argc < 1+1) {
RedisModule_WrongArity(ctx);
return REDISMODULE_ERR;
}
// 处理参数
for (int i = 1; i < argc; i++) {
// 轻解构 --> Info *info
if (updateInfos(argv[i]) == 0) {
return REDISMODULE_ERR;
}
}
RedisModule_ReplyWithLongLong(ctx, argc);
return REDISMODULE_OK;
}
//
int IECGetAll(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
// 校验参数: 公共地址 + 信息体地址/偏移量
if (argc < 1+2) {
RedisModule_WrongArity(ctx);
return REDISMODULE_ERR;
}
// 初始化处理参数
long long pubIdx = -1;
long long infoIdx = -1;
RedisModule_StringToLongLong(argv[1], &pubIdx);
if (pubIdx < 0 || pubIdx >= PUB_IDX_COUNT) {
RedisModule_WrongArity(ctx);
return REDISMODULE_ERR;
}
RedisModule_StringToLongLong(argv[2], &infoIdx);
if (infoIdx < 0 || infoIdx >= INFO_IDX_COUNT) {
RedisModule_WrongArity(ctx);
return REDISMODULE_ERR;
}
// 处理计算数据
struct Info **infos = Idx2Infos[pubIdx];
if (infos == NULL) {
RedisModule_WrongArity(ctx);
return REDISMODULE_ERR;
}
struct Info *info = infos[infoIdx];
if (info == NULL) {
RedisModule_ReplyWithNull(ctx);
return REDISMODULE_OK;
}
//
char key[128];
sprintf(key, "info_%d_%d", pubIdx, infoIdx); // TODO
RedisModuleCallReply *reply = RedisModule_Call(ctx, "HGETALL", "s", key);
// 检查回复类型
if (RedisModule_CallReplyType(reply) != REDISMODULE_REPLY_ARRAY) {
// 错误处理...
}
// 回复数据
RedisModule_ReplyWithArray(ctx, VAR_IDX_COUNT); // TODO
RedisModule_ReplyWithString(ctx,info->cause);
RedisModule_ReplyWithString(ctx,info->info);
RedisModule_ReplyWithString(ctx,info->tms);
// 遍历回复中的每一对键值
for (size_t i = 0; i < RedisModule_CallReplyLength(reply); i += 2) {
RedisModuleCallReply *keyReply = RedisModule_CallReplyArrayElement(reply, i);
RedisModuleCallReply *valueReply = RedisModule_CallReplyArrayElement(reply, i + 1);
// 获取键和值
RedisModuleString *keyStr = RedisModule_CreateStringFromCallReply(keyReply);
RedisModuleString *valueStr = RedisModule_CreateStringFromCallReply(valueReply);
// 使用键和值...
// 释放字符串对象
RedisModule_FreeString(ctx, keyStr);
RedisModule_FreeString(ctx, valueStr);
}
// 释放回复对象
RedisModule_FreeCallReply(reply);
return REDISMODULE_OK;
}
//
int IECGetVar(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
// 校验参数: 公共地址 + 信息体地址/偏移量 + field
if (argc < 1+2) {
RedisModule_WrongArity(ctx);
return REDISMODULE_ERR;
}
// 初始化处理参数
long long pubIdx = -1;
long long infoIdx = -1;
long long fieldIdx = -1;
RedisModule_StringToLongLong(argv[1], &pubIdx);
if (pubIdx < 0 || pubIdx >= PUB_IDX_COUNT) {
RedisModule_WrongArity(ctx);
return REDISMODULE_ERR;
}
RedisModule_StringToLongLong(argv[2], &infoIdx);
if (infoIdx < 0 || infoIdx >= INFO_IDX_COUNT) {
RedisModule_WrongArity(ctx);
return REDISMODULE_ERR;
}
if (argc > 1+2) {
RedisModule_StringToLongLong(argv[3], &fieldIdx);
if (fieldIdx < 0 || fieldIdx > VAR_IDX_COUNT) {
RedisModule_WrongArity(ctx);
return REDISMODULE_ERR;
}
}
// 处理计算数据
struct Info **infos = Idx2Infos[pubIdx];
if (infos == NULL) {
RedisModule_WrongArity(ctx);
return REDISMODULE_ERR;
}
struct Info *info = infos[infoIdx];
if (info == NULL) {
RedisModule_ReplyWithNull(ctx);
return REDISMODULE_OK;
}
// 回复数据
if (argc == 1+2) {
RedisModule_ReplyWithArray(ctx, VAR_IDX_COUNT);
RedisModule_ReplyWithString(ctx,info->cause);
RedisModule_ReplyWithString(ctx,info->info);
RedisModule_ReplyWithString(ctx,info->tms);
}else if (argc > 1+2) {
switch (fieldIdx) {
case 0:
RedisModule_ReplyWithArray(ctx, 1);
RedisModule_ReplyWithString(ctx, info->cause);
break;
case 1:
RedisModule_ReplyWithArray(ctx, 1);
RedisModule_ReplyWithString(ctx, info->info);
break;
case 2:
RedisModule_ReplyWithArray(ctx, 1);
RedisModule_ReplyWithString(ctx, info->tms);
break;
default:
RedisModule_ReplyWithNull(ctx);
}
}
// 返回
return REDISMODULE_OK;
}
// 启动参数:缓冲区编码(默认128全初始化)
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
int pubIdxCount = PUB_IDX_COUNT;
int initCount = PUB_IDX_COUNT;
if (argc == 1) {
unsigned long long index;
RedisModule_StringToULongLong(argv[0], &index);
if (index > PUB_IDX_COUNT) {
pubIdxCount = index;
initCount = index;
}
}
if (argc > 0 && argc < PUB_IDX_COUNT) {
initCount = argc;
}
Idx2Infos = (Info ***)malloc(pubIdxCount * sizeof(Info **));
if (Idx2Infos == NULL) {
return REDISMODULE_ERR;
}
memset(Idx2Infos, 0, pubIdxCount);
for (int i = 0; i < initCount; i++) {
Info **infos = (Info **)malloc(INFO_IDX_COUNT*sizeof(Info *));
if (infos == NULL) {
return REDISMODULE_ERR;
}
memset(infos, 0, INFO_IDX_COUNT);
for (int j = 0;j < INFO_IDX_COUNT; j++) {
infos[j] = (Info *)malloc(sizeof(Info));
memset(infos[j], 0, sizeof(Info));
}
if (initCount < pubIdxCount) {
unsigned long long index;
RedisModule_StringToULongLong(argv[i], &index);
if (index < 0 || index > PUB_IDX_COUNT) {
return REDISMODULE_ERR;
}
Idx2Infos[index] = infos;
}else{
Idx2Infos[i] = infos;
}
}
const char *module = "moduleiec";
const char *cmdSetVar = "iec.setvar";
const char *cmdGetAll = "iec.getall";
const char *cmdGetVar = "iec.getvar";
if (RedisModule_Init(ctx, module, 1, REDISMODULE_APIVER_1) == REDISMODULE_ERR)
return REDISMODULE_ERR;
if (RedisModule_CreateCommand(ctx, cmdSetVar, IECSetVar, "", 0, 0, 0) == REDISMODULE_ERR)
return REDISMODULE_ERR;
if (RedisModule_CreateCommand(ctx, cmdGetAll, IECGetAll, "", 0, 0, 0) == REDISMODULE_ERR)
return REDISMODULE_ERR;
if (RedisModule_CreateCommand(ctx, cmdGetVar, IECGetVar, "", 0, 0, 0) == REDISMODULE_ERR)
return REDISMODULE_ERR;
return REDISMODULE_OK;
}