1use crate::buffer::{Reader, Writer};
19use std::mem;
20
21use crate::error::Error;
22use crate::meta::MetaString;
23use crate::resolver::meta_resolver::{MetaReaderResolver, MetaWriterResolver};
24use crate::resolver::meta_string_resolver::{MetaStringReaderResolver, MetaStringWriterResolver};
25use crate::resolver::ref_resolver::{RefReader, RefWriter};
26use crate::resolver::type_resolver::{TypeInfo, TypeResolver};
27use crate::types;
28use crate::util::Spinlock;
29use std::rc::Rc;
30
31#[allow(clippy::needless_lifetimes)]
34pub struct WriteContext<'a> {
35 type_resolver: TypeResolver,
37 compatible: bool,
38 share_meta: bool,
39 compress_string: bool,
40 xlang: bool,
41 check_struct_version: bool,
42
43 default_writer: Option<Writer<'a>>,
45 pub writer: Writer<'a>,
46 meta_resolver: MetaWriterResolver,
47 meta_string_resolver: MetaStringWriterResolver,
48 pub ref_writer: RefWriter,
49}
50
51#[allow(clippy::needless_lifetimes)]
52impl<'a> WriteContext<'a> {
53 pub fn new(
54 type_resolver: TypeResolver,
55 compatible: bool,
56 share_meta: bool,
57 compress_string: bool,
58 xlang: bool,
59 check_struct_version: bool,
60 ) -> WriteContext<'a> {
61 WriteContext {
62 type_resolver,
63 compatible,
64 share_meta,
65 compress_string,
66 xlang,
67 check_struct_version,
68 default_writer: None,
69 writer: Writer::from_buffer(Self::get_leak_buffer()),
70 meta_resolver: MetaWriterResolver::default(),
71 meta_string_resolver: MetaStringWriterResolver::default(),
72 ref_writer: RefWriter::new(),
73 }
74 }
75
76 #[inline(always)]
77 fn get_leak_buffer() -> &'static mut Vec<u8> {
78 Box::leak(Box::new(vec![]))
79 }
80
81 #[inline(always)]
82 pub fn attach_writer(&mut self, writer: Writer<'a>) {
83 let old = mem::replace(&mut self.writer, writer);
84 self.default_writer = Some(old);
85 }
86
87 #[inline(always)]
88 pub fn detach_writer(&mut self) {
89 let default = mem::take(&mut self.default_writer);
90 self.writer = default.unwrap();
91 }
92
93 #[inline(always)]
95 pub fn get_type_resolver(&self) -> &TypeResolver {
96 &self.type_resolver
97 }
98
99 #[inline(always)]
100 pub fn get_type_info(&self, type_id: &std::any::TypeId) -> Result<Rc<TypeInfo>, Error> {
101 self.type_resolver.get_type_info(type_id)
102 }
103
104 #[inline(always)]
106 pub fn is_compatible(&self) -> bool {
107 self.compatible
108 }
109
110 #[inline(always)]
112 pub fn is_share_meta(&self) -> bool {
113 self.share_meta
114 }
115
116 #[inline(always)]
118 pub fn is_compress_string(&self) -> bool {
119 self.compress_string
120 }
121
122 #[inline(always)]
124 pub fn is_xlang(&self) -> bool {
125 self.xlang
126 }
127
128 #[inline(always)]
130 pub fn is_check_struct_version(&self) -> bool {
131 self.check_struct_version
132 }
133
134 #[inline(always)]
135 pub fn empty(&mut self) -> bool {
136 self.meta_resolver.empty()
137 }
138
139 #[inline(always)]
140 pub fn push_meta(&mut self, type_id: std::any::TypeId) -> Result<usize, Error> {
141 self.meta_resolver.push(type_id, &self.type_resolver)
142 }
143
144 #[inline(always)]
145 pub fn write_meta(&mut self, offset: usize) {
146 let len = self.writer.len();
147 self.writer
148 .set_bytes(offset, &((len - offset - 4) as u32).to_le_bytes());
149 self.meta_resolver.to_bytes(&mut self.writer);
150 }
151
152 pub fn write_any_typeinfo(
153 &mut self,
154 fory_type_id: u32,
155 concrete_type_id: std::any::TypeId,
156 ) -> Result<Rc<TypeInfo>, Error> {
157 if types::is_internal_type(fory_type_id) {
158 self.writer.write_varuint32(fory_type_id);
159 return self
160 .type_resolver
161 .get_type_info_by_id(fory_type_id)
162 .ok_or_else(|| Error::type_error("Type info for internal type not found"));
163 }
164 let type_info = self.type_resolver.get_type_info(&concrete_type_id)?;
165 let fory_type_id = type_info.get_type_id();
166 let namespace = type_info.get_namespace();
167 let type_name = type_info.get_type_name();
168 self.writer.write_varuint32(fory_type_id);
169 match fory_type_id & 0xff {
171 types::NAMED_COMPATIBLE_STRUCT | types::COMPATIBLE_STRUCT => {
172 let meta_index =
173 self.meta_resolver
174 .push(concrete_type_id, &self.type_resolver)? as u32;
175 self.writer.write_varuint32(meta_index);
176 }
177 types::NAMED_ENUM | types::NAMED_EXT | types::NAMED_STRUCT => {
178 if self.is_share_meta() {
179 let meta_index = self
180 .meta_resolver
181 .push(concrete_type_id, &self.type_resolver)?
182 as u32;
183 self.writer.write_varuint32(meta_index);
184 } else {
185 self.write_meta_string_bytes(namespace)?;
186 self.write_meta_string_bytes(type_name)?;
187 }
188 }
189 _ => {
190 }
192 }
193 Ok(type_info)
194 }
195
196 #[inline(always)]
197 pub fn write_meta_string_bytes(&mut self, ms: Rc<MetaString>) -> Result<(), Error> {
198 self.meta_string_resolver
199 .write_meta_string_bytes(&mut self.writer, ms)
200 }
201
202 #[inline(always)]
203 pub fn reset(&mut self) {
204 self.meta_resolver.reset();
205 self.meta_string_resolver.reset();
206 self.ref_writer.reset();
207 }
208}
209
210#[allow(clippy::needless_lifetimes)]
211impl<'a> Drop for WriteContext<'a> {
212 fn drop(&mut self) {
213 unsafe {
214 drop(Box::from_raw(self.writer.bf));
215 }
216 }
217}
218
219#[allow(clippy::needless_lifetimes)]
224unsafe impl<'a> Send for WriteContext<'a> {}
225#[allow(clippy::needless_lifetimes)]
226unsafe impl<'a> Sync for WriteContext<'a> {}
227
228pub struct ReadContext<'a> {
231 type_resolver: TypeResolver,
233 compatible: bool,
234 share_meta: bool,
235 xlang: bool,
236 max_dyn_depth: u32,
237 check_struct_version: bool,
238
239 pub reader: Reader<'a>,
241 pub meta_resolver: MetaReaderResolver,
242 meta_string_resolver: MetaStringReaderResolver,
243 pub ref_reader: RefReader,
244 current_depth: u32,
245}
246
247#[allow(clippy::needless_lifetimes)]
252unsafe impl<'a> Send for ReadContext<'a> {}
253#[allow(clippy::needless_lifetimes)]
254unsafe impl<'a> Sync for ReadContext<'a> {}
255
256impl<'a> ReadContext<'a> {
257 pub fn new(
258 type_resolver: TypeResolver,
259 compatible: bool,
260 share_meta: bool,
261 xlang: bool,
262 max_dyn_depth: u32,
263 check_struct_version: bool,
264 ) -> ReadContext<'a> {
265 ReadContext {
266 type_resolver,
267 compatible,
268 share_meta,
269 xlang,
270 max_dyn_depth,
271 check_struct_version,
272 reader: Reader::default(),
273 meta_resolver: MetaReaderResolver::default(),
274 meta_string_resolver: MetaStringReaderResolver::default(),
275 ref_reader: RefReader::new(),
276 current_depth: 0,
277 }
278 }
279
280 #[inline(always)]
282 pub fn get_type_resolver(&self) -> &TypeResolver {
283 &self.type_resolver
284 }
285
286 #[inline(always)]
288 pub fn is_compatible(&self) -> bool {
289 self.compatible
290 }
291
292 #[inline(always)]
294 pub fn is_share_meta(&self) -> bool {
295 self.share_meta
296 }
297
298 #[inline(always)]
300 pub fn is_xlang(&self) -> bool {
301 self.xlang
302 }
303
304 #[inline(always)]
306 pub fn is_check_struct_version(&self) -> bool {
307 self.check_struct_version
308 }
309
310 #[inline(always)]
312 pub fn max_dyn_depth(&self) -> u32 {
313 self.max_dyn_depth
314 }
315
316 #[inline(always)]
317 pub fn init(&mut self, max_dyn_depth: u32) {
318 self.max_dyn_depth = max_dyn_depth;
319 self.current_depth = 0;
320 }
321
322 #[inline(always)]
323 pub fn attach_reader(&mut self, reader: Reader<'a>) {
324 self.reader = reader;
325 }
326
327 #[inline(always)]
328 pub fn detach_reader(&mut self) -> Reader<'_> {
329 mem::take(&mut self.reader)
330 }
331
332 #[inline(always)]
333 pub fn get_type_info_by_index(&self, type_index: usize) -> Result<&Rc<TypeInfo>, Error> {
334 self.meta_resolver.get(type_index).ok_or_else(|| {
335 Error::type_error(format!("TypeInfo not found for type index: {}", type_index))
336 })
337 }
338
339 #[inline(always)]
340 pub fn load_type_meta(&mut self, offset: usize) -> Result<usize, Error> {
341 self.meta_resolver.load(
342 &self.type_resolver,
343 &mut Reader::new(&self.reader.slice_after_cursor()[offset..]),
344 )
345 }
346
347 pub fn read_any_typeinfo(&mut self) -> Result<Rc<TypeInfo>, Error> {
348 let fory_type_id = self.reader.read_varuint32()?;
349 match fory_type_id & 0xff {
351 types::NAMED_COMPATIBLE_STRUCT | types::COMPATIBLE_STRUCT => {
352 let meta_index = self.reader.read_varuint32()? as usize;
353 let type_info = self.get_type_info_by_index(meta_index)?.clone();
354 Ok(type_info)
355 }
356 types::NAMED_ENUM | types::NAMED_EXT | types::NAMED_STRUCT => {
357 if self.is_share_meta() {
358 let meta_index = self.reader.read_varuint32()? as usize;
359 let type_info = self.get_type_info_by_index(meta_index)?.clone();
360 Ok(type_info)
361 } else {
362 let namespace = self.read_meta_string()?.to_owned();
363 let type_name = self.read_meta_string()?.to_owned();
364 let rc_namespace = Rc::from(namespace);
365 let rc_type_name = Rc::from(type_name);
366 self.type_resolver
367 .get_type_info_by_meta_string_name(rc_namespace, rc_type_name)
368 .ok_or_else(|| Error::type_error("Name harness not found"))
369 }
370 }
371 _ => self
372 .type_resolver
373 .get_type_info_by_id(fory_type_id)
374 .ok_or_else(|| Error::type_error("ID harness not found")),
375 }
376 }
377
378 #[inline(always)]
379 pub fn get_type_info(&self, type_id: &std::any::TypeId) -> Result<Rc<TypeInfo>, Error> {
380 self.type_resolver.get_type_info(type_id)
381 }
382
383 #[inline(always)]
384 pub fn read_meta_string(&mut self) -> Result<&MetaString, Error> {
385 self.meta_string_resolver.read_meta_string(&mut self.reader)
386 }
387
388 #[inline(always)]
389 pub fn inc_depth(&mut self) -> Result<(), Error> {
390 self.current_depth += 1;
391 if self.current_depth > self.max_dyn_depth() {
392 return Err(Error::depth_exceed(format!(
393 "Maximum dynamic object nesting depth ({}) exceeded. Current depth: {}. \
394 This may indicate a circular reference or overly deep object graph. \
395 Consider increasing max_dyn_depth if this is expected.",
396 self.max_dyn_depth(),
397 self.current_depth
398 )));
399 }
400 Ok(())
401 }
402
403 #[inline(always)]
404 pub fn dec_depth(&mut self) {
405 self.current_depth = self.current_depth.saturating_sub(1);
406 }
407
408 #[inline(always)]
409 pub fn reset(&mut self) {
410 self.meta_resolver.reset();
411 self.meta_string_resolver.reset();
412 self.ref_reader.reset();
413 }
414}
415
416pub struct Pool<T> {
417 items: Spinlock<Vec<T>>,
418 factory: Box<dyn Fn() -> T + Send + Sync>,
419}
420
421impl<T> Pool<T> {
422 pub fn new<F>(factory: F) -> Self
423 where
424 F: Fn() -> T + Send + Sync + 'static,
425 {
426 Pool {
427 items: Spinlock::new(vec![]),
428 factory: Box::new(factory),
429 }
430 }
431
432 #[inline(always)]
433 pub fn borrow_mut<Result>(&self, handler: impl FnOnce(&mut T) -> Result) -> Result {
434 let mut obj = self.get();
435 let result = handler(&mut obj);
436 self.put(obj);
437 result
438 }
439
440 #[inline(always)]
441 fn get(&self) -> T {
442 self.items.lock().pop().unwrap_or_else(|| (self.factory)())
443 }
444
445 #[inline(always)]
447 fn put(&self, item: T) {
448 self.items.lock().push(item);
449 }
450}