intuicio_frontend_simpleton/library/
bytes.rs

1use crate::{Array, Boolean, Integer, Map, Real, Reference, Text};
2use byteorder::{NativeEndian, NetworkEndian, ReadBytesExt, WriteBytesExt};
3use intuicio_core::{registry::Registry, IntuicioStruct};
4use intuicio_derive::{intuicio_method, intuicio_methods, IntuicioStruct};
5use std::io::{Cursor, Read, Write};
6
7#[repr(u8)]
8#[derive(Debug, Default, Copy, Clone)]
9enum DataType {
10    #[default]
11    Null = 0,
12    Boolean = 1,
13    Integer8 = 2,
14    Integer16 = 3,
15    Integer32 = 4,
16    Integer64 = 5,
17    Real = 7,
18    Text = 8,
19    Array = 9,
20    Map = 10,
21}
22
23#[derive(IntuicioStruct, Default)]
24#[intuicio(name = "Bytes", module_name = "bytes")]
25pub struct Bytes {
26    #[intuicio(ignore)]
27    buffer: Cursor<Vec<u8>>,
28    #[intuicio(ignore)]
29    native_endian: bool,
30}
31
32#[intuicio_methods(module_name = "bytes")]
33impl Bytes {
34    pub fn new_raw(bytes: Vec<u8>) -> Self {
35        Self {
36            buffer: Cursor::new(bytes),
37            native_endian: false,
38        }
39    }
40
41    pub fn get_ref(&self) -> &[u8] {
42        self.buffer.get_ref().as_slice()
43    }
44
45    pub fn get_mut(&mut self) -> &mut [u8] {
46        self.buffer.get_mut().as_mut_slice()
47    }
48
49    #[allow(clippy::new_ret_no_self)]
50    #[intuicio_method(use_registry)]
51    pub fn new(registry: &Registry) -> Reference {
52        Reference::new(Bytes::default(), registry)
53    }
54
55    #[intuicio_method(use_registry)]
56    pub fn from(registry: &Registry, array: Reference) -> Reference {
57        let buffer = array
58            .read::<Array>()
59            .unwrap()
60            .iter()
61            .map(|byte| *byte.read::<Integer>().unwrap() as u8)
62            .collect();
63        Reference::new(Self::new_raw(buffer), registry)
64    }
65
66    #[intuicio_method(use_registry)]
67    pub fn into(registry: &Registry, bytes: Reference) -> Reference {
68        let array = bytes
69            .read::<Bytes>()
70            .unwrap()
71            .buffer
72            .get_ref()
73            .iter()
74            .map(|byte| Reference::new_integer(*byte as Integer, registry))
75            .collect();
76        Reference::new_array(array, registry)
77    }
78
79    #[intuicio_method(use_registry)]
80    pub fn size(registry: &Registry, bytes: Reference) -> Reference {
81        let bytes = bytes.read::<Bytes>().unwrap();
82        Reference::new_integer(bytes.buffer.get_ref().len() as Integer, registry)
83    }
84
85    #[intuicio_method(use_registry)]
86    pub fn position(registry: &Registry, bytes: Reference) -> Reference {
87        let bytes = bytes.read::<Bytes>().unwrap();
88        Reference::new_integer(bytes.buffer.position() as Integer, registry)
89    }
90
91    #[intuicio_method()]
92    pub fn set_position(mut bytes: Reference, position: Reference) -> Reference {
93        let mut bytes = bytes.write::<Bytes>().unwrap();
94        bytes
95            .buffer
96            .set_position(*position.read::<Integer>().unwrap() as u64);
97        Reference::null()
98    }
99
100    #[intuicio_method(use_registry)]
101    pub fn native_endian(registry: &Registry, bytes: Reference) -> Reference {
102        let bytes = bytes.read::<Bytes>().unwrap();
103        Reference::new_boolean(bytes.native_endian, registry)
104    }
105
106    #[intuicio_method()]
107    pub fn set_native_endian(mut bytes: Reference, mode: Reference) -> Reference {
108        let mut bytes = bytes.write::<Bytes>().unwrap();
109        bytes.native_endian = *mode.read::<Boolean>().unwrap();
110        Reference::null()
111    }
112
113    #[intuicio_method()]
114    pub fn clear(mut bytes: Reference) -> Reference {
115        let mut bytes = bytes.write::<Bytes>().unwrap();
116        bytes.buffer.set_position(0);
117        bytes.buffer.get_mut().clear();
118        Reference::null()
119    }
120
121    #[intuicio_method(use_registry)]
122    pub fn get_bit(registry: &Registry, bytes: Reference, index: Reference) -> Reference {
123        let bytes = bytes.read::<Bytes>().unwrap();
124        let index = *index.read::<Integer>().unwrap() as usize;
125        let offset = index % std::mem::size_of::<u8>();
126        let index = index / std::mem::size_of::<u8>();
127        let result = bytes.buffer.get_ref()[index] & (1 << offset);
128        Reference::new_boolean(result != 0, registry)
129    }
130
131    #[intuicio_method(use_registry)]
132    pub fn set_bit(mut bytes: Reference, index: Reference, value: Reference) -> Reference {
133        let mut bytes = bytes.write::<Bytes>().unwrap();
134        let index = *index.read::<Integer>().unwrap() as usize;
135        let value = *value.read::<Boolean>().unwrap();
136        let offset = index % std::mem::size_of::<u8>();
137        let index = index / std::mem::size_of::<u8>();
138        let byte = &mut bytes.buffer.get_mut()[index];
139        let enabled = (*byte & (1 << offset)) != 0;
140        if enabled != value {
141            *byte ^= 1 << offset;
142        }
143        Reference::null()
144    }
145
146    #[intuicio_method(use_registry)]
147    pub fn get_integer(registry: &Registry, bytes: Reference, index: Reference) -> Reference {
148        let bytes = bytes.read::<Bytes>().unwrap();
149        let index = *index.read::<Integer>().unwrap() as usize;
150        let buffer = unsafe { bytes.get_ref().align_to::<Integer>().1 };
151        Reference::new_integer(buffer[index], registry)
152    }
153
154    #[intuicio_method(use_registry)]
155    pub fn set_integer(mut bytes: Reference, index: Reference, value: Reference) -> Reference {
156        let mut bytes = bytes.write::<Bytes>().unwrap();
157        let index = *index.read::<Integer>().unwrap() as usize;
158        let value = *value.read::<Integer>().unwrap();
159        let buffer = unsafe { bytes.get_mut().align_to_mut::<Integer>().1 };
160        buffer[index] = value;
161        Reference::null()
162    }
163
164    #[intuicio_method(use_registry)]
165    pub fn get_real(registry: &Registry, bytes: Reference, index: Reference) -> Reference {
166        let bytes = bytes.read::<Bytes>().unwrap();
167        let index = *index.read::<Integer>().unwrap() as usize;
168        let buffer = unsafe { bytes.get_ref().align_to::<Real>().1 };
169        Reference::new_real(buffer[index], registry)
170    }
171
172    #[intuicio_method(use_registry)]
173    pub fn set_real(mut bytes: Reference, index: Reference, value: Reference) -> Reference {
174        let mut bytes = bytes.write::<Bytes>().unwrap();
175        let index = *index.read::<Integer>().unwrap() as usize;
176        let value = *value.read::<Real>().unwrap();
177        let buffer = unsafe { bytes.get_mut().align_to_mut::<Real>().1 };
178        buffer[index] = value;
179        Reference::null()
180    }
181
182    #[intuicio_method(use_registry)]
183    pub fn read_boolean(registry: &Registry, bytes: Reference) -> Reference {
184        Self::read_u8(registry, bytes)
185    }
186
187    #[intuicio_method(use_registry)]
188    pub fn read_u8(registry: &Registry, mut bytes: Reference) -> Reference {
189        let mut bytes = bytes.write::<Bytes>().unwrap();
190        bytes
191            .buffer
192            .read_u8()
193            .map(|value| Reference::new_integer(value as Integer, registry))
194            .unwrap_or_default()
195    }
196
197    #[intuicio_method(use_registry)]
198    pub fn read_u16(registry: &Registry, mut bytes: Reference) -> Reference {
199        let mut bytes = bytes.write::<Bytes>().unwrap();
200        let result = if bytes.native_endian {
201            bytes.buffer.read_u16::<NativeEndian>()
202        } else {
203            bytes.buffer.read_u16::<NetworkEndian>()
204        };
205        result
206            .map(|value| Reference::new_integer(value as Integer, registry))
207            .unwrap_or_default()
208    }
209
210    #[intuicio_method(use_registry)]
211    pub fn read_u32(registry: &Registry, mut bytes: Reference) -> Reference {
212        let mut bytes = bytes.write::<Bytes>().unwrap();
213        let result = if bytes.native_endian {
214            bytes.buffer.read_u32::<NativeEndian>()
215        } else {
216            bytes.buffer.read_u32::<NetworkEndian>()
217        };
218        result
219            .map(|value| Reference::new_integer(value as Integer, registry))
220            .unwrap_or_default()
221    }
222
223    #[intuicio_method(use_registry)]
224    pub fn read_u64(registry: &Registry, mut bytes: Reference) -> Reference {
225        let mut bytes = bytes.write::<Bytes>().unwrap();
226        let result = if bytes.native_endian {
227            bytes.buffer.read_u64::<NativeEndian>()
228        } else {
229            bytes.buffer.read_u64::<NetworkEndian>()
230        };
231        result
232            .map(|value| Reference::new_integer(value as Integer, registry))
233            .unwrap_or_default()
234    }
235
236    #[intuicio_method(use_registry)]
237    pub fn read_i8(registry: &Registry, mut bytes: Reference) -> Reference {
238        let mut bytes = bytes.write::<Bytes>().unwrap();
239        bytes
240            .buffer
241            .read_i8()
242            .map(|value| Reference::new_integer(value as Integer, registry))
243            .unwrap_or_default()
244    }
245
246    #[intuicio_method(use_registry)]
247    pub fn read_i16(registry: &Registry, mut bytes: Reference) -> Reference {
248        let mut bytes = bytes.write::<Bytes>().unwrap();
249        let result = if bytes.native_endian {
250            bytes.buffer.read_i16::<NativeEndian>()
251        } else {
252            bytes.buffer.read_i16::<NetworkEndian>()
253        };
254        result
255            .map(|value| Reference::new_integer(value as Integer, registry))
256            .unwrap_or_default()
257    }
258
259    #[intuicio_method(use_registry)]
260    pub fn read_i32(registry: &Registry, mut bytes: Reference) -> Reference {
261        let mut bytes = bytes.write::<Bytes>().unwrap();
262        let result = if bytes.native_endian {
263            bytes.buffer.read_i32::<NativeEndian>()
264        } else {
265            bytes.buffer.read_i32::<NetworkEndian>()
266        };
267        result
268            .map(|value| Reference::new_integer(value as Integer, registry))
269            .unwrap_or_default()
270    }
271
272    #[intuicio_method(use_registry)]
273    pub fn read_i64(registry: &Registry, mut bytes: Reference) -> Reference {
274        let mut bytes = bytes.write::<Bytes>().unwrap();
275        let result = if bytes.native_endian {
276            bytes.buffer.read_i64::<NativeEndian>()
277        } else {
278            bytes.buffer.read_i64::<NetworkEndian>()
279        };
280        result
281            .map(|value| Reference::new_integer(value as Integer, registry))
282            .unwrap_or_default()
283    }
284
285    #[intuicio_method(use_registry)]
286    pub fn read_f32(registry: &Registry, mut bytes: Reference) -> Reference {
287        let mut bytes = bytes.write::<Bytes>().unwrap();
288        let result = if bytes.native_endian {
289            bytes.buffer.read_f32::<NativeEndian>()
290        } else {
291            bytes.buffer.read_f32::<NetworkEndian>()
292        };
293        result
294            .map(|value| Reference::new_real(value as Real, registry))
295            .unwrap_or_default()
296    }
297
298    #[intuicio_method(use_registry)]
299    pub fn read_f64(registry: &Registry, mut bytes: Reference) -> Reference {
300        let mut bytes = bytes.write::<Bytes>().unwrap();
301        let result = if bytes.native_endian {
302            bytes.buffer.read_f64::<NativeEndian>()
303        } else {
304            bytes.buffer.read_f64::<NetworkEndian>()
305        };
306        result
307            .map(|value| Reference::new_real(value as Real, registry))
308            .unwrap_or_default()
309    }
310
311    #[intuicio_method(use_registry)]
312    pub fn read_text(registry: &Registry, mut bytes: Reference, size: Reference) -> Reference {
313        let mut bytes = bytes.write::<Bytes>().unwrap();
314        let size = *size.read::<Integer>().unwrap() as usize;
315        let mut result = vec![0; size];
316        bytes
317            .buffer
318            .read_exact(&mut result)
319            .map(|_| Reference::new_text(String::from_utf8_lossy(&result).to_string(), registry))
320            .unwrap_or_default()
321    }
322
323    #[intuicio_method(use_registry)]
324    pub fn read_bytes(registry: &Registry, mut bytes: Reference, size: Reference) -> Reference {
325        let mut bytes = bytes.write::<Bytes>().unwrap();
326        let size = *size.read::<Integer>().unwrap() as usize;
327        let mut result = vec![0; size];
328        bytes
329            .buffer
330            .read_exact(&mut result)
331            .map(|_| Reference::new(Self::new_raw(result), registry))
332            .unwrap_or_default()
333    }
334
335    #[intuicio_method(use_registry)]
336    pub fn write_boolean(registry: &Registry, bytes: Reference, value: Reference) -> Reference {
337        Self::write_u8(registry, bytes, value)
338    }
339
340    #[intuicio_method(use_registry)]
341    pub fn write_u8(registry: &Registry, mut bytes: Reference, value: Reference) -> Reference {
342        let mut bytes = bytes.write::<Bytes>().unwrap();
343        let value = *value.read::<Integer>().unwrap() as u8;
344        Reference::new_boolean(bytes.buffer.write_u8(value).is_ok(), registry)
345    }
346
347    #[intuicio_method(use_registry)]
348    pub fn write_u16(registry: &Registry, mut bytes: Reference, value: Reference) -> Reference {
349        let mut bytes = bytes.write::<Bytes>().unwrap();
350        let value = *value.read::<Integer>().unwrap() as u16;
351        Reference::new_boolean(
352            if bytes.native_endian {
353                bytes.buffer.write_u16::<NativeEndian>(value).is_ok()
354            } else {
355                bytes.buffer.write_u16::<NetworkEndian>(value).is_ok()
356            },
357            registry,
358        )
359    }
360
361    #[intuicio_method(use_registry)]
362    pub fn write_u32(registry: &Registry, mut bytes: Reference, value: Reference) -> Reference {
363        let mut bytes = bytes.write::<Bytes>().unwrap();
364        let value = *value.read::<Integer>().unwrap() as u32;
365        Reference::new_boolean(
366            if bytes.native_endian {
367                bytes.buffer.write_u32::<NativeEndian>(value).is_ok()
368            } else {
369                bytes.buffer.write_u32::<NetworkEndian>(value).is_ok()
370            },
371            registry,
372        )
373    }
374
375    #[intuicio_method(use_registry)]
376    pub fn write_u64(registry: &Registry, mut bytes: Reference, value: Reference) -> Reference {
377        let mut bytes = bytes.write::<Bytes>().unwrap();
378        let value = *value.read::<Integer>().unwrap() as u64;
379        Reference::new_boolean(
380            if bytes.native_endian {
381                bytes.buffer.write_u64::<NativeEndian>(value).is_ok()
382            } else {
383                bytes.buffer.write_u64::<NetworkEndian>(value).is_ok()
384            },
385            registry,
386        )
387    }
388
389    #[intuicio_method(use_registry)]
390    pub fn write_i8(registry: &Registry, mut bytes: Reference, value: Reference) -> Reference {
391        let mut bytes = bytes.write::<Bytes>().unwrap();
392        let value = *value.read::<Integer>().unwrap() as i8;
393        Reference::new_boolean(bytes.buffer.write_i8(value).is_ok(), registry)
394    }
395
396    #[intuicio_method(use_registry)]
397    pub fn write_i16(registry: &Registry, mut bytes: Reference, value: Reference) -> Reference {
398        let mut bytes = bytes.write::<Bytes>().unwrap();
399        let value = *value.read::<Integer>().unwrap() as i16;
400        Reference::new_boolean(
401            if bytes.native_endian {
402                bytes.buffer.write_i16::<NativeEndian>(value).is_ok()
403            } else {
404                bytes.buffer.write_i16::<NetworkEndian>(value).is_ok()
405            },
406            registry,
407        )
408    }
409
410    #[intuicio_method(use_registry)]
411    pub fn write_i32(registry: &Registry, mut bytes: Reference, value: Reference) -> Reference {
412        let mut bytes = bytes.write::<Bytes>().unwrap();
413        let value = *value.read::<Integer>().unwrap() as i32;
414        Reference::new_boolean(
415            if bytes.native_endian {
416                bytes.buffer.write_i32::<NativeEndian>(value).is_ok()
417            } else {
418                bytes.buffer.write_i32::<NetworkEndian>(value).is_ok()
419            },
420            registry,
421        )
422    }
423
424    #[intuicio_method(use_registry)]
425    pub fn write_i64(registry: &Registry, mut bytes: Reference, value: Reference) -> Reference {
426        let mut bytes = bytes.write::<Bytes>().unwrap();
427        let value = *value.read::<Integer>().unwrap();
428        Reference::new_boolean(
429            if bytes.native_endian {
430                bytes.buffer.write_i64::<NativeEndian>(value).is_ok()
431            } else {
432                bytes.buffer.write_i64::<NetworkEndian>(value).is_ok()
433            },
434            registry,
435        )
436    }
437
438    #[intuicio_method(use_registry)]
439    pub fn write_f32(registry: &Registry, mut bytes: Reference, value: Reference) -> Reference {
440        let mut bytes = bytes.write::<Bytes>().unwrap();
441        let value = *value.read::<Real>().unwrap() as f32;
442        Reference::new_boolean(
443            if bytes.native_endian {
444                bytes.buffer.write_f32::<NativeEndian>(value).is_ok()
445            } else {
446                bytes.buffer.write_f32::<NetworkEndian>(value).is_ok()
447            },
448            registry,
449        )
450    }
451
452    #[intuicio_method(use_registry)]
453    pub fn write_f64(registry: &Registry, mut bytes: Reference, value: Reference) -> Reference {
454        let mut bytes = bytes.write::<Bytes>().unwrap();
455        let value = *value.read::<Real>().unwrap();
456        Reference::new_boolean(
457            if bytes.native_endian {
458                bytes.buffer.write_f64::<NativeEndian>(value).is_ok()
459            } else {
460                bytes.buffer.write_f64::<NetworkEndian>(value).is_ok()
461            },
462            registry,
463        )
464    }
465
466    #[intuicio_method(use_registry)]
467    pub fn write_text(registry: &Registry, mut bytes: Reference, value: Reference) -> Reference {
468        let mut bytes = bytes.write::<Bytes>().unwrap();
469        let buffer = value.read::<Text>().unwrap();
470        if bytes.buffer.write_all(buffer.as_bytes()).is_ok() {
471            Reference::new_integer(buffer.len() as Integer, registry)
472        } else {
473            Reference::new_integer(0, registry)
474        }
475    }
476
477    #[intuicio_method(use_registry)]
478    pub fn write_bytes(registry: &Registry, mut bytes: Reference, value: Reference) -> Reference {
479        let mut bytes = bytes.write::<Bytes>().unwrap();
480        let value = value.read::<Bytes>().unwrap();
481        if bytes.buffer.write_all(value.buffer.get_ref()).is_ok() {
482            Reference::new_integer(value.buffer.get_ref().len() as Integer, registry)
483        } else {
484            Reference::new_integer(0, registry)
485        }
486    }
487
488    #[intuicio_method()]
489    pub fn serialize(mut bytes: Reference, value: Reference) -> Reference {
490        let mut bytes = bytes.write::<Bytes>().unwrap();
491        Self::write(bytes.native_endian, &mut bytes.buffer, &value);
492        Reference::null()
493    }
494
495    #[intuicio_method(use_registry)]
496    pub fn deserialize(registry: &Registry, mut bytes: Reference) -> Reference {
497        let mut bytes = bytes.write::<Bytes>().unwrap();
498        Self::read(registry, bytes.native_endian, &mut bytes.buffer)
499    }
500
501    fn read_type(buffer: &mut Cursor<Vec<u8>>) -> DataType {
502        let result = buffer.read_u8().unwrap();
503        unsafe { std::mem::transmute(result) }
504    }
505
506    fn read(registry: &Registry, native_endian: bool, buffer: &mut Cursor<Vec<u8>>) -> Reference {
507        match Self::read_type(buffer) {
508            DataType::Null => Reference::null(),
509            DataType::Boolean => Reference::new_boolean(buffer.read_u8().unwrap() != 0, registry),
510            DataType::Integer8 => Reference::new_integer(buffer.read_i8().unwrap() as _, registry),
511            DataType::Integer16 => Reference::new_integer(
512                if native_endian {
513                    buffer.read_i16::<NativeEndian>().unwrap()
514                } else {
515                    buffer.read_i16::<NetworkEndian>().unwrap()
516                } as _,
517                registry,
518            ),
519            DataType::Integer32 => Reference::new_integer(
520                if native_endian {
521                    buffer.read_i32::<NativeEndian>().unwrap()
522                } else {
523                    buffer.read_i32::<NetworkEndian>().unwrap()
524                } as _,
525                registry,
526            ),
527            DataType::Integer64 => Reference::new_integer(
528                if native_endian {
529                    buffer.read_i64::<NativeEndian>().unwrap()
530                } else {
531                    buffer.read_i64::<NetworkEndian>().unwrap()
532                } as _,
533                registry,
534            ),
535            DataType::Real => Reference::new_real(
536                if native_endian {
537                    buffer.read_f64::<NativeEndian>().unwrap()
538                } else {
539                    buffer.read_f64::<NetworkEndian>().unwrap()
540                } as _,
541                registry,
542            ),
543            DataType::Text => {
544                let size = if native_endian {
545                    buffer.read_u32::<NativeEndian>().unwrap()
546                } else {
547                    buffer.read_u32::<NetworkEndian>().unwrap()
548                } as usize;
549                let mut bytes = vec![0; size];
550                buffer.read_exact(&mut bytes).unwrap();
551                Reference::new_text(String::from_utf8_lossy(&bytes).to_string(), registry)
552            }
553            DataType::Array => {
554                let count = if native_endian {
555                    buffer.read_u32::<NativeEndian>().unwrap()
556                } else {
557                    buffer.read_u32::<NetworkEndian>().unwrap()
558                } as usize;
559                let mut result = Array::with_capacity(count);
560                for _ in 0..count {
561                    result.push(Self::read(registry, native_endian, buffer));
562                }
563                Reference::new_array(result, registry)
564            }
565            DataType::Map => {
566                let count = if native_endian {
567                    buffer.read_u32::<NativeEndian>().unwrap()
568                } else {
569                    buffer.read_u32::<NetworkEndian>().unwrap()
570                } as usize;
571                let mut result = Map::with_capacity(count);
572                for _ in 0..count {
573                    let size = buffer.read_u8().unwrap() as usize;
574                    let mut bytes = vec![0; size];
575                    buffer.read_exact(&mut bytes).unwrap();
576                    result.insert(
577                        String::from_utf8_lossy(&bytes).to_string(),
578                        Self::read(registry, native_endian, buffer),
579                    );
580                }
581                Reference::new_map(result, registry)
582            }
583        }
584    }
585
586    fn write_type(buffer: &mut Cursor<Vec<u8>>, data_type: DataType) {
587        buffer.write_u8(data_type as u8).unwrap();
588    }
589
590    fn write(native_endian: bool, buffer: &mut Cursor<Vec<u8>>, value: &Reference) {
591        if value.is_null() {
592            Self::write_type(buffer, DataType::Null);
593        } else if let Some(value) = value.read::<Boolean>() {
594            Self::write_type(buffer, DataType::Boolean);
595            buffer.write_u8(*value as _).unwrap();
596        } else if let Some(value) = value.read::<Integer>() {
597            if *value & i8::MAX as i64 == *value {
598                Self::write_type(buffer, DataType::Integer8);
599                buffer.write_i8(*value as _).unwrap();
600            } else if *value & i16::MAX as i64 == *value {
601                Self::write_type(buffer, DataType::Integer16);
602                if native_endian {
603                    buffer.write_i16::<NativeEndian>(*value as _).unwrap();
604                } else {
605                    buffer.write_i16::<NetworkEndian>(*value as _).unwrap();
606                }
607            } else if *value & i32::MAX as i64 == *value {
608                Self::write_type(buffer, DataType::Integer32);
609                if native_endian {
610                    buffer.write_i32::<NativeEndian>(*value as _).unwrap();
611                } else {
612                    buffer.write_i32::<NetworkEndian>(*value as _).unwrap();
613                }
614            } else {
615                Self::write_type(buffer, DataType::Integer64);
616                if native_endian {
617                    buffer.write_i64::<NativeEndian>(*value as _).unwrap();
618                } else {
619                    buffer.write_i64::<NetworkEndian>(*value as _).unwrap();
620                }
621            }
622        } else if let Some(value) = value.read::<Real>() {
623            Self::write_type(buffer, DataType::Real);
624            if native_endian {
625                buffer.write_f64::<NativeEndian>(*value as _).unwrap();
626            } else {
627                buffer.write_f64::<NetworkEndian>(*value as _).unwrap();
628            }
629        } else if let Some(value) = value.read::<Text>() {
630            Self::write_type(buffer, DataType::Text);
631            let bytes = value.as_bytes();
632            if native_endian {
633                buffer.write_u32::<NativeEndian>(bytes.len() as _).unwrap();
634            } else {
635                buffer.write_u32::<NetworkEndian>(bytes.len() as _).unwrap();
636            }
637            buffer.write_all(bytes).unwrap();
638        } else if let Some(value) = value.read::<Array>() {
639            Self::write_type(buffer, DataType::Array);
640            if native_endian {
641                buffer.write_u32::<NativeEndian>(value.len() as _).unwrap();
642            } else {
643                buffer.write_u32::<NetworkEndian>(value.len() as _).unwrap();
644            }
645            for value in value.iter() {
646                Self::write(native_endian, buffer, value);
647            }
648        } else if let Some(value) = value.read::<Map>() {
649            Self::write_type(buffer, DataType::Map);
650            if native_endian {
651                buffer.write_u32::<NativeEndian>(value.len() as _).unwrap();
652            } else {
653                buffer.write_u32::<NetworkEndian>(value.len() as _).unwrap();
654            }
655            for (key, value) in value.iter() {
656                let bytes = key.as_bytes();
657                buffer.write_u8(bytes.len() as _).unwrap();
658                buffer.write_all(bytes).unwrap();
659                Self::write(native_endian, buffer, value);
660            }
661        }
662    }
663}
664
665pub fn install(registry: &mut Registry) {
666    registry.add_type(Bytes::define_struct(registry));
667    registry.add_function(Bytes::new__define_function(registry));
668    registry.add_function(Bytes::from__define_function(registry));
669    registry.add_function(Bytes::into__define_function(registry));
670    registry.add_function(Bytes::size__define_function(registry));
671    registry.add_function(Bytes::position__define_function(registry));
672    registry.add_function(Bytes::set_position__define_function(registry));
673    registry.add_function(Bytes::native_endian__define_function(registry));
674    registry.add_function(Bytes::set_native_endian__define_function(registry));
675    registry.add_function(Bytes::clear__define_function(registry));
676    registry.add_function(Bytes::get_bit__define_function(registry));
677    registry.add_function(Bytes::set_bit__define_function(registry));
678    registry.add_function(Bytes::get_integer__define_function(registry));
679    registry.add_function(Bytes::set_integer__define_function(registry));
680    registry.add_function(Bytes::get_real__define_function(registry));
681    registry.add_function(Bytes::set_real__define_function(registry));
682    registry.add_function(Bytes::read_boolean__define_function(registry));
683    registry.add_function(Bytes::read_u8__define_function(registry));
684    registry.add_function(Bytes::read_u16__define_function(registry));
685    registry.add_function(Bytes::read_u32__define_function(registry));
686    registry.add_function(Bytes::read_u64__define_function(registry));
687    registry.add_function(Bytes::read_i8__define_function(registry));
688    registry.add_function(Bytes::read_i16__define_function(registry));
689    registry.add_function(Bytes::read_i32__define_function(registry));
690    registry.add_function(Bytes::read_i64__define_function(registry));
691    registry.add_function(Bytes::read_f32__define_function(registry));
692    registry.add_function(Bytes::read_f64__define_function(registry));
693    registry.add_function(Bytes::read_text__define_function(registry));
694    registry.add_function(Bytes::read_bytes__define_function(registry));
695    registry.add_function(Bytes::write_boolean__define_function(registry));
696    registry.add_function(Bytes::write_u8__define_function(registry));
697    registry.add_function(Bytes::write_u16__define_function(registry));
698    registry.add_function(Bytes::write_u32__define_function(registry));
699    registry.add_function(Bytes::write_u64__define_function(registry));
700    registry.add_function(Bytes::write_i8__define_function(registry));
701    registry.add_function(Bytes::write_i16__define_function(registry));
702    registry.add_function(Bytes::write_i32__define_function(registry));
703    registry.add_function(Bytes::write_i64__define_function(registry));
704    registry.add_function(Bytes::write_f32__define_function(registry));
705    registry.add_function(Bytes::write_f64__define_function(registry));
706    registry.add_function(Bytes::write_text__define_function(registry));
707    registry.add_function(Bytes::write_bytes__define_function(registry));
708    registry.add_function(Bytes::serialize__define_function(registry));
709    registry.add_function(Bytes::deserialize__define_function(registry));
710}