Simplify Array::pad.
This commit is contained in:
parent
d47bfa431a
commit
c5cb2d5e0f
@ -9,18 +9,18 @@ use std::borrow::Borrow;
|
||||
use std::prelude::v1::*;
|
||||
|
||||
impl Dynamic {
|
||||
/// Recursively calculate the sizes of a value.
|
||||
/// Recursively calculate the sizes of an array.
|
||||
///
|
||||
/// Sizes returned are `(` [`Array`][crate::Array], [`Map`][crate::Map] and [`String`] `)`.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if any interior data is shared (should never happen).
|
||||
pub(crate) fn calc_data_sizes(&self, _top: bool) -> (usize, usize, usize) {
|
||||
match self.0 {
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
Union::Array(ref arr, ..) => {
|
||||
arr.iter()
|
||||
#[inline]
|
||||
pub(crate) fn calc_array_sizes(array: &crate::Array, _top: bool) -> (usize, usize, usize) {
|
||||
array
|
||||
.iter()
|
||||
.fold((0, 0, 0), |(ax, mx, sx), value| match value.0 {
|
||||
Union::Array(..) => {
|
||||
let (a, m, s) = value.calc_data_sizes(false);
|
||||
@ -36,10 +36,16 @@ impl Dynamic {
|
||||
_ => (ax + 1, mx, sx),
|
||||
})
|
||||
}
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
Union::Blob(ref blob, ..) => (blob.len(), 0, 0),
|
||||
/// Recursively calculate the sizes of a map.
|
||||
///
|
||||
/// Sizes returned are `(` [`Array`][crate::Array], [`Map`][crate::Map] and [`String`] `)`.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if any interior data is shared (should never happen).
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
Union::Map(ref map, ..) => {
|
||||
#[inline]
|
||||
pub(crate) fn calc_map_sizes(map: &crate::Map, _top: bool) -> (usize, usize, usize) {
|
||||
map.values()
|
||||
.fold((0, 0, 0), |(ax, mx, sx), value| match value.0 {
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
@ -57,6 +63,22 @@ impl Dynamic {
|
||||
_ => (ax, mx + 1, sx),
|
||||
})
|
||||
}
|
||||
/// Recursively calculate the sizes of a value.
|
||||
///
|
||||
/// Sizes returned are `(` [`Array`][crate::Array], [`Map`][crate::Map] and [`String`] `)`.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if any interior data is shared (should never happen).
|
||||
#[inline]
|
||||
pub(crate) fn calc_data_sizes(&self, _top: bool) -> (usize, usize, usize) {
|
||||
match self.0 {
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
Union::Array(ref arr, ..) => Self::calc_array_sizes(&**arr, _top),
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
Union::Blob(ref blob, ..) => (blob.len(), 0, 0),
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
Union::Map(ref map, ..) => Self::calc_map_sizes(&**map, _top),
|
||||
Union::Str(ref s, ..) => (0, 0, s.len()),
|
||||
#[cfg(not(feature = "no_closure"))]
|
||||
Union::Shared(..) if _top => self.read_lock::<Self>().unwrap().calc_data_sizes(true),
|
||||
|
@ -235,52 +235,15 @@ pub mod array_functions {
|
||||
|
||||
// Check if array will be over max size limit
|
||||
#[cfg(not(feature = "unchecked"))]
|
||||
{
|
||||
use crate::types::dynamic::Union;
|
||||
if _ctx.engine().max_array_size() > 0 {
|
||||
let pad = len - array.len();
|
||||
let (a, m, s) = Dynamic::calc_array_sizes(array, true);
|
||||
let (ax, mx, sx) = item.calc_data_sizes(true);
|
||||
|
||||
if _ctx.engine().max_array_size() > 0 && len > _ctx.engine().max_array_size() {
|
||||
return Err(
|
||||
ERR::ErrorDataTooLarge("Size of array".to_string(), Position::NONE).into(),
|
||||
);
|
||||
_ctx.engine()
|
||||
.throw_on_size((a + pad + ax * pad, m + mx * pad, s + sx * pad))?;
|
||||
}
|
||||
|
||||
let check_sizes = match item.0 {
|
||||
Union::Str(..) => true,
|
||||
Union::Array(..) => true,
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
Union::Map(..) => true,
|
||||
_ => false,
|
||||
};
|
||||
|
||||
if check_sizes {
|
||||
let mut arr_len = array.len();
|
||||
let mut arr = Dynamic::from_array(mem::take(array));
|
||||
|
||||
let (mut a1, mut m1, mut s1) = arr.calc_data_sizes(true);
|
||||
let (a2, m2, s2) = item.calc_data_sizes(true);
|
||||
|
||||
{
|
||||
let mut guard = arr.write_lock::<Array>().unwrap();
|
||||
|
||||
while arr_len < len {
|
||||
a1 += a2;
|
||||
m1 += m2;
|
||||
s1 += s2;
|
||||
|
||||
_ctx.engine().throw_on_size((a1, m1, s1))?;
|
||||
|
||||
guard.push(item.clone());
|
||||
arr_len += 1;
|
||||
}
|
||||
}
|
||||
|
||||
*array = arr.into_array().unwrap();
|
||||
} else {
|
||||
array.resize(len, item);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "unchecked")]
|
||||
array.resize(len, item);
|
||||
|
||||
Ok(())
|
||||
|
Loading…
Reference in New Issue
Block a user