1use nom::{
2 bytes::complete::{tag, take},
3 combinator::map,
4 multi::count,
5 number::complete::{
6 be_f32, be_f64, be_i16, be_i32, be_i64, be_i8, be_u16, be_u32, be_u64, be_u8,
7 },
8 IResult,
9};
10
11use crate::constants::*;
12use crate::handle::HandleTable;
13use crate::types::*;
14
15pub fn preprocess_jdk8u20(data: &[u8]) -> Vec<u8> {
24 let pattern: &[u8] = &[0x00, 0x7e, 0x00, 0x09];
25 if let Some(pos) = data.windows(4).position(|w| w == pattern) {
26 let mut result = Vec::with_capacity(data.len() + 1);
27 result.extend_from_slice(&data[..pos + 4]);
28 result.push(TC_ENDBLOCKDATA);
29 result.extend_from_slice(&data[pos + 4..]);
30 result
31 } else {
32 data.to_vec()
33 }
34}
35
36pub fn parse_serialization_stream(input: &[u8]) -> IResult<&[u8], SerializationStream> {
43 let result = parse_serialization_stream_inner(input);
44 if result.is_ok() {
45 return result;
46 }
47 let preprocessed = preprocess_jdk8u20(input);
49 if preprocessed.len() == input.len() {
50 return result;
52 }
53 match parse_serialization_stream_inner(&preprocessed) {
54 Ok((_, stream)) => Ok((&input[input.len()..], stream)),
55 Err(_) => result,
56 }
57}
58
59fn parse_serialization_stream_inner(input: &[u8]) -> IResult<&[u8], SerializationStream> {
60 let (input, _) = tag(&[0xAC, 0xED])(input)?;
62 let (input, version) = be_u16(input)?;
64
65 let mut handle_table = HandleTable::new();
66 let mut remaining = input;
67 let mut contents = Vec::new();
68
69 while !remaining.is_empty() {
70 let (rem, content) = parse_content(remaining, &mut handle_table)?;
71 contents.push(content);
72 remaining = rem;
73 }
74
75 Ok((remaining, SerializationStream { version, contents }))
76}
77
78fn parse_content<'a>(
79 input: &'a [u8],
80 handles: &mut HandleTable,
81) -> IResult<&'a [u8], ContentElement> {
82 let tc = peek_tc(input)?;
83 match tc {
84 TC_BLOCKDATA | TC_BLOCKDATALONG => {
85 let (input, bd) = parse_block_data(input)?;
86 Ok((input, ContentElement::BlockData(bd)))
87 }
88 _ => {
89 let (input, obj) = parse_object(input, handles)?;
90 Ok((input, ContentElement::Object(obj)))
91 }
92 }
93}
94
95fn peek_tc(input: &[u8]) -> Result<u8, nom::Err<nom::error::Error<&[u8]>>> {
97 if input.is_empty() {
98 return Err(nom::Err::Error(nom::error::Error::new(
99 input,
100 nom::error::ErrorKind::Eof,
101 )));
102 }
103 Ok(input[0])
104}
105
106fn parse_object<'a>(input: &'a [u8], handles: &mut HandleTable) -> IResult<&'a [u8], StreamObject> {
107 let (input, tc) = be_u8(input)?;
108 match tc {
109 TC_NULL => Ok((input, StreamObject::NullReference)),
110 TC_REFERENCE => {
111 let (input, handle) = be_u32(input)?;
112 Ok((input, StreamObject::PrevObject { handle }))
113 }
114 TC_CLASSDESC => {
115 let (input, desc) = parse_normal_class_desc(input, handles)?;
116 Ok((
117 input,
118 StreamObject::NewClassDesc(ClassDesc::Normal(Box::new(desc))),
119 ))
120 }
121 TC_PROXYCLASSDESC => {
122 let (input, desc) = parse_proxy_class_desc(input, handles)?;
123 Ok((input, StreamObject::NewClassDesc(ClassDesc::Proxy(desc))))
124 }
125 TC_OBJECT => {
126 let (input, obj) = parse_new_object(input, handles)?;
127 Ok((input, StreamObject::NewObject(obj)))
128 }
129 TC_STRING => {
130 let (input, s) = parse_tc_string(input, handles, false)?;
131 Ok((input, StreamObject::NewString(s)))
132 }
133 TC_LONGSTRING => {
134 let (input, s) = parse_tc_string(input, handles, true)?;
135 Ok((input, StreamObject::NewString(s)))
136 }
137 TC_ARRAY => {
138 let (input, arr) = parse_new_array(input, handles)?;
139 Ok((input, StreamObject::NewArray(arr)))
140 }
141 TC_CLASS => {
142 let (input, cls) = parse_new_class(input, handles)?;
143 Ok((input, StreamObject::NewClass(cls)))
144 }
145 TC_ENUM => {
146 let (input, en) = parse_new_enum(input, handles)?;
147 Ok((input, StreamObject::NewEnum(en)))
148 }
149 TC_RESET => {
150 handles.reset();
151 Ok((input, StreamObject::Reset))
152 }
153 TC_BLOCKDATA | TC_BLOCKDATALONG => {
154 Err(nom::Err::Error(nom::error::Error::new(
157 input,
158 nom::error::ErrorKind::Tag,
159 )))
160 }
161 TC_EXCEPTION => {
162 Ok((input, StreamObject::Exception))
165 }
166 TC_ENDBLOCKDATA => Err(nom::Err::Error(nom::error::Error::new(
167 input,
168 nom::error::ErrorKind::Tag,
169 ))),
170 _ => Err(nom::Err::Error(nom::error::Error::new(
171 input,
172 nom::error::ErrorKind::Tag,
173 ))),
174 }
175}
176
177fn parse_class_desc_ref<'a>(
178 input: &'a [u8],
179 handles: &mut HandleTable,
180) -> IResult<&'a [u8], ClassDescRef> {
181 let (input, tc) = be_u8(input)?;
182 match tc {
183 TC_NULL => Ok((input, ClassDescRef::Null)),
184 TC_REFERENCE => {
185 let (input, handle) = be_u32(input)?;
186 Ok((input, ClassDescRef::Reference { handle }))
187 }
188 TC_CLASSDESC => {
189 let (input, desc) = parse_normal_class_desc(input, handles)?;
190 Ok((
191 input,
192 ClassDescRef::Inline(Box::new(ClassDesc::Normal(Box::new(desc)))),
193 ))
194 }
195 TC_PROXYCLASSDESC => {
196 let (input, desc) = parse_proxy_class_desc(input, handles)?;
197 Ok((
198 input,
199 ClassDescRef::Inline(Box::new(ClassDesc::Proxy(desc))),
200 ))
201 }
202 _ => Err(nom::Err::Error(nom::error::Error::new(
203 input,
204 nom::error::ErrorKind::Tag,
205 ))),
206 }
207}
208
209fn parse_normal_class_desc<'a>(
210 input: &'a [u8],
211 handles: &mut HandleTable,
212) -> IResult<&'a [u8], NormalClassDesc> {
213 let handle = handles.assign_handle();
215 let (input, class_name) = parse_utf(input)?;
217 let (input, serial_version_uid) = be_i64(input)?;
219 let (input, flags) = be_u8(input)?;
221 let (input, fields) = parse_fields_desc(input, handles)?;
223 let (input, class_annotation) = parse_class_annotation(input, handles)?;
225 let (input, super_class_desc) = parse_class_desc_ref(input, handles)?;
227
228 let desc = NormalClassDesc {
229 class_name,
230 serial_version_uid,
231 handle,
232 flags,
233 fields,
234 class_annotation,
235 super_class_desc: Box::new(super_class_desc),
236 };
237
238 handles.update(
240 handle,
241 StreamObject::NewClassDesc(ClassDesc::Normal(Box::new(desc.clone()))),
242 );
243
244 Ok((input, desc))
245}
246
247fn parse_proxy_class_desc<'a>(
248 input: &'a [u8],
249 handles: &mut HandleTable,
250) -> IResult<&'a [u8], ProxyClassDesc> {
251 let handle = handles.assign_handle();
253 let (input, interface_count) = be_u32(input)?;
255 let (input, interface_names) = count(parse_utf, interface_count as usize)(input)?;
256 let (input, class_annotation) = parse_class_annotation(input, handles)?;
258 let (input, super_class_desc) = parse_class_desc_ref(input, handles)?;
260
261 let desc = ProxyClassDesc {
262 handle,
263 interface_names,
264 class_annotation,
265 super_class_desc: Box::new(super_class_desc),
266 };
267
268 handles.update(
270 handle,
271 StreamObject::NewClassDesc(ClassDesc::Proxy(desc.clone())),
272 );
273
274 Ok((input, desc))
275}
276
277fn parse_fields_desc<'a>(
278 input: &'a [u8],
279 handles: &mut HandleTable,
280) -> IResult<&'a [u8], Vec<FieldDesc>> {
281 let (input, field_count) = be_u16(input)?;
282 let mut remaining = input;
283 let mut fields = Vec::with_capacity(field_count as usize);
284 for _ in 0..field_count {
285 let (rem, field) = parse_field_desc(remaining, handles)?;
286 fields.push(field);
287 remaining = rem;
288 }
289 Ok((remaining, fields))
290}
291
292fn parse_field_desc<'a>(
293 input: &'a [u8],
294 handles: &mut HandleTable,
295) -> IResult<&'a [u8], FieldDesc> {
296 let (input, type_code) = be_u8(input)?;
297 let (input, field_name) = parse_utf(input)?;
298 match type_code {
299 b'B' | b'C' | b'D' | b'F' | b'I' | b'J' | b'S' | b'Z' => Ok((
300 input,
301 FieldDesc::Primitive(PrimitiveFieldDesc {
302 type_code,
303 field_name,
304 }),
305 )),
306 b'L' | b'[' => {
307 let (input, class_name) = parse_string_object(input, handles)?;
309 Ok((
310 input,
311 FieldDesc::Object(ObjectFieldDesc {
312 type_code,
313 field_name,
314 class_name,
315 }),
316 ))
317 }
318 _ => Err(nom::Err::Error(nom::error::Error::new(
319 input,
320 nom::error::ErrorKind::Tag,
321 ))),
322 }
323}
324
325fn parse_string_object<'a>(
328 input: &'a [u8],
329 handles: &mut HandleTable,
330) -> IResult<&'a [u8], String> {
331 let (input, tc) = be_u8(input)?;
332 match tc {
333 TC_STRING => {
334 let (input, value) = parse_utf(input)?;
335 let _handle = handles.assign(StreamObject::NewString(StreamString {
336 value: value.clone(),
337 handle: 0,
338 is_long: false,
339 }));
340 Ok((input, value))
341 }
342 TC_LONGSTRING => {
343 let (input, value) = parse_long_utf(input)?;
344 let _handle = handles.assign(StreamObject::NewString(StreamString {
345 value: value.clone(),
346 handle: 0,
347 is_long: true,
348 }));
349 Ok((input, value))
350 }
351 TC_REFERENCE => {
352 let (input, handle) = be_u32(input)?;
353 let value = handles
355 .get(handle)
356 .and_then(|obj| {
357 if let StreamObject::NewString(s) = obj {
358 Some(s.value.clone())
359 } else {
360 None
361 }
362 })
363 .unwrap_or_else(|| format!("<ref:{:#08x}>", handle));
364 Ok((input, value))
365 }
366 TC_NULL => Ok((input, String::new())),
367 _ => Err(nom::Err::Error(nom::error::Error::new(
368 input,
369 nom::error::ErrorKind::Tag,
370 ))),
371 }
372}
373
374fn parse_class_annotation<'a>(
375 input: &'a [u8],
376 handles: &mut HandleTable,
377) -> IResult<&'a [u8], Vec<AnnotationElement>> {
378 let mut remaining = input;
379 let mut elements = Vec::new();
380 loop {
381 let tc = peek_tc(remaining)?;
382 if tc == TC_ENDBLOCKDATA {
383 let (rem, _) = be_u8(remaining)?; return Ok((rem, elements));
385 }
386 if tc == TC_BLOCKDATA || tc == TC_BLOCKDATALONG {
387 let (rem, bd) = parse_block_data(remaining)?;
388 elements.push(AnnotationElement::BlockData(bd));
389 remaining = rem;
390 } else {
391 let (rem, obj) = parse_object(remaining, handles)?;
392 elements.push(AnnotationElement::Object(obj));
393 remaining = rem;
394 }
395 }
396}
397
398fn parse_new_object<'a>(
399 input: &'a [u8],
400 handles: &mut HandleTable,
401) -> IResult<&'a [u8], NewObject> {
402 let (input, class_desc) = parse_class_desc_ref(input, handles)?;
404 let handle = handles.assign_handle();
406 let (input, class_data) = parse_class_data_hierarchy(input, &class_desc, handles)?;
408
409 let obj = NewObject {
410 class_desc: class_desc.clone(),
411 handle,
412 class_data,
413 };
414 handles.update(handle, StreamObject::NewObject(obj.clone()));
415 Ok((input, obj))
416}
417
418fn parse_class_data_hierarchy<'a>(
419 input: &'a [u8],
420 class_desc_ref: &ClassDescRef,
421 handles: &mut HandleTable,
422) -> IResult<&'a [u8], Vec<ClassData>> {
423 let hierarchy = collect_class_hierarchy(class_desc_ref, handles);
425 let mut remaining = input;
426 let mut class_data = Vec::new();
427
428 for desc in &hierarchy {
429 let (rem, data) = parse_class_data(remaining, desc, handles)?;
430 class_data.push(data);
431 remaining = rem;
432 }
433
434 Ok((remaining, class_data))
435}
436
437fn collect_class_hierarchy(
440 class_desc_ref: &ClassDescRef,
441 handles: &HandleTable,
442) -> Vec<NormalClassDesc> {
443 let mut hierarchy = Vec::new();
444 let mut current = Some(class_desc_ref);
445
446 while let Some(desc_ref) = current {
447 match desc_ref {
448 ClassDescRef::Null => break,
449 ClassDescRef::Reference { handle } => {
450 match handles.get(*handle) {
452 Some(StreamObject::NewClassDesc(ClassDesc::Normal(desc))) => {
453 let super_ref = &*desc.super_class_desc;
454 hierarchy.push((**desc).clone());
455 current = Some(super_ref);
456 }
457 Some(StreamObject::NewClassDesc(ClassDesc::Proxy(_))) => break,
458 _ => break,
459 }
460 }
461 ClassDescRef::Inline(class_desc) => match class_desc.as_ref() {
462 ClassDesc::Normal(desc) => {
463 let super_ref = &*desc.super_class_desc;
464 hierarchy.push((**desc).clone());
465 current = Some(super_ref);
466 }
467 ClassDesc::Proxy(_) => {
468 break;
469 }
470 },
471 }
472 }
473
474 hierarchy.reverse();
476 hierarchy
477}
478
479fn parse_class_data<'a>(
480 input: &'a [u8],
481 desc: &NormalClassDesc,
482 handles: &mut HandleTable,
483) -> IResult<&'a [u8], ClassData> {
484 if desc.is_externalizable() {
485 if desc.has_block_data() {
486 let (input, annotation) = parse_object_annotation(input, handles)?;
488 Ok((input, ClassData::ExternalBlockData(annotation)))
489 } else {
490 let (input, annotation) = parse_object_annotation(input, handles)?;
497 Ok((input, ClassData::ExternalBlockData(annotation)))
498 }
499 } else if desc.is_serializable() {
500 if desc.has_write_method() {
501 let snap = handles.snapshot();
506 if let Ok((input, field_values)) = parse_field_values(input, &desc.fields, handles) {
507 let field_set = FieldValueSet {
508 values: field_values,
509 };
510 if let Ok((input, annotation)) = parse_object_annotation(input, handles) {
511 return Ok((
512 input,
513 ClassData::WriteMethodWithFields(field_set, annotation),
514 ));
515 }
516 }
517 handles.rollback(snap);
519 let (input, annotation) = parse_object_annotation(input, handles)?;
520 Ok((input, ClassData::WriteMethod(annotation)))
521 } else {
522 let (input, field_values) = parse_field_values(input, &desc.fields, handles)?;
523 let field_set = FieldValueSet {
524 values: field_values,
525 };
526 Ok((input, ClassData::NoWriteMethod(field_set)))
527 }
528 } else {
529 Ok((
531 input,
532 ClassData::NoWriteMethod(FieldValueSet { values: vec![] }),
533 ))
534 }
535}
536
537fn parse_field_values<'a>(
538 input: &'a [u8],
539 fields: &[FieldDesc],
540 handles: &mut HandleTable,
541) -> IResult<&'a [u8], Vec<FieldValue>> {
542 let mut remaining = input;
543 let mut values = Vec::with_capacity(fields.len());
544
545 for field in fields {
546 let (rem, value) = parse_field_value(remaining, field, handles)?;
547 values.push(value);
548 remaining = rem;
549 }
550
551 Ok((remaining, values))
552}
553
554fn parse_field_value<'a>(
555 input: &'a [u8],
556 field: &FieldDesc,
557 handles: &mut HandleTable,
558) -> IResult<&'a [u8], FieldValue> {
559 match field {
560 FieldDesc::Primitive(pf) => match pf.type_code {
561 b'B' => map(be_i8, FieldValue::Byte)(input),
562 b'C' => map(be_u16, FieldValue::Char)(input),
563 b'D' => map(be_f64, FieldValue::Double)(input),
564 b'F' => map(be_f32, FieldValue::Float)(input),
565 b'I' => map(be_i32, FieldValue::Int)(input),
566 b'J' => map(be_i64, FieldValue::Long)(input),
567 b'S' => map(be_i16, FieldValue::Short)(input),
568 b'Z' => map(be_u8, |v| FieldValue::Boolean(v != 0))(input),
569 _ => Err(nom::Err::Error(nom::error::Error::new(
570 input,
571 nom::error::ErrorKind::Tag,
572 ))),
573 },
574 FieldDesc::Object(_) => {
575 let (input, obj) = parse_object(input, handles)?;
576 match obj {
577 StreamObject::NullReference => Ok((input, FieldValue::Object(None))),
578 obj => Ok((input, FieldValue::Object(Some(Box::new(obj))))),
579 }
580 }
581 }
582}
583
584fn parse_object_annotation<'a>(
585 input: &'a [u8],
586 handles: &mut HandleTable,
587) -> IResult<&'a [u8], ObjectAnnotation> {
588 let mut remaining = input;
589 let mut contents = Vec::new();
590 loop {
591 let tc = peek_tc(remaining)?;
592 if tc == TC_ENDBLOCKDATA {
593 let (rem, _) = be_u8(remaining)?; return Ok((rem, ObjectAnnotation { contents }));
595 }
596 if tc == TC_BLOCKDATA || tc == TC_BLOCKDATALONG {
597 let (rem, bd) = parse_block_data(remaining)?;
598 contents.push(AnnotationElement::BlockData(bd));
599 remaining = rem;
600 } else {
601 let (rem, obj) = parse_object(remaining, handles)?;
602 contents.push(AnnotationElement::Object(obj));
603 remaining = rem;
604 }
605 }
606}
607
608fn parse_new_class<'a>(input: &'a [u8], handles: &mut HandleTable) -> IResult<&'a [u8], NewClass> {
609 let (input, class_desc) = parse_class_desc_ref(input, handles)?;
610 let handle = handles.assign_handle();
611 let cls = NewClass {
612 class_desc: class_desc.clone(),
613 handle,
614 };
615 handles.update(handle, StreamObject::NewClass(cls.clone()));
616 Ok((input, cls))
617}
618
619fn parse_new_array<'a>(input: &'a [u8], handles: &mut HandleTable) -> IResult<&'a [u8], NewArray> {
620 let (input, class_desc) = parse_class_desc_ref(input, handles)?;
622 let (input, size) = be_u32(input)?;
624 let handle = handles.assign_handle();
626 let (input, values) = parse_array_values(input, &class_desc, size as usize, handles)?;
628
629 let arr = NewArray {
630 class_desc,
631 handle,
632 size,
633 values,
634 };
635 handles.update(handle, StreamObject::NewArray(arr.clone()));
636 Ok((input, arr))
637}
638
639fn parse_array_values<'a>(
640 input: &'a [u8],
641 class_desc: &ClassDescRef,
642 size: usize,
643 handles: &mut HandleTable,
644) -> IResult<&'a [u8], ArrayValues> {
645 let class_name = match class_desc {
648 ClassDescRef::Inline(cd) => match cd.as_ref() {
649 ClassDesc::Normal(desc) => desc.class_name.as_str(),
650 ClassDesc::Proxy(_) => "",
651 },
652 ClassDescRef::Reference { handle } => {
653 handles
655 .get(*handle)
656 .and_then(|obj| {
657 if let StreamObject::NewClassDesc(ClassDesc::Normal(desc)) = obj {
658 Some(desc.class_name.as_str())
659 } else {
660 None
661 }
662 })
663 .unwrap_or("")
664 }
665 ClassDescRef::Null => "",
666 };
667
668 match get_array_component_type(class_name) {
670 ArrayComponentType::Byte => {
671 let (input, vals) = count(be_i8, size)(input)?;
672 Ok((input, ArrayValues::Byte(vals)))
673 }
674 ArrayComponentType::Char => {
675 let (input, vals) = count(be_u16, size)(input)?;
676 Ok((input, ArrayValues::Char(vals)))
677 }
678 ArrayComponentType::Double => {
679 let (input, vals) = count(be_f64, size)(input)?;
680 Ok((input, ArrayValues::Double(vals)))
681 }
682 ArrayComponentType::Float => {
683 let (input, vals) = count(be_f32, size)(input)?;
684 Ok((input, ArrayValues::Float(vals)))
685 }
686 ArrayComponentType::Int => {
687 let (input, vals) = count(be_i32, size)(input)?;
688 Ok((input, ArrayValues::Int(vals)))
689 }
690 ArrayComponentType::Long => {
691 let (input, vals) = count(be_i64, size)(input)?;
692 Ok((input, ArrayValues::Long(vals)))
693 }
694 ArrayComponentType::Short => {
695 let (input, vals) = count(be_i16, size)(input)?;
696 Ok((input, ArrayValues::Short(vals)))
697 }
698 ArrayComponentType::Boolean => {
699 let (input, vals) = count(be_u8, size)(input)?;
700 Ok((input, ArrayValues::Boolean(vals)))
701 }
702 ArrayComponentType::Object => {
703 let mut remaining = input;
704 let mut vals = Vec::with_capacity(size);
705 for _ in 0..size {
706 let (rem, obj) = parse_object(remaining, handles)?;
707 match obj {
708 StreamObject::NullReference => vals.push(None),
709 obj => vals.push(Some(obj)),
710 }
711 remaining = rem;
712 }
713 Ok((remaining, ArrayValues::Object(vals)))
714 }
715 }
716}
717
718enum ArrayComponentType {
719 Byte,
720 Char,
721 Double,
722 Float,
723 Int,
724 Long,
725 Short,
726 Boolean,
727 Object,
728}
729
730fn get_array_component_type(class_name: &str) -> ArrayComponentType {
731 let mut chars = class_name.chars().peekable();
733 let mut depth = 0;
734 while chars.peek() == Some(&'[') {
735 chars.next();
736 depth += 1;
737 }
738
739 if depth == 0 {
740 return ArrayComponentType::Object;
741 }
742
743 if depth > 1 {
745 return ArrayComponentType::Object;
746 }
747
748 match chars.next() {
750 Some('B') => ArrayComponentType::Byte,
751 Some('C') => ArrayComponentType::Char,
752 Some('D') => ArrayComponentType::Double,
753 Some('F') => ArrayComponentType::Float,
754 Some('I') => ArrayComponentType::Int,
755 Some('J') => ArrayComponentType::Long,
756 Some('S') => ArrayComponentType::Short,
757 Some('Z') => ArrayComponentType::Boolean,
758 Some('L') | None => ArrayComponentType::Object,
759 _ => ArrayComponentType::Object,
760 }
761}
762
763fn parse_new_enum<'a>(input: &'a [u8], handles: &mut HandleTable) -> IResult<&'a [u8], NewEnum> {
764 let (input, class_desc) = parse_class_desc_ref(input, handles)?;
766 let handle = handles.assign_handle();
768 let (input, constant_name) = parse_enum_constant_name(input, handles)?;
770
771 let en = NewEnum {
772 class_desc,
773 handle,
774 constant_name,
775 };
776 handles.update(handle, StreamObject::NewEnum(en.clone()));
777 Ok((input, en))
778}
779
780fn parse_enum_constant_name<'a>(
781 input: &'a [u8],
782 handles: &mut HandleTable,
783) -> IResult<&'a [u8], StreamString> {
784 let (input, tc) = be_u8(input)?;
785 match tc {
786 TC_STRING => parse_tc_string(input, handles, false),
787 TC_LONGSTRING => parse_tc_string(input, handles, true),
788 TC_REFERENCE => {
789 let (input, handle) = be_u32(input)?;
790 Ok((
792 input,
793 StreamString {
794 value: format!("<ref:{:#08x}>", handle),
795 handle: 0, is_long: false,
797 },
798 ))
799 }
800 _ => Err(nom::Err::Error(nom::error::Error::new(
801 input,
802 nom::error::ErrorKind::Tag,
803 ))),
804 }
805}
806
807fn parse_tc_string<'a>(
808 input: &'a [u8],
809 handles: &mut HandleTable,
810 is_long: bool,
811) -> IResult<&'a [u8], StreamString> {
812 let (input, value) = if is_long {
813 parse_long_utf(input)?
814 } else {
815 parse_utf(input)?
816 };
817 let stream_string = StreamString {
818 value: value.clone(),
819 handle: 0,
820 is_long,
821 };
822 let handle = handles.assign(StreamObject::NewString(stream_string.clone()));
823 let result = StreamString {
824 value,
825 handle,
826 is_long,
827 };
828 Ok((input, result))
829}
830
831fn parse_utf(input: &[u8]) -> IResult<&[u8], String> {
833 let (input, length) = be_u16(input)?;
834 let (input, bytes) = take(length as usize)(input)?;
835 let value = cesu8::from_java_cesu8(bytes)
836 .map(|s| s.into_owned())
837 .unwrap_or_else(|_| String::from_utf8_lossy(bytes).into_owned());
838 Ok((input, value))
839}
840
841fn parse_long_utf(input: &[u8]) -> IResult<&[u8], String> {
843 let (input, length) = be_u64(input)?;
844 let (input, bytes) = take(length as usize)(input)?;
845 let value = cesu8::from_java_cesu8(bytes)
846 .map(|s| s.into_owned())
847 .unwrap_or_else(|_| String::from_utf8_lossy(bytes).into_owned());
848 Ok((input, value))
849}
850
851fn parse_block_data(input: &[u8]) -> IResult<&[u8], BlockData> {
852 let (input, tc) = be_u8(input)?;
853 parse_block_data_from_tc(input, tc)
854}
855
856fn parse_block_data_from_tc(input: &[u8], tc: u8) -> IResult<&[u8], BlockData> {
857 match tc {
858 TC_BLOCKDATA => {
859 let (input, size) = be_u8(input)?;
860 let (input, data) = take(size as usize)(input)?;
861 Ok((
862 input,
863 BlockData::Short {
864 data: data.to_vec(),
865 },
866 ))
867 }
868 TC_BLOCKDATALONG => {
869 let (input, size) = be_u32(input)?;
870 let (input, data) = take(size as usize)(input)?;
871 Ok((
872 input,
873 BlockData::Long {
874 data: data.to_vec(),
875 },
876 ))
877 }
878 _ => Err(nom::Err::Error(nom::error::Error::new(
879 input,
880 nom::error::ErrorKind::Tag,
881 ))),
882 }
883}