1use crate::buffer::{Reader, Writer};
19use crate::config::Config;
20use std::collections::HashMap;
21use std::mem;
22
23use crate::error::Error;
24use crate::meta::MetaString;
25use crate::resolver::meta_resolver::{MetaReaderResolver, MetaWriterResolver};
26use crate::resolver::meta_string_resolver::{MetaStringReaderResolver, MetaStringWriterResolver};
27use crate::resolver::ref_resolver::{RefReader, RefWriter};
28use crate::resolver::type_resolver::{TypeInfo, TypeResolver};
29use crate::types;
30use std::rc::Rc;
31
32pub struct ContextCache<T> {
36 cached_id: u64,
38 cached_context: Option<Box<T>>,
39 others: HashMap<u64, Box<T>>,
41}
42
43impl<T> ContextCache<T> {
44 pub fn new() -> Self {
45 ContextCache {
46 cached_id: u64::MAX,
47 cached_context: None,
48 others: HashMap::new(),
49 }
50 }
51
52 #[inline(always)]
53 pub fn get_or_insert(&mut self, id: u64, create: impl FnOnce() -> Box<T>) -> &mut T {
54 if self.cached_id == id {
55 return self.cached_context.as_mut().unwrap();
57 }
58
59 if self.cached_context.is_some() {
61 let old_id = self.cached_id;
63 let old_context = self.cached_context.take().unwrap();
64 self.others.insert(old_id, old_context);
65 }
66
67 let context = self.others.remove(&id).unwrap_or_else(create);
69 self.cached_id = id;
70 self.cached_context = Some(context);
71 self.cached_context.as_mut().unwrap()
72 }
73
74 #[inline(always)]
77 pub fn get_or_insert_result<E>(
78 &mut self,
79 id: u64,
80 create: impl FnOnce() -> Result<Box<T>, E>,
81 ) -> Result<&mut T, E> {
82 if self.cached_id == id {
83 return Ok(self.cached_context.as_mut().unwrap());
85 }
86
87 if self.cached_context.is_some() {
89 let old_id = self.cached_id;
91 let old_context = self.cached_context.take().unwrap();
92 self.others.insert(old_id, old_context);
93 }
94
95 let context = match self.others.remove(&id) {
97 Some(ctx) => ctx,
98 None => create()?,
99 };
100 self.cached_id = id;
101 self.cached_context = Some(context);
102 Ok(self.cached_context.as_mut().unwrap())
103 }
104}
105
106impl<T> Default for ContextCache<T> {
107 fn default() -> Self {
108 Self::new()
109 }
110}
111
112#[allow(clippy::needless_lifetimes)]
115pub struct WriteContext<'a> {
116 type_resolver: TypeResolver,
118 compatible: bool,
119 share_meta: bool,
120 compress_string: bool,
121 xlang: bool,
122 check_struct_version: bool,
123
124 default_writer: Option<Writer<'a>>,
126 pub writer: Writer<'a>,
127 meta_resolver: MetaWriterResolver,
128 meta_string_resolver: MetaStringWriterResolver,
129 pub ref_writer: RefWriter,
130}
131
132#[allow(clippy::needless_lifetimes)]
133impl<'a> WriteContext<'a> {
134 pub fn new(type_resolver: TypeResolver, config: Config) -> WriteContext<'a> {
135 WriteContext {
136 type_resolver,
137 compatible: config.compatible,
138 share_meta: config.share_meta,
139 compress_string: config.compress_string,
140 xlang: config.xlang,
141 check_struct_version: config.check_struct_version,
142 default_writer: None,
143 writer: Writer::from_buffer(Self::get_leak_buffer()),
144 meta_resolver: MetaWriterResolver::default(),
145 meta_string_resolver: MetaStringWriterResolver::default(),
146 ref_writer: RefWriter::new(),
147 }
148 }
149
150 #[inline(always)]
151 fn get_leak_buffer() -> &'static mut Vec<u8> {
152 Box::leak(Box::new(vec![]))
153 }
154
155 #[inline(always)]
156 pub fn attach_writer(&mut self, writer: Writer<'a>) {
157 let old = mem::replace(&mut self.writer, writer);
158 self.default_writer = Some(old);
159 }
160
161 #[inline(always)]
162 pub fn detach_writer(&mut self) {
163 let default = mem::take(&mut self.default_writer);
164 self.writer = default.unwrap();
165 }
166
167 #[inline(always)]
169 pub fn get_type_resolver(&self) -> &TypeResolver {
170 &self.type_resolver
171 }
172
173 #[inline(always)]
174 pub fn get_type_info(&self, type_id: &std::any::TypeId) -> Result<Rc<TypeInfo>, Error> {
175 self.type_resolver.get_type_info(type_id)
176 }
177
178 #[inline(always)]
180 pub fn is_compatible(&self) -> bool {
181 self.compatible
182 }
183
184 #[inline(always)]
186 pub fn is_share_meta(&self) -> bool {
187 self.share_meta
188 }
189
190 #[inline(always)]
192 pub fn is_compress_string(&self) -> bool {
193 self.compress_string
194 }
195
196 #[inline(always)]
198 pub fn is_xlang(&self) -> bool {
199 self.xlang
200 }
201
202 #[inline(always)]
204 pub fn is_check_struct_version(&self) -> bool {
205 self.check_struct_version
206 }
207
208 #[inline(always)]
209 pub fn empty(&mut self) -> bool {
210 self.meta_resolver.empty()
211 }
212
213 #[inline(always)]
214 pub fn push_meta(&mut self, type_id: std::any::TypeId) -> Result<usize, Error> {
215 self.meta_resolver.push(type_id, &self.type_resolver)
216 }
217
218 #[inline(always)]
219 pub fn write_meta(&mut self, offset: usize) {
220 let len = self.writer.len();
221 self.writer
222 .set_bytes(offset, &((len - offset - 4) as u32).to_le_bytes());
223 self.meta_resolver.to_bytes(&mut self.writer);
224 }
225
226 pub fn write_any_typeinfo(
227 &mut self,
228 fory_type_id: u32,
229 concrete_type_id: std::any::TypeId,
230 ) -> Result<Rc<TypeInfo>, Error> {
231 if types::is_internal_type(fory_type_id) {
232 self.writer.write_varuint32(fory_type_id);
233 return self
234 .type_resolver
235 .get_type_info_by_id(fory_type_id)
236 .ok_or_else(|| Error::type_error("Type info for internal type not found"));
237 }
238 let type_info = self.type_resolver.get_type_info(&concrete_type_id)?;
239 let fory_type_id = type_info.get_type_id();
240 let namespace = type_info.get_namespace();
241 let type_name = type_info.get_type_name();
242 self.writer.write_varuint32(fory_type_id);
243 match fory_type_id & 0xff {
245 types::NAMED_COMPATIBLE_STRUCT | types::COMPATIBLE_STRUCT => {
246 let meta_index =
247 self.meta_resolver
248 .push(concrete_type_id, &self.type_resolver)? as u32;
249 self.writer.write_varuint32(meta_index);
250 }
251 types::NAMED_ENUM | types::NAMED_EXT | types::NAMED_STRUCT => {
252 if self.is_share_meta() {
253 let meta_index = self
254 .meta_resolver
255 .push(concrete_type_id, &self.type_resolver)?
256 as u32;
257 self.writer.write_varuint32(meta_index);
258 } else {
259 self.write_meta_string_bytes(namespace)?;
260 self.write_meta_string_bytes(type_name)?;
261 }
262 }
263 _ => {
264 }
266 }
267 Ok(type_info)
268 }
269
270 #[inline(always)]
271 pub fn write_meta_string_bytes(&mut self, ms: Rc<MetaString>) -> Result<(), Error> {
272 self.meta_string_resolver
273 .write_meta_string_bytes(&mut self.writer, ms)
274 }
275
276 #[inline(always)]
277 pub fn reset(&mut self) {
278 self.meta_resolver.reset();
279 self.meta_string_resolver.reset();
280 self.ref_writer.reset();
281 }
282}
283
284#[allow(clippy::needless_lifetimes)]
285impl<'a> Drop for WriteContext<'a> {
286 fn drop(&mut self) {
287 unsafe {
288 drop(Box::from_raw(self.writer.bf));
289 }
290 }
291}
292
293#[allow(clippy::needless_lifetimes)]
298unsafe impl<'a> Send for WriteContext<'a> {}
299#[allow(clippy::needless_lifetimes)]
300unsafe impl<'a> Sync for WriteContext<'a> {}
301
302pub struct ReadContext<'a> {
305 type_resolver: TypeResolver,
307 compatible: bool,
308 share_meta: bool,
309 xlang: bool,
310 max_dyn_depth: u32,
311 check_struct_version: bool,
312
313 pub reader: Reader<'a>,
315 pub meta_resolver: MetaReaderResolver,
316 meta_string_resolver: MetaStringReaderResolver,
317 pub ref_reader: RefReader,
318 current_depth: u32,
319}
320
321#[allow(clippy::needless_lifetimes)]
326unsafe impl<'a> Send for ReadContext<'a> {}
327#[allow(clippy::needless_lifetimes)]
328unsafe impl<'a> Sync for ReadContext<'a> {}
329
330impl<'a> ReadContext<'a> {
331 pub fn new(type_resolver: TypeResolver, config: Config) -> ReadContext<'a> {
332 ReadContext {
333 type_resolver,
334 compatible: config.compatible,
335 share_meta: config.share_meta,
336 xlang: config.xlang,
337 max_dyn_depth: config.max_dyn_depth,
338 check_struct_version: config.check_struct_version,
339 reader: Reader::default(),
340 meta_resolver: MetaReaderResolver::default(),
341 meta_string_resolver: MetaStringReaderResolver::default(),
342 ref_reader: RefReader::new(),
343 current_depth: 0,
344 }
345 }
346
347 #[inline(always)]
349 pub fn get_type_resolver(&self) -> &TypeResolver {
350 &self.type_resolver
351 }
352
353 #[inline(always)]
355 pub fn is_compatible(&self) -> bool {
356 self.compatible
357 }
358
359 #[inline(always)]
361 pub fn is_share_meta(&self) -> bool {
362 self.share_meta
363 }
364
365 #[inline(always)]
367 pub fn is_xlang(&self) -> bool {
368 self.xlang
369 }
370
371 #[inline(always)]
373 pub fn is_check_struct_version(&self) -> bool {
374 self.check_struct_version
375 }
376
377 #[inline(always)]
379 pub fn max_dyn_depth(&self) -> u32 {
380 self.max_dyn_depth
381 }
382
383 #[inline(always)]
384 pub fn attach_reader(&mut self, reader: Reader<'a>) {
385 self.reader = reader;
386 }
387
388 #[inline(always)]
389 pub fn detach_reader(&mut self) -> Reader<'_> {
390 mem::take(&mut self.reader)
391 }
392
393 #[inline(always)]
394 pub fn get_type_info_by_index(&self, type_index: usize) -> Result<&Rc<TypeInfo>, Error> {
395 self.meta_resolver.get(type_index).ok_or_else(|| {
396 Error::type_error(format!("TypeInfo not found for type index: {}", type_index))
397 })
398 }
399
400 #[inline(always)]
401 pub fn get_meta(&self, type_index: usize) -> Result<&Rc<TypeInfo>, Error> {
402 self.get_type_info_by_index(type_index)
403 }
404
405 #[inline(always)]
406 pub fn load_type_meta(&mut self, offset: usize) -> Result<usize, Error> {
407 self.meta_resolver.load(
408 &self.type_resolver,
409 &mut Reader::new(&self.reader.slice_after_cursor()[offset..]),
410 )
411 }
412
413 pub fn read_any_typeinfo(&mut self) -> Result<Rc<TypeInfo>, Error> {
414 let fory_type_id = self.reader.read_varuint32()?;
415 match fory_type_id & 0xff {
417 types::NAMED_COMPATIBLE_STRUCT | types::COMPATIBLE_STRUCT => {
418 let meta_index = self.reader.read_varuint32()? as usize;
419 let type_info = self.get_type_info_by_index(meta_index)?.clone();
420 Ok(type_info)
421 }
422 types::NAMED_ENUM | types::NAMED_EXT | types::NAMED_STRUCT => {
423 if self.is_share_meta() {
424 let meta_index = self.reader.read_varuint32()? as usize;
425 let type_info = self.get_type_info_by_index(meta_index)?.clone();
426 Ok(type_info)
427 } else {
428 let namespace = self.read_meta_string()?.to_owned();
429 let type_name = self.read_meta_string()?.to_owned();
430 let rc_namespace = Rc::from(namespace);
431 let rc_type_name = Rc::from(type_name);
432 self.type_resolver
433 .get_type_info_by_meta_string_name(rc_namespace, rc_type_name)
434 .ok_or_else(|| Error::type_error("Name harness not found"))
435 }
436 }
437 _ => self
438 .type_resolver
439 .get_type_info_by_id(fory_type_id)
440 .ok_or_else(|| Error::type_error("ID harness not found")),
441 }
442 }
443
444 #[inline(always)]
445 pub fn get_type_info(&self, type_id: &std::any::TypeId) -> Result<Rc<TypeInfo>, Error> {
446 self.type_resolver.get_type_info(type_id)
447 }
448
449 #[inline(always)]
450 pub fn read_meta_string(&mut self) -> Result<&MetaString, Error> {
451 self.meta_string_resolver.read_meta_string(&mut self.reader)
452 }
453
454 #[inline(always)]
455 pub fn inc_depth(&mut self) -> Result<(), Error> {
456 self.current_depth += 1;
457 if self.current_depth > self.max_dyn_depth() {
458 return Err(Error::depth_exceed(format!(
459 "Maximum dynamic object nesting depth ({}) exceeded. Current depth: {}. \
460 This may indicate a circular reference or overly deep object graph. \
461 Consider increasing max_dyn_depth if this is expected.",
462 self.max_dyn_depth(),
463 self.current_depth
464 )));
465 }
466 Ok(())
467 }
468
469 #[inline(always)]
470 pub fn dec_depth(&mut self) {
471 self.current_depth = self.current_depth.saturating_sub(1);
472 }
473
474 #[inline(always)]
475 pub fn reset(&mut self) {
476 self.meta_resolver.reset();
477 self.meta_string_resolver.reset();
478 self.ref_reader.reset();
479 self.current_depth = 0;
480 }
481}