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.git


The following commit(s) were added to refs/heads/main by this push:
     new a7850d5fd refactor(xlang): remove magic number from protocol (#3137)
a7850d5fd is described below

commit a7850d5fd2a17bbaba3cfaf5d3bc7568946e41a0
Author: Shawn Yang <[email protected]>
AuthorDate: Tue Jan 13 11:51:30 2026 +0800

    refactor(xlang): remove magic number from protocol (#3137)
    
    ## Why?
    
    Magic number is more commonly used in file format, the serialization
    framework should not inlucde that, and it's up to user to add magic
    number if they need it
    
    ## What does this PR do?
    
    Remove magic number from protocol and all languages
    
    ## Related issues
    
    
    
    ## Does this PR introduce any user-facing change?
    
    
    
    - [ ] Does this PR introduce any public API change?
    - [ ] Does this PR introduce any binary protocol compatibility change?
    
    ## Benchmark
---
 cpp/fory/serialization/fory.h                      | 26 ++++++++++------------
 cpp/fory/serialization/serialization_test.cc       | 22 +++++++++---------
 cpp/fory/serialization/serializer.h                | 24 +++++---------------
 .../fory/lib/src/const/fory_header_const.dart      |  2 --
 .../lib/src/serializer/fory_header_serializer.dart |  4 ----
 docs/guide/xlang/troubleshooting.md                | 19 ----------------
 docs/specification/xlang_serialization_spec.md     | 15 +++++--------
 go/fory/fory.go                                    | 25 ++++-----------------
 go/fory/fory_test.go                               |  6 ++---
 .../src/main/java/org/apache/fory/Fory.java        | 12 ----------
 .../java/org/apache/fory/xlang/XlangTestBase.java  |  2 +-
 javascript/packages/fory/lib/fory.ts               |  6 +----
 javascript/packages/fory/lib/type.ts               |  2 --
 javascript/test/fory.test.ts                       | 12 ++++------
 python/pyfory/_fory.py                             |  9 --------
 python/pyfory/serialization.pyx                    | 10 ---------
 rust/fory-core/src/fory.rs                         | 17 +-------------
 rust/fory-core/src/types.rs                        |  2 --
 18 files changed, 48 insertions(+), 167 deletions(-)

diff --git a/cpp/fory/serialization/fory.h b/cpp/fory/serialization/fory.h
index 8af54a1d0..0637c9697 100644
--- a/cpp/fory/serialization/fory.h
+++ b/cpp/fory/serialization/fory.h
@@ -557,7 +557,7 @@ private:
   explicit Fory(const Config &config, std::shared_ptr<TypeResolver> resolver)
       : BaseFory(config, std::move(resolver)), finalized_(false),
         precomputed_header_(compute_header(config.xlang)),
-        header_length_(config.xlang ? 4 : 3) {}
+        header_length_(config.xlang ? 2 : 1) {}
 
   /// Constructor for ThreadSafeFory pool - resolver is already finalized.
   struct PreFinalized {};
@@ -565,7 +565,7 @@ private:
                 PreFinalized)
       : BaseFory(config, std::move(resolver)), finalized_(false),
         precomputed_header_(compute_header(config.xlang)),
-        header_length_(config.xlang ? 4 : 3) {
+        header_length_(config.xlang ? 2 : 1) {
     // Pre-finalized, immediately create contexts
     ensure_finalized();
   }
@@ -589,11 +589,9 @@ private:
   }
 
   /// Compute the precomputed header value.
-  static uint32_t compute_header(bool xlang) {
-    uint32_t header = 0;
-    // Magic number (2 bytes, little endian)
-    header |= (MAGIC_NUMBER & 0xFFFF);
-    // Flags byte at position 2
+  static uint16_t compute_header(bool xlang) {
+    uint16_t header = 0;
+    // Flags byte at position 0
     uint8_t flags = 0;
     if (is_little_endian_system()) {
       flags |= (1 << 1); // bit 1: endian flag
@@ -601,9 +599,9 @@ private:
     if (xlang) {
       flags |= (1 << 2); // bit 2: xlang flag
     }
-    header |= (static_cast<uint32_t>(flags) << 16);
-    // Language byte at position 3 (only used if xlang)
-    header |= (static_cast<uint32_t>(Language::CPP) << 24);
+    header |= flags;
+    // Language byte at position 1 (only used if xlang)
+    header |= (static_cast<uint16_t>(Language::CPP) << 8);
     return header;
   }
 
@@ -612,9 +610,9 @@ private:
   Result<size_t, Error> serialize_impl(const T &obj, Buffer &buffer) {
     size_t start_pos = buffer.writer_index();
 
-    // Write precomputed header (4 bytes), then adjust index if not xlang
-    buffer.Grow(4);
-    buffer.UnsafePut<uint32_t>(buffer.writer_index(), precomputed_header_);
+    // Write precomputed header (2 bytes), then adjust index if not xlang
+    buffer.Grow(2);
+    buffer.UnsafePut<uint16_t>(buffer.writer_index(), precomputed_header_);
     buffer.IncreaseWriterIndex(header_length_);
 
     // Reserve space for meta offset in compatible mode
@@ -676,7 +674,7 @@ private:
   }
 
   bool finalized_;
-  uint32_t precomputed_header_;
+  uint16_t precomputed_header_;
   uint8_t header_length_;
   std::optional<WriteContext> write_ctx_;
   std::optional<ReadContext> read_ctx_;
diff --git a/cpp/fory/serialization/serialization_test.cc 
b/cpp/fory/serialization/serialization_test.cc
index fb240e4e9..bf584bdbd 100644
--- a/cpp/fory/serialization/serialization_test.cc
+++ b/cpp/fory/serialization/serialization_test.cc
@@ -239,10 +239,10 @@ TEST(SerializationTest, EnumSerializesOrdinalValue) {
   std::vector<uint8_t> bytes = bytes_result.value();
   // Xlang spec: enums are serialized as varuint32, not fixed int32_t
   // With registration, type_id = (1 << 8) + ENUM = 279, which takes 2 bytes as
-  // varuint32 Expected: 4 (header) + 1 (ref flag) + 2 (type id as varuint) + 1
-  // (ordinal as varuint32) = 8 bytes
-  ASSERT_GE(bytes.size(), 4 + 1 + 2 + 1);
-  size_t offset = 4;
+  // varuint32 Expected: 2 (header) + 1 (ref flag) + 2 (type id as varuint) + 1
+  // (ordinal as varuint32) = 6 bytes
+  ASSERT_GE(bytes.size(), 2 + 1 + 2 + 1);
+  size_t offset = 2;
   EXPECT_EQ(bytes[offset], static_cast<uint8_t>(NOT_NULL_VALUE_FLAG));
   // Type ID 279 = (1 << 8) + ENUM encoded as varuint32: 0x97, 0x02
   EXPECT_EQ(bytes[offset + 1], 0x97);
@@ -261,8 +261,8 @@ TEST(SerializationTest, OldEnumSerializesOrdinalValue) {
 
   std::vector<uint8_t> bytes = bytes_result.value();
   // With registration, type_id = (1 << 8) + ENUM = 279, which takes 2 bytes
-  ASSERT_GE(bytes.size(), 4 + 1 + 2 + 1);
-  size_t offset = 4;
+  ASSERT_GE(bytes.size(), 2 + 1 + 2 + 1);
+  size_t offset = 2;
   EXPECT_EQ(bytes[offset], static_cast<uint8_t>(NOT_NULL_VALUE_FLAG));
   // Type ID 279 encoded as varuint32: 0x97, 0x02
   EXPECT_EQ(bytes[offset + 1], 0x97);
@@ -281,8 +281,8 @@ TEST(SerializationTest, 
EnumOrdinalMappingHandlesNonZeroStart) {
 
   std::vector<uint8_t> bytes = bytes_result.value();
   // With registration, type_id = (1 << 8) + ENUM = 279, which takes 2 bytes
-  ASSERT_GE(bytes.size(), 4 + 1 + 2 + 1);
-  size_t offset = 4;
+  ASSERT_GE(bytes.size(), 2 + 1 + 2 + 1);
+  size_t offset = 2;
   EXPECT_EQ(bytes[offset], static_cast<uint8_t>(NOT_NULL_VALUE_FLAG));
   // Type ID 279 encoded as varuint32: 0x97, 0x02
   EXPECT_EQ(bytes[offset + 1], 0x97);
@@ -305,7 +305,7 @@ TEST(SerializationTest, 
EnumOrdinalMappingRejectsInvalidOrdinal) {
       << "Serialization failed: " << bytes_result.error().to_string();
 
   std::vector<uint8_t> bytes = bytes_result.value();
-  size_t offset = 4;
+  size_t offset = 2;
   // With registration, type_id takes 2 bytes, ordinal is at offset + 3
   // Replace the valid ordinal with an invalid one (99 as varuint32)
   bytes[offset + 3] = 99;
@@ -324,8 +324,8 @@ TEST(SerializationTest, 
OldEnumOrdinalMappingHandlesNonZeroStart) {
 
   std::vector<uint8_t> bytes = bytes_result.value();
   // With registration, type_id = (1 << 8) + ENUM = 279, which takes 2 bytes
-  ASSERT_GE(bytes.size(), 4 + 1 + 2 + 1);
-  size_t offset = 4;
+  ASSERT_GE(bytes.size(), 2 + 1 + 2 + 1);
+  size_t offset = 2;
   EXPECT_EQ(bytes[offset], static_cast<uint8_t>(NOT_NULL_VALUE_FLAG));
   // Type ID 279 encoded as varuint32: 0x97, 0x02
   EXPECT_EQ(bytes[offset + 1], 0x97);
diff --git a/cpp/fory/serialization/serializer.h 
b/cpp/fory/serialization/serializer.h
index 3084d06f6..ae6c4f24e 100644
--- a/cpp/fory/serialization/serializer.h
+++ b/cpp/fory/serialization/serializer.h
@@ -60,9 +60,6 @@ namespace serialization {
 // Protocol Constants
 // ============================================================================
 
-/// Fory protocol magic number (0x62d4)
-constexpr uint16_t MAGIC_NUMBER = 0x62d4;
-
 /// Language identifiers
 /// Must match Java's Language enum ordinal values
 enum class Language : uint8_t {
@@ -90,7 +87,6 @@ inline bool is_little_endian_system() {
 
 /// Fory header information
 struct HeaderInfo {
-  uint16_t magic;
   bool is_null;
   bool is_little_endian;
   bool is_xlang;
@@ -104,32 +100,24 @@ struct HeaderInfo {
 /// @param buffer Input buffer
 /// @return Header information or error
 inline Result<HeaderInfo, Error> read_header(Buffer &buffer) {
-  // Check minimum header size (3 bytes: magic + flags)
-  if (buffer.reader_index() + 3 > buffer.size()) {
+  // Check minimum header size (1 byte: flags)
+  if (buffer.reader_index() + 1 > buffer.size()) {
     return Unexpected(
-        Error::buffer_out_of_bound(buffer.reader_index(), 3, buffer.size()));
+        Error::buffer_out_of_bound(buffer.reader_index(), 1, buffer.size()));
   }
 
   HeaderInfo info;
   uint32_t start_pos = buffer.reader_index();
 
-  // Read magic number
-  info.magic = buffer.Get<uint16_t>(start_pos);
-  if (info.magic != MAGIC_NUMBER) {
-    return Unexpected(
-        Error::invalid_data("Invalid magic number: expected 0x62d4, got 0x" +
-                            std::to_string(info.magic)));
-  }
-
   // Read flags byte
-  uint8_t flags = buffer.GetByteAs<uint8_t>(start_pos + 2);
+  uint8_t flags = buffer.GetByteAs<uint8_t>(start_pos);
   info.is_null = (flags & (1 << 0)) != 0;
   info.is_little_endian = (flags & (1 << 1)) != 0;
   info.is_xlang = (flags & (1 << 2)) != 0;
   info.is_oob = (flags & (1 << 3)) != 0;
 
-  // Update reader index (3 bytes consumed: magic + flags)
-  buffer.IncreaseReaderIndex(3);
+  // Update reader index (1 byte consumed: flags)
+  buffer.IncreaseReaderIndex(1);
 
   // Java writes a language byte after header in xlang mode - read and ignore 
it
   if (info.is_xlang) {
diff --git a/dart/packages/fory/lib/src/const/fory_header_const.dart 
b/dart/packages/fory/lib/src/const/fory_header_const.dart
index 4e6c6aa80..36758952d 100644
--- a/dart/packages/fory/lib/src/const/fory_header_const.dart
+++ b/dart/packages/fory/lib/src/const/fory_header_const.dart
@@ -18,8 +18,6 @@
  */
 
 class ForyHeaderConst{
-  static const int magicNumber = 0x62d4;
-
   static const int nullFlag = 1;
   static const int littleEndianFlag = 1 << 1;
   static const int crossLanguageFlag = 1 << 2;
diff --git a/dart/packages/fory/lib/src/serializer/fory_header_serializer.dart 
b/dart/packages/fory/lib/src/serializer/fory_header_serializer.dart
index 1078a22b7..eeacd3947 100644
--- a/dart/packages/fory/lib/src/serializer/fory_header_serializer.dart
+++ b/dart/packages/fory/lib/src/serializer/fory_header_serializer.dart
@@ -38,9 +38,6 @@ final class ForyHeaderSerializer {
   ForyHeaderSerializer._();
 
   HeaderBrief? read(ByteReader br, ForyConfig conf) {
-    int magicNumber = br.readUint16();
-    // Note: In AOT mode, assert will be removed, do not put code that affects 
subsequent logic in assert
-    assert(magicNumber == ForyHeaderConst.magicNumber, 'no magic number 
detected');
     int bitmap = br.readInt8();
     // header: nullFlag
     if ((bitmap & ForyHeaderConst.nullFlag) != 0){
@@ -77,7 +74,6 @@ final class ForyHeaderSerializer {
   }
 
   void write(ByteWriter bd, bool objNull, ForyConfig conf) {
-    bd.writeInt16(ForyHeaderConst.magicNumber);
     int bitmap = ForyHeaderConst.littleEndianFlag;
     bitmap |= ForyHeaderConst.crossLanguageFlag;
     if (objNull){
diff --git a/docs/guide/xlang/troubleshooting.md 
b/docs/guide/xlang/troubleshooting.md
index bba9d51e3..52419484c 100644
--- a/docs/guide/xlang/troubleshooting.md
+++ b/docs/guide/xlang/troubleshooting.md
@@ -200,25 +200,6 @@ fory = pyfory.Fory(ref_tracking=True)
 
 ## 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:**
diff --git a/docs/specification/xlang_serialization_spec.md 
b/docs/specification/xlang_serialization_spec.md
index be6f27f35..ef653cd96 100644
--- a/docs/specification/xlang_serialization_spec.md
+++ b/docs/specification/xlang_serialization_spec.md
@@ -251,26 +251,24 @@ Fory will write the byte order for that object into the 
data instead of converti
 Fory header format for xlang serialization:
 
 ```
-|    2 bytes   |        1 byte bitmap           |   1 byte   |          
optional 4 bytes          |
-+--------------+--------------------------------+------------+------------------------------------+
-| magic number |  4 bits reserved | 4 bits meta |  language  | unsigned int 
for meta start offset |
+|        1 byte bitmap           |   1 byte   |          optional 4 bytes      
    |
++--------------------------------+------------+------------------------------------+
+|  4 bits reserved | 4 bits meta |  language  | unsigned int for meta start 
offset |
 ```
 
 Detailed byte layout:
 
 ```
-Byte 0-1: Magic number (0x62d4) - little endian
-Byte 2:   Bitmap flags
+Byte 0:   Bitmap flags
           - Bit 0: null flag (0x01)
           - Bit 1: endian flag (0x02)
           - Bit 2: xlang flag (0x04)
           - Bit 3: oob flag (0x08)
           - Bits 4-7: reserved
-Byte 3:   Language ID (only present when xlang flag is set)
-Byte 4-7: Meta start offset (only present when meta share mode is enabled)
+Byte 1:   Language ID (only present when xlang flag is set)
+Byte 2-5: Meta start offset (only present when meta share mode is enabled)
 ```
 
-- **magic number**: `0x62d4` (2 bytes, little endian) - used to identify fory 
xlang serialization protocol.
 - **null flag** (bit 0): 1 when object is null, 0 otherwise. If an object is 
null, only this flag and endian flag are set.
 - **endian flag** (bit 1): 1 when data is encoded by little endian, 0 for big 
endian. Modern implementations always use little endian.
 - **xlang flag** (bit 2): 1 when serialization uses Fory xlang format, 0 when 
serialization uses Fory language-native format.
@@ -1528,7 +1526,6 @@ This section provides a step-by-step guide for 
implementing Fory xlang serializa
    - [ ] Optionally implement Hybrid encoding (TAGGED_INT64/TAGGED_UINT64) for 
int64
 
 3. **Header Handling**
-   - [ ] Write magic number `0x62d4`
    - [ ] Write/read bitmap flags (null, endian, xlang, oob)
    - [ ] Write/read language ID
    - [ ] Handle meta start offset placeholder (for schema evolution)
diff --git a/go/fory/fory.go b/go/fory/fory.go
index bf02cb6e8..970374e70 100644
--- a/go/fory/fory.go
+++ b/go/fory/fory.go
@@ -31,9 +31,6 @@ import (
 // Errors
 // ============================================================================
 
-// ErrMagicNumber indicates an invalid magic number in the data stream
-var ErrMagicNumber = errors.New("fory: invalid magic number")
-
 // ErrNoSerializer indicates no serializer is registered for a type
 var ErrNoSerializer = errors.New("fory: no serializer registered for type")
 
@@ -41,11 +38,6 @@ var ErrNoSerializer = errors.New("fory: no serializer 
registered for type")
 // Constants
 // ============================================================================
 
-// Protocol constants
-const (
-       MAGIC_NUMBER int16 = 0x62D4
-)
-
 // Language constants for protocol header
 const (
        LangXLANG uint8 = iota
@@ -514,8 +506,7 @@ func (f *Fory) resetWriteState() {
 func (f *Fory) SerializeTo(buf *ByteBuffer, value any) error {
        // Handle nil values
        if isNilValue(value) {
-               // Use Java-compatible null format: 3 bytes (magic + bitmap 
with isNilFlag)
-               buf.WriteInt16(MAGIC_NUMBER)
+               // Use Java-compatible null format: 1 byte (bitmap with 
isNilFlag)
                buf.WriteByte_(IsNilFlag)
                return nil
        }
@@ -855,8 +846,6 @@ func (f *Fory) serializeReflectValue(value reflect.Value) 
([]byte, error) {
 
 // writeHeader writes the Fory protocol header
 func writeHeader(ctx *WriteContext, config Config) {
-       ctx.buffer.WriteInt16(MAGIC_NUMBER)
-
        var bitmap byte = 0
        if nativeEndian == binary.LittleEndian {
                bitmap |= LittleEndianFlag
@@ -885,10 +874,9 @@ func isNilValue(value any) bool {
        return false
 }
 
-// writeNullHeader writes a null object header (3 bytes: magic + bitmap with 
isNilFlag)
+// writeNullHeader writes a null object header (1 byte: bitmap with isNilFlag)
 // This is compatible with Java's null serialization format
 func writeNullHeader(ctx *WriteContext) {
-       ctx.buffer.WriteInt16(MAGIC_NUMBER)
        ctx.buffer.WriteByte_(IsNilFlag) // bitmap with only isNilFlag set
 }
 
@@ -902,17 +890,12 @@ const NullObjectMetaOffset int32 = -0x7FFFFFFF
 // Sets error on ctx if header is invalid (use ctx.HasError() to check)
 func readHeader(ctx *ReadContext) int32 {
        err := ctx.Err()
-       magicNumber := ctx.buffer.ReadInt16(err)
+       bitmap := ctx.buffer.ReadByte(err)
        if ctx.HasError() {
                return 0
        }
-       if magicNumber != MAGIC_NUMBER {
-               ctx.SetError(DeserializationError("invalid magic number"))
-               return 0
-       }
-       bitmap := ctx.buffer.ReadByte(err)
 
-       // Check if this is a null object - only magic number + bitmap with 
isNilFlag was written
+       // Check if this is a null object - only bitmap with isNilFlag was 
written
        if (bitmap & IsNilFlag) != 0 {
                return NullObjectMetaOffset
        }
diff --git a/go/fory/fory_test.go b/go/fory/fory_test.go
index e42911cb5..fef69a066 100644
--- a/go/fory/fory_test.go
+++ b/go/fory/fory_test.go
@@ -310,10 +310,8 @@ func TestSerializeBeginWithMagicNumber(t *testing.T) {
        bytes, err := fory.Marshal(strSlice)
        require.Nil(t, err, fmt.Sprintf("serialize value %s with type %s 
failed: %s",
                reflect.ValueOf(strSlice), reflect.TypeOf(strSlice), err))
-       // Contains at least two bytes.
-       require.True(t, len(bytes) > 2)
-       magicNumber := int16(bytes[0]) | (int16(bytes[1]) << 8)
-       require.Equal(t, magicNumber, MAGIC_NUMBER)
+       // Contains at least one byte for the bitmap.
+       require.True(t, len(bytes) >= 1)
 }
 
 type Foo struct {
diff --git a/java/fory-core/src/main/java/org/apache/fory/Fory.java 
b/java/fory-core/src/main/java/org/apache/fory/Fory.java
index 0188055e6..dd9c11e30 100644
--- a/java/fory-core/src/main/java/org/apache/fory/Fory.java
+++ b/java/fory-core/src/main/java/org/apache/fory/Fory.java
@@ -104,7 +104,6 @@ public final class Fory implements BaseFory {
   private static final byte isOutOfBandFlag = 1 << 3;
   private static final boolean isLittleEndian = ByteOrder.nativeOrder() == 
ByteOrder.LITTLE_ENDIAN;
   private static final byte BITMAP = isLittleEndian ? isLittleEndianFlag : 0;
-  private static final short MAGIC_NUMBER = 0x62D4;
 
   private final Config config;
   private final boolean refTracking;
@@ -298,9 +297,6 @@ public final class Fory implements BaseFory {
 
   @Override
   public MemoryBuffer serialize(MemoryBuffer buffer, Object obj, 
BufferCallback callback) {
-    if (crossLanguage) {
-      buffer.writeInt16(MAGIC_NUMBER);
-    }
     byte bitmap = BITMAP;
     if (crossLanguage) {
       bitmap |= isCrossLanguageFlag;
@@ -831,14 +827,6 @@ public final class Fory implements BaseFory {
         throwDepthDeserializationException();
       }
       depth = 0;
-      if (crossLanguage) {
-        short magicNumber = buffer.readInt16();
-        assert magicNumber == MAGIC_NUMBER
-            : String.format(
-                "The fory xlang serialization must start with magic number 
0x%x. Please "
-                    + "check whether the serialization is based on the xlang 
protocol and the data didn't corrupt.",
-                MAGIC_NUMBER);
-      }
       byte bitmap = buffer.readByte();
       if ((bitmap & isNilFlag) == isNilFlag) {
         return null;
diff --git 
a/java/fory-core/src/test/java/org/apache/fory/xlang/XlangTestBase.java 
b/java/fory-core/src/test/java/org/apache/fory/xlang/XlangTestBase.java
index 837ff1152..06217ad3e 100644
--- a/java/fory-core/src/test/java/org/apache/fory/xlang/XlangTestBase.java
+++ b/java/fory-core/src/test/java/org/apache/fory/xlang/XlangTestBase.java
@@ -213,7 +213,7 @@ public abstract class XlangTestBase extends ForyTestBase {
   }
 
   protected void runPeer(ExecutionContext ctx) {
-    runPeer(ctx, 30);
+    runPeer(ctx, 60);
   }
 
   protected void runPeer(ExecutionContext ctx, int timeoutSeconds) {
diff --git a/javascript/packages/fory/lib/fory.ts 
b/javascript/packages/fory/lib/fory.ts
index f3579fb56..21f1ed117 100644
--- a/javascript/packages/fory/lib/fory.ts
+++ b/javascript/packages/fory/lib/fory.ts
@@ -21,7 +21,7 @@ import ClassResolver from "./classResolver";
 import { BinaryWriter } from "./writer";
 import { BinaryReader } from "./reader";
 import { ReferenceResolver } from "./referenceResolver";
-import { ConfigFlags, Serializer, Config, Language, MAGIC_NUMBER, Mode, 
ForyTypeInfoSymbol, WithForyClsInfo } from "./type";
+import { ConfigFlags, Serializer, Config, Language, Mode, ForyTypeInfoSymbol, 
WithForyClsInfo } from "./type";
 import { OwnershipError } from "./error";
 import { InputType, ResultType, TypeInfo } from "./typeInfo";
 import { Gen, AnySerializer } from "./gen";
@@ -110,9 +110,6 @@ export default class {
     this.binaryReader.reset(bytes);
     this.typeMetaResolver.reset();
     this.metaStringResolver.reset();
-    if (this.binaryReader.int16() !== MAGIC_NUMBER) {
-      throw new Error("the fory xlang serialization must start with magic 
number 0x%x. Please check whether the serialization is based on the xlang 
protocol and the data didn't corrupt");
-    }
     const bitmap = this.binaryReader.uint8();
     if ((bitmap & ConfigFlags.isNullFlag) === ConfigFlags.isNullFlag) {
       return null;
@@ -152,7 +149,6 @@ export default class {
     }
     bitmap |= ConfigFlags.isLittleEndianFlag;
     bitmap |= ConfigFlags.isCrossLanguageFlag;
-    this.binaryWriter.int16(MAGIC_NUMBER);
     this.binaryWriter.uint8(bitmap);
     this.binaryWriter.uint8(Language.JAVASCRIPT);
     const cursor = this.binaryWriter.getCursor();
diff --git a/javascript/packages/fory/lib/type.ts 
b/javascript/packages/fory/lib/type.ts
index b4583e49a..cf06f9cbe 100644
--- a/javascript/packages/fory/lib/type.ts
+++ b/javascript/packages/fory/lib/type.ts
@@ -241,8 +241,6 @@ export enum Language {
   DART = 7,
 }
 
-export const MAGIC_NUMBER = 0x62D4;
-
 export interface WithForyClsInfo {
   structTypeInfo: StructTypeInfo;
 }
diff --git a/javascript/test/fory.test.ts b/javascript/test/fory.test.ts
index 3e9d04486..86bc93f22 100644
--- a/javascript/test/fory.test.ts
+++ b/javascript/test/fory.test.ts
@@ -20,22 +20,18 @@
 import Fory, { TypeInfo, Type } from '../packages/fory/index';
 import { describe, expect, test } from '@jest/globals';
 import { fromUint8Array } from '../packages/fory/lib/platformBuffer';
-import { MAGIC_NUMBER } from '../packages/fory/lib/type';
-
-const high = MAGIC_NUMBER >> 8;
-const low = MAGIC_NUMBER & 0xff;
 
 describe('fory', () => {
     test('should deserialize null work', () => {
         const fory = new Fory();
 
-        expect(fory.deserialize(new Uint8Array([low, high, 1]))).toBe(null)
+        expect(fory.deserialize(new Uint8Array([1]))).toBe(null)
     });
 
     test('should deserialize big endian work', () => {
         const fory = new Fory();
         try {
-            fory.deserialize(new Uint8Array([low, high, 0]))
+            fory.deserialize(new Uint8Array([0]))
             throw new Error('unreachable code')
         } catch (error) {
             expect(error.message).toBe('big endian is not supported now');
@@ -45,7 +41,7 @@ describe('fory', () => {
     test('should deserialize xlang disable work', () => {
         const fory = new Fory();
         try {
-            fory.deserialize(new Uint8Array([low, high, 2]))
+            fory.deserialize(new Uint8Array([2]))
             throw new Error('unreachable code')
         } catch (error) {
             expect(error.message).toBe('support crosslanguage mode only');
@@ -55,7 +51,7 @@ describe('fory', () => {
     test('should deserialize xlang disable work', () => {
         const fory = new Fory();
         try {
-            fory.deserialize(new Uint8Array([low, high, 14]))
+            fory.deserialize(new Uint8Array([14]))
             throw new Error('unreachable code')
         } catch (error) {
             expect(error.message).toBe('outofband mode is not supported now');
diff --git a/python/pyfory/_fory.py b/python/pyfory/_fory.py
index 2d67d8d85..b11028e82 100644
--- a/python/pyfory/_fory.py
+++ b/python/pyfory/_fory.py
@@ -41,7 +41,6 @@ except ImportError:
 logger = logging.getLogger(__name__)
 
 
-MAGIC_NUMBER = 0x62D4
 DEFAULT_DYNAMIC_WRITE_META_STR_ID = -1
 DYNAMIC_TYPE_ID = -1
 USE_TYPE_NAME = 0
@@ -453,8 +452,6 @@ class Fory:
         if buffer is None:
             self.buffer.writer_index = 0
             buffer = self.buffer
-        if self.language == Language.XLANG:
-            buffer.write_int16(MAGIC_NUMBER)
         mask_index = buffer.writer_index
         # 1byte used for bit mask
         buffer.grow(1)
@@ -610,12 +607,6 @@ class Fory:
             buffer = Buffer(buffer)
         if unsupported_objects is not None:
             self._unsupported_objects = iter(unsupported_objects)
-        if self.language == Language.XLANG:
-            magic_numer = buffer.read_int16()
-            assert magic_numer == MAGIC_NUMBER, (
-                f"The fory xlang serialization must start with magic number 
{hex(MAGIC_NUMBER)}. "
-                "Please check whether the serialization is based on the xlang 
protocol and the data didn't corrupt."
-            )
         reader_index = buffer.reader_index
         buffer.reader_index = reader_index + 1
         if get_bit(buffer, reader_index, 0):
diff --git a/python/pyfory/serialization.pyx b/python/pyfory/serialization.pyx
index 76ff98aef..f73c809f3 100644
--- a/python/pyfory/serialization.pyx
+++ b/python/pyfory/serialization.pyx
@@ -276,7 +276,6 @@ cdef int8_t FLOAT64_TYPE_ID = fmod.FLOAT64_TYPE_ID
 cdef int8_t BOOL_TYPE_ID = fmod.BOOL_TYPE_ID
 cdef int8_t STRING_TYPE_ID = fmod.STRING_TYPE_ID
 
-cdef int16_t MAGIC_NUMBER = fmod.MAGIC_NUMBER
 cdef int32_t NOT_NULL_INT64_FLAG = fmod.NOT_NULL_INT64_FLAG
 cdef int32_t NOT_NULL_FLOAT64_FLAG = fmod.NOT_NULL_FLOAT64_FLAG
 cdef int32_t NOT_NULL_BOOL_FLAG = fmod.NOT_NULL_BOOL_FLAG
@@ -1188,8 +1187,6 @@ cdef class Fory:
         if buffer is None:
             self.buffer.writer_index = 0
             buffer = self.buffer
-        if self.language == Language.XLANG:
-            buffer.write_int16(MAGIC_NUMBER)
         cdef int32_t mask_index = buffer.writer_index
         # 1byte used for bit mask
         buffer.grow(1)
@@ -1355,13 +1352,6 @@ cdef class Fory:
         self.depth += 1
         if unsupported_objects is not None:
             self._unsupported_objects = iter(unsupported_objects)
-        if self.language == Language.XLANG:
-            magic_numer = buffer.read_int16()
-            assert magic_numer == MAGIC_NUMBER, (
-                f"The fory xlang serialization must start with magic number 
{hex(MAGIC_NUMBER)}. "
-                "Please check whether the serialization is based on the xlang 
protocol and the "
-                "data didn't corrupt."
-            )
         cdef int32_t reader_index = buffer.reader_index
         buffer.reader_index = reader_index + 1
         if get_bit(buffer, reader_index, 0):
diff --git a/rust/fory-core/src/fory.rs b/rust/fory-core/src/fory.rs
index 165de4bfc..59d37ca30 100644
--- a/rust/fory-core/src/fory.rs
+++ b/rust/fory-core/src/fory.rs
@@ -26,7 +26,7 @@ use crate::serializer::{Serializer, StructSerializer};
 use crate::types::config_flags::IS_NULL_FLAG;
 use crate::types::{
     config_flags::{IS_CROSS_LANGUAGE_FLAG, IS_LITTLE_ENDIAN_FLAG},
-    Language, RefMode, MAGIC_NUMBER, SIZE_OF_REF_AND_TYPE,
+    Language, RefMode, SIZE_OF_REF_AND_TYPE,
 };
 use std::cell::UnsafeCell;
 use std::mem;
@@ -833,9 +833,6 @@ impl Fory {
     pub fn write_head<T: Serializer>(&self, is_none: bool, writer: &mut 
Writer) {
         const HEAD_SIZE: usize = 10;
         writer.reserve(T::fory_reserved_space() + SIZE_OF_REF_AND_TYPE + 
HEAD_SIZE);
-        if self.config.xlang {
-            writer.write_u16(MAGIC_NUMBER);
-        }
         #[cfg(target_endian = "big")]
         let mut bitmap = 0;
         #[cfg(target_endian = "little")]
@@ -1031,18 +1028,6 @@ impl Fory {
 
     #[inline(always)]
     fn read_head(&self, reader: &mut Reader) -> Result<bool, Error> {
-        if self.config.xlang {
-            let magic_numer = reader.read_u16()?;
-            ensure!(
-                magic_numer == MAGIC_NUMBER,
-                Error::invalid_data(format!(
-                    "The fory xlang serialization must start with magic number 
{:X}. \
-                    Please check whether the serialization is based on the 
xlang protocol \
-                    and the data didn't corrupt.",
-                    MAGIC_NUMBER
-                ))
-            )
-        }
         let bitmap = reader.read_u8()?;
         let peer_is_xlang = (bitmap & IS_CROSS_LANGUAGE_FLAG) != 0;
         ensure!(
diff --git a/rust/fory-core/src/types.rs b/rust/fory-core/src/types.rs
index aae344331..de54603ac 100644
--- a/rust/fory-core/src/types.rs
+++ b/rust/fory-core/src/types.rs
@@ -522,8 +522,6 @@ impl TryFrom<u8> for Language {
 // every object start with i8 i16 reference flag and type flag
 pub const SIZE_OF_REF_AND_TYPE: usize = mem::size_of::<i8>() + 
mem::size_of::<i16>();
 
-pub const MAGIC_NUMBER: u16 = 0x62d4;
-
 /// Formats a combined type ID into a human-readable string.
 ///
 /// Combined type IDs have the format: `(registered_id << 8) + 
internal_type_id`.


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to