1use crate::nbt_version::{BedrockDisk, BedrockNetVarInt, Java, JavaNetAfter1_20_2, NbtReadTrait};
2use crate::{nbt_version, NbtError, NbtResult, NbtValue};
3
4pub struct NbtReader<'data> {
6 pub data: &'data mut [u8],
8 pub cursor: usize,
10}
11
12impl nbt_version::NbtReadTrait for nbt_version::Java {
18 #[inline]
19 fn read_nbt_string(reader: &mut NbtReader) -> NbtResult<String> {
20 let len = reader.read_be_u16() as usize;
21 reader.read_string(len)
22 }
23 #[inline]
24 fn read_i8_array(reader: &mut NbtReader) -> NbtResult<Vec<i8>> {
25 let len = reader.read_be_i32() as usize;
26 let value = reader.read_i8_array(len);
27 Ok(value)
28 }
29 #[inline]
30 fn read_i32_array(reader: &mut NbtReader) -> NbtResult<Vec<i32>> {
31 let len = reader.read_be_i32() as usize;
32 let value = reader.read_be_i32_array(len);
33 Ok(value)
34 }
35 #[inline]
36 fn read_i64_array(reader: &mut NbtReader) -> NbtResult<Vec<i64>> {
37 let len = reader.read_be_i32() as usize;
38 let value = reader.read_be_i64_array(len);
39 Ok(value)
40 }
41 #[inline]
42 fn read_compound(reader: &mut NbtReader) -> NbtResult<Vec<(String, NbtValue)>> {
43 let mut compound = Vec::with_capacity(10);
44 loop {
45 let tag_id = reader.read_u8();
46 if tag_id == 0 {
47 break;
48 }
49 let name = Java::read_nbt_string(reader)?;
50 let value = match tag_id {
51 1 => NbtValue::Byte(reader.read_i8()),
52 2 => NbtValue::Short(reader.read_be_i16()),
53 3 => NbtValue::Int(reader.read_be_i32()),
54 4 => NbtValue::Long(reader.read_be_i64()),
55 5 => NbtValue::Float(reader.read_be_f32()),
56 6 => NbtValue::Double(reader.read_be_f64()),
57 7 => NbtValue::ByteArray(Java::read_i8_array(reader)?),
58 8 => NbtValue::String(Java::read_nbt_string(reader)?),
59 9 => NbtValue::List(Java::read_list(reader)?),
60 10 => NbtValue::Compound(
61 Some(name.clone()),
62 nbt_version::Java::read_compound(reader)?,
63 ),
64 11 => NbtValue::IntArray(Java::read_i32_array(reader)?),
65 12 => NbtValue::LongArray(Java::read_i64_array(reader)?),
66 _ => return Err(NbtError::UnknownType(tag_id)),
67 };
68 compound.push((name, value));
69 }
70 Ok(compound)
71 }
72 #[inline]
73 fn read_list(reader: &mut NbtReader) -> NbtResult<Vec<NbtValue>> {
74 let type_id = reader.read_u8();
75 let len = reader.read_be_i32() as usize;
76 let mut list = Vec::with_capacity(len);
77 for _ in 0..len {
78 let value = match type_id {
79 1 => NbtValue::Byte(reader.read_i8()),
80 2 => NbtValue::Short(reader.read_be_i16()),
81 3 => NbtValue::Int(reader.read_be_i32()),
82 4 => NbtValue::Long(reader.read_be_i64()),
83 5 => NbtValue::Float(reader.read_be_f32()),
84 6 => NbtValue::Double(reader.read_be_f64()),
85 7 => NbtValue::ByteArray(Java::read_i8_array(reader)?),
86 8 => NbtValue::String(Java::read_nbt_string(reader)?),
87 9 => NbtValue::List(Java::read_list(reader)?),
88 10 => NbtValue::Compound(None, nbt_version::Java::read_compound(reader)?),
89 11 => NbtValue::IntArray(Java::read_i32_array(reader)?),
90 12 => NbtValue::LongArray(Java::read_i64_array(reader)?),
91 _ => return Err(NbtError::UnknownType(type_id)),
92 };
93 list.push(value);
94 }
95 Ok(list)
96 }
97
98 fn from_reader(mut reader: NbtReader) -> NbtResult<NbtValue> {
99 match reader.read_u8() {
101 10 => {
102 let name = Java::read_nbt_string(&mut reader)?;
103 Ok(NbtValue::Compound(Some(name), nbt_version::Java::read_compound(&mut reader)?))
104 }
105 x => Err(NbtError::WrongRootType(x)),
106 }
107 }
108}
109
110impl NbtReadTrait for JavaNetAfter1_20_2 {
114 #[inline]
115 fn read_nbt_string(reader: &mut NbtReader) -> NbtResult<String> {
116 Java::read_nbt_string(reader)
117 }
118 #[inline]
119 fn read_i8_array(reader: &mut NbtReader) -> NbtResult<Vec<i8>> { Java::read_i8_array(reader) }
120 #[inline]
121 fn read_i32_array(reader: &mut NbtReader) -> NbtResult<Vec<i32>> {
122 Java::read_i32_array(reader)
123 }
124 #[inline]
125 fn read_i64_array(reader: &mut NbtReader) -> NbtResult<Vec<i64>> {
126 Java::read_i64_array(reader)
127 }
128 #[inline]
129 fn read_compound(reader: &mut NbtReader) -> NbtResult<Vec<(String, NbtValue)>> {
130 Java::read_compound(reader)
131 }
132 #[inline]
133 fn read_list(reader: &mut NbtReader) -> NbtResult<Vec<NbtValue>> { Java::read_list(reader) }
134
135 fn from_reader(mut reader: NbtReader) -> NbtResult<NbtValue> {
136 match reader.read_u8() {
138 10 => {
139 Ok(NbtValue::Compound(None, nbt_version::Java::read_compound(&mut reader)?))
141 }
142 x => Err(NbtError::WrongRootType(x)),
143 }
144 }
145}
146
147impl NbtReadTrait for BedrockDisk {
151 #[inline]
152 fn read_nbt_string(reader: &mut NbtReader) -> NbtResult<String> {
153 let len = reader.read_le_u16() as usize;
154 reader.read_string(len)
155 }
156 #[inline]
157 fn read_i8_array(reader: &mut NbtReader) -> NbtResult<Vec<i8>> {
158 let len = reader.read_le_i32() as usize;
159 let value = reader.read_i8_array(len);
160 Ok(value)
161 }
162 #[inline]
163 fn read_i32_array(reader: &mut NbtReader) -> NbtResult<Vec<i32>> {
164 let len = reader.read_le_i32() as usize;
165 let value = reader.read_le_i32_array(len);
166 Ok(value)
167 }
168 #[inline]
169 fn read_i64_array(reader: &mut NbtReader) -> NbtResult<Vec<i64>> {
170 let len = reader.read_le_i32() as usize;
171 let value = reader.read_le_i64_array(len);
172 Ok(value)
173 }
174 #[inline]
175 fn read_compound(reader: &mut NbtReader) -> NbtResult<Vec<(String, NbtValue)>> {
176 let mut compound = Vec::with_capacity(10);
177 loop {
178 let tag_id = reader.read_u8();
179 if tag_id == 0 {
180 break;
181 }
182 let name = BedrockDisk::read_nbt_string(reader)?;
183 let value = match tag_id {
184 1 => NbtValue::Byte(reader.read_i8()),
185 2 => NbtValue::Short(reader.read_le_i16()),
186 3 => NbtValue::Int(reader.read_le_i32()),
187 4 => NbtValue::Long(reader.read_le_i64()),
188 5 => NbtValue::Float(reader.read_le_f32()),
189 6 => NbtValue::Double(reader.read_le_f64()),
190 7 => NbtValue::ByteArray(BedrockDisk::read_i8_array(reader)?),
191 8 => NbtValue::String(BedrockDisk::read_nbt_string(reader)?),
192 9 => NbtValue::List(BedrockDisk::read_list(reader)?),
193 10 => NbtValue::Compound(None, nbt_version::BedrockDisk::read_compound(reader)?),
194 11 => NbtValue::IntArray(BedrockDisk::read_i32_array(reader)?),
195 12 => NbtValue::LongArray(BedrockDisk::read_i64_array(reader)?),
196 _ => return Err(NbtError::UnknownType(tag_id)),
197 };
198 compound.push((name, value));
199 }
200 Ok(compound)
201 }
202 #[inline]
203 fn read_list(reader: &mut NbtReader) -> NbtResult<Vec<NbtValue>> {
204 let type_id = reader.read_u8();
205 let len = reader.read_le_i32() as usize;
206 let mut list = Vec::with_capacity(len);
207 for _ in 0..len {
208 let value = match type_id {
209 1 => NbtValue::Byte(reader.read_i8()),
210 2 => NbtValue::Short(reader.read_le_i16()),
211 3 => NbtValue::Int(reader.read_le_i32()),
212 4 => NbtValue::Long(reader.read_le_i64()),
213 5 => NbtValue::Float(reader.read_le_f32()),
214 6 => NbtValue::Double(reader.read_le_f64()),
215 7 => NbtValue::ByteArray(BedrockDisk::read_i8_array(reader)?),
216 8 => NbtValue::String(BedrockDisk::read_nbt_string(reader)?),
217 9 => NbtValue::List(BedrockDisk::read_list(reader)?),
218 10 => NbtValue::Compound(None, nbt_version::BedrockDisk::read_compound(reader)?),
219 11 => NbtValue::IntArray(BedrockDisk::read_i32_array(reader)?),
220 12 => NbtValue::LongArray(BedrockDisk::read_i64_array(reader)?),
221 _ => return Err(NbtError::UnknownType(type_id)),
222 };
223 list.push(value);
224 }
225 Ok(list)
226 }
227
228 fn from_reader(mut reader: NbtReader) -> NbtResult<NbtValue> {
229 match reader.read_u8() {
231 9 => {
232 Ok(NbtValue::List(nbt_version::BedrockDisk::read_list(&mut reader)?))
234 }
235 10 => {
236 let name = BedrockDisk::read_nbt_string(&mut reader)?;
238 Ok(NbtValue::Compound(
239 Some(name),
240 nbt_version::BedrockDisk::read_compound(&mut reader)?,
241 ))
242 }
243 x => Err(NbtError::WrongRootType(x)),
245 }
246 }
247}
248
249impl NbtReadTrait for BedrockNetVarInt {
251 fn read_nbt_string(reader: &mut NbtReader) -> NbtResult<String> {
252 let len = reader.read_var_i32()? as usize;
253 reader.read_string(len)
254 }
255 fn read_i8_array(reader: &mut NbtReader) -> NbtResult<Vec<i8>> {
256 let len = reader.read_zigzag_var_i32()? as usize;
257 let value = reader.read_i8_array(len);
258 Ok(value)
259 }
260 fn read_i32_array(reader: &mut NbtReader) -> NbtResult<Vec<i32>> {
261 let len = reader.read_zigzag_var_i32()? as usize;
262 let value = reader.read_le_i32_array(len);
263 Ok(value)
264 }
265 fn read_i64_array(reader: &mut NbtReader) -> NbtResult<Vec<i64>> {
266 let len = reader.read_zigzag_var_i32()? as usize;
267 let value = reader.read_le_i64_array(len);
268 Ok(value)
269 }
270 fn read_compound(reader: &mut NbtReader) -> NbtResult<Vec<(String, NbtValue)>> {
271 let mut compound = Vec::with_capacity(10);
272 loop {
273 let tag_id = reader.read_u8();
274 if tag_id == 0 {
275 break;
276 }
277 let name = BedrockNetVarInt::read_nbt_string(reader)?;
278 let value = match tag_id {
279 1 => NbtValue::Byte(reader.read_i8()),
280 2 => NbtValue::Short(reader.read_le_i16()),
281 3 => NbtValue::Int(reader.read_zigzag_var_i32()?),
282 4 => NbtValue::Long(reader.read_zigzag_var_i64()?),
283 5 => NbtValue::Float(reader.read_le_f32()),
284 6 => NbtValue::Double(reader.read_le_f64()),
285 7 => NbtValue::ByteArray(BedrockNetVarInt::read_i8_array(reader)?),
286 8 => NbtValue::String(BedrockNetVarInt::read_nbt_string(reader)?),
287 9 => NbtValue::List(BedrockNetVarInt::read_list(reader)?),
288 10 => NbtValue::Compound(None, BedrockNetVarInt::read_compound(reader)?),
289 11 => NbtValue::IntArray(BedrockNetVarInt::read_i32_array(reader)?),
290 12 => NbtValue::LongArray(BedrockNetVarInt::read_i64_array(reader)?),
291 _ => return Err(NbtError::UnknownType(tag_id)),
292 };
293 compound.push((name, value));
294 }
295 Ok(compound)
296 }
297 fn read_list(reader: &mut NbtReader) -> NbtResult<Vec<NbtValue>> {
298 let type_id = reader.read_u8();
299 let len = reader.read_zigzag_var_i32()? as usize;
300 let mut list = Vec::with_capacity(len);
301 for _ in 0..len {
302 let value = match type_id {
303 1 => NbtValue::Byte(reader.read_i8()),
304 2 => NbtValue::Short(reader.read_le_i16()),
305 3 => NbtValue::Int(reader.read_zigzag_var_i32()?),
306 4 => NbtValue::Long(reader.read_zigzag_var_i64()?),
307 5 => NbtValue::Float(reader.read_le_f32()),
308 6 => NbtValue::Double(reader.read_le_f64()),
309 7 => NbtValue::ByteArray(BedrockNetVarInt::read_i8_array(reader)?),
310 8 => NbtValue::String(BedrockNetVarInt::read_nbt_string(reader)?),
311 9 => NbtValue::List(BedrockNetVarInt::read_list(reader)?),
312 10 => NbtValue::Compound(None, BedrockNetVarInt::read_compound(reader)?),
313 11 => NbtValue::IntArray(BedrockNetVarInt::read_i32_array(reader)?),
314 12 => NbtValue::LongArray(BedrockNetVarInt::read_i64_array(reader)?),
315 _ => return Err(NbtError::UnknownType(type_id)),
316 };
317 list.push(value);
318 }
319 Ok(list)
320 }
321 fn from_reader(mut reader: NbtReader) -> NbtResult<NbtValue> {
322 match reader.read_u8() {
323 9 => {
324 Ok(NbtValue::List(BedrockNetVarInt::read_list(&mut reader)?))
326 }
327 10 => {
328 let name = BedrockNetVarInt::read_nbt_string(&mut reader)?;
330 Ok(NbtValue::Compound(Some(name), BedrockNetVarInt::read_compound(&mut reader)?))
331 }
332 x => Err(NbtError::WrongRootType(x)),
334 }
335 }
336}
337
338macro_rules! read_uncheck {
339 ($be_name:ident, $le_name:ident, $ty:ty, $size:literal) => {
340 #[doc = concat!("读取 ", stringify!($ty), " 类型 ", $size, " 长度的数据")]
341 #[inline]
348 pub unsafe fn $be_name(&mut self) -> $ty {
349 let ptr = self.data.as_ptr().add(self.cursor) as *const $ty;
351 let value = std::ptr::read_unaligned(ptr);
352 self.cursor += std::mem::size_of::<$ty>();
353 value.to_be()
354 }
355
356 #[doc = concat!("读取 ", stringify!($ty), " 类型 ", $size, " 长度的数据")]
357 #[inline]
364 pub unsafe fn $le_name(&mut self) -> $ty {
365 let ptr = self.data.as_ptr().add(self.cursor) as *const $ty;
367 let value = std::ptr::read_unaligned(ptr);
368 self.cursor += std::mem::size_of::<$ty>();
369 value.to_le()
370 }
371 };
372}
373
374impl NbtReader<'_> {
375 pub fn new(data: &mut [u8]) -> NbtReader { NbtReader { data, cursor: 0 } }
376 #[inline]
378 pub fn roll_back(&mut self, len: usize) { self.cursor -= len; }
379 #[inline]
381 pub fn roll_down(&mut self, len: usize) { self.cursor += len; }
382 #[inline]
384 pub fn read_u8(&mut self) -> u8 {
385 let value = self.data[self.cursor];
386 self.cursor += 1;
387 value
388 }
389 #[inline]
391 pub fn read_i8(&mut self) -> i8 { self.read_u8() as i8 }
392 read_uncheck!(read_be_i16_unsafe, read_le_i16_unsafe, i16, 2);
393 read_uncheck!(read_be_u16_unsafe, read_le_u16_unsafe, u16, 2);
394 read_uncheck!(read_be_i32_unsafe, read_le_i32_unsafe, i32, 4);
395 read_uncheck!(read_be_u32_unsafe, read_le_u32_unsafe, u32, 4);
396 read_uncheck!(read_be_i64_unsafe, read_le_i64_unsafe, i64, 8);
397 read_uncheck!(read_be_u64_unsafe, read_le_u64_unsafe, u64, 8);
398 #[inline]
404 pub fn read_be_i16(&mut self) -> i16 {
405 let value = i16::from_be_bytes([self.data[self.cursor], self.data[self.cursor + 1]]);
406 self.cursor += 2;
407 value
408 }
409 #[inline]
413 pub fn read_le_i16(&mut self) -> i16 {
414 let value = i16::from_le_bytes([self.data[self.cursor], self.data[self.cursor + 1]]);
415 self.cursor += 2;
416 value
417 }
418 #[inline]
424 pub fn read_be_u16(&mut self) -> u16 { self.read_be_i16() as u16 }
425 #[inline]
431 pub fn read_le_u16(&mut self) -> u16 { self.read_le_i16() as u16 }
432 #[inline]
438 pub fn read_be_i32(&mut self) -> i32 {
439 let value = i32::from_be_bytes([
440 self.data[self.cursor],
441 self.data[self.cursor + 1],
442 self.data[self.cursor + 2],
443 self.data[self.cursor + 3],
444 ]);
445 self.cursor += 4;
446 value
447 }
448 #[inline]
454 pub fn read_var_i32(&mut self) -> NbtResult<i32> {
455 let mut value = 0;
456 let mut size = 0;
457 loop {
458 let byte = self.read_u8();
459 value |= ((byte & 0b0111_1111) as i32) << (size * 7);
460 size += 1;
461 if size > 5 {
462 return Err(NbtError::VarIntTooBig(value as usize));
463 }
464 if (byte & 0b1000_0000) == 0 {
465 break;
466 }
467 }
468 Ok(value)
469 }
470 #[inline]
476 pub fn read_var_i64(&mut self) -> NbtResult<i64> {
477 let mut value = 0;
478 let mut size = 0;
479 loop {
480 let byte = self.read_u8();
481 value |= ((byte & 0b0111_1111) as i64) << (size * 7);
482 size += 1;
483 if size > 10 {
484 return Err(NbtError::VarlongTooBig(value as usize));
485 }
486 if (byte & 0b1000_0000) == 0 {
487 break;
488 }
489 }
490 Ok(value)
491 }
492 #[inline]
496 pub fn read_zigzag_var_i32(&mut self) -> NbtResult<i32> {
497 let value = self.read_var_i32()?;
498 Ok((value >> 1) ^ (-(value & 1)))
499 }
500 #[inline]
504 pub fn read_zigzag_var_i64(&mut self) -> NbtResult<i64> {
505 let value = self.read_var_i64()?;
506 Ok((value >> 1) ^ (-(value & 1)))
507 }
508 #[inline]
512 pub fn read_le_i32(&mut self) -> i32 {
513 let value = i32::from_le_bytes([
514 self.data[self.cursor],
515 self.data[self.cursor + 1],
516 self.data[self.cursor + 2],
517 self.data[self.cursor + 3],
518 ]);
519 self.cursor += 4;
520 value
521 }
522 #[inline]
528 pub fn read_be_u32(&mut self) -> u32 {
529 let value = u32::from_be_bytes([
530 self.data[self.cursor],
531 self.data[self.cursor + 1],
532 self.data[self.cursor + 2],
533 self.data[self.cursor + 3],
534 ]);
535 self.cursor += 4;
536 value
537 }
538 #[inline]
544 pub fn read_le_u32(&mut self) -> u32 {
545 let value = u32::from_le_bytes([
546 self.data[self.cursor],
547 self.data[self.cursor + 1],
548 self.data[self.cursor + 2],
549 self.data[self.cursor + 3],
550 ]);
551 self.cursor += 4;
552 value
553 }
554 #[inline]
560 pub fn read_be_i64(&mut self) -> i64 {
561 let value = i64::from_be_bytes([
562 self.data[self.cursor],
563 self.data[self.cursor + 1],
564 self.data[self.cursor + 2],
565 self.data[self.cursor + 3],
566 self.data[self.cursor + 4],
567 self.data[self.cursor + 5],
568 self.data[self.cursor + 6],
569 self.data[self.cursor + 7],
570 ]);
571 self.cursor += 8;
572 value
573 }
574 #[inline]
580 pub fn read_le_i64(&mut self) -> i64 {
581 let value = i64::from_le_bytes([
582 self.data[self.cursor],
583 self.data[self.cursor + 1],
584 self.data[self.cursor + 2],
585 self.data[self.cursor + 3],
586 self.data[self.cursor + 4],
587 self.data[self.cursor + 5],
588 self.data[self.cursor + 6],
589 self.data[self.cursor + 7],
590 ]);
591 self.cursor += 8;
592 value
593 }
594 #[inline]
600 pub fn read_be_u64(&mut self) -> u64 {
601 let value = u64::from_be_bytes([
602 self.data[self.cursor],
603 self.data[self.cursor + 1],
604 self.data[self.cursor + 2],
605 self.data[self.cursor + 3],
606 self.data[self.cursor + 4],
607 self.data[self.cursor + 5],
608 self.data[self.cursor + 6],
609 self.data[self.cursor + 7],
610 ]);
611 self.cursor += 8;
612 value
613 }
614 #[inline]
620 pub fn read_le_u64(&mut self) -> u64 {
621 let value = u64::from_le_bytes([
622 self.data[self.cursor],
623 self.data[self.cursor + 1],
624 self.data[self.cursor + 2],
625 self.data[self.cursor + 3],
626 self.data[self.cursor + 4],
627 self.data[self.cursor + 5],
628 self.data[self.cursor + 6],
629 self.data[self.cursor + 7],
630 ]);
631 self.cursor += 8;
632 value
633 }
634 #[inline]
638 pub fn read_be_f32(&mut self) -> f32 { f32::from_bits(self.read_be_u32()) }
639 #[inline]
643 pub fn read_le_f32(&mut self) -> f32 { f32::from_bits(self.read_le_u32()) }
644 #[inline]
648 pub fn read_be_f64(&mut self) -> f64 { f64::from_bits(self.read_be_u64()) }
649 #[inline]
653 pub fn read_le_f64(&mut self) -> f64 { f64::from_bits(self.read_le_u64()) }
654 #[inline]
660 pub unsafe fn read_be_f32_unsafe(&mut self) -> f32 {
661 let value = self.read_be_u32_unsafe();
662 std::mem::transmute::<u32, f32>(value)
663 }
664 #[inline]
670 pub unsafe fn read_le_f32_unsafe(&mut self) -> f32 {
671 let value = self.read_le_u32_unsafe();
672 std::mem::transmute::<u32, f32>(value)
673 }
674 #[inline]
680 pub unsafe fn read_be_f64_unsafe(&mut self) -> f64 {
681 let value = self.read_be_u64_unsafe();
682 std::mem::transmute::<u64, f64>(value)
683 }
684 #[inline]
690 pub unsafe fn read_le_f64_unsafe(&mut self) -> f64 {
691 let value = self.read_le_u64_unsafe();
692 std::mem::transmute::<u64, f64>(value)
693 }
694 #[inline]
700 pub fn read_u8_array(&mut self, len: usize) -> &[u8] {
701 let value = &self.data[self.cursor..self.cursor + len];
702 self.cursor += len;
703 value
704 }
705 #[inline]
711 pub unsafe fn read_i8_array_unsafe(&mut self, len: usize) -> Vec<i8> {
712 let value = std::slice::from_raw_parts(self.data[self.cursor..].as_ptr() as *const i8, len);
713 self.cursor += len;
714 value.to_vec()
715 }
716 #[inline]
722 pub fn read_i8_array(&mut self, len: usize) -> Vec<i8> {
723 let value = self.data[self.cursor..self.cursor + len].iter().map(|&n| n as i8).collect();
724 self.cursor += len;
725 value
726 }
727 #[inline]
733 pub unsafe fn read_be_i16_array_unsafe(&mut self, len: usize) -> Vec<i16> {
734 let mut value: Vec<i16> = Vec::with_capacity(len);
735 std::ptr::copy_nonoverlapping(
736 self.data[self.cursor..].as_ptr() as *const u8,
737 value.as_ptr() as *mut u8,
738 len * 2,
739 );
740 value.set_len(len);
741 for n in &mut value {
742 *n = n.to_be();
743 }
744 self.cursor += len * 2;
745 value
746 }
747 #[inline]
753 pub unsafe fn read_be_i32_array_unsafe(&mut self, len: usize) -> Vec<i32> {
754 let mut value: Vec<i32> = Vec::with_capacity(len);
755 std::ptr::copy_nonoverlapping(
756 self.data[self.cursor..].as_ptr() as *const u8,
757 value.as_ptr() as *mut u8,
758 len * 4,
759 );
760 value.set_len(len);
761 for n in &mut value {
762 *n = n.to_be();
763 }
764 self.cursor += len * 4;
765 value
766 }
767 #[inline]
773 pub unsafe fn read_be_i64_array_unsafe(&mut self, len: usize) -> Vec<i64> {
774 let mut value: Vec<i64> = Vec::with_capacity(len);
775 std::ptr::copy_nonoverlapping(
776 self.data[self.cursor..].as_ptr() as *const u8,
777 value.as_ptr() as *mut u8,
778 len * 8,
779 );
780 value.set_len(len);
781 for n in &mut value {
782 *n = n.to_be();
783 }
784 self.cursor += len * 8;
785 value
786 }
787 #[inline]
793 pub fn read_be_i32_array(&mut self, len: usize) -> Vec<i32> {
794 let value = self.data[self.cursor..self.cursor + len * 4]
795 .chunks_exact(4)
796 .map(|n| i32::from_be_bytes(n[0..4].try_into().unwrap()))
797 .collect();
798 self.cursor += len * 4;
799 value
800 }
801 #[inline]
807 pub fn read_be_i64_array(&mut self, len: usize) -> Vec<i64> {
808 let value = self.data[self.cursor..self.cursor + len * 8]
809 .chunks_exact(8)
810 .map(|n| i64::from_be_bytes(n[0..8].try_into().unwrap()))
811 .collect();
812 self.cursor += len * 8;
813 value
814 }
815 #[inline]
821 pub fn read_le_i16_array(&mut self, len: usize) -> Vec<i16> {
822 let value = self.data[self.cursor..self.cursor + len * 2]
823 .chunks_exact(2)
824 .map(|n| i16::from_le_bytes(n[0..2].try_into().unwrap()))
825 .collect();
826 self.cursor += len * 2;
827 value
828 }
829 #[inline]
835 pub fn read_le_i32_array(&mut self, len: usize) -> Vec<i32> {
836 let value = self.data[self.cursor..self.cursor + len * 4]
837 .chunks_exact(4)
838 .map(|n| i32::from_le_bytes(n[0..4].try_into().unwrap()))
839 .collect();
840 self.cursor += len * 4;
841 value
842 }
843 #[inline]
849 pub fn read_le_i64_array(&mut self, len: usize) -> Vec<i64> {
850 let value = self.data[self.cursor..self.cursor + len * 8]
851 .chunks_exact(8)
852 .map(|n| i64::from_le_bytes(n[0..8].try_into().unwrap()))
853 .collect();
854 self.cursor += len * 8;
855 value
856 }
857 #[inline]
863 pub fn read_string(&mut self, len: usize) -> Result<String, NbtError> {
864 if len + self.cursor > self.data.len() {
865 return Err(NbtError::CursorOverflow(self.cursor, len, self.data.len()));
866 }
867 let value = String::from_utf8_lossy(&self.data[self.cursor..self.cursor + len]);
868 self.cursor += len;
869 Ok(value.into_owned())
870 }
871}