Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

struct_pack 不支持自定义序列化函数吗 #502

Closed
RAVER0306 opened this issue Nov 22, 2023 · 13 comments · Fixed by #514
Closed

struct_pack 不支持自定义序列化函数吗 #502

RAVER0306 opened this issue Nov 22, 2023 · 13 comments · Fixed by #514

Comments

@RAVER0306
Copy link
Contributor

struct_pack 不支持自定义序列化函数吗

@poor-circle
Copy link
Collaborator

#472

@poor-circle
Copy link
Collaborator

你看看这个是不是你想要的

@RAVER0306
Copy link
Contributor Author

你看看这个是不是你想要的

#include
#include
#include

#include "zpp_bits.h"

using namespace std;

struct Props
{
int x{};
int y{};

unsigned char* p;

constexpr static auto serialize(auto& archive, auto& self)
{
	using archive_type = std::remove_cvref_t<decltype(archive)>;
	if constexpr (archive_type::kind() == zpp::bits::kind::in) {
		std::vector<unsigned char> vec;
		auto result = archive(self.x, self.y, vec);
		unsigned char* ptr = vec.data();;
		self.p = new unsigned char[vec.size()];
		std::copy(vec.begin(), vec.end(), self.p);
		return result;
	}
	else if constexpr (archive_type::kind() == zpp::bits::kind::out) {
		std::vector<unsigned char> vec(self.p, self.p + self.x * self.y);
		auto result = archive(self.x, self.y, vec);
		return result;
	}
	else {
		return std::make_error_code(std::errc::invalid_argument);
	}
}

};

struct Person
{
std::string name;
int age{};

Props props{10, 10};

};

int main()
{
auto [data, in, out] = zpp::bits::data_in_out();

Person p1{ "Person1", 25 };
Person p2{ "Person2", 35 };


p1.props.p = new unsigned char[100]();
p2.props.p = new unsigned char[100]();

p1.props.p[2] = 'H';
p2.props.p[3] = 'W';

p1.props.p[98] = 'X';
p2.props.p[97] = 'Y';

auto result = out(p1, p2);
if (failure(result))
{
	std::cout << "Failed to write data to file! " << std::endl;
}

Person p3, p4;

result = in(p3, p4);
if (failure(result)) {
	std::cout << "Failed to read data from file! " << std::endl;
}
else {
	std::cout << std::format("Read data from file: {},{},{},{}", p3.name, p3.age, static_cast<char>(p3.props.p[2]), static_cast<char>(p3.props.p[98])) << std::endl;
	std::cout << std::format("Read data from file: {},{},{},{}", p4.name, p4.age, static_cast<char>(p4.props.p[3]), static_cast<char>(p4.props.p[97])) << std::endl;
}

cout << "Hello CMake." << endl;
return 0;

}

似乎不是,类似于这种方式的方法有吗

@RAVER0306
Copy link
Contributor Author

是不是自定义实现如下方法就行了

template<struct_pack::writer_t writer_t>
void serialize_to(writer_t writer, const ZZ&zz);
template<struct_pack::reader_t reader_t>
void deserialize_to(ZZ&zz, reader_t reader);

@poor-circle
Copy link
Collaborator

是不是自定义实现如下方法就行了

template<struct_pack::writer_t writer_t> void serialize_to(writer_t writer, const ZZ&zz); template<struct_pack::reader_t reader_t> void deserialize_to(ZZ&zz, reader_t reader);

设计是这样的,不过目前我在忙另外一个feature,这个我尽快支持一下吧。

@RAVER0306
Copy link
Contributor Author

是不是自定义实现如下方法就行了

template<struct_pack::writer_t writer_t> void serialize_to(writer_t writer, const ZZ&zz); template<struct_pack::reader_t reader_t> void deserialize_to(ZZ&zz, reader_t reader);

设计是这样的,不过目前我在忙另外一个feature,这个我尽快支持一下吧。

辛苦了

@RAVER0306
Copy link
Contributor Author

#pragma once

#include <vector>

#include <ylt/struct_pack.hpp>

struct PropsPack
{
	int x{};
	int y{};

	unsigned char* p{ nullptr };
};

namespace struct_pack {
	template <uint64_t conf = sp_config::DEFAULT, typename Writer>
	STRUCT_PACK_INLINE void serialize_to(Writer& writer, const PropsPack& self)
	{
		std::vector<unsigned char> vec(self.p, self.p + self.x * self.y);
		auto data_offset = writer.size();
		auto info = detail::get_serialize_runtime_info<conf>(self.x, self.y, vec);
		auto total = data_offset + info.size();
		detail::resize(writer, total);
		auto real_writer = struct_pack::detail::memory_writer{ (char*)writer.data() + data_offset };
		struct_pack::detail::serialize_to<conf>(real_writer, info, self.x, self.y, vec);
	}

	template <uint64_t conf = sp_config::DEFAULT, typename... Args, detail::deserialize_view View>
	[[nodiscard]] STRUCT_PACK_INLINE struct_pack::errc deserialize_to(PropsPack& self, const View& v, Args &...args) {
		detail::memory_reader reader{ (const char*)v.data(), (const char*)v.data() + v.size() };
		detail::unpacker<detail::memory_reader, conf> in(reader);

		std::vector<unsigned char> vec;
		auto result = in.deserialize(self.x, self.y, vec, args...);
		unsigned char* ptr = vec.data();;
		self.p = new unsigned char[vec.size()];
		std::copy(vec.begin(), vec.end(), self.p);
		return result;
	}
}
#include "CMakeProject1.h"

#include <iostream>
#include <fstream>
#include <format>
#include <string>

using namespace std;

int main()
{
	PropsPack z{ 10, 10 };
	z.p = new unsigned char[z.x * z.y]();

	z.p[2] = 'H';
	z.p[9] = 'W';

	std::vector<char> result_pack;
	struct_pack::serialize_to(result_pack, z);

	PropsPack zz;
	auto result = struct_pack::deserialize_to(zz, result_pack);

	std::cout << std::format("{},{}", static_cast<char>(zz.p[2]), static_cast<char>(zz.p[9])) << std::endl;

	return 0;
}

目前这样可以正常序列化和反序列化

@RAVER0306 RAVER0306 reopened this Nov 24, 2023
@RAVER0306
Copy link
Contributor Author

template<struct_pack::writer_t writer_t>
void serialize_to(writer_t writer, const ZZ&zz);
template<struct_pack::reader_t reader_t>
void deserialize_to(ZZ&zz, reader_t reader);

这个不能出现自定义类型的嵌套吗,如何才能支持自定义类型的嵌套呢

@poor-circle
Copy link
Collaborator

poor-circle commented Nov 24, 2023

template<struct_pack::writer_t writer_t> void serialize_to(writer_t writer, const ZZ&zz); template<struct_pack::reader_t reader_t> void deserialize_to(ZZ&zz, reader_t reader);

这个不能出现自定义类型的嵌套吗,如何才能支持自定义类型的嵌套呢

你这个类型有两个维度,因此不属于 https://alibaba.github.io/yalantinglibs/zh/struct_pack/struct_pack_type_system.html 里面的任何一种已有的类型,目前struct_pack允许自定义的类型必须能够抽象为类型系统中已经存在的某一种类型。

对于不属于类型系统中的用户自定义类型支持,需要等 #472

@RAVER0306
Copy link
Contributor Author

template<struct_pack::writer_t writer_t> void serialize_to(writer_t writer, const ZZ&zz); template<struct_pack::reader_t reader_t> void deserialize_to(ZZ&zz, reader_t reader);
这个不能出现自定义类型的嵌套吗,如何才能支持自定义类型的嵌套呢

你这个类型有两个维度,因此不属于 https://alibaba.github.io/yalantinglibs/zh/struct_pack/struct_pack_type_system.html 里面的任何一种已有的类型,目前struct_pack允许自定义的类型必须属于类型系统中已经存在的某一种类型。

对于不属于类型系统中的用户自定义类型支持,需要等 #472

那目前来说有什么好的解决方法吗

@poor-circle
Copy link
Collaborator

template<struct_pack::writer_t writer_t> void serialize_to(writer_t writer, const ZZ&zz); template<struct_pack::reader_t reader_t> void deserialize_to(ZZ&zz, reader_t reader);
这个不能出现自定义类型的嵌套吗,如何才能支持自定义类型的嵌套呢

你这个类型有两个维度,因此不属于 https://alibaba.github.io/yalantinglibs/zh/struct_pack/struct_pack_type_system.html 里面的任何一种已有的类型,目前struct_pack允许自定义的类型必须属于类型系统中已经存在的某一种类型。
对于不属于类型系统中的用户自定义类型支持,需要等 #472

那目前来说有什么好的解决方法吗

我这两天初步支持一下吧。

@RAVER0306
Copy link
Contributor Author

template<struct_pack::writer_t writer_t> void serialize_to(writer_t writer, const ZZ&zz); template<struct_pack::reader_t reader_t> void deserialize_to(ZZ&zz, reader_t reader);
这个不能出现自定义类型的嵌套吗,如何才能支持自定义类型的嵌套呢

你这个类型有两个维度,因此不属于 https://alibaba.github.io/yalantinglibs/zh/struct_pack/struct_pack_type_system.html 里面的任何一种已有的类型,目前struct_pack允许自定义的类型必须属于类型系统中已经存在的某一种类型。
对于不属于类型系统中的用户自定义类型支持,需要等 #472

那目前来说有什么好的解决方法吗

我这两天初步支持一下吧。

好吧,非常感谢你的帮助

@poor-circle
Copy link
Collaborator

poor-circle commented Dec 5, 2023

任意类型的自定义序列化已支持,见 #514文档

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants