blob: 875ea82b74a9aea050b4444389d6bd6bc665dbb9 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* Fory C++ Serialization Example
*
* This example demonstrates how to use Fory for high-performance
* serialization and deserialization of C++ objects.
*/
#include <cstdint>
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include "fory/serialization/fory.h"
// Define a simple struct with primitive fields
struct Point {
int32_t x;
int32_t y;
bool operator==(const Point &other) const {
return x == other.x && y == other.y;
}
};
// Register struct fields with Fory using FORY_STRUCT macro
FORY_STRUCT(Point, x, y);
// Define a more complex struct with various field types
struct Person {
std::string name;
int32_t age;
std::vector<std::string> hobbies;
bool operator==(const Person &other) const {
return name == other.name && age == other.age && hobbies == other.hobbies;
}
};
FORY_STRUCT(Person, name, age, hobbies);
// Define a nested struct
struct Team {
std::string team_name;
std::vector<Person> members;
Point headquarters;
bool operator==(const Team &other) const {
return team_name == other.team_name && members == other.members &&
headquarters == other.headquarters;
}
};
FORY_STRUCT(Team, team_name, members, headquarters);
// Define an enum
enum class Status { PENDING, ACTIVE, COMPLETED };
// Helper function to print bytes
void print_bytes(const std::vector<uint8_t> &bytes) {
std::cout << "Serialized bytes (" << bytes.size() << " bytes): ";
for (size_t i = 0; i < std::min(bytes.size(), size_t(20)); ++i) {
printf("%02x ", bytes[i]);
}
if (bytes.size() > 20) {
std::cout << "...";
}
std::cout << std::endl;
}
int main() {
std::cout << "=== Fory C++ Serialization Example ===" << std::endl
<< std::endl;
// Create a Fory instance with xlang (cross-language) mode enabled
auto fory = fory::serialization::Fory::builder()
.xlang(true) // Enable cross-language serialization
.track_ref(false) // Disable reference tracking for simplicity
.build();
// Register struct types (required for struct serialization)
fory.register_struct<Point>(1);
fory.register_struct<Person>(2);
fory.register_struct<Team>(3);
// ============================================================================
// Example 1: Primitive types
// ============================================================================
std::cout << "--- Example 1: Primitive Types ---" << std::endl;
{
int32_t original = 42;
auto bytes_result = fory.serialize(original);
if (bytes_result.ok()) {
auto bytes = bytes_result.value();
print_bytes(bytes);
auto result = fory.deserialize<int32_t>(bytes.data(), bytes.size());
if (result.ok()) {
std::cout << "Original: " << original
<< ", Deserialized: " << result.value() << std::endl;
}
}
}
std::cout << std::endl;
// ============================================================================
// Example 2: String
// ============================================================================
std::cout << "--- Example 2: String ---" << std::endl;
{
std::string original = "Hello, Fory!";
auto bytes_result = fory.serialize(original);
if (bytes_result.ok()) {
auto bytes = bytes_result.value();
print_bytes(bytes);
auto result = fory.deserialize<std::string>(bytes.data(), bytes.size());
if (result.ok()) {
std::cout << "Original: \"" << original << "\", Deserialized: \""
<< result.value() << "\"" << std::endl;
}
}
}
std::cout << std::endl;
// ============================================================================
// Example 3: Vector
// ============================================================================
std::cout << "--- Example 3: Vector ---" << std::endl;
{
std::vector<int32_t> original = {1, 2, 3, 4, 5};
auto bytes_result = fory.serialize(original);
if (bytes_result.ok()) {
auto bytes = bytes_result.value();
print_bytes(bytes);
auto result =
fory.deserialize<std::vector<int32_t>>(bytes.data(), bytes.size());
if (result.ok()) {
std::cout << "Original: [";
for (size_t i = 0; i < original.size(); ++i) {
std::cout << original[i] << (i < original.size() - 1 ? ", " : "");
}
std::cout << "], Deserialized: [";
auto &v = result.value();
for (size_t i = 0; i < v.size(); ++i) {
std::cout << v[i] << (i < v.size() - 1 ? ", " : "");
}
std::cout << "]" << std::endl;
}
}
}
std::cout << std::endl;
// ============================================================================
// Example 4: Map
// ============================================================================
std::cout << "--- Example 4: Map ---" << std::endl;
{
std::map<std::string, int32_t> original = {
{"apple", 1}, {"banana", 2}, {"cherry", 3}};
auto bytes_result = fory.serialize(original);
if (bytes_result.ok()) {
auto bytes = bytes_result.value();
print_bytes(bytes);
auto result = fory.deserialize<std::map<std::string, int32_t>>(
bytes.data(), bytes.size());
if (result.ok()) {
std::cout << "Original: {";
for (auto it = original.begin(); it != original.end(); ++it) {
std::cout << "\"" << it->first << "\": " << it->second;
if (std::next(it) != original.end())
std::cout << ", ";
}
std::cout << "}" << std::endl;
auto &m = result.value();
std::cout << "Deserialized: {";
for (auto it = m.begin(); it != m.end(); ++it) {
std::cout << "\"" << it->first << "\": " << it->second;
if (std::next(it) != m.end())
std::cout << ", ";
}
std::cout << "}" << std::endl;
}
}
}
std::cout << std::endl;
// ============================================================================
// Example 5: Simple Struct
// ============================================================================
std::cout << "--- Example 5: Simple Struct ---" << std::endl;
{
Point original{10, 20};
auto bytes_result = fory.serialize(original);
if (bytes_result.ok()) {
auto bytes = bytes_result.value();
print_bytes(bytes);
auto result = fory.deserialize<Point>(bytes.data(), bytes.size());
if (result.ok()) {
auto &p = result.value();
std::cout << "Original: Point{x=" << original.x << ", y=" << original.y
<< "}" << std::endl;
std::cout << "Deserialized: Point{x=" << p.x << ", y=" << p.y << "}"
<< std::endl;
std::cout << "Equal: " << (original == p ? "true" : "false")
<< std::endl;
}
}
}
std::cout << std::endl;
// ============================================================================
// Example 6: Complex Struct
// ============================================================================
std::cout << "--- Example 6: Complex Struct ---" << std::endl;
{
Person original{"Alice", 30, {"reading", "coding", "hiking"}};
auto bytes_result = fory.serialize(original);
if (bytes_result.ok()) {
auto bytes = bytes_result.value();
print_bytes(bytes);
auto result = fory.deserialize<Person>(bytes.data(), bytes.size());
if (result.ok()) {
auto &p = result.value();
std::cout << "Original: Person{name=\"" << original.name
<< "\", age=" << original.age << ", hobbies=[";
for (size_t i = 0; i < original.hobbies.size(); ++i) {
std::cout << "\"" << original.hobbies[i] << "\""
<< (i < original.hobbies.size() - 1 ? ", " : "");
}
std::cout << "]}" << std::endl;
std::cout << "Deserialized: Person{name=\"" << p.name
<< "\", age=" << p.age << ", hobbies=[";
for (size_t i = 0; i < p.hobbies.size(); ++i) {
std::cout << "\"" << p.hobbies[i] << "\""
<< (i < p.hobbies.size() - 1 ? ", " : "");
}
std::cout << "]}" << std::endl;
std::cout << "Equal: " << (original == p ? "true" : "false")
<< std::endl;
}
}
}
std::cout << std::endl;
// ============================================================================
// Example 7: Nested Struct
// ============================================================================
std::cout << "--- Example 7: Nested Struct ---" << std::endl;
{
Team original{"Engineering",
{{"Bob", 25, {"gaming"}}, {"Carol", 28, {"music", "art"}}},
{100, 200}};
auto bytes_result = fory.serialize(original);
if (bytes_result.ok()) {
auto bytes = bytes_result.value();
print_bytes(bytes);
auto result = fory.deserialize<Team>(bytes.data(), bytes.size());
if (result.ok()) {
auto &t = result.value();
std::cout << "Original team: \"" << original.team_name << "\" with "
<< original.members.size() << " members" << std::endl;
std::cout << "Deserialized team: \"" << t.team_name << "\" with "
<< t.members.size() << " members" << std::endl;
std::cout << "Headquarters: (" << t.headquarters.x << ", "
<< t.headquarters.y << ")" << std::endl;
std::cout << "Equal: " << (original == t ? "true" : "false")
<< std::endl;
}
}
}
std::cout << std::endl;
// ============================================================================
// Example 8: Enum
// ============================================================================
std::cout << "--- Example 8: Enum ---" << std::endl;
{
Status original = Status::ACTIVE;
auto bytes_result = fory.serialize(original);
if (bytes_result.ok()) {
auto bytes = bytes_result.value();
print_bytes(bytes);
auto result = fory.deserialize<Status>(bytes.data(), bytes.size());
if (result.ok()) {
std::cout << "Original: " << static_cast<int>(original)
<< ", Deserialized: " << static_cast<int>(result.value())
<< std::endl;
std::cout << "Equal: "
<< (original == result.value() ? "true" : "false")
<< std::endl;
}
}
}
std::cout << std::endl;
std::cout << "=== All examples completed successfully! ===" << std::endl;
return 0;
}