From 1d85ab6cee5ef5b3fdc93832756924558a4cecaf Mon Sep 17 00:00:00 2001
From: Chloe <48113593+kawaiizenbo@users.noreply.github.com>
Date: Sun, 3 Oct 2021 10:55:40 -0700
Subject: [PATCH 01/12] Create LICENSE
---
LICENSE | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
create mode 100644 LICENSE
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..eb806a8
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2021 KawaiiZenbo
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
From 370a93260948c02c5bc3f89f580ed700954e5396 Mon Sep 17 00:00:00 2001
From: kawaiizenbo <48113593+kawaiizenbo@users.noreply.github.com>
Date: Sun, 3 Oct 2021 11:16:52 -0700
Subject: [PATCH 02/12] rev up those friers we just replaced the broken libary
with a rebuilt one
---
IPASorter/IPASorter.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/IPASorter/IPASorter.csproj b/IPASorter/IPASorter.csproj
index d7bd561..c514386 100644
--- a/IPASorter/IPASorter.csproj
+++ b/IPASorter/IPASorter.csproj
@@ -7,7 +7,7 @@
- ..\..\..\..\Documents\GitHub\PlistCS\PlistCS\PlistCS\bin\Release\PlistCS.dll
+ ..\..\..\..\Documents\GitHub\fork\PlistCS\PlistCS\bin\Release\netcoreapp3.1\PlistCS.dll
From f45d99ab5c1203ed5beebf700e005033c389d5ad Mon Sep 17 00:00:00 2001
From: kawaiizenbo <48113593+kawaiizenbo@users.noreply.github.com>
Date: Sun, 3 Oct 2021 11:18:59 -0700
Subject: [PATCH 03/12] rev up those fryers i'm a dumbass lmao
---
IPASorter/IPASorter.csproj | 2 +-
IPASorter/PlistCS.dll | Bin 0 -> 17920 bytes
2 files changed, 1 insertion(+), 1 deletion(-)
create mode 100644 IPASorter/PlistCS.dll
diff --git a/IPASorter/IPASorter.csproj b/IPASorter/IPASorter.csproj
index c514386..5733140 100644
--- a/IPASorter/IPASorter.csproj
+++ b/IPASorter/IPASorter.csproj
@@ -7,7 +7,7 @@
- ..\..\..\..\Documents\GitHub\fork\PlistCS\PlistCS\bin\Release\netcoreapp3.1\PlistCS.dll
+ PlistCS.dll
diff --git a/IPASorter/PlistCS.dll b/IPASorter/PlistCS.dll
new file mode 100644
index 0000000000000000000000000000000000000000..7d8fb5d91a1c5c08eddd7a837923a555d6b28298
GIT binary patch
literal 17920
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
T&t~;Ix^J)i!*#(QvgQ99y;K*^
literal 0
HcmV?d00001
From fcf6830e2d546099ee6860b9003c7a1a02f7b6dd Mon Sep 17 00:00:00 2001
From: kawaiizenbo <48113593+kawaiizenbo@users.noreply.github.com>
Date: Sun, 3 Oct 2021 11:24:22 -0700
Subject: [PATCH 04/12] make it not backslashes who cares about windows 7
---
IPASorter/Program.cs | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/IPASorter/Program.cs b/IPASorter/Program.cs
index a4b2e97..12ddf90 100644
--- a/IPASorter/Program.cs
+++ b/IPASorter/Program.cs
@@ -19,14 +19,14 @@ namespace IPASorter
static void Main(string[] args)
{
Console.WriteLine("IPASorter by KawaiiZenbo");
- if(Directory.Exists(".\\sortertemp"))
+ if(Directory.Exists("./sortertemp"))
{
- Directory.Delete(".\\sortertemp", true);
+ Directory.Delete("./sortertemp", true);
}
// parse filepath if given
- string argsFilePath = args.Length != 0 ? args[0] : ".\\";
- if (!argsFilePath.EndsWith("/") || !argsFilePath.EndsWith("\\")) argsFilePath += "/";
+ string argsFilePath = args.Length != 0 ? args[0] : "./";
+ if (!argsFilePath.EndsWith("/") || !argsFilePath.EndsWith("/")) argsFilePath += "/";
// run steps
FileScanner(argsFilePath);
@@ -48,7 +48,7 @@ namespace IPASorter
{
files.Add(new IPAFile
{
- fileName = s.Split('/')[s.Split('/').Length -1].Split('\\')[s.Split('/')[s.Split('/').Length - 1].Split('\\').Length - 1],
+ fileName = s.Split('/')[s.Split('/').Length -1].Split('/')[s.Split('/')[s.Split('/').Length - 1].Split('/').Length - 1],
path = s,
md5sum = CalculateMD5(s)
}) ;
@@ -58,19 +58,19 @@ namespace IPASorter
// step 2
static void InfoPlistRenamer()
{
- Directory.CreateDirectory(".\\sortertemp");
+ Directory.CreateDirectory("./sortertemp");
foreach (IPAFile i in files)
{
Console.WriteLine($"fixing name of {i.fileName}");
// extract ipa
- Directory.CreateDirectory($".\\sortertemp\\{i.fileName}");
- ZipFile.ExtractToDirectory(i.path, $".\\sortertemp\\{i.fileName}");
- string appPath = $".\\sortertemp\\{i.fileName}\\Payload\\{Directory.GetDirectories($".\\sortertemp\\{i.fileName}\\Payload\\")[0].Split('\\')[Directory.GetDirectories($".\\sortertemp\\{i.fileName}\\Payload\\")[0].Split('\\').Length - 1]}";
+ Directory.CreateDirectory($"./sortertemp/{i.fileName}");
+ ZipFile.ExtractToDirectory(i.path, $"./sortertemp/{i.fileName}");
+ string appPath = $"./sortertemp/{i.fileName}/Payload/{Directory.GetDirectories($"./sortertemp/{i.fileName}/Payload/")[0].Split('/')[Directory.GetDirectories($"./sortertemp/{i.fileName}/Payload/")[0].Split('/').Length - 1]}";
// parse plist
- Dictionary plist = (Dictionary)Plist.readPlist(appPath + "\\Info.plist");
- Directory.Delete($".\\sortertemp\\{i.fileName}", true);
+ Dictionary plist = (Dictionary)Plist.readPlist(appPath + "/Info.plist");
+ Directory.Delete($"./sortertemp/{i.fileName}", true);
i.CFBundleIdentifier = plist["CFBundleIdentifier"].ToString();
i.CFBundleVersion = plist["CFBundleVersion"].ToString();
i.MinimumOSVersion = plist["MinimumOSVersion"].ToString();
@@ -81,7 +81,7 @@ namespace IPASorter
i.path = i.path.Replace(i.fileName, newFileName);
i.fileName = newFileName;
}
- Directory.Delete(".\\sortertemp", true);
+ Directory.Delete("./sortertemp", true);
}
// optional step 3
From 323f348410970e915243c2823d843e55e1a86d60 Mon Sep 17 00:00:00 2001
From: kawaiizenbo <48113593+kawaiizenbo@users.noreply.github.com>
Date: Sun, 3 Oct 2021 19:45:36 -0700
Subject: [PATCH 05/12] a lot of fixes and updates
---
IPASorter/FileClass.cs | 6 +++
IPASorter/Program.cs | 91 ++++++++++++++++++++++++++++++++++--------
README.md | 7 ++--
3 files changed, 83 insertions(+), 21 deletions(-)
diff --git a/IPASorter/FileClass.cs b/IPASorter/FileClass.cs
index ac4228b..6e3b624 100644
--- a/IPASorter/FileClass.cs
+++ b/IPASorter/FileClass.cs
@@ -12,5 +12,11 @@ namespace IPASorter
public string CFBundleIdentifier { get; set; }
public string CFBundleVersion { get; set; }
public string MinimumOSVersion { get; set; }
+ public string CFBundleDisplayName { get; set; }
+ }
+
+ public class AppList
+ {
+ public IPAFile[] apps { get; set; }
}
}
diff --git a/IPASorter/Program.cs b/IPASorter/Program.cs
index 12ddf90..dbfd39a 100644
--- a/IPASorter/Program.cs
+++ b/IPASorter/Program.cs
@@ -7,6 +7,8 @@ using System.IO.Compression;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
+using System.Text.Json;
+using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace IPASorter
@@ -26,16 +28,14 @@ namespace IPASorter
// parse filepath if given
string argsFilePath = args.Length != 0 ? args[0] : "./";
- if (!argsFilePath.EndsWith("/") || !argsFilePath.EndsWith("/")) argsFilePath += "/";
+ if (!argsFilePath.EndsWith("/")) argsFilePath += "/";
// run steps
FileScanner(argsFilePath);
// MD5Eliminator(); obsolete
- InfoPlistRenamer();
- if(args.Length > 1 && args[1] == "-si")
- {
- SortByiOSCompatibility();
- }
+ InfoPlistRenamer(argsFilePath);
+ SortByiOSCompatibility(argsFilePath);
+ GenerateJson();
Console.WriteLine("complete :)");
}
@@ -43,12 +43,14 @@ namespace IPASorter
// step 1
static void FileScanner(string path)
{
+ Console.WriteLine("Scanning subdirectories for IPA files");
List tmp = Directory.GetFiles(path, "*.ipa", SearchOption.AllDirectories).ToList();
foreach (string s in tmp)
{
+ Console.WriteLine($"Found {s}");
files.Add(new IPAFile
{
- fileName = s.Split('/')[s.Split('/').Length -1].Split('/')[s.Split('/')[s.Split('/').Length - 1].Split('/').Length - 1],
+ fileName = s.Split('/')[s.Split('/').Length -1],
path = s,
md5sum = CalculateMD5(s)
}) ;
@@ -56,9 +58,10 @@ namespace IPASorter
}
// step 2
- static void InfoPlistRenamer()
+ static void InfoPlistRenamer(string path)
{
Directory.CreateDirectory("./sortertemp");
+ Directory.CreateDirectory($"{path}/incomplete");
foreach (IPAFile i in files)
{
Console.WriteLine($"fixing name of {i.fileName}");
@@ -66,17 +69,47 @@ namespace IPASorter
// extract ipa
Directory.CreateDirectory($"./sortertemp/{i.fileName}");
ZipFile.ExtractToDirectory(i.path, $"./sortertemp/{i.fileName}");
- string appPath = $"./sortertemp/{i.fileName}/Payload/{Directory.GetDirectories($"./sortertemp/{i.fileName}/Payload/")[0].Split('/')[Directory.GetDirectories($"./sortertemp/{i.fileName}/Payload/")[0].Split('/').Length - 1]}";
-
// parse plist
- Dictionary plist = (Dictionary)Plist.readPlist(appPath + "/Info.plist");
+ Dictionary plist = new Dictionary();
+ try
+ {
+ string appPath = $"./sortertemp/{i.fileName}/Payload/{Directory.GetDirectories($"./sortertemp/{i.fileName}/Payload/")[0].Split('/')[Directory.GetDirectories($"./sortertemp/{i.fileName}/Payload/")[0].Split('/').Length - 1]}";
+ plist = (Dictionary)Plist.readPlist(appPath + "/Info.plist");
+ }
+ catch(Exception)
+ {
+ Console.WriteLine($"{i.fileName} has a missing/damaged Info.plist. moving to the broken directory...");
+ File.Move(i.path, $"{path}/incomplete/{i.fileName.Replace(".ipa", $"-{i.md5sum}.ipa")}", true);
+ i.path = $"{path}/incomplete/{i.fileName.Replace(".ipa", $"-{i.md5sum}.ipa")}";
+ continue;
+ }
Directory.Delete($"./sortertemp/{i.fileName}", true);
i.CFBundleIdentifier = plist["CFBundleIdentifier"].ToString();
- i.CFBundleVersion = plist["CFBundleVersion"].ToString();
- i.MinimumOSVersion = plist["MinimumOSVersion"].ToString();
+ try
+ {
+ i.CFBundleDisplayName = RemoveIllegalFileNameChars(plist["CFBundleDisplayName"].ToString());
+ }
+ catch (KeyNotFoundException)
+ {
+ i.CFBundleDisplayName = i.CFBundleIdentifier.Split('.')[2];
+ }
+ string whichToUse = "CFBundleVersion";
+ if (plist["CFBundleVersion"].ToString() == "1")
+ {
+ whichToUse = "CFBundleShortVersionString";
+ }
+ i.CFBundleVersion = plist[whichToUse].ToString();
+ try
+ {
+ i.MinimumOSVersion = plist["MinimumOSVersion"].ToString();
+ }
+ catch (KeyNotFoundException)
+ {
+ i.MinimumOSVersion = "2.0";
+ }
// rename file
- string newFileName = $"{plist["CFBundleIdentifier"]}-{plist["CFBundleVersion"]}-(iOS_{plist["MinimumOSVersion"]})-{i.md5sum}.ipa";
+ string newFileName = $"{i.CFBundleDisplayName}-({i.CFBundleIdentifier})-{i.CFBundleVersion}-(iOS_{i.MinimumOSVersion})-{i.md5sum}.ipa";
File.Move(i.path, i.path.Replace(i.fileName, newFileName), true);
i.path = i.path.Replace(i.fileName, newFileName);
i.fileName = newFileName;
@@ -84,13 +117,30 @@ namespace IPASorter
Directory.Delete("./sortertemp", true);
}
- // optional step 3
- static void SortByiOSCompatibility()
+ // step 3
+ static void SortByiOSCompatibility(string path)
{
+ Console.WriteLine("Sorting apps by minimum iOS version");
+ foreach(IPAFile i in files)
+ {
+ if (i.path == "DO NOT ENUMERATE") continue;
+ Directory.CreateDirectory($"{path}/iOS{i.MinimumOSVersion.Split('.')[0]}/{i.CFBundleIdentifier}");
+ File.Move(i.path, $"{path}/iOS{i.MinimumOSVersion.Split('.')[0]}/{i.CFBundleIdentifier}/{i.fileName}", true);
+ i.path = $"{path}/iOS{i.MinimumOSVersion.Split('.')[0]}/{i.CFBundleIdentifier}/{i.fileName}";
+ }
}
- // othet stuff
+ // step 4
+ static void GenerateJson()
+ {
+ AppList apps = new AppList();
+ apps.apps = files.ToArray();
+ string appsJson = JsonSerializer.Serialize(apps);
+ File.WriteAllText("./apps.json", appsJson);
+ }
+
+ // other stuff (hate)
static string CalculateMD5(string fileName)
{
using (var md5 = MD5.Create())
@@ -102,6 +152,13 @@ namespace IPASorter
}
}
}
+
+ public static string RemoveIllegalFileNameChars(string input, string replacement = "")
+ {
+ var regexSearch = new string(Path.GetInvalidFileNameChars()) + new string(Path.GetInvalidPathChars());
+ var r = new Regex(string.Format("[{0}]", Regex.Escape(regexSearch)));
+ return r.Replace(input, replacement);
+ }
}
}
diff --git a/README.md b/README.md
index 293ba5a..cb1c98c 100644
--- a/README.md
+++ b/README.md
@@ -2,10 +2,9 @@
Cross platform sorter for iOS app packages (IPAs)
## Command line arguments
-`IPASorter `
-Running with no arguments will sort from the directory the program is in with no sorting options.
-### Sorting Options
-coming soon
+`IPASorter ` or
+`dotnet IPASorter.dll `
+Running with no arguments will sort from the directory the program is in.
requires .net core 3.1 or later
From 3bef56b0874cbf2b75c114e76edacb6f1f283022 Mon Sep 17 00:00:00 2001
From: kawaiizenbo <48113593+kawaiizenbo@users.noreply.github.com>
Date: Sun, 3 Oct 2021 20:00:30 -0700
Subject: [PATCH 06/12] little oops
---
IPASorter/Program.cs | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/IPASorter/Program.cs b/IPASorter/Program.cs
index dbfd39a..94b2371 100644
--- a/IPASorter/Program.cs
+++ b/IPASorter/Program.cs
@@ -68,7 +68,18 @@ namespace IPASorter
// extract ipa
Directory.CreateDirectory($"./sortertemp/{i.fileName}");
- ZipFile.ExtractToDirectory(i.path, $"./sortertemp/{i.fileName}");
+ try
+ {
+ ZipFile.ExtractToDirectory(i.path, $"./sortertemp/{i.fileName}");
+ }
+ catch (Exception)
+ {
+ Console.WriteLine($"{i.fileName} is damaged. moving to the broken directory...");
+ File.Move(i.path, $"{path}/incomplete/{i.fileName.Replace(".ipa", $"-{i.md5sum}.ipa")}", true);
+ i.path = $"{path}/incomplete/{i.fileName.Replace(".ipa", $"-{i.md5sum}.ipa")}";
+ i.MinimumOSVersion = "DO NOT ENUMERATE";
+ continue;
+ }
// parse plist
Dictionary plist = new Dictionary();
try
@@ -81,6 +92,7 @@ namespace IPASorter
Console.WriteLine($"{i.fileName} has a missing/damaged Info.plist. moving to the broken directory...");
File.Move(i.path, $"{path}/incomplete/{i.fileName.Replace(".ipa", $"-{i.md5sum}.ipa")}", true);
i.path = $"{path}/incomplete/{i.fileName.Replace(".ipa", $"-{i.md5sum}.ipa")}";
+ i.MinimumOSVersion = "DO NOT ENUMERATE";
continue;
}
Directory.Delete($"./sortertemp/{i.fileName}", true);
@@ -124,7 +136,7 @@ namespace IPASorter
foreach(IPAFile i in files)
{
- if (i.path == "DO NOT ENUMERATE") continue;
+ if (i.MinimumOSVersion == "DO NOT ENUMERATE") continue;
Directory.CreateDirectory($"{path}/iOS{i.MinimumOSVersion.Split('.')[0]}/{i.CFBundleIdentifier}");
File.Move(i.path, $"{path}/iOS{i.MinimumOSVersion.Split('.')[0]}/{i.CFBundleIdentifier}/{i.fileName}", true);
i.path = $"{path}/iOS{i.MinimumOSVersion.Split('.')[0]}/{i.CFBundleIdentifier}/{i.fileName}";
From 0e09c535572ca24c3cff41a6d991c0dfb3a50af4 Mon Sep 17 00:00:00 2001
From: KawaiiZenbo <48113593+kawaiizenbo@users.noreply.github.com>
Date: Mon, 25 Apr 2022 13:25:43 -0700
Subject: [PATCH 07/12] Update LICENSE
---
LICENSE | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/LICENSE b/LICENSE
index eb806a8..806e2ac 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2021 KawaiiZenbo
+Copyright (c) 2021 the KawaiiZenbos/the Gum Hive
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
From 713c286dffadaa02503048dbbc739f0906f10192 Mon Sep 17 00:00:00 2001
From: kawaiizenbo <48113593+kawaiizenbo@users.noreply.github.com>
Date: Sat, 18 Jun 2022 15:54:26 -0700
Subject: [PATCH 08/12] consider your bugs hunted
---
IPASorter/FileClass.cs | 22 -
IPASorter/IPASorter.csproj | 6 -
IPASorter/Plist.cs | 961 +++++++++++++++++++++++++++++++++++++
IPASorter/PlistCS.dll | Bin 17920 -> 0 bytes
IPASorter/Program.cs | 211 ++++----
5 files changed, 1091 insertions(+), 109 deletions(-)
delete mode 100644 IPASorter/FileClass.cs
create mode 100644 IPASorter/Plist.cs
delete mode 100644 IPASorter/PlistCS.dll
diff --git a/IPASorter/FileClass.cs b/IPASorter/FileClass.cs
deleted file mode 100644
index 6e3b624..0000000
--- a/IPASorter/FileClass.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace IPASorter
-{
- public class IPAFile
- {
- public string path { get; set; }
- public string md5sum { get; set; }
- public string fileName { get; set; }
- public string CFBundleIdentifier { get; set; }
- public string CFBundleVersion { get; set; }
- public string MinimumOSVersion { get; set; }
- public string CFBundleDisplayName { get; set; }
- }
-
- public class AppList
- {
- public IPAFile[] apps { get; set; }
- }
-}
diff --git a/IPASorter/IPASorter.csproj b/IPASorter/IPASorter.csproj
index 5733140..c73e0d1 100644
--- a/IPASorter/IPASorter.csproj
+++ b/IPASorter/IPASorter.csproj
@@ -5,10 +5,4 @@
netcoreapp3.1
-
-
- PlistCS.dll
-
-
-
diff --git a/IPASorter/Plist.cs b/IPASorter/Plist.cs
new file mode 100644
index 0000000..f52c364
--- /dev/null
+++ b/IPASorter/Plist.cs
@@ -0,0 +1,961 @@
+//
+// PlistCS Property List (plist) serialization and parsing library.
+//
+// https://github.com/animetrics/PlistCS
+//
+// Copyright (c) 2011 Animetrics Inc. (marc@animetrics.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Xml;
+
+namespace PlistCS
+{
+ public static class Plist
+ {
+ private static List offsetTable = new List();
+ private static List objectTable = new List();
+ private static int refCount;
+ private static int objRefSize;
+ private static int offsetByteSize;
+ private static long offsetTableOffset;
+
+ #region Public Functions
+
+ public static object readPlist(string path)
+ {
+ using (FileStream f = new FileStream(path, FileMode.Open, FileAccess.Read))
+ {
+ return readPlist(f, plistType.Auto);
+ }
+ }
+
+ public static object readPlistSource(string source)
+ {
+ return readPlist(System.Text.Encoding.UTF8.GetBytes(source));
+ }
+
+ public static object readPlist(byte[] data)
+ {
+ return readPlist(new MemoryStream(data), plistType.Auto);
+ }
+
+ public static plistType getPlistType(Stream stream)
+ {
+ byte[] magicHeader = new byte[8];
+ stream.Read(magicHeader, 0, 8);
+
+ if (BitConverter.ToInt64(magicHeader, 0) == 3472403351741427810)
+ {
+ return plistType.Binary;
+ }
+ else
+ {
+ return plistType.Xml;
+ }
+ }
+
+ public static object readPlist(Stream stream, plistType type)
+ {
+ if (type == plistType.Auto)
+ {
+ type = getPlistType(stream);
+ stream.Seek(0, SeekOrigin.Begin);
+ }
+
+ if (type == plistType.Binary)
+ {
+ using (BinaryReader reader = new BinaryReader(stream))
+ {
+ byte[] data = reader.ReadBytes((int)reader.BaseStream.Length);
+ return readBinary(data);
+ }
+ }
+ else
+ {
+ XmlDocument xml = new XmlDocument();
+ xml.XmlResolver = null;
+ xml.Load(stream);
+ return readXml(xml);
+ }
+ }
+
+ public static void writeXml(object value, string path)
+ {
+ using (StreamWriter writer = new StreamWriter(path))
+ {
+ writer.Write(writeXml(value));
+ }
+ }
+
+ public static void writeXml(object value, Stream stream)
+ {
+ using (StreamWriter writer = new StreamWriter(stream))
+ {
+ writer.Write(writeXml(value));
+ }
+ }
+
+ public static string writeXml(object value)
+ {
+ using (MemoryStream ms = new MemoryStream())
+ {
+ XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
+ xmlWriterSettings.Encoding = new System.Text.UTF8Encoding(false);
+ xmlWriterSettings.ConformanceLevel = ConformanceLevel.Document;
+ xmlWriterSettings.Indent = true;
+
+ using (XmlWriter xmlWriter = XmlWriter.Create(ms, xmlWriterSettings))
+ {
+ xmlWriter.WriteStartDocument();
+ //xmlWriter.WriteComment("DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" " + "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\"");
+ xmlWriter.WriteDocType("plist", "-//Apple Computer//DTD PLIST 1.0//EN", "http://www.apple.com/DTDs/PropertyList-1.0.dtd", null);
+ xmlWriter.WriteStartElement("plist");
+ xmlWriter.WriteAttributeString("version", "1.0");
+ compose(value, xmlWriter);
+ xmlWriter.WriteEndElement();
+ xmlWriter.WriteEndDocument();
+ xmlWriter.Flush();
+ xmlWriter.Close();
+ return System.Text.Encoding.UTF8.GetString(ms.ToArray());
+ }
+ }
+ }
+
+ public static void writeBinary(object value, string path)
+ {
+ using (BinaryWriter writer = new BinaryWriter(new FileStream(path, FileMode.Create)))
+ {
+ writer.Write(writeBinary(value));
+ }
+ }
+
+ public static void writeBinary(object value, Stream stream)
+ {
+ using (BinaryWriter writer = new BinaryWriter(stream))
+ {
+ writer.Write(writeBinary(value));
+ }
+ }
+
+ public static byte[] writeBinary(object value)
+ {
+ offsetTable.Clear();
+ objectTable.Clear();
+ refCount = 0;
+ objRefSize = 0;
+ offsetByteSize = 0;
+ offsetTableOffset = 0;
+
+ //Do not count the root node, subtract by 1
+ int totalRefs = countObject(value) - 1;
+
+ refCount = totalRefs;
+
+ objRefSize = RegulateNullBytes(BitConverter.GetBytes(refCount)).Length;
+
+ composeBinary(value);
+
+ writeBinaryString("bplist00", false);
+
+ offsetTableOffset = (long)objectTable.Count;
+
+ offsetTable.Add(objectTable.Count - 8);
+
+ offsetByteSize = RegulateNullBytes(BitConverter.GetBytes(offsetTable[offsetTable.Count - 1])).Length;
+
+ List offsetBytes = new List();
+
+ offsetTable.Reverse();
+
+ for (int i = 0; i < offsetTable.Count; i++)
+ {
+ offsetTable[i] = objectTable.Count - offsetTable[i];
+ byte[] buffer = RegulateNullBytes(BitConverter.GetBytes(offsetTable[i]), offsetByteSize);
+ Array.Reverse(buffer);
+ offsetBytes.AddRange(buffer);
+ }
+
+ objectTable.AddRange(offsetBytes);
+
+ objectTable.AddRange(new byte[6]);
+ objectTable.Add(Convert.ToByte(offsetByteSize));
+ objectTable.Add(Convert.ToByte(objRefSize));
+
+ var a = BitConverter.GetBytes((long)totalRefs + 1);
+ Array.Reverse(a);
+ objectTable.AddRange(a);
+
+ objectTable.AddRange(BitConverter.GetBytes((long)0));
+ a = BitConverter.GetBytes(offsetTableOffset);
+ Array.Reverse(a);
+ objectTable.AddRange(a);
+
+ return objectTable.ToArray();
+ }
+
+ #endregion
+
+ #region Private Functions
+
+ private static object readXml(XmlDocument xml)
+ {
+ XmlNode rootNode = xml.DocumentElement.ChildNodes[0];
+ return parse(rootNode);
+ }
+
+ private static object readBinary(byte[] data)
+ {
+ offsetTable.Clear();
+ List offsetTableBytes = new List();
+ objectTable.Clear();
+ refCount = 0;
+ objRefSize = 0;
+ offsetByteSize = 0;
+ offsetTableOffset = 0;
+
+ List bList = new List(data);
+
+ List trailer = bList.GetRange(bList.Count - 32, 32);
+
+ parseTrailer(trailer);
+
+ objectTable = bList.GetRange(0, (int)offsetTableOffset);
+
+ offsetTableBytes = bList.GetRange((int)offsetTableOffset, bList.Count - (int)offsetTableOffset - 32);
+
+ parseOffsetTable(offsetTableBytes);
+
+ return parseBinary(0);
+ }
+
+ private static Dictionary parseDictionary(XmlNode node)
+ {
+ XmlNodeList children = node.ChildNodes;
+ if (children.Count % 2 != 0)
+ {
+ throw new DataMisalignedException("Dictionary elements must have an even number of child nodes");
+ }
+
+ Dictionary dict = new Dictionary();
+
+ for (int i = 0; i < children.Count; i += 2)
+ {
+ XmlNode keynode = children[i];
+ XmlNode valnode = children[i + 1];
+
+ if (keynode.Name != "key")
+ {
+ throw new ApplicationException("expected a key node");
+ }
+
+ object result = parse(valnode);
+
+ if (result != null)
+ {
+ dict.Add(keynode.InnerText, result);
+ }
+ }
+
+ return dict;
+ }
+
+ private static List