acl/app/wizard_demo/pkv/proto/redis_coder.cpp

198 lines
5.2 KiB
C++
Raw Normal View History

2023-07-19 19:07:53 +08:00
//
// Created by shuxin <20><><EFBFBD><EFBFBD>zheng on 2023/7/19.
//
#include "stdafx.h"
2023-07-21 16:20:04 +08:00
#include "redis_coder.h"
2023-07-19 19:07:53 +08:00
namespace pkv {
2023-07-21 16:20:04 +08:00
redis_coder::redis_coder() {
curr_ = std::make_shared<redis_object>(nullptr);
2023-07-20 19:24:18 +08:00
}
2023-07-19 19:07:53 +08:00
2023-07-23 23:18:37 +08:00
void redis_coder::clear() {
objs_.clear();
}
2023-07-21 16:20:04 +08:00
const char* redis_coder::update(const char* data, size_t& len) {
2023-07-19 19:07:53 +08:00
while (len > 0) {
2023-07-20 19:24:18 +08:00
data = curr_->update(data, len);
2023-07-19 19:07:53 +08:00
if (curr_->finish()) {
2023-07-21 14:20:47 +08:00
objs_.push_back(curr_);
curr_ = std::make_shared<redis_object>(nullptr);
2023-07-20 19:24:18 +08:00
} else if (curr_->failed()) {
break;
2023-07-19 19:07:53 +08:00
}
}
2023-07-20 19:24:18 +08:00
return data;
}
2023-07-21 16:20:04 +08:00
redis_object& redis_coder::create_object() {
auto obj = std::make_shared<redis_object>(nullptr);
objs_.emplace_back(obj);
2023-07-21 16:20:04 +08:00
return *obj;
}
bool redis_coder::to_string(acl::string& out) const {
2023-07-20 22:56:34 +08:00
for (const auto& obj : objs_) {
2023-07-20 19:24:18 +08:00
if (!obj->to_string(out)) {
return false;
}
}
return true;
}
2023-07-21 16:20:04 +08:00
//////////////////////////////////////////////////////////////////////////////
2023-07-20 22:56:34 +08:00
//////////////////////////////////////////////////////////////////////////////
2023-07-20 19:24:18 +08:00
bool test_redis_parse(const char* filepath) {
2023-07-21 14:20:47 +08:00
if (!test_redis_parse_once(filepath)) {
return false;
}
printf("\r\n");
if (!test_redis_parse_stream(filepath)) {
return false;
}
return true;
}
bool test_redis_parse_once(const char* filepath) {
2023-07-20 19:24:18 +08:00
acl::string buf;
if (!acl::ifstream::load(filepath, buf)) {
printf("load %s error %s\r\n", filepath, acl::last_serror());
return false;
}
2023-07-21 16:20:04 +08:00
redis_coder parser;
2023-07-20 19:24:18 +08:00
const char* data = buf.c_str();
size_t len = buf.size();
const char* left = parser.update(data, len);
if (len > 0) {
2023-07-21 14:20:47 +08:00
printf(">>>%s: parse failed<<<\r\n", __func__);
2023-07-20 19:24:18 +08:00
printf("%s\r\n", left);
return false;
}
2023-07-21 14:20:47 +08:00
printf(">>>%s: parse success<<<\r\n", __func__);
2023-07-20 19:24:18 +08:00
acl::string out;
if (!parser.to_string(out)) {
2023-07-21 14:20:47 +08:00
printf(">>>%s: build failed<<<\r\n", __func__);
2023-07-20 19:24:18 +08:00
return false;
}
if (out != buf) {
2023-07-21 14:20:47 +08:00
printf(">>>%s: build failed<<<\r\n", __func__);
2023-07-20 19:24:18 +08:00
printf("output:\r\n|%s|\r\n", out.c_str());
printf("input:\r\n|%s|\r\n", buf.c_str());
acl::string filetmp(filepath);
filetmp += ".tmp";
acl::ofstream fp;
if (fp.open_trunc(filetmp)) {
fp.write(out);
}
return false;
}
printf("%s\r\n", out.c_str());
2023-07-21 14:20:47 +08:00
printf(">>>%s: build successfully<<<\r\n", __func__);
return true;
}
bool test_redis_parse_stream(const char* filepath) {
acl::string buf;
if (!acl::ifstream::load(filepath, buf)) {
printf("load %s error %s\r\n", filepath, acl::last_serror());
return false;
}
2023-07-20 19:24:18 +08:00
2023-07-21 16:20:04 +08:00
redis_coder parser;
2023-07-21 14:20:47 +08:00
const char* data = buf.c_str();
size_t len = buf.size();
for (size_t i = 0; i < len; i++) {
char ch = *data++;
size_t n = 1;
//putchar(ch);
const char* left = parser.update(&ch, n);
if (n > 0) {
printf(">>>%s(%d): parse failed, left=%s<<<\r\n", __func__, __LINE__, left);
return false;
}
}
printf(">>%s(%d): parse successfully<<<\r\n", __func__, __LINE__);
acl::string out;
if (!parser.to_string(out)) {
printf(">>%s(%d): build failed<<\r\n", __func__, __LINE__);
return false;
}
if (out != buf) {
printf("%s\r\n", out.c_str());
printf(">>%s(%d): build failed<<\r\n", __func__, __LINE__);
return false;
}
printf("%s\r\n", out.c_str());
2023-07-21 19:12:12 +08:00
const char* cmd = parser.get_objects()[0]->get_cmd();
printf(">>%s(%d): build successfully, cmd=%s<<\r\n",
__func__, __LINE__, cmd ? cmd : "unknown");
2023-07-20 19:24:18 +08:00
return true;
2023-07-19 19:07:53 +08:00
}
2023-07-21 16:20:04 +08:00
//////////////////////////////////////////////////////////////////////////////
bool test_redis_build() {
redis_coder builder;
auto& obj = builder.create_object();
2023-07-21 19:12:12 +08:00
#if 0
2023-07-21 16:20:04 +08:00
obj.create_child().set_string("HMSET");
obj.create_child().set_string("hash-key");
obj.create_child().set_string("field1");
obj.create_child().set_string("vaule1");
obj.create_child().set_string("field2");
obj.create_child().set_string("value2");
obj.create_child().set_string("field3");
obj.create_child().set_string("value3");
#else
2023-07-21 19:12:12 +08:00
obj.create_child().set_string("HMSET", true)
2023-07-21 16:20:04 +08:00
.create_child().set_string("hash-key", true)
.create_child().set_string("field1", true)
.create_child().set_string("value1", true)
.create_child().set_string("field2", true)
.create_child().set_string("value2", true)
.create_child().set_string("field3", true)
.create_child().set_string("value3", true);
#endif
acl::string buf;
if (builder.to_string(buf)) {
2023-07-21 19:12:12 +08:00
const char* cmd = obj.get_cmd();
printf("%s(%d): build redis successfully, cmd=%s\r\n",
__func__, __LINE__, cmd ? cmd : "unknown");
2023-07-21 16:20:04 +08:00
printf("[%s]\r\n", buf.c_str());
} else {
printf("%s(%d): build redis failed\r\n", __func__, __LINE__);
return false;
}
return true;
}
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
2023-07-19 19:07:53 +08:00
} // namespace pkv