| /* |
| * 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; |
| } |