From: Ben Pfaff Date: Mon, 29 Dec 2025 15:22:54 +0000 (-0800) Subject: work X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a9158da9756d9b11d34abd82ec3a9b13d5cba292;p=pspp work --- diff --git a/rust/doc/src/spv/legacy-detail-xml.md b/rust/doc/src/spv/legacy-detail-xml.md index a8f158b380..9041aff072 100644 --- a/rust/doc/src/spv/legacy-detail-xml.md +++ b/rust/doc/src/spv/legacy-detail-xml.md @@ -31,6 +31,20 @@ Instead, write tables in the light binary format. +## Overview + +The legacy table format represents the pivot table as a collection of +1-dimensional data series with equal length, forming a 2-dimensional +table. The data series include: + +* `cell`, which contains a data element in the table. + +* `dimension#categories`, one per dimension, which contain integer + indexes into the categories in the dimension, counting up from 0. + +* `dimension#group#`, one for each level of grouping within a + dimension, + ## The `visualization` Element ``` diff --git a/rust/pspp/src/cli/show_spv.rs b/rust/pspp/src/cli/show_spv.rs index 494e8a2352..dd97506da2 100644 --- a/rust/pspp/src/cli/show_spv.rs +++ b/rust/pspp/src/cli/show_spv.rs @@ -105,91 +105,100 @@ impl Display for Mode { impl ShowSpv { pub fn run(self) -> Result<()> { match self.mode { - Mode::Directory => { - let item = pspp::spv::ReadOptions::new(|e| eprintln!("{e}")) - .with_password(self.password) - .open_file(&self.input)? - .into_items(); - let items = self.criteria.apply(item); - for child in items { - print_item_directory(&child, 0, self.show_member_names); - } - Ok(()) - } - Mode::View => { - let item = pspp::spv::ReadOptions::new(|e| eprintln!("{e}")) - .with_password(self.password) - .open_file(&self.input)? - .into_items(); - let items = self.criteria.apply(item); - for child in items { - println!("{child}"); - } - Ok(()) - } - Mode::LegacyData => { - let mut spv_file = pspp::spv::ReadOptions::new(|e| eprintln!("{e}")) - .with_password(self.password) - .open_file(&self.input)?; - - let items = self.criteria.apply(spv_file.items); - for item in items { - for item in ItemRefIterator::with_hidden(&item) { - if let Some(spv_info) = dbg!(&item.spv_info) - && let Some(members) = &spv_info.members - && let SpvMembers::LegacyTable { xml: _, binary } = &members - { - let mut bin_member = spv_file.archive.by_name(&binary)?; - let mut bin_data = Vec::with_capacity(bin_member.size() as usize); - bin_member.read_to_end(&mut bin_data)?; - let mut cursor = Cursor::new(bin_data); - let legacy_bin = LegacyBin::read(&mut cursor).map_err(|e| { - e.with_message(format!( - "While parsing {binary:?} as legacy binary SPV member" - )) - })?; - let data = legacy_bin.decode(); - let n_values = data - .values() - .flat_map(|map| map.values()) - .map(|values| values.len()) - .max() - .unwrap_or(0); - let index = Dimension::new( - Group::new("Index") - .with_multiple(Leaf::numbers(0..n_values)) - .with_label_shown(), + Mode::Directory => self.directory(), + Mode::View => self.view(), + Mode::LegacyData => self.legacy_data(), + Mode::GetTableLook => todo!(), + Mode::ConvertTableLook => todo!(), + } + } + + fn directory(self) -> Result<()> { + let item = pspp::spv::ReadOptions::new(|e| eprintln!("{e}")) + .with_password(self.password) + .open_file(&self.input)? + .into_items(); + let items = self.criteria.apply(item); + for child in items { + print_item_directory(&child, 0, self.show_member_names); + } + Ok(()) + } + + fn view(self) -> Result<()> { + let item = pspp::spv::ReadOptions::new(|e| eprintln!("{e}")) + .with_password(self.password) + .open_file(&self.input)? + .into_items(); + let items = self.criteria.apply(item); + for child in items { + println!("{child}"); + } + Ok(()) + } + + fn legacy_data(self) -> Result<()> { + let mut spv_file = pspp::spv::ReadOptions::new(|e| eprintln!("{e}")) + .with_password(self.password) + .open_file(&self.input)?; + + let items = self.criteria.apply(spv_file.items); + for item in items { + for item in ItemRefIterator::with_hidden(&item) { + if let Some(spv_info) = dbg!(&item.spv_info) + && let Some(members) = &spv_info.members + && let SpvMembers::LegacyTable { xml: _, binary } = &members + { + let mut bin_member = spv_file.archive.by_name(&binary)?; + let mut bin_data = Vec::with_capacity(bin_member.size() as usize); + bin_member.read_to_end(&mut bin_data)?; + let mut cursor = Cursor::new(bin_data); + let legacy_bin = LegacyBin::read(&mut cursor).map_err(|e| { + e.with_message(format!( + "While parsing {binary:?} as legacy binary SPV member" + )) + })?; + let data = legacy_bin.decode(); + let n_values = data + .values() + .flat_map(|map| map.values()) + .map(|values| values.len()) + .max() + .unwrap_or(0); + let index = Dimension::new( + Group::new("Index") + .with_multiple(Leaf::numbers(0..n_values)) + .with_label_shown(), + ); + let variables = Dimension::new(Group::new("Variables").with_multiple( + data.iter().map(|(name, contents)| { + Group::new(name.as_str()).with_multiple(contents.keys().map(|name| { + name.replace("categories", "\ncategories") + .replace("labels", "\nlabels") + .replace("group", "\ngroup") + .replace("Label", "\nLabel") + })) + }), + )); + let mut pivot_table = + PivotTable::new([(Axis3::Y, index), (Axis3::X, variables)]); + let formats = HashMap::new(); + for (variable_index, (variable_name, values)) in + data.values().flat_map(|map| map.iter()).enumerate() + { + for (value_index, data_value) in values.iter().enumerate() { + let value = Value::new_datum(&data_value.value).with_value_label( + (variable_name == "cellFormat") + .then(|| data_value.as_format(&formats).to_string()), ); - let variables = Dimension::new(Group::new("Variables").with_multiple( - data.iter().map(|(name, contents)| { - Group::new(name.as_str()).with_multiple(contents.keys()) - }), - )); - let mut pivot_table = - PivotTable::new([(Axis3::Y, index), (Axis3::X, variables)]); - let formats = HashMap::new(); - for (variable_index, (variable_name, values)) in - data.values().flat_map(|map| map.iter()).enumerate() - { - for (value_index, data_value) in values.iter().enumerate() { - let value = Value::new_datum(&data_value.value) - .with_value_label( - (variable_name == "cellFormat").then(|| { - data_value.as_format(&formats).to_string() - }), - ); - pivot_table.insert([value_index, variable_index], value); - } - } - println!("{pivot_table}"); + pivot_table.insert([value_index, variable_index], value); } } + println!("{pivot_table}"); } - Ok(()) } - Mode::GetTableLook => todo!(), - Mode::ConvertTableLook => todo!(), } + Ok(()) } }