Cross-language header layout: 1-byte bitmap. Bit 0: xlang flag, Bit 1: out-of-band flag, Bits 2-7 reserved. serialize/deserialize are the root object APIs. Nested serialization and deserialization go through WriteContext and ReadContext.
| 75 | * through {@link WriteContext} and {@link ReadContext}. |
| 76 | */ |
| 77 | @NotThreadSafe |
| 78 | public final class Fory implements BaseFory { |
| 79 | private static final Logger LOG = LoggerFactory.getLogger(Fory.class); |
| 80 | |
| 81 | public static final byte NULL_FLAG = -3; |
| 82 | // This flag indicates that object is a not-null value. |
| 83 | // We don't use another byte to indicate REF, so that we can save one byte. |
| 84 | public static final byte REF_FLAG = -2; |
| 85 | // this flag indicates that the object is a non-null value. |
| 86 | public static final byte NOT_NULL_VALUE_FLAG = -1; |
| 87 | // this flag indicates that the object is a referencable and first write. |
| 88 | public static final byte REF_VALUE_FLAG = 0; |
| 89 | public static final byte NOT_SUPPORT_XLANG = 0; |
| 90 | private static final byte isCrossLanguageFlag = 1; |
| 91 | private static final byte isOutOfBandFlag = 1 << 1; |
| 92 | private static final byte reservedBitmapFlags = (byte) ~0b11; |
| 93 | |
| 94 | private final Config config; |
| 95 | private final TypeResolver typeResolver; |
| 96 | private final SharedRegistry sharedRegistry; |
| 97 | private final ClassLoader classLoader; |
| 98 | private final JITContext jitContext; |
| 99 | private final WriteContext writeContext; |
| 100 | private final ReadContext readContext; |
| 101 | private final CopyContext copyContext; |
| 102 | private final IdentityHashMap<ForyModule, Boolean> installedModules = new IdentityHashMap<>(); |
| 103 | private final byte headerBitmap; |
| 104 | private MemoryBuffer buffer; |
| 105 | |
| 106 | private static String[] splitRegistrationName(String name) { |
| 107 | Preconditions.checkNotNull(name); |
| 108 | String namespace = ""; |
| 109 | String typeName = name; |
| 110 | int idx = name.lastIndexOf('.'); |
| 111 | if (idx >= 0) { |
| 112 | namespace = name.substring(0, idx); |
| 113 | typeName = name.substring(idx + 1); |
| 114 | } |
| 115 | Preconditions.checkArgument(!typeName.isEmpty(), "Name must include a non-empty type name"); |
| 116 | return new String[] {namespace, typeName}; |
| 117 | } |
| 118 | |
| 119 | public Fory(ForyBuilder builder, ClassLoader classLoader) { |
| 120 | this(builder, classLoader, null); |
| 121 | } |
| 122 | |
| 123 | public Fory(ForyBuilder builder, ClassLoader classLoader, SharedRegistry sharedRegistry) { |
| 124 | // Prefer the explicit constructor argument over retaining loader state on the builder used to |
| 125 | // create thread-safe factories. |
| 126 | config = new Config(builder); |
| 127 | if (sharedRegistry == null) { |
| 128 | sharedRegistry = new SharedRegistry(); |
| 129 | } |
| 130 | sharedRegistry.setRemoteSchemaLimits( |
| 131 | config.maxSchemaVersionsPerType(), config.maxAverageSchemaVersionsPerType()); |
| 132 | if (classLoader == null) { |
| 133 | classLoader = Thread.currentThread().getContextClassLoader(); |
| 134 | if (classLoader == null) { |