| 159 | /// (this means that underlying null values are copied as is). |
| 160 | #[inline] |
| 161 | pub fn append_array(&mut self, array: &GenericByteArray<T>) -> Result<(), ArrowError> { |
| 162 | use num_traits::CheckedAdd; |
| 163 | if array.len() == 0 { |
| 164 | return Ok(()); |
| 165 | } |
| 166 | |
| 167 | let offsets = array.offsets(); |
| 168 | |
| 169 | // If the offsets are contiguous, we can append them directly avoiding the need to align |
| 170 | // for example, when the first appended array is not sliced (starts at offset 0) |
| 171 | if self.next_offset() == offsets[0] { |
| 172 | self.offsets_builder.extend_from_slice(&offsets[1..]); |
| 173 | } else { |
| 174 | // Shifting all the offsets |
| 175 | let shift: T::Offset = self.next_offset() - offsets[0]; |
| 176 | |
| 177 | if shift.checked_add(&offsets[offsets.len() - 1]).is_none() { |
| 178 | return Err(ArrowError::OffsetOverflowError( |
| 179 | shift.as_usize() + offsets[offsets.len() - 1].as_usize(), |
| 180 | )); |
| 181 | } |
| 182 | |
| 183 | self.offsets_builder |
| 184 | .extend(offsets[1..].iter().map(|&offset| offset + shift)); |
| 185 | } |
| 186 | |
| 187 | // Append underlying values, starting from the first offset and ending at the last offset |
| 188 | self.value_builder.extend_from_slice( |
| 189 | &array.values().as_slice()[offsets[0].as_usize()..offsets[array.len()].as_usize()], |
| 190 | ); |
| 191 | |
| 192 | if let Some(null_buffer) = array.nulls() { |
| 193 | self.null_buffer_builder.append_buffer(null_buffer); |
| 194 | } else { |
| 195 | self.null_buffer_builder.append_n_non_nulls(array.len()); |
| 196 | } |
| 197 | Ok(()) |
| 198 | } |
| 199 | |
| 200 | /// Builds the [`GenericByteArray`] and reset this builder. |
| 201 | pub fn finish(&mut self) -> GenericByteArray<T> { |