Skip to content

Commit

Permalink
Merge pull request #5 from raleighlittles/feature/adding-language-sup…
Browse files Browse the repository at this point in the history
…port-to-preferences-file

Added support for parsing languages from Preferences file
  • Loading branch information
raleighlittles authored Jan 18, 2024
2 parents 6b0433b + 5728a9a commit 0d83327
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 5 deletions.
Binary file added docs/iPod_setup_languages.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed docs/ipod_languages_screenshot.png
Binary file not shown.
3 changes: 3 additions & 0 deletions parser/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,6 @@ edition = "2021"
[dependencies]
chrono = "0.4.31"
csv = "1.3.0"

# Languages parsing
isolang = "2.4.0"
2 changes: 1 addition & 1 deletion parser/src/constants/preferences_constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,4 @@ pub const VOLUME_LIMIT_OFFSET : usize = 2896; // 0xB50
pub const VOLUME_LIMIT_LEN : usize = 1;

pub const REGION_OFFSET : usize = 2928; // 0xB70
pub const REGION_LEN : usize = 1;
pub const REGION_LEN : usize = 2;
4 changes: 2 additions & 2 deletions parser/src/parsers/preferences_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ pub fn parse_preferences_file(itunesdb_file_as_bytes: Vec<u8>) {

println!("Daylight Savings Time enabled?: {}", preferences::is_daylight_savings_enabled(dst_setting_raw as u8));

let language_selection_idx = helpers::get_slice_as_le_u32(idx, &itunesdb_file_as_bytes, preferences_constants::LANGUAGE_SELECTION_OFFSET, preferences_constants::LANGUAGE_SELECTION_LEN);
let lang_selection_idx = helpers::get_slice_as_le_u32(idx, &itunesdb_file_as_bytes, preferences_constants::LANGUAGE_SELECTION_OFFSET, preferences_constants::LANGUAGE_SELECTION_LEN);

println!("Selected language idx: {}", language_selection_idx);
println!("Selected language idx: {} ~ Parses to '{}'", lang_selection_idx, preferences::decode_language_from_idx(lang_selection_idx as u8));

let tz_info_raw = helpers::get_slice_as_le_u32(idx, &itunesdb_file_as_bytes, preferences_constants::TIMEZONE_INFO_OFFSET, preferences_constants::TIMEZONE_INFO_LEN);

Expand Down
48 changes: 46 additions & 2 deletions parser/src/preferences.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
* Provides functionality for working with the Preferences file
*/

use std::num::Wrapping;

pub fn is_daylight_savings_enabled(raw_dst_setting : u8) -> bool {

Expand All @@ -14,11 +13,56 @@ pub fn is_daylight_savings_enabled(raw_dst_setting : u8) -> bool {
return raw_dst_setting == dst_enabled_val;
}

/// This function is a little bit dubious, the logic for it was added in a comment on the original documentation
/// and I get invalid values with it sometimes.
pub fn decode_timezone(raw_timezone_info : u8) -> u8 {

let gmt_timezone_const = 0x19; // 25d, supposed to represent GMT (UTC+0)

let timezone_hour = (Wrapping(raw_timezone_info)) - Wrapping(gmt_timezone_const);
let timezone_hour = (std::num::Wrapping(raw_timezone_info)) - std::num::Wrapping(gmt_timezone_const);

return timezone_hour.0 / 2;
}

/// This was a little bit tricky to figure out. The index comes from when the device starts up for the first time, and
/// asks you to choose the language list.
/// I couldn't find anywhere this was documented so I ended up having to find an old iPod myself, reset it, and scroll
/// through the list of available languages.
/// Note that interestingly, the string tables on the iPod (stored in the UISS_combined.plist file) have the language strings
/// installed for "Thai" (`th-TH`), even though in the settings you can't actually change the device to that language.
pub fn decode_language_from_idx(lang_idx : u8) -> String {

let selected_lang : Option<isolang::Language> = match lang_idx {
0_u8 | 1_u8 => isolang::Language::from_639_1("en"),
2_u8 => isolang::Language::from_639_1("ja"),
3_u8 => isolang::Language::from_639_1("cs"),
4_u8 => isolang::Language::from_639_1("da"),
5_u8 => isolang::Language::from_639_1("de"),
6_u8 => isolang::Language::from_639_1("es"),
7_u8 => isolang::Language::from_639_1("fr"),
8_u8 => isolang::Language::from_639_1("el"),
9_u8 => isolang::Language::from_639_1("hr"),
10_u8 =>isolang::Language::from_639_1("it"),
11_u8 => isolang::Language::from_639_1("hu"),
12_u8 => isolang::Language::from_639_1("nl"),
13_u8 => isolang::Language::from_639_1("no"),
14_u8 | 15_u8 => isolang::Language::from_639_1("pt"),
16_u8 => isolang::Language::from_639_1("ru"),
17_u8 => isolang::Language::from_639_1("pl"),
18_u8 => isolang::Language::from_639_1("ro"),
19_u8 => isolang::Language::from_639_1("sk"),
20_u8 => isolang::Language::from_639_1("fi"),
21_u8 => isolang::Language::from_639_1("sv"),
22_u8 => isolang::Language::from_639_1("tr"),
23_u8 => isolang::Language::from_639_1("ar"),
24_u8 => isolang::Language::from_639_1("ko"),
25_u8 | 26_u8 | 27_u8 => isolang::Language::from_639_1("zh"),
28_u8 => isolang::Language::from_639_1("he"),
unknown_lang_code => {
panic!("'{}' is not a valid ISO-639-1 language code", unknown_lang_code);
}

};

return selected_lang.unwrap().to_name().to_string();
}

0 comments on commit 0d83327

Please sign in to comment.