Skip to content

Commit e34a339

Browse files
committed
Merge remote-tracking branch 'origin/master' into multiline
# Conflicts: # src/util.rs # src/workbench/tab.rs # src/workbench/workbench.rs
2 parents 5808b39 + 3f0788f commit e34a339

16 files changed

Lines changed: 161 additions & 108 deletions

File tree

src/elements/array.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,20 +132,23 @@ macro_rules! array {
132132
Ok((s.strip_prefix(']').ok_or(s.len())?, array))
133133
}
134134

135-
fn from_bytes<'a, D: $crate::serialization::Decoder<'a>>(decoder: &mut D) -> $crate::elements::result::NbtParseResult<Self> {
135+
fn from_bytes<'a, D: $crate::serialization::Decoder<'a>>(decoder: &mut D, _: Self::ExtraParseInfo) -> $crate::elements::result::NbtParseResult<Self> {
136136
use $crate::elements::result::*;
137137

138138
decoder.assert_len(4)?;
139139
let len = unsafe { decoder.u32() } as usize;
140140
decoder.assert_len(len * core::mem::size_of::<<Self::ChildType as $crate::elements::PrimitiveNbtElementVariant>::InnerType>())?;
141-
let mut vec = from_opt(Vec::try_with_capacity(len).ok(), "Could not allocate enough memory for Vec")?;
141+
let mut vec = from_result(Vec::try_with_capacity(len))?;
142142
for _ in 0..len {
143143
let element = $constructor(unsafe {
144144
core::mem::transmute(<<Self::ChildType as $crate::elements::PrimitiveNbtElementVariant>::InnerType>::from_ne_bytes(
145145
decoder.read_ne_bytes::<{ core::mem::size_of::<<Self::ChildType as $crate::elements::PrimitiveNbtElementVariant>::InnerType>() }>(),
146146
))
147147
});
148-
from_opt(vec.push_within_capacity(element).ok(), "Vec was longer than originally stated")?;
148+
match vec.push_within_capacity(element) {
149+
Ok(()) => {},
150+
Err(_) => return err("Vec was longer than originally stated"),
151+
}
149152
}
150153
let mut array = Self {
151154
values: unsafe { Box::try_new(vec).unwrap_unchecked() },

src/elements/chunk.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ impl DerefMut for NbtChunk {
9393
}
9494

9595
impl NbtElementVariant for NbtChunk {
96+
type ExtraParseInfo = usize;
97+
9698
const ID: u8 = 64 | 1;
9799
const UV: Vec2u = CHUNK_UV;
98100
const GHOST_UV: Vec2u = CHUNK_GHOST_UV;
@@ -121,9 +123,8 @@ impl NbtElementVariant for NbtChunk {
121123
Ok((s, Self::new(compound, (x, z), FileFormat::Zlib, now().as_secs() as u32)))
122124
}
123125

124-
fn from_bytes<'a, D: Decoder<'a>>(decoder: &mut D) -> NbtParseResult<Self>
126+
fn from_bytes<'a, D: Decoder<'a>>(decoder: &mut D, idx: usize) -> NbtParseResult<Self>
125127
where Self: Sized {
126-
let idx = from_opt(decoder.extra_data().write().take(), "Expected an index supplied as an extra field")?;
127128
let bytes = decoder.rest();
128129
let (offsets, bytes) = from_opt(bytes.split_first_chunk::<4096>(), "header wasn't big enough")?;
129130
let (last_modifieds, bytes) = from_opt(bytes.split_first_chunk::<4096>(), "header wasn't big enough")?;
@@ -140,20 +141,21 @@ impl NbtElementVariant for NbtChunk {
140141
.read()
141142
});
142143
if offset < 512 {
143-
return ok(NbtChunk::unloaded_from_pos(idx))
144+
return ok(NbtChunk::unloaded_from_pos(idx));
144145
}
145146
let pos = ((idx % 16) as u8, (idx / 16) as u8);
146147
let len = (offset as usize & 0xFF) * 4096;
148+
// value does include header so we must offset against that
147149
let offset = ((offset >> 8) - 2) as usize * 4096;
148150
if bytes.len() < offset + len {
149-
return err("Offset goes outside bytes")
151+
return err("Offset goes outside bytes");
150152
}
151153
let data = &bytes[offset..offset + len];
152154

153155
if let &[a, b, c, d, compression, ref data @ ..] = data {
154156
let chunk_len = from_opt((u32::from_be_bytes([a, b, c, d]) as usize).checked_sub(1), "Chunk was inside header.")?;
155157
if data.len() < chunk_len {
156-
return err("Offset is invalid")
158+
return err("Offset is invalid");
157159
}
158160
let data = &data[..chunk_len];
159161
let (compression, element) = match compression {

src/elements/compound.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use crate::serialization::{Decoder, PrettyDisplay, PrettyFormatter, UncheckedBuf
1818
use crate::util::{StrExt, Vec2u, width_ascii};
1919
#[cfg(target_arch = "wasm32")]
2020
use crate::wasm::{FakeScope as Scope, fake_scope as scope};
21-
use crate::{config, hash};
21+
use crate::{config, hash, util};
2222

2323
#[repr(C)]
2424
pub struct NbtCompound {
@@ -148,7 +148,7 @@ impl NbtElementVariant for NbtCompound {
148148
Ok((s, compound))
149149
}
150150

151-
fn from_bytes<'a, D: Decoder<'a>>(decoder: &mut D) -> NbtParseResult<Self>
151+
fn from_bytes<'a, D: Decoder<'a>>(decoder: &mut D, _: Self::ExtraParseInfo) -> NbtParseResult<Self>
152152
where Self: Sized {
153153
use super::result::*;
154154

@@ -683,12 +683,13 @@ impl CompoundMap {
683683
Some(entry)
684684
}
685685

686-
/// This function creates a mapping such that the `mapping[n]`th entry should move to the `n`th index to be sorted.
686+
/// This function creates a mapping such that the `n`th entry should move to the `mapping[n]`th index to be sorted.\
687687
#[must_use]
688688
pub fn create_sort_mapping<F: FnMut(&CompoundEntry, &CompoundEntry) -> Ordering>(&self, mut f: F) -> Box<[usize]> {
689689
let mut mapping = (0..self.len()).collect::<Vec<_>>();
690690
mapping.sort_unstable_by(|&a, &b| f(unsafe { self.entries.get_unchecked(a) }, unsafe { self.entries.get_unchecked(b) }));
691-
mapping.into_boxed_slice()
691+
// SAFETY: definitely a valid mapping that was generated
692+
unsafe{ util::invert_mapping_unchecked(&mapping) }
692693
}
693694

694695
pub fn update_key(&mut self, idx: usize, key: CompactString) -> Option<CompactString> {

src/elements/element.rs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -444,18 +444,18 @@ impl NbtElement {
444444
use super::result::*;
445445

446446
ok(match element {
447-
NbtByte::ID => Self::Byte(NbtByte::from_bytes(decoder)?),
448-
NbtShort::ID => Self::Short(NbtShort::from_bytes(decoder)?),
449-
NbtInt::ID => Self::Int(NbtInt::from_bytes(decoder)?),
450-
NbtLong::ID => Self::Long(NbtLong::from_bytes(decoder)?),
451-
NbtFloat::ID => Self::Float(NbtFloat::from_bytes(decoder)?),
452-
NbtDouble::ID => Self::Double(NbtDouble::from_bytes(decoder)?),
453-
NbtByteArray::ID => Self::ByteArray(NbtByteArray::from_bytes(decoder)?),
454-
NbtString::ID => Self::String(NbtString::from_bytes(decoder)?),
455-
NbtList::ID => Self::List(NbtList::from_bytes(decoder)?),
456-
NbtCompound::ID => Self::Compound(NbtCompound::from_bytes(decoder)?),
457-
NbtIntArray::ID => Self::IntArray(NbtIntArray::from_bytes(decoder)?),
458-
NbtLongArray::ID => Self::LongArray(NbtLongArray::from_bytes(decoder)?),
447+
NbtByte::ID => Self::Byte(NbtByte::from_bytes(decoder, ())?),
448+
NbtShort::ID => Self::Short(NbtShort::from_bytes(decoder, ())?),
449+
NbtInt::ID => Self::Int(NbtInt::from_bytes(decoder, ())?),
450+
NbtLong::ID => Self::Long(NbtLong::from_bytes(decoder, ())?),
451+
NbtFloat::ID => Self::Float(NbtFloat::from_bytes(decoder, ())?),
452+
NbtDouble::ID => Self::Double(NbtDouble::from_bytes(decoder, ())?),
453+
NbtByteArray::ID => Self::ByteArray(NbtByteArray::from_bytes(decoder, ())?),
454+
NbtString::ID => Self::String(NbtString::from_bytes(decoder, ())?),
455+
NbtList::ID => Self::List(NbtList::from_bytes(decoder, ())?),
456+
NbtCompound::ID => Self::Compound(NbtCompound::from_bytes(decoder, ())?),
457+
NbtIntArray::ID => Self::IntArray(NbtIntArray::from_bytes(decoder, ())?),
458+
NbtLongArray::ID => Self::LongArray(NbtLongArray::from_bytes(decoder, ())?),
459459
_ => return err("Invalid NBT type"),
460460
})
461461
}
@@ -493,7 +493,7 @@ impl NbtElement {
493493
if is_ok(&decoder.assert_len(2)) && unsafe { decoder.u16() } != 0_u16.to_be() {
494494
decoder.skip(-2_isize as usize);
495495
}
496-
let nbt = Self::Compound(NbtCompound::from_bytes(&mut decoder)?);
496+
let nbt = Self::Compound(NbtCompound::from_bytes(&mut decoder, ())?);
497497
if is_ok(&decoder.assert_len(1)) {
498498
return err("Format should take all the bytes");
499499
}
@@ -502,7 +502,7 @@ impl NbtElement {
502502

503503
pub fn from_be_mca(bytes: &[u8]) -> NbtParseResult<Self> {
504504
let mut decoder = BigEndianDecoder::new(bytes);
505-
NbtRegion::from_bytes(&mut decoder).map(Self::Region)
505+
NbtRegion::from_bytes(&mut decoder, ()).map(Self::Region)
506506
}
507507

508508
#[must_use]
@@ -517,13 +517,13 @@ impl NbtElement {
517517
decoder.assert_len(2)?;
518518
let skip = unsafe { decoder.u16() } as usize;
519519
decoder.skip(skip);
520-
ok((Self::Compound(NbtCompound::from_bytes(&mut decoder)?), decoder.has_header()))
520+
ok((Self::Compound(NbtCompound::from_bytes(&mut decoder, ())?), decoder.has_header()))
521521
}
522522
NbtList::ID => {
523523
decoder.assert_len(2)?;
524524
let skip = unsafe { decoder.u16() } as usize;
525525
decoder.skip(skip);
526-
ok((Self::List(NbtList::from_bytes(&mut decoder)?), decoder.has_header()))
526+
ok((Self::List(NbtList::from_bytes(&mut decoder, ())?), decoder.has_header()))
527527
}
528528
_ => err("Little-endian should start with either Compound or List"),
529529
};

src/elements/list.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -175,16 +175,14 @@ impl NbtElementVariant for NbtList {
175175
Ok((s, list))
176176
}
177177

178-
fn from_bytes<'a, D: Decoder<'a>>(decoder: &mut D) -> NbtParseResult<Self>
178+
fn from_bytes<'a, D: Decoder<'a>>(decoder: &mut D, _: Self::ExtraParseInfo) -> NbtParseResult<Self>
179179
where Self: Sized {
180180
use super::result::*;
181181

182182
decoder.assert_len(5)?;
183183
let element = unsafe { decoder.u8() };
184184
let len = unsafe { decoder.u32() } as usize;
185-
let mut vec = from_opt(Vec::try_with_capacity(len).ok(), "Could not allocate enough memory for Vec")?;
186-
let mut true_height = 1;
187-
let mut extracted_inner_element = false;
185+
let mut vec = from_result(Vec::try_with_capacity(len))?;
188186
for _ in 0..len {
189187
let mut element = NbtElement::from_bytes(element, decoder)?;
190188
// SAFETY: no caches have been made
@@ -193,13 +191,12 @@ impl NbtElementVariant for NbtList {
193191
.try_compound_singleton_into_inner()
194192
.unwrap_or_else(|element| element)
195193
};
196-
true_height += element.true_height() as u32;
197194
from_opt(vec.push_within_capacity(element).ok(), "Vec was larger that stated")?;
198195
}
199196
let mut list = Self {
200197
elements: unsafe { Box::try_new(vec).unwrap_unchecked() },
201-
height: 1 + len as u32,
202-
true_height,
198+
height: 1,
199+
true_height: 1,
203200
max_depth: 0,
204201
elements_bitset: 1 << element,
205202
open: false,

src/elements/mod.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,14 +121,16 @@ pub trait Matches {
121121
}
122122

123123
pub trait NbtElementVariant: Clone + PartialEq + Display + Matches + Default + PrettyDisplay {
124+
type ExtraParseInfo = ();
125+
124126
const ID: u8;
125127
const UV: Vec2u;
126128
const GHOST_UV: Vec2u;
127129

128130
fn from_str0(s: &str) -> Result<(&str, Self), usize>
129131
where Self: Sized;
130132

131-
fn from_bytes<'a, D: Decoder<'a>>(decoder: &mut D) -> NbtParseResult<Self>
133+
fn from_bytes<'a, D: Decoder<'a>>(decoder: &mut D, extra: Self::ExtraParseInfo) -> NbtParseResult<Self>
132134
where Self: Sized;
133135

134136
fn to_be_bytes(&self, writer: &mut UncheckedBufWriter);
@@ -205,7 +207,7 @@ pub trait ComplexNbtElementVariant: NbtElementVariant {
205207

206208
fn recache(&mut self);
207209

208-
fn on_style_change(&mut self, bookmarks: &mut MarkedLines) -> bool { false }
210+
fn on_style_change(&mut self, _bookmarks: &mut MarkedLines) -> bool { false }
209211

210212
#[must_use]
211213
fn get(&self, idx: usize) -> Option<&Self::Entry>;

src/elements/primitive.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ macro_rules! primitive {
3737
Err(s.len())
3838
}
3939

40-
fn from_bytes<'a, D: $crate::serialization::Decoder<'a>>(decoder: &mut D) -> $crate::elements::result::NbtParseResult<Self> {
40+
fn from_bytes<'a, D: $crate::serialization::Decoder<'a>>(decoder: &mut D, _: Self::ExtraParseInfo) -> $crate::elements::result::NbtParseResult<Self> {
4141
use $crate::elements::result::*;
4242

4343
unsafe {

src/elements/region.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ impl NbtElementVariant for NbtRegion {
170170
Ok((s, region))
171171
}
172172

173-
fn from_bytes<'a, D: Decoder<'a>>(decoder: &mut D) -> NbtParseResult<Self>
173+
fn from_bytes<'a, D: Decoder<'a>>(decoder: &mut D, _: Self::ExtraParseInfo) -> NbtParseResult<Self>
174174
where Self: Sized {
175175
use super::result::*;
176176

@@ -183,17 +183,12 @@ impl NbtElementVariant for NbtRegion {
183183
let mut threads = Vec::with_capacity(1024);
184184

185185
for idx in 0..1024 {
186-
while decoder.extra_data().read().is_some() {
187-
core::hint::spin_loop();
188-
}
189-
*decoder.extra_data().write() = Some(idx);
190-
191186
let d2: &mut D = unsafe {
192187
(decoder as *const D)
193188
.cast_mut()
194189
.as_mut_unchecked()
195190
};
196-
threads.push(s.spawn(move || NbtChunk::from_bytes(d2)));
191+
threads.push(s.spawn(move || NbtChunk::from_bytes(d2, idx)));
197192
}
198193

199194
for (idx, thread) in threads.into_iter().enumerate() {

src/elements/string.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ impl NbtElementVariant for NbtString {
4444
Ok((s, Self { str: TwentyThree::new(str) }))
4545
}
4646

47-
fn from_bytes<'a, D: Decoder<'a>>(decoder: &mut D) -> NbtParseResult<Self>
47+
fn from_bytes<'a, D: Decoder<'a>>(decoder: &mut D, _: Self::ExtraParseInfo) -> NbtParseResult<Self>
4848
where Self: Sized {
4949
use super::result::*;
5050

src/main.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
#![allow(semicolon_in_expressions_from_macros, internal_features, incomplete_features)]
22
#![warn(clippy::pedantic)]
3+
#![allow(unsafe_op_in_unsafe_fn)] // todo, fix
34
#![feature(
45
allocator_api,
6+
associated_type_defaults,
57
cold_path,
68
duration_millis_float,
79
inherent_associated_types,

0 commit comments

Comments
 (0)