This is an automated email from the ASF dual-hosted git repository.
chaokunyang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/fory-site.git
The following commit(s) were added to refs/heads/main by this push:
new 278180183 π synced local 'docs/docs/guide/' with remote 'docs/guide/'
278180183 is described below
commit 27818018334d5cc66e22630c0fcd3fe662cb4d77
Author: chaokunyang <[email protected]>
AuthorDate: Thu Dec 11 03:03:35 2025 +0000
π synced local 'docs/docs/guide/' with remote 'docs/guide/'
---
docs/docs/guide/cpp/type-registration.md | 10 +-
docs/docs/guide/xlang/getting-started.md | 292 +++++++++++++++++++++++
docs/docs/guide/xlang/index.md | 107 ++++++++-
docs/docs/guide/xlang/row_format.md | 83 +++----
docs/docs/guide/xlang/serialization.md | 386 +++++++++++++------------------
docs/docs/guide/xlang/troubleshooting.md | 321 +++++++++++++++++++++++++
docs/docs/guide/xlang/zero-copy.md | 207 +++++++++++++++++
7 files changed, 1124 insertions(+), 282 deletions(-)
diff --git a/docs/docs/guide/cpp/type-registration.md
b/docs/docs/guide/cpp/type-registration.md
index 7b930c060..653c22b98 100644
--- a/docs/docs/guide/cpp/type-registration.md
+++ b/docs/docs/guide/cpp/type-registration.md
@@ -74,14 +74,14 @@ fory.register_struct<Order>(2);
## Registering Enums
-For simple enums with continuous values starting from 0, no macro is needed:
+Use `register_enum<T>(type_id)` to register an enum type. For simple enums
with continuous values starting from 0, no macro is needed:
```cpp
// Simple continuous enum - no FORY_ENUM needed
enum class Color { RED, GREEN, BLUE }; // Values: 0, 1, 2
-// Just register directly
-fory.register_struct<Color>(0);
+// Register with register_enum
+fory.register_enum<Color>(0);
```
For enums with non-continuous values, use the `FORY_ENUM` macro to map values
to ordinals:
@@ -96,8 +96,8 @@ enum LegacyStatus { UNKNOWN = -1, OK = 0, ERROR = 1 };
FORY_ENUM(::LegacyStatus, UNKNOWN, OK, ERROR);
// Register after FORY_ENUM
-fory.register_struct<Priority>(1);
-fory.register_struct<LegacyStatus>(2);
+fory.register_enum<Priority>(1);
+fory.register_enum<LegacyStatus>(2);
```
**When to use `FORY_ENUM`:**
diff --git a/docs/docs/guide/xlang/getting-started.md
b/docs/docs/guide/xlang/getting-started.md
new file mode 100644
index 000000000..45e7263ee
--- /dev/null
+++ b/docs/docs/guide/xlang/getting-started.md
@@ -0,0 +1,292 @@
+---
+title: Getting Started
+sidebar_position: 1
+id: xlang_getting_started
+license: |
+ 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.
+---
+
+This guide covers installation and basic setup for cross-language
serialization in all supported languages.
+
+## Installation
+
+### Java
+
+**Maven:**
+
+```xml
+<dependency>
+ <groupId>org.apache.fory</groupId>
+ <artifactId>fory-core</artifactId>
+ <version>0.13.2</version>
+</dependency>
+```
+
+**Gradle:**
+
+```gradle
+implementation 'org.apache.fory:fory-core:0.13.2'
+```
+
+### Python
+
+```bash
+pip install pyfory
+```
+
+### Go
+
+```bash
+go get github.com/apache/fory/go/fory
+```
+
+### Rust
+
+```toml
+[dependencies]
+fory = "0.13"
+```
+
+### JavaScript
+
+```bash
+npm install @apache-fory/fory
+```
+
+### C++
+
+Use Bazel or CMake to build from source. See [C++ Guide](../cpp/index.md) for
details.
+
+## Enable Cross-Language Mode
+
+Each language requires enabling xlang mode to ensure binary compatibility
across languages.
+
+### Java
+
+```java
+import org.apache.fory.*;
+import org.apache.fory.config.*;
+
+Fory fory = Fory.builder()
+ .withLanguage(Language.XLANG) // Enable cross-language mode
+ .withRefTracking(true) // Optional: for circular references
+ .build();
+```
+
+### Python
+
+```python
+import pyfory
+
+# xlang mode is enabled by default
+fory = pyfory.Fory()
+
+# Explicit configuration
+fory = pyfory.Fory(ref_tracking=True)
+```
+
+### Go
+
+```go
+import forygo "github.com/apache/fory/go/fory"
+
+fory := forygo.NewFory()
+// Or with reference tracking
+fory := forygo.NewFory(true)
+```
+
+### Rust
+
+```rust
+use fory::Fory;
+
+let fory = Fory::default();
+```
+
+### JavaScript
+
+```javascript
+import Fory from "@apache-fory/fory";
+
+const fory = new Fory();
+```
+
+### C++
+
+```cpp
+#include "fory/serialization/fory.h"
+
+using namespace fory::serialization;
+
+auto fory = Fory::builder()
+ .xlang(true)
+ .build();
+```
+
+## Type Registration
+
+Custom types must be registered with consistent names or IDs across all
languages.
+
+### Register by Name (Recommended)
+
+Using string names is more flexible and less prone to conflicts:
+
+**Java:**
+
+```java
+fory.register(Person.class, "example.Person");
+```
+
+**Python:**
+
+```python
+fory.register_type(Person, typename="example.Person")
+```
+
+**Go:**
+
+```go
+fory.RegisterNamedType(Person{}, "example.Person")
+```
+
+**Rust:**
+
+```rust
+#[derive(Fory)]
+#[tag("example.Person")]
+struct Person {
+ name: String,
+ age: i32,
+}
+```
+
+**JavaScript:**
+
+```javascript
+const description = Type.object("example.Person", {
+ name: Type.string(),
+ age: Type.int32(),
+});
+fory.registerSerializer(description);
+```
+
+**C++:**
+
+```cpp
+fory.register_struct<Person>("example.Person");
+// For enums, use register_enum:
+// fory.register_enum<Color>("example.Color");
+```
+
+### Register by ID
+
+Using numeric IDs is faster and produces smaller binary output:
+
+**Java:**
+
+```java
+fory.register(Person.class, 100);
+```
+
+**Python:**
+
+```python
+fory.register_type(Person, type_id=100)
+```
+
+**Go:**
+
+```go
+fory.Register(Person{}, 100)
+```
+
+**C++:**
+
+```cpp
+fory.register_struct<Person>(100);
+// For enums, use register_enum:
+// fory.register_enum<Color>(101);
+```
+
+## Hello World Example
+
+A complete example showing serialization in Java and deserialization in Python:
+
+### Java (Serializer)
+
+```java
+import org.apache.fory.*;
+import org.apache.fory.config.*;
+import java.nio.file.*;
+
+public class Person {
+ public String name;
+ public int age;
+}
+
+public class HelloWorld {
+ public static void main(String[] args) throws Exception {
+ Fory fory = Fory.builder()
+ .withLanguage(Language.XLANG)
+ .build();
+ fory.register(Person.class, "example.Person");
+
+ Person person = new Person();
+ person.name = "Alice";
+ person.age = 30;
+
+ byte[] bytes = fory.serialize(person);
+ Files.write(Path.of("person.bin"), bytes);
+ System.out.println("Serialized to person.bin");
+ }
+}
+```
+
+### Python (Deserializer)
+
+```python
+import pyfory
+from dataclasses import dataclass
+
+@dataclass
+class Person:
+ name: str
+ age: pyfory.Int32Type
+
+fory = pyfory.Fory()
+fory.register_type(Person, typename="example.Person")
+
+with open("person.bin", "rb") as f:
+ data = f.read()
+
+person = fory.deserialize(data)
+print(f"Name: {person.name}, Age: {person.age}")
+# Output: Name: Alice, Age: 30
+```
+
+## Best Practices
+
+1. **Use consistent type names**: Ensure all languages use the same type name
or ID
+2. **Enable reference tracking**: If your data has circular or shared
references
+3. **Reuse Fory instances**: Creating Fory is expensive; reuse instances
+4. **Use type annotations**: In Python, use `pyfory.Int32Type` etc. for
precise type mapping
+5. **Test cross-language**: Verify serialization works across all target
languages
+
+## Next Steps
+
+- [Type
Mapping](https://fory.apache.org/docs/specification/xlang_type_mapping) -
Cross-language type mapping reference
+- [Serialization](serialization.md) - Detailed serialization examples
+- [Troubleshooting](troubleshooting.md) - Common issues and solutions
diff --git a/docs/docs/guide/xlang/index.md b/docs/docs/guide/xlang/index.md
index 59d60ef6d..7a36c06dc 100644
--- a/docs/docs/guide/xlang/index.md
+++ b/docs/docs/guide/xlang/index.md
@@ -1,5 +1,5 @@
---
-title: Cross Language
+title: Cross-Language Serialization Guide
sidebar_position: 0
id: xlang_serialization_index
license: |
@@ -18,3 +18,108 @@ license: |
See the License for the specific language governing permissions and
limitations under the License.
---
+
+Apache Foryβ’ xlang (cross-language) serialization enables seamless data
exchange between different programming languages. Serialize data in one
language and deserialize it in anotherβwithout IDL definitions, schema
compilation, or manual data conversion.
+
+## Features
+
+- **No IDL Required**: Serialize any object automatically without Protocol
Buffers, Thrift, or other IDL definitions
+- **Multi-Language Support**: Java, Python, C++, Go, Rust, JavaScript all
interoperate seamlessly
+- **Reference Support**: Shared and circular references work across language
boundaries
+- **Schema Evolution**: Forward/backward compatibility when class definitions
change
+- **Zero-Copy**: Out-of-band serialization for large binary data
+- **High Performance**: JIT compilation and optimized binary protocol
+
+## Supported Languages
+
+| Language | Status | Package |
+| ---------- | ------ | -------------------------------- |
+| Java | β
| `org.apache.fory:fory-core` |
+| Python | β
| `pyfory` |
+| C++ | β
| Bazel/CMake build |
+| Go | β
| `github.com/apache/fory/go/fory` |
+| Rust | β
| `fory` crate |
+| JavaScript | β
| `@apache-fory/fory` |
+
+## When to Use Xlang Mode
+
+**Use xlang mode when:**
+
+- Building multi-language microservices
+- Creating polyglot data pipelines
+- Sharing data between frontend (JavaScript) and backend (Java/Python/Go)
+
+**Use language-native mode when:**
+
+- All serialization/deserialization happens in the same language
+- Maximum performance is required (native mode is faster)
+- You need language-specific features (Python pickle compatibility, Java
serialization hooks)
+
+## Quick Example
+
+### Java (Producer)
+
+```java
+import org.apache.fory.*;
+import org.apache.fory.config.*;
+
+public class Person {
+ public String name;
+ public int age;
+}
+
+Fory fory = Fory.builder()
+ .withLanguage(Language.XLANG)
+ .build();
+fory.register(Person.class, "example.Person");
+
+Person person = new Person();
+person.name = "Alice";
+person.age = 30;
+byte[] bytes = fory.serialize(person);
+// Send bytes to Python, Go, Rust, etc.
+```
+
+### Python (Consumer)
+
+```python
+import pyfory
+from dataclasses import dataclass
+
+@dataclass
+class Person:
+ name: str
+ age: pyfory.Int32Type
+
+fory = pyfory.Fory()
+fory.register_type(Person, typename="example.Person")
+
+# Receive bytes from Java
+person = fory.deserialize(bytes_from_java)
+print(f"{person.name}, {person.age}") # Alice, 30
+```
+
+## Documentation
+
+| Topic
| Description |
+|
----------------------------------------------------------------------------- |
------------------------------------------------ |
+| [Getting Started](getting-started.md)
| Installation and basic setup for all languages |
+| [Type
Mapping](https://fory.apache.org/docs/specification/xlang_type_mapping) |
Cross-language type mapping reference |
+| [Serialization](serialization.md)
| Built-in types, custom types, reference handling |
+| [Zero-Copy](zero-copy.md)
| Out-of-band serialization for large data |
+| [Row Format](row_format.md)
| Cache-friendly binary format with random access |
+| [Troubleshooting](troubleshooting.md)
| Common issues and solutions |
+
+## Language-Specific Guides
+
+For language-specific details and API reference:
+
+- [Java Cross-Language Guide](../java/cross-language.md)
+- [Python Cross-Language Guide](../python/cross-language.md)
+- [C++ Cross-Language Guide](../cpp/cross-language.md)
+- [Rust Cross-Language Guide](../rust/cross-language.md)
+
+## Specifications
+
+- [Xlang Serialization
Specification](https://fory.apache.org/docs/next/specification/fory_xlang_serialization_spec)
- Binary protocol details
+- [Type Mapping
Specification](https://fory.apache.org/docs/next/specification/xlang_type_mapping)
- Complete type mapping reference
diff --git a/docs/docs/guide/xlang/row_format.md
b/docs/docs/guide/xlang/row_format.md
index ec6df6d63..58b20fe5c 100644
--- a/docs/docs/guide/xlang/row_format.md
+++ b/docs/docs/guide/xlang/row_format.md
@@ -1,5 +1,5 @@
---
-title: Row Format Guide
+title: Row Format
sidebar_position: 5
id: row_format
license: |
@@ -19,6 +19,15 @@ license: |
limitations under the License.
---
+Fory Row Format is a cache-friendly binary format designed for efficient
random access and partial serialization. Unlike object graph serialization, row
format allows you to read individual fields without deserializing the entire
object.
+
+## Features
+
+- **Zero-Copy Random Access**: Read specific fields directly from binary data
+- **Partial Serialization**: Skip unnecessary fields during serialization
+- **Cross-Language Compatible**: Row format data can be shared between Java,
Python, and C++
+- **Apache Arrow Integration**: Convert row format to/from Arrow RecordBatch
for analytics (Java/Python)
+
## Java
```java
@@ -47,21 +56,21 @@ for (int i = 0; i < 1000000; i++) {
bars.add(bar);
}
foo.f4 = bars;
-// Can be zero-copy read by python
+// Can be zero-copy read by Python
BinaryRow binaryRow = encoder.toRow(foo);
-// can be data from python
+// Can be data from Python
Foo newFoo = encoder.fromRow(binaryRow);
-// zero-copy read List<Integer> f2
+// Zero-copy read List<Integer> f2
BinaryArray binaryArray2 = binaryRow.getArray(1);
-// zero-copy read List<Bar> f4
+// Zero-copy read List<Bar> f4
BinaryArray binaryArray4 = binaryRow.getArray(3);
-// zero-copy read 11th element of `readList<Bar> f4`
+// Zero-copy read 11th element of List<Bar> f4
BinaryRow barStruct = binaryArray4.getStruct(10);
-// zero-copy read 6th of f2 of 11th element of `readList<Bar> f4`
+// Zero-copy read 6th element of f2 of 11th element of List<Bar> f4
barStruct.getArray(1).getInt64(5);
RowEncoder<Bar> barEncoder = Encoders.bean(Bar.class);
-// deserialize part of data.
+// Deserialize part of data
Bar newBar = barEncoder.fromRow(barStruct);
Bar newBar2 = barEncoder.fromRow(binaryArray4.getStruct(20));
```
@@ -97,11 +106,11 @@ print(new_foo.f2[100000], new_foo.f4[100000].f1,
new_foo.f4[200000].f2[5])
print(f"pickle end: {datetime.datetime.now()}")
```
-### Apache Arrow Support
+## Apache Arrow Support
-Apache Foryβ’ Row Format also supports automatic conversion from/to Arrow
Table/RecordBatch.
+Fory Row Format supports automatic conversion from/to Arrow Table/RecordBatch
for analytics workloads.
-Java:
+### Java
```java
Schema schema = TypeInference.inferSchema(BeanA.class);
@@ -114,9 +123,18 @@ for (int i = 0; i < 10; i++) {
return arrowWriter.finishAsRecordBatch();
```
+### Python
+
+```python
+import pyfory
+encoder = pyfory.encoder(Foo)
+encoder.to_arrow_record_batch([foo] * 10000)
+encoder.to_arrow_table([foo] * 10000)
+```
+
## Support for Interface and Extension Types
-Fory now supports row format mapping for Java `interface` types and subclassed
(`extends`) types, enabling more dynamic and flexible data schemas.
+Fory supports row format mapping for Java `interface` types and subclassed
(`extends`) types, enabling more dynamic and flexible data schemas.
These enhancements were introduced in
[#2243](https://github.com/apache/fory/pull/2243),
[#2250](https://github.com/apache/fory/pull/2250), and
[#2256](https://github.com/apache/fory/pull/2256).
@@ -143,7 +161,6 @@ dog.name = "Bingo";
BinaryRow row = encoder.toRow(dog);
Animal decoded = encoder.fromRow(row);
System.out.println(decoded.speak()); // Woof
-
```
### Example: Extension Type with RowEncoder
@@ -164,42 +181,10 @@ child.parentField = "Hello";
child.childField = "World";
BinaryRow row = encoder.toRow(child);
Parent decoded = encoder.fromRow(row);
-
-```
-
-Python:
-
-```python
-import pyfory
-encoder = pyfory.encoder(Foo)
-encoder.to_arrow_record_batch([foo] * 10000)
-encoder.to_arrow_table([foo] * 10000)
```
-C++
+## See Also
-```c++
-std::shared_ptr<ArrowWriter> arrow_writer;
-EXPECT_TRUE(
- ArrowWriter::Make(schema, ::arrow::default_memory_pool(), &arrow_writer)
- .ok());
-for (auto &row : rows) {
- EXPECT_TRUE(arrow_writer->Write(row).ok());
-}
-std::shared_ptr<::arrow::RecordBatch> record_batch;
-EXPECT_TRUE(arrow_writer->Finish(&record_batch).ok());
-EXPECT_TRUE(record_batch->Validate().ok());
-EXPECT_EQ(record_batch->num_columns(), schema->num_fields());
-EXPECT_EQ(record_batch->num_rows(), row_nums);
-```
-
-```java
-Schema schema = TypeInference.inferSchema(BeanA.class);
-ArrowWriter arrowWriter = ArrowUtils.createArrowWriter(schema);
-Encoder<BeanA> encoder = Encoders.rowEncoder(BeanA.class);
-for (int i = 0; i < 10; i++) {
- BeanA beanA = BeanA.createBeanA(2);
- arrowWriter.write(encoder.toRow(beanA));
-}
-return arrowWriter.finishAsRecordBatch();
-```
+- [Row Format
Specification](https://fory.apache.org/docs/next/specification/fory_row_format_spec)
- Binary format details
+- [Java Row Format Guide](../java/row-format.md) - Java-specific row format
documentation
+- [Python Row Format Guide](../python/row-format.md) - Python-specific row
format documentation
diff --git a/docs/docs/guide/xlang/serialization.md
b/docs/docs/guide/xlang/serialization.md
index a5715a60a..0b2085ab0 100644
--- a/docs/docs/guide/xlang/serialization.md
+++ b/docs/docs/guide/xlang/serialization.md
@@ -1,6 +1,6 @@
---
-title: Xlang Serialization Guide
-sidebar_position: 4
+title: Serialization
+sidebar_position: 3
id: xlang_serialization
license: |
Licensed to the Apache Software Foundation (ASF) under one or more
@@ -19,11 +19,13 @@ license: |
limitations under the License.
---
-## Serialize built-in types
+This page demonstrates cross-language serialization patterns with examples in
all supported languages. Data serialized in one language can be deserialized in
any other supported language.
-Common types can be serialized automatically: primitive numeric types, string,
binary, array, list, map and so on.
+## Serialize Built-in Types
-**Java**
+Common types can be serialized automatically without registration: primitive
numeric types, string, binary, array, list, map, and more.
+
+### Java
```java
import org.apache.fory.*;
@@ -36,20 +38,20 @@ public class Example1 {
Fory fory = Fory.builder().withLanguage(Language.XLANG).build();
List<Object> list = ofArrayList(true, false, "str", -1.1, 1, new int[100],
new double[20]);
byte[] bytes = fory.serialize(list);
- // bytes can be data serialized by other languages.
+ // bytes can be deserialized by other languages
fory.deserialize(bytes);
Map<Object, Object> map = new HashMap<>();
map.put("k1", "v1");
map.put("k2", list);
map.put("k3", -1);
bytes = fory.serialize(map);
- // bytes can be data serialized by other languages.
+ // bytes can be deserialized by other languages
fory.deserialize(bytes);
}
}
```
-**Python**
+### Python
```python
import pyfory
@@ -59,61 +61,62 @@ fory = pyfory.Fory()
object_list = [True, False, "str", -1.1, 1,
np.full(100, 0, dtype=np.int32), np.full(20, 0.0,
dtype=np.double)]
data = fory.serialize(object_list)
-# bytes can be data serialized by other languages.
+# bytes can be deserialized by other languages
new_list = fory.deserialize(data)
object_map = {"k1": "v1", "k2": object_list, "k3": -1}
data = fory.serialize(object_map)
-# bytes can be data serialized by other languages.
+# bytes can be deserialized by other languages
new_map = fory.deserialize(data)
print(new_map)
```
-**Golang**
+### Go
```go
package main
-import forygo "github.com/apache/fory/fory/go/fory"
+import forygo "github.com/apache/fory/go/fory"
import "fmt"
func main() {
- list := []interface{}{true, false, "str", -1.1, 1, make([]int32, 10),
make([]float64, 20)}
- fory := forygo.NewFory()
- bytes, err := fory.Marshal(list)
- if err != nil {
- panic(err)
- }
- var newValue interface{}
- // bytes can be data serialized by other languages.
- if err := fory.Unmarshal(bytes, &newValue); err != nil {
- panic(err)
- }
- fmt.Println(newValue)
- dict := map[string]interface{}{
- "k1": "v1",
- "k2": list,
- "k3": -1,
- }
- bytes, err = fory.Marshal(dict)
- if err != nil {
- panic(err)
- }
- // bytes can be data serialized by other languages.
- if err := fory.Unmarshal(bytes, &newValue); err != nil {
- panic(err)
- }
- fmt.Println(newValue)
+ list := []interface{}{true, false, "str", -1.1, 1, make([]int32, 10),
make([]float64, 20)}
+ fory := forygo.NewFory()
+ bytes, err := fory.Marshal(list)
+ if err != nil {
+ panic(err)
+ }
+ var newValue interface{}
+ // bytes can be deserialized by other languages
+ if err := fory.Unmarshal(bytes, &newValue); err != nil {
+ panic(err)
+ }
+ fmt.Println(newValue)
+ dict := map[string]interface{}{
+ "k1": "v1",
+ "k2": list,
+ "k3": -1,
+ }
+ bytes, err = fory.Marshal(dict)
+ if err != nil {
+ panic(err)
+ }
+ // bytes can be deserialized by other languages
+ if err := fory.Unmarshal(bytes, &newValue); err != nil {
+ panic(err)
+ }
+ fmt.Println(newValue)
}
```
-**JavaScript**
+### JavaScript
```javascript
import Fory from "@apache-fory/fory";
/**
- * @apache-fory/hps use v8's fast-calls-api that can be called directly by
jit, ensure that the version of Node is 20 or above.
- * Experimental feature, installation success cannot be guaranteed at this
moment
+ * @apache-fory/hps use v8's fast-calls-api that can be called directly by jit,
+ * ensure that the version of Node is 20 or above.
+ * Experimental feature, installation success cannot be guaranteed at this
moment.
* If you are unable to install the module, replace it with `const hps = null;`
**/
import hps from "@apache-fory/hps";
@@ -124,10 +127,9 @@ const result = fory.deserialize(input);
console.log(result);
```
-**Rust**
+### Rust
```rust
-use chrono::{NaiveDate, NaiveDateTime};
use fory::{from_buffer, to_buffer, Fory};
use std::collections::HashMap;
@@ -138,11 +140,11 @@ fn run() {
}
```
-## Serialize custom types
+## Serialize Custom Types
-Serializing user-defined types needs registering the custom type using the
register API to establish the mapping relationship between the type in
different languages.
+User-defined types must be registered using the register API to establish the
mapping relationship between types in different languages. Use consistent type
names across all languages.
-**Java**
+### Java
```java
import org.apache.fory.*;
@@ -196,13 +198,13 @@ public class Example2 {
fory.register(SomeClass1.class, "example.SomeClass1");
fory.register(SomeClass2.class, "example.SomeClass2");
byte[] bytes = fory.serialize(createObject());
- // bytes can be data serialized by other languages.
+ // bytes can be deserialized by other languages
System.out.println(fory.deserialize(bytes));
}
}
```
-**Python**
+### Python
```python
from dataclasses import dataclass
@@ -226,8 +228,7 @@ class SomeClass2:
f6: pyfory.Int16Type = None
f7: pyfory.Int32Type = None
# int type will be taken as `pyfory.Int64Type`.
- # use `pyfory.Int32Type` for type hint if peer
- # are more narrow type.
+ # use `pyfory.Int32Type` for type hint if peer uses more narrow type.
f8: int = None
f9: pyfory.Float32Type = None
# float type will be taken as `pyfory.Float64Type`
@@ -256,88 +257,89 @@ if __name__ == "__main__":
f12=[-1, 4],
)
data = f.serialize(obj)
- # bytes can be data serialized by other languages.
+ # bytes can be deserialized by other languages
print(f.deserialize(data))
```
-**Golang**
+### Go
```go
package main
-import forygo "github.com/apache/fory/fory/go/fory"
+import forygo "github.com/apache/fory/go/fory"
import "fmt"
func main() {
- type SomeClass1 struct {
- F1 interface{}
- F2 string
- F3 []interface{}
- F4 map[int8]int32
- F5 int8
- F6 int16
- F7 int32
- F8 int64
- F9 float32
- F10 float64
- F11 []int16
- F12 fory.Int16Slice
- }
-
- type SomeClas2 struct {
- F1 interface{}
- F2 map[int8]int32
- }
- fory := forygo.NewFory()
- if err := fory.RegisterNamedType(SomeClass1{}, "example.SomeClass1"); err !=
nil {
- panic(err)
- }
- if err := fory.RegisterNamedType(SomeClass2{}, "example.SomeClass2"); err !=
nil {
- panic(err)
- }
- obj1 := &SomeClass1{}
- obj1.F1 = true
- obj1.F2 = map[int8]int32{-1: 2}
- obj := &SomeClass1{}
- obj.F1 = obj1
- obj.F2 = "abc"
- obj.F3 = []interface{}{"abc", "abc"}
- f4 := map[int8]int32{1: 2}
- obj.F4 = f4
- obj.F5 = fory.MaxInt8
- obj.F6 = fory.MaxInt16
- obj.F7 = fory.MaxInt32
- obj.F8 = fory.MaxInt64
- obj.F9 = 1.0 / 2
- obj.F10 = 1 / 3.0
- obj.F11 = []int16{1, 2}
- obj.F12 = []int16{-1, 4}
- bytes, err := fory.Marshal(obj);
- if err != nil {
- panic(err)
- }
- var newValue interface{}
- // bytes can be data serialized by other languages.
- if err := fory.Unmarshal(bytes, &newValue); err != nil {
- panic(err)
- }
- fmt.Println(newValue)
+ type SomeClass1 struct {
+ F1 interface{}
+ F2 string
+ F3 []interface{}
+ F4 map[int8]int32
+ F5 int8
+ F6 int16
+ F7 int32
+ F8 int64
+ F9 float32
+ F10 float64
+ F11 []int16
+ F12 fory.Int16Slice
+ }
+
+ type SomeClass2 struct {
+ F1 interface{}
+ F2 map[int8]int32
+ }
+ fory := forygo.NewFory()
+ if err := fory.RegisterTagType("example.SomeClass1", SomeClass1{}); err !=
nil {
+ panic(err)
+ }
+ if err := fory.RegisterTagType("example.SomeClass2", SomeClass2{}); err !=
nil {
+ panic(err)
+ }
+ obj1 := &SomeClass1{}
+ obj1.F1 = true
+ obj1.F2 = map[int8]int32{-1: 2}
+ obj := &SomeClass1{}
+ obj.F1 = obj1
+ obj.F2 = "abc"
+ obj.F3 = []interface{}{"abc", "abc"}
+ f4 := map[int8]int32{1: 2}
+ obj.F4 = f4
+ obj.F5 = fory.MaxInt8
+ obj.F6 = fory.MaxInt16
+ obj.F7 = fory.MaxInt32
+ obj.F8 = fory.MaxInt64
+ obj.F9 = 1.0 / 2
+ obj.F10 = 1 / 3.0
+ obj.F11 = []int16{1, 2}
+ obj.F12 = []int16{-1, 4}
+ bytes, err := fory.Marshal(obj);
+ if err != nil {
+ panic(err)
+ }
+ var newValue interface{}
+ // bytes can be deserialized by other languages
+ if err := fory.Unmarshal(bytes, &newValue); err != nil {
+ panic(err)
+ }
+ fmt.Println(newValue)
}
```
-**JavaScript**
+### JavaScript
```javascript
import Fory, { Type, InternalSerializerType } from "@apache-fory/fory";
/**
- * @apache-fory/hps use v8's fast-calls-api that can be called directly by
jit, ensure that the version of Node is 20 or above.
- * Experimental feature, installation success cannot be guaranteed at this
moment
+ * @apache-fory/hps use v8's fast-calls-api that can be called directly by jit,
+ * ensure that the version of Node is 20 or above.
+ * Experimental feature, installation success cannot be guaranteed at this
moment.
* If you are unable to install the module, replace it with `const hps = null;`
**/
import hps from "@apache-fory/hps";
-// Now we describe data structures using JSON, but in the future, we will use
more ways.
+// Describe data structures using JSON schema
const description = Type.object("example.foo", {
foo: Type.string(),
});
@@ -348,7 +350,7 @@ const result = deserialize(input);
console.log(result);
```
-**Rust**
+### Rust
```rust
use chrono::{NaiveDate, NaiveDateTime};
@@ -407,11 +409,11 @@ fn complex_struct() {
}
```
-## Serialize Shared Reference and Circular Reference
+## Serialize Shared and Circular References
-Shared reference and circular reference can be serialized automatically, no
duplicate data or recursion error.
+Shared references and circular references can be serialized automatically with
no duplicate data or recursion errors. Enable reference tracking to use this
feature.
-**Java**
+### Java
```java
import org.apache.fory.*;
@@ -439,13 +441,13 @@ public class ReferenceExample {
.withRefTracking(true).build();
fory.register(SomeClass.class, "example.SomeClass");
byte[] bytes = fory.serialize(createObject());
- // bytes can be data serialized by other languages.
+ // bytes can be deserialized by other languages
System.out.println(fory.deserialize(bytes));
}
}
```
-**Python**
+### Python
```python
from typing import Dict
@@ -462,63 +464,65 @@ obj = SomeClass()
obj.f2 = {"k1": "v1", "k2": "v2"}
obj.f1, obj.f3 = obj, obj.f2
data = fory.serialize(obj)
-# bytes can be data serialized by other languages.
+# bytes can be deserialized by other languages
print(fory.deserialize(data))
```
-**Golang**
+### Go
```go
package main
-import forygo "github.com/apache/fory/fory/go/fory"
+import forygo "github.com/apache/fory/go/fory"
import "fmt"
func main() {
- type SomeClass struct {
- F1 *SomeClass
- F2 map[string]string
- F3 map[string]string
- }
- fory := forygo.NewFory(true)
- if err := fory.Register(SomeClass{}, 65); err != nil {
- panic(err)
- }
- value := &SomeClass{F2: map[string]string{"k1": "v1", "k2": "v2"}}
- value.F3 = value.F2
- value.F1 = value
- bytes, err := fory.Marshal(value)
- if err != nil {
- }
- var newValue interface{}
- // bytes can be data serialized by other languages.
- if err := fory.Unmarshal(bytes, &newValue); err != nil {
- panic(err)
- }
- fmt.Println(newValue)
+ type SomeClass struct {
+ F1 *SomeClass
+ F2 map[string]string
+ F3 map[string]string
+ }
+ fory := forygo.NewFory(true)
+ if err := fory.Register(SomeClass{}, 65); err != nil {
+ panic(err)
+ }
+ value := &SomeClass{F2: map[string]string{"k1": "v1", "k2": "v2"}}
+ value.F3 = value.F2
+ value.F1 = value
+ bytes, err := fory.Marshal(value)
+ if err != nil {
+ panic(err)
+ }
+ var newValue interface{}
+ // bytes can be deserialized by other languages
+ if err := fory.Unmarshal(bytes, &newValue); err != nil {
+ panic(err)
+ }
+ fmt.Println(newValue)
}
```
-**JavaScript**
+### JavaScript
```javascript
-import Fory, { Type } from '@apache-fory/fory';
+import Fory, { Type } from "@apache-fory/fory";
/**
- * @apache-fory/hps use v8's fast-calls-api that can be called directly by
jit, ensure that the version of Node is 20 or above.
- * Experimental feature, installation success cannot be guaranteed at this
moment
+ * @apache-fory/hps use v8's fast-calls-api that can be called directly by jit,
+ * ensure that the version of Node is 20 or above.
+ * Experimental feature, installation success cannot be guaranteed at this
moment.
* If you are unable to install the module, replace it with `const hps = null;`
**/
-import hps from '@apache-fory/hps';
+import hps from "@apache-fory/hps";
-const description = Type.object('example.foo', {
+const description = Type.object("example.foo", {
foo: Type.string(),
- bar: Type.object('example.foo'),
+ bar: Type.object("example.foo"),
});
const fory = new Fory({ hps });
const { serialize, deserialize } = fory.registerSerializer(description);
const data: any = {
- foo: 'hello fory',
+ foo: "hello fory",
};
data.bar = data;
const input = serialize(data);
@@ -526,85 +530,13 @@ const result = deserialize(input);
console.log(result.bar.foo === result.foo);
```
-**JavaScript**
-Reference cannot be implemented because of rust ownership restrictions
+### Rust
-## Zero-Copy Serialization
+Circular references cannot be implemented in Rust due to ownership
restrictions.
-**Java**
+## See Also
-```java
-import org.apache.fory.*;
-import org.apache.fory.config.*;
-import org.apache.fory.serializer.BufferObject;
-import org.apache.fory.memory.MemoryBuffer;
-
-import java.util.*;
-import java.util.stream.Collectors;
-
-public class ZeroCopyExample {
- // mvn exec:java -Dexec.mainClass="io.ray.fory.examples.ZeroCopyExample"
- public static void main(String[] args) {
- Fory fory = Fory.builder().withLanguage(Language.XLANG).build();
- List<Object> list = ofArrayList("str", new byte[1000], new int[100], new
double[100]);
- Collection<BufferObject> bufferObjects = new ArrayList<>();
- byte[] bytes = fory.serialize(list, e -> !bufferObjects.add(e));
- // bytes can be data serialized by other languages.
- List<MemoryBuffer> buffers = bufferObjects.stream()
- .map(BufferObject::toBuffer).collect(Collectors.toList());
- System.out.println(fory.deserialize(bytes, buffers));
- }
-}
-```
-
-**Python**
-
-```python
-import array
-import pyfory
-import numpy as np
-
-fory = pyfory.Fory()
-list_ = ["str", bytes(bytearray(1000)),
- array.array("i", range(100)), np.full(100, 0.0, dtype=np.double)]
-serialized_objects = []
-data = fory.serialize(list_, buffer_callback=serialized_objects.append)
-buffers = [o.to_buffer() for o in serialized_objects]
-# bytes can be data serialized by other languages.
-print(fory.deserialize(data, buffers=buffers))
-```
-
-**Golang**
-
-```go
-package main
-
-import forygo "github.com/apache/fory/fory/go/fory"
-import "fmt"
-
-func main() {
- fory := forygo.NewFory()
- list := []interface{}{"str", make([]byte, 1000)}
- buf := fory.NewByteBuffer(nil)
- var bufferObjects []fory.BufferObject
- fory.Serialize(buf, list, func(o fory.BufferObject) bool {
- bufferObjects = append(bufferObjects, o)
- return false
- })
- var newList []interface{}
- var buffers []*fory.ByteBuffer
- for _, o := range bufferObjects {
- buffers = append(buffers, o.ToBuffer())
- }
- if err := fory.Deserialize(buf, &newList, buffers); err != nil {
- panic(err)
- }
- fmt.Println(newList)
-}
-```
-
-**JavaScript**
-
-```javascript
-// Coming soon
-```
+- [Zero-Copy Serialization](zero-copy.md) - Out-of-band serialization for
large data
+- [Type
Mapping](https://fory.apache.org/docs/specification/xlang_type_mapping) -
Cross-language type mapping reference
+- [Getting Started](getting-started.md) - Installation and setup
+- [Xlang Serialization
Specification](https://fory.apache.org/docs/next/specification/fory_xlang_serialization_spec)
- Binary protocol details
diff --git a/docs/docs/guide/xlang/troubleshooting.md
b/docs/docs/guide/xlang/troubleshooting.md
new file mode 100644
index 000000000..26c4707ed
--- /dev/null
+++ b/docs/docs/guide/xlang/troubleshooting.md
@@ -0,0 +1,321 @@
+---
+title: Troubleshooting
+sidebar_position: 6
+id: xlang_troubleshooting
+license: |
+ 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.
+---
+
+This page covers common issues and solutions when using cross-language
serialization.
+
+## Type Registration Errors
+
+### "Type not registered" Error
+
+**Symptom:**
+
+```
+Error: Type 'example.Person' is not registered
+```
+
+**Cause:** The type was not registered before deserialization, or the type
name doesn't match.
+
+**Solution:**
+
+1. Ensure the type is registered with the same name on both sides:
+
+ ```java
+ // Java
+ fory.register(Person.class, "example.Person");
+ ```
+
+ ```python
+ # Python
+ fory.register_type(Person, typename="example.Person")
+ ```
+
+2. Check for typos or case differences in type names
+
+3. Register types before any serialization/deserialization calls
+
+### "Type ID mismatch" Error
+
+**Symptom:**
+
+```
+Error: Expected type ID 100, got 101
+```
+
+**Cause:** Different type IDs used across languages.
+
+**Solution:** Use consistent type IDs:
+
+```java
+// Java
+fory.register(Person.class, 100);
+fory.register(Address.class, 101);
+```
+
+```python
+# Python
+fory.register_type(Person, type_id=100)
+fory.register_type(Address, type_id=101)
+```
+
+## Type Mapping Issues
+
+### Integer Overflow
+
+**Symptom:** Values are truncated or wrapped unexpectedly.
+
+**Cause:** Using different integer sizes across languages.
+
+**Solution:**
+
+1. In Python, use explicit type annotations:
+
+ ```python
+ @dataclass
+ class Data:
+ value: pyfory.Int32Type # Not just 'int'
+ ```
+
+2. Ensure integer ranges are compatible:
+ - `int8`: -128 to 127
+ - `int16`: -32,768 to 32,767
+ - `int32`: -2,147,483,648 to 2,147,483,647
+
+### Float Precision Loss
+
+**Symptom:** Float values have unexpected precision.
+
+**Cause:** Mixing `float32` and `float64` types.
+
+**Solution:**
+
+1. Use consistent float types:
+
+ ```python
+ @dataclass
+ class Data:
+ value: pyfory.Float32Type # Explicit 32-bit float
+ ```
+
+2. Be aware that Python's `float` maps to `float64` by default
+
+### String Encoding Errors
+
+**Symptom:**
+
+```
+Error: Invalid UTF-8 sequence
+```
+
+**Cause:** Non-UTF-8 encoded strings.
+
+**Solution:**
+
+1. Ensure all strings are valid UTF-8
+2. In Python, decode bytes before serialization:
+
+ ```python
+ text = raw_bytes.decode('utf-8')
+ ```
+
+## Field Order Issues
+
+### "Field mismatch" Error
+
+**Symptom:** Deserialized objects have wrong field values.
+
+**Cause:** Field order differs between languages.
+
+**Solution:** Fory sorts fields by their snake_cased names. Ensure field names
are consistent:
+
+```java
+// Java - fields will be sorted: age, email, name
+public class Person {
+ public String name;
+ public int age;
+ public String email;
+}
+```
+
+```python
+# Python - same field order
+@dataclass
+class Person:
+ name: str
+ age: pyfory.Int32Type
+ email: str
+```
+
+## Reference Tracking Issues
+
+### Stack Overflow with Circular References
+
+**Symptom:**
+
+```
+StackOverflowError or RecursionError
+```
+
+**Cause:** Reference tracking is disabled but data has circular references.
+
+**Solution:** Enable reference tracking:
+
+```java
+// Java
+Fory fory = Fory.builder()
+ .withLanguage(Language.XLANG)
+ .withRefTracking(true)
+ .build();
+```
+
+```python
+# Python
+fory = pyfory.Fory(ref_tracking=True)
+```
+
+### Duplicate Objects
+
+**Symptom:** Shared objects are duplicated after deserialization.
+
+**Cause:** Reference tracking is disabled.
+
+**Solution:** Enable reference tracking if objects are shared within the graph.
+
+## Language Mode Issues
+
+### "Invalid magic number" Error
+
+**Symptom:**
+
+```
+Error: Invalid magic number in header
+```
+
+**Cause:** One side is using Java-native mode instead of xlang mode.
+
+**Solution:** Ensure both sides use xlang mode:
+
+```java
+// Java - must use Language.XLANG
+Fory fory = Fory.builder()
+ .withLanguage(Language.XLANG)
+ .build();
+```
+
+### Incompatible Types in Xlang Mode
+
+**Symptom:**
+
+```
+Error: Type 'Optional' is not supported in xlang mode
+```
+
+**Cause:** Using Java-specific types that don't have cross-language
equivalents.
+
+**Solution:** Use compatible types:
+
+```java
+// Instead of Optional<String>
+public String email; // nullable
+
+// Instead of BigDecimal
+public double amount;
+
+// Instead of EnumSet<Status>
+public Set<Status> statuses;
+```
+
+## Version Compatibility
+
+### Serialization Format Changed
+
+**Symptom:** Deserialization fails after upgrading Fory.
+
+**Cause:** Breaking changes in serialization format.
+
+**Solution:**
+
+1. Ensure all services use compatible Fory versions
+2. Check release notes for breaking changes
+3. Consider using schema evolution (compatible mode) for gradual upgrades
+
+## Debugging Tips
+
+### Enable Debug Logging
+
+**Java:**
+
+```java
+// Add to JVM options
+-Dfory.debug=true
+```
+
+**Python:**
+
+```python
+import logging
+logging.getLogger('pyfory').setLevel(logging.DEBUG)
+```
+
+### Inspect Serialized Data
+
+Use hex dump to inspect the binary format:
+
+```python
+data = fory.serialize(obj)
+print(data.hex())
+```
+
+### Test Round-Trip
+
+Always test round-trip serialization in each language:
+
+```java
+byte[] bytes = fory.serialize(obj);
+Object result = fory.deserialize(bytes);
+assert obj.equals(result);
+```
+
+### Cross-Language Testing
+
+Test serialization across all target languages before deployment:
+
+```bash
+# Serialize in Java
+java -jar serializer.jar > data.bin
+
+# Deserialize in Python
+python deserializer.py data.bin
+```
+
+## Common Mistakes
+
+1. **Not registering types**: Always register custom types before use
+2. **Inconsistent type names/IDs**: Use the same names/IDs across all languages
+3. **Forgetting xlang mode**: Use `Language.XLANG` in Java
+4. **Wrong type annotations**: Use `pyfory.Int32Type` etc. in Python
+5. **Ignoring reference tracking**: Enable for circular/shared references
+
+## See Also
+
+- [Type
Mapping](https://fory.apache.org/docs/specification/xlang_type_mapping) -
Cross-language type mapping reference
+- [Getting Started](getting-started.md) - Setup guide
+- [Java Troubleshooting](../java/troubleshooting.md) - Java-specific issues
+- [Python Troubleshooting](../python/troubleshooting.md) - Python-specific
issues
diff --git a/docs/docs/guide/xlang/zero-copy.md
b/docs/docs/guide/xlang/zero-copy.md
new file mode 100644
index 000000000..3d2e83b1a
--- /dev/null
+++ b/docs/docs/guide/xlang/zero-copy.md
@@ -0,0 +1,207 @@
+---
+title: Zero-Copy Serialization
+sidebar_position: 4
+id: xlang_zero_copy
+license: |
+ 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.
+---
+
+Zero-copy serialization allows large binary data (byte arrays, numeric arrays)
to be serialized out-of-band, avoiding memory copies and reducing serialization
overhead.
+
+## When to Use Zero-Copy
+
+Use zero-copy serialization when:
+
+- Serializing large byte arrays or binary blobs
+- Working with numeric arrays (int[], double[], etc.)
+- Transferring data over high-performance networks
+- Memory efficiency is critical
+
+## How It Works
+
+1. **Serialization**: Large buffers are extracted and returned separately via
a callback
+2. **Transport**: The main serialized data and buffer objects are transmitted
separately
+3. **Deserialization**: Buffers are provided back to reconstruct the original
object
+
+This avoids copying large data into the main serialization buffer.
+
+## Java
+
+```java
+import org.apache.fory.*;
+import org.apache.fory.config.*;
+import org.apache.fory.serializer.BufferObject;
+import org.apache.fory.memory.MemoryBuffer;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+public class ZeroCopyExample {
+ public static void main(String[] args) {
+ Fory fory = Fory.builder().withLanguage(Language.XLANG).build();
+
+ // Data with large arrays
+ List<Object> list = List.of(
+ "str",
+ new byte[1000], // Large byte array
+ new int[100], // Large int array
+ new double[100] // Large double array
+ );
+
+ // Collect buffer objects during serialization
+ Collection<BufferObject> bufferObjects = new ArrayList<>();
+ byte[] bytes = fory.serialize(list, e -> !bufferObjects.add(e));
+
+ // Convert to buffers for transport
+ List<MemoryBuffer> buffers = bufferObjects.stream()
+ .map(BufferObject::toBuffer)
+ .collect(Collectors.toList());
+
+ // Deserialize with buffers
+ Object result = fory.deserialize(bytes, buffers);
+ System.out.println(result);
+ }
+}
+```
+
+## Python
+
+```python
+import array
+import pyfory
+import numpy as np
+
+fory = pyfory.Fory()
+
+# Data with large arrays
+data = [
+ "str",
+ bytes(bytearray(1000)), # Large byte array
+ array.array("i", range(100)), # Large int array
+ np.full(100, 0.0, dtype=np.double) # Large numpy array
+]
+
+# Collect buffer objects during serialization
+serialized_objects = []
+serialized_data = fory.serialize(data,
buffer_callback=serialized_objects.append)
+
+# Convert to buffers for transport
+buffers = [obj.to_buffer() for obj in serialized_objects]
+
+# Deserialize with buffers
+result = fory.deserialize(serialized_data, buffers=buffers)
+print(result)
+```
+
+## Go
+
+```go
+package main
+
+import forygo "github.com/apache/fory/go/fory"
+import "fmt"
+
+func main() {
+ fory := forygo.NewFory()
+
+ // Data with large arrays
+ list := []interface{}{
+ "str",
+ make([]byte, 1000), // Large byte array
+ }
+
+ buf := fory.NewByteBuffer(nil)
+ var bufferObjects []fory.BufferObject
+
+ // Collect buffer objects during serialization
+ fory.Serialize(buf, list, func(o fory.BufferObject) bool {
+ bufferObjects = append(bufferObjects, o)
+ return false
+ })
+
+ // Convert to buffers for transport
+ var buffers []*fory.ByteBuffer
+ for _, o := range bufferObjects {
+ buffers = append(buffers, o.ToBuffer())
+ }
+
+ // Deserialize with buffers
+ var newList []interface{}
+ if err := fory.Deserialize(buf, &newList, buffers); err != nil {
+ panic(err)
+ }
+ fmt.Println(newList)
+}
+```
+
+## JavaScript
+
+```javascript
+// Zero-copy support coming soon
+```
+
+## Use Cases
+
+### High-Performance Data Transfer
+
+When sending large datasets over the network:
+
+```java
+// Sender
+Collection<BufferObject> buffers = new ArrayList<>();
+byte[] metadata = fory.serialize(dataObject, e -> !buffers.add(e));
+
+// Send metadata and buffers separately
+network.sendMetadata(metadata);
+for (BufferObject buf : buffers) {
+ network.sendBuffer(buf.toBuffer());
+}
+
+// Receiver
+byte[] metadata = network.receiveMetadata();
+List<MemoryBuffer> buffers = network.receiveBuffers();
+Object data = fory.deserialize(metadata, buffers);
+```
+
+### Memory-Mapped Files
+
+Zero-copy works well with memory-mapped files:
+
+```java
+// Write
+Collection<BufferObject> buffers = new ArrayList<>();
+byte[] data = fory.serialize(largeObject, e -> !buffers.add(e));
+writeToFile("data.bin", data);
+for (int i = 0; i < buffers.size(); i++) {
+ writeToFile("buffer" + i + ".bin", buffers.get(i).toBuffer());
+}
+
+// Read
+byte[] data = readFromFile("data.bin");
+List<MemoryBuffer> buffers = readBufferFiles();
+Object result = fory.deserialize(data, buffers);
+```
+
+## Performance Considerations
+
+1. **Threshold**: Small arrays may not benefit from zero-copy due to callback
overhead
+2. **Network**: Zero-copy is most beneficial when buffers can be sent without
copying
+3. **Memory**: Reduces peak memory usage by avoiding buffer copies
+
+## See Also
+
+- [Serialization](serialization.md) - Standard serialization examples
+- [Python Out-of-Band Guide](../python/out-of-band.md) - Python-specific
zero-copy details
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]