aboutsummaryrefslogtreecommitdiff
path: root/Src/plist
diff options
context:
space:
mode:
Diffstat (limited to 'Src/plist')
-rw-r--r--Src/plist/loader.cpp169
-rw-r--r--Src/plist/loader.h36
-rw-r--r--Src/plist/plist.sln30
-rw-r--r--Src/plist/plist.vcxproj217
-rw-r--r--Src/plist/plist.vcxproj.filters30
-rw-r--r--Src/plist/types.cpp240
-rw-r--r--Src/plist/types.h262
7 files changed, 984 insertions, 0 deletions
diff --git a/Src/plist/loader.cpp b/Src/plist/loader.cpp
new file mode 100644
index 00000000..c3675593
--- /dev/null
+++ b/Src/plist/loader.cpp
@@ -0,0 +1,169 @@
+//------------------------------------------------------------------------
+//
+// iTunes XML Library Reader
+// Copyright (C) 2003-2011 Nullsoft, Inc.
+//
+//------------------------------------------------------------------------
+
+#include "loader.h"
+#include <windows.h>
+#include <commdlg.h>
+#include <bfc/string/stringdict.h>
+
+
+#define ATTRIB_TRUE 256
+#define ATTRIB_FALSE 257
+
+//------------------------------------------------------------------------
+// xml tags
+//------------------------------------------------------------------------
+BEGIN_STRINGDICTIONARY(_itunestypes)
+SDI(L"key", PLISTDATA_KEY);
+SDI(L"dict", PLISTDATA_DICT);
+SDI(L"integer", PLISTDATA_INTEGER);
+SDI(L"string", PLISTDATA_STRING);
+SDI(L"date", PLISTDATA_DATE);
+SDI(L"array", PLISTDATA_ARRAY);
+SDI(L"data", PLISTDATA_RAW);
+SDI(L"true", ATTRIB_TRUE);
+SDI(L"false", ATTRIB_FALSE);
+END_STRINGDICTIONARY(_itunestypes, itunestypes)
+
+//------------------------------------------------------------------------
+plistLoader::plistLoader() : plistKey(L"root")
+{
+ m_context.push(this);
+}
+
+//------------------------------------------------------------------------
+plistLoader::~plistLoader()
+{
+}
+
+
+//------------------------------------------------------------------------
+// element opens (or singleton), push new key/dictionary/array, handle value singletons (true/false), defer job to closing tag for other data types
+//------------------------------------------------------------------------
+void plistLoader::xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params) {
+ m_cdata = 0;
+ int a = itunestypes.getId(xmltag);
+ switch (a) {
+ case PLISTDATA_KEY:
+ m_cdata = L"";
+ m_context.push(new plistKey());
+ m_dict.top()->addKey((plistKey *)m_context.top());
+ break;
+ case PLISTDATA_DICT:
+ {
+ m_dict.push(new plistDict());
+ plistData *contextTop = m_context.top();
+ contextTop->setData(static_cast<plistDict *>(m_dict.top()));
+ }
+ break;
+ case PLISTDATA_ARRAY:
+ {
+ plistArray *new_array = new plistArray;
+ plistData *contextTop = m_context.top();
+ contextTop->setData(new_array);
+ m_context.push(new_array);
+ m_dict.push(new_array);
+ break;
+ }
+ case PLISTDATA_STRING:
+ break;
+ case PLISTDATA_INTEGER:
+ break;
+ case PLISTDATA_DATE:
+ break;
+ case PLISTDATA_RAW:
+ break;
+ case PLISTDATA_REAL:
+ break;
+ case ATTRIB_TRUE: {
+ m_context.top()->setData(new plistBoolean(true));
+ if (m_context.top()->getType() == PLISTDATA_KEY) m_context.pop();
+ break;
+ }
+ case ATTRIB_FALSE: {
+ m_context.top()->setData(new plistBoolean(false));
+ if (m_context.top()->getType() == PLISTDATA_KEY) m_context.pop();
+ break;
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+// element closes, set data for last key/array, pop key/array/dictionary from stack
+//------------------------------------------------------------------------
+void plistLoader::xmlReaderOnEndElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag) {
+ int a = itunestypes.getId(xmltag);
+ switch (a) {
+ case PLISTDATA_KEY:
+ ASSERT(m_context.top()->getType() == PLISTDATA_KEY);
+ ((plistKey*)m_context.top())->setName(m_cdata);
+ break;
+ case PLISTDATA_DICT:
+ if (m_context.top()->getType() == PLISTDATA_KEY) m_context.pop();
+ m_dict.pop();
+ break;
+ case PLISTDATA_ARRAY: {
+ /*if (m_context.top()->getType() == PLISTDATA_KEY)*/ m_context.pop();
+ //ASSERT(m_context.top()->getType() == PLISTDATA_ARRAY);
+ //plistArray *a = (plistArray *)m_context.top();
+ //m_context.pop();
+ //m_context.top()->setData(a);
+ m_dict.pop();
+ break;
+ }
+ case PLISTDATA_STRING: {
+ plistString *s = new plistString(m_cdata);
+ m_context.top()->setData(s);
+ if (m_context.top()->getType() == PLISTDATA_KEY) m_context.pop();
+ break;
+ }
+ case PLISTDATA_INTEGER: {
+ plistInteger *i = new plistInteger();
+ i->setString(m_cdata);
+ m_context.top()->setData(i);
+ if (m_context.top()->getType() == PLISTDATA_KEY) m_context.pop();
+ break;
+ }
+ case PLISTDATA_REAL: {
+ plistReal *r = new plistReal();
+ r->setString(m_cdata);
+ m_context.top()->setData(r);
+ if (m_context.top()->getType() == PLISTDATA_KEY) m_context.pop();
+ break;
+ }
+ case PLISTDATA_DATE: {
+ plistDate *d = new plistDate();
+ d->setString(m_cdata);
+ m_context.top()->setData(d);
+ if (m_context.top()->getType() == PLISTDATA_KEY) m_context.pop();
+ break;
+ }
+ case PLISTDATA_RAW: {
+ plistRaw *r = new plistRaw();
+ r->setString(m_cdata);
+ m_context.top()->setData(r);
+ if (m_context.top()->getType() == PLISTDATA_KEY) m_context.pop();
+ break;
+ }
+ }
+ m_cdata = 0;
+}
+
+//------------------------------------------------------------------------
+// record c_data
+//------------------------------------------------------------------------
+void plistLoader::xmlReaderOnCharacterDataCallback(const wchar_t *xmlpath, const wchar_t *xmltag, const wchar_t *str) {
+ m_cdata += str;
+}
+
+#define CBCLASS plistLoader
+START_DISPATCH;
+VCB(ONSTARTELEMENT, xmlReaderOnStartElementCallback)
+VCB(ONCHARDATA, xmlReaderOnCharacterDataCallback)
+VCB(ONENDELEMENT, xmlReaderOnEndElementCallback)
+END_DISPATCH;
+#undef CBCLASS \ No newline at end of file
diff --git a/Src/plist/loader.h b/Src/plist/loader.h
new file mode 100644
index 00000000..195d11b3
--- /dev/null
+++ b/Src/plist/loader.h
@@ -0,0 +1,36 @@
+//------------------------------------------------------------------------
+//
+// iTunes XML Library Reader
+// Copyright (C) 2003-2012 Nullsoft, Inc.
+//
+//------------------------------------------------------------------------
+
+#ifndef NULLSOFT_PLIST_LOADER_H
+#define NULLSOFT_PLIST_LOADER_H
+
+#include "types.h"
+#include "../xml/ifc_xmlreadercallback.h"
+#include <bfc/string/stringw.h>
+#include <bfc/stack.h>
+
+//------------------------------------------------------------------------
+class plistLoader : public ifc_xmlreadercallback, public plistKey {
+public:
+ plistLoader();
+ virtual ~plistLoader();
+
+ virtual void xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params);
+ virtual void xmlReaderOnEndElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag);
+ virtual void xmlReaderOnCharacterDataCallback(const wchar_t *xmlpath, const wchar_t *xmltag, const wchar_t *str);
+private:
+ Stack<plistData *> m_context; // either a key or an array, this is where data gets inserted next
+ Stack<plistKeyholder *> m_dict;
+ StringW m_cdata;
+
+protected:
+ RECVS_DISPATCH;
+};
+
+#endif
+
+//------------------------------------------------------------------------ \ No newline at end of file
diff --git a/Src/plist/plist.sln b/Src/plist/plist.sln
new file mode 100644
index 00000000..e9c7ec5f
--- /dev/null
+++ b/Src/plist/plist.sln
@@ -0,0 +1,30 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.29424.173
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "plist", "plist.vcxproj", "{5ED1729B-EA41-4163-9506-741A8B76F625}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Debug|x64 = Debug|x64
+ Release|Win32 = Release|Win32
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {5ED1729B-EA41-4163-9506-741A8B76F625}.Debug|Win32.ActiveCfg = Debug|Win32
+ {5ED1729B-EA41-4163-9506-741A8B76F625}.Debug|Win32.Build.0 = Debug|Win32
+ {5ED1729B-EA41-4163-9506-741A8B76F625}.Debug|x64.ActiveCfg = Debug|x64
+ {5ED1729B-EA41-4163-9506-741A8B76F625}.Debug|x64.Build.0 = Debug|x64
+ {5ED1729B-EA41-4163-9506-741A8B76F625}.Release|Win32.ActiveCfg = Release|Win32
+ {5ED1729B-EA41-4163-9506-741A8B76F625}.Release|Win32.Build.0 = Release|Win32
+ {5ED1729B-EA41-4163-9506-741A8B76F625}.Release|x64.ActiveCfg = Release|x64
+ {5ED1729B-EA41-4163-9506-741A8B76F625}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {8A265E7E-ACA5-46A3-B174-2A25F526A06D}
+ EndGlobalSection
+EndGlobal
diff --git a/Src/plist/plist.vcxproj b/Src/plist/plist.vcxproj
new file mode 100644
index 00000000..44a2c278
--- /dev/null
+++ b/Src/plist/plist.vcxproj
@@ -0,0 +1,217 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{5ED1729B-EA41-4163-9506-741A8B76F625}</ProjectGuid>
+ <RootNamespace>plist</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <LinkIncremental>true</LinkIncremental>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg">
+ <VcpkgEnableManifest>false</VcpkgEnableManifest>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <VcpkgInstalledDir>
+ </VcpkgInstalledDir>
+ <VcpkgUseStatic>false</VcpkgUseStatic>
+ <VcpkgConfiguration>Debug</VcpkgConfiguration>
+ <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <VcpkgInstalledDir>
+ </VcpkgInstalledDir>
+ <VcpkgUseStatic>false</VcpkgUseStatic>
+ <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <VcpkgInstalledDir>
+ </VcpkgInstalledDir>
+ <VcpkgUseStatic>false</VcpkgUseStatic>
+ <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
+ <VcpkgConfiguration>Debug</VcpkgConfiguration>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <VcpkgInstalledDir>
+ </VcpkgInstalledDir>
+ <VcpkgUseStatic>false</VcpkgUseStatic>
+ <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>../Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Lib>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>../Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN64;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Lib>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MinSpace</Optimization>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <AdditionalIncludeDirectories>../Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Lib>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <Optimization>MinSpace</Optimization>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <AdditionalIncludeDirectories>../Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN64;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Lib>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="loader.cpp" />
+ <ClCompile Include="types.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="loader.h" />
+ <ClInclude Include="types.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Wasabi\Wasabi.vcxproj">
+ <Project>{3e0bfa8a-b86a-42e9-a33f-ec294f823f7f}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/Src/plist/plist.vcxproj.filters b/Src/plist/plist.vcxproj.filters
new file mode 100644
index 00000000..934be6b2
--- /dev/null
+++ b/Src/plist/plist.vcxproj.filters
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <ClCompile Include="loader.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="types.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="loader.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="types.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{cb593512-db76-4543-81a4-64da0d31f4ef}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Ressource Files">
+ <UniqueIdentifier>{3d920b5c-c6fc-4524-b042-2848c3f5193c}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{b3a77050-99be-40d0-bb37-4b05194da732}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/Src/plist/types.cpp b/Src/plist/types.cpp
new file mode 100644
index 00000000..348359c2
--- /dev/null
+++ b/Src/plist/types.cpp
@@ -0,0 +1,240 @@
+//------------------------------------------------------------------------
+//
+// iTunes XML Library Data Structures
+// Copyright (C) 2003-2011 Nullsoft, Inc.
+//
+//------------------------------------------------------------------------
+
+#include "types.h"
+#include <bfc/util/base64.h>
+#include <stdint.h>
+
+//------------------------------------------------------------------------
+void plistData::setString(const wchar_t *str) {
+ plistString string(str);
+ setData(&string);
+}
+
+//------------------------------------------------------------------------
+// raw data
+//------------------------------------------------------------------------
+void plistRaw::setData(plistData *d) {
+ while (d && d->getType() == PLISTDATA_KEY) d = ((plistKey*)d)->getData();
+ if (!d) return;
+ switch (d->getType()) {
+ case PLISTDATA_RAW: {
+ int size;
+ void *m = ((plistRaw*)d)->getMem(&size);
+ setMem(m, size);
+ break;
+ }
+ case PLISTDATA_INTEGER: {
+ int v = (int)((plistInteger *)d)->getValue();
+ setMem(&v, sizeof(v));
+ break;
+ }
+ case PLISTDATA_REAL: {
+ double v = ((plistReal *)d)->getValue();
+ setMem(&v, sizeof(v));
+ break;
+ }
+ case PLISTDATA_DATE: {
+ time_t v = ((plistDate *)d)->getDate();
+ setMem(&v, sizeof(v));
+ break;
+ }
+ case PLISTDATA_STRING: {
+ const wchar_t *s = ((plistString *)d)->getString();
+ MemBlock<wchar_t> t64;
+ size_t len = wcslen(s);
+ t64.setSize((int)len);
+ t64.setMemory(s, (int)len);
+ MemBlock<char> data;
+ Base64::decode(t64, data);
+ setMem(data, data.getSize());
+ break;
+ }
+ case PLISTDATA_BOOLEAN:
+ {
+ int8_t b = !!((plistBoolean *)d)->getValue();
+ setMem(&b, 1);
+ }
+ break;
+ case PLISTDATA_ARRAY: {
+ //OutputDebugString(L"Unsupported call to setData() with an array as a parameter\n");
+ break;
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+const wchar_t *plistRaw::getString() const {
+ MemBlock<wchar_t> t64;
+ Base64::encode(mem, t64, 72);
+ encoded.ncpy(t64.getMemory(), t64.getSize());
+ return encoded;
+}
+
+//------------------------------------------------------------------------
+// integer
+//------------------------------------------------------------------------
+void plistInteger::setData(plistData *d) {
+ while (d && d->getType() == PLISTDATA_KEY) d = ((plistKey*)d)->getData();
+ if (!d) return;
+ switch (d->getType()) {
+ case PLISTDATA_RAW: {
+ int size;
+ void *m = ((plistRaw*)d)->getMem(&size);
+ switch(size)
+ {
+ case 1:
+ setValue(*((int8_t *)m));
+ break;
+ case 2:
+ setValue(*((int16_t *)m));
+ break;
+ case 4:
+ setValue(*((int32_t *)m));
+ break;
+ case 8:
+ setValue(*((int64_t *)m));
+ break;
+ }
+ break;
+ }
+ case PLISTDATA_BOOLEAN:
+ {
+ int64_t b = !!((plistBoolean *)d)->getValue();
+ setValue(b);
+ }
+ break;
+ case PLISTDATA_INTEGER: {
+ setValue(((plistInteger *)d)->getValue());
+ break;
+ }
+ case PLISTDATA_REAL: {
+ setValue((int64_t)((plistReal *)d)->getValue());
+ break;
+ }
+ case PLISTDATA_DATE: {
+ setValue(((plistDate *)d)->getDate());
+ break;
+ }
+ case PLISTDATA_STRING: {
+ const wchar_t *s = ((plistString *)d)->getString();
+#ifdef _WIN32
+ setValue(_wtoi64(s));
+#else
+ setValue(wcstoll(s, 0, 10));
+#endif
+ break;
+ }
+ case PLISTDATA_ARRAY: {
+ //OutputDebugString(L"Unsupported conversion from array to int\n");
+ break;
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+// string
+//------------------------------------------------------------------------
+void plistString::setData(plistData *d) {
+ while (d && d->getType() == PLISTDATA_KEY) d = ((plistKey*)d)->getData();
+ if (!d) return;
+ setString(d->getString());
+}
+
+//------------------------------------------------------------------------
+// date
+//------------------------------------------------------------------------
+void plistDate::setData(plistData *d) {
+ while (d && d->getType() == PLISTDATA_KEY) d = ((plistKey*)d)->getData();
+ if (!d) return;
+ switch (d->getType()) {
+ case PLISTDATA_RAW: {
+ int size;
+ void *m = ((plistRaw*)d)->getMem(&size);
+ if (size >= 4)
+ setDate(*(time_t*)m); // assume we have a time_t*
+ break;
+ }
+ case PLISTDATA_INTEGER: {
+ setDate((time_t)((plistInteger *)d)->getValue());
+ break;
+ }
+ case PLISTDATA_DATE: {
+ setDate(((plistDate *)d)->getDate());
+ break;
+ }
+ case PLISTDATA_REAL: {
+ setDate((int)((plistReal *)d)->getValue());
+ break;
+ }
+ case PLISTDATA_STRING: {
+ setString(d->getString());
+ break;
+ }
+ case PLISTDATA_ARRAY: {
+ OutputDebugString(L"Unsupported conversion from array to date\n");
+ break;
+ }
+ }
+}
+void plistDate::setString(const wchar_t *_str)
+{
+ if (wcslen(_str) == 20) // naive (but safe) parser
+ {
+ tm import_time= {0,};
+ import_time.tm_year = _wtoi(&_str[0])-1900;
+ import_time.tm_mon = _wtoi(&_str[5])-1;
+ import_time.tm_mday = _wtoi(&_str[8]);
+ import_time.tm_hour = _wtoi(&_str[11]);
+ import_time.tm_min = _wtoi(&_str[14]);
+ import_time.tm_sec = _wtoi(&_str[17]);
+
+ when=_mkgmtime(&import_time);
+ }
+}
+//------------------------------------------------------------------------
+// real
+//------------------------------------------------------------------------
+void plistReal::setData(plistData *d) {
+ while (d && d->getType() == PLISTDATA_KEY) d = ((plistKey*)d)->getData();
+ if (!d) return;
+ switch (d->getType()) {
+ case PLISTDATA_RAW: {
+ int size;
+ void *m = ((plistRaw*)d)->getMem(&size);
+ if (size >= 8)
+ setValue(*((double *)m));
+ break;
+ }
+ case PLISTDATA_INTEGER: {
+ setValue((double)((plistInteger *)d)->getValue());
+ break;
+ }
+ case PLISTDATA_REAL: {
+ setValue(((plistReal *)d)->getValue());
+ break;
+ }
+ case PLISTDATA_DATE: {
+ setValue((double)(((plistDate *)d)->getDate()));
+ break;
+ }
+ case PLISTDATA_STRING: {
+ const wchar_t *s = ((plistString *)d)->getString();
+ setValue(WTOF(s));
+ break;
+ }
+ case PLISTDATA_ARRAY: {
+ //OutputDebugString(L"Unsupported conversion from array to real\n");
+ break;
+ }
+ }
+}
+
+void plistBoolean::setData(plistData *d)
+{
+ // TODO: implement. but how necessary is this really?
+} \ No newline at end of file
diff --git a/Src/plist/types.h b/Src/plist/types.h
new file mode 100644
index 00000000..bc96d9ed
--- /dev/null
+++ b/Src/plist/types.h
@@ -0,0 +1,262 @@
+//------------------------------------------------------------------------
+//
+// Apple plist XML Library Data Structures
+// Copyright (C) 2003 Nullsoft, Inc.
+//
+//------------------------------------------------------------------------
+
+#ifndef NULLSOFT_PLIST_TYPES_H
+#define NULLSOFT_PLIST_TYPES_H
+
+#include <bfc/memblock.h>
+#include <time.h>
+#include <bfc/string/bfcstring.h>
+#include <bfc/string/stringw.h>
+#include <bfc/ptrlist.h>
+
+//------------------------------------------------------------------------
+// Base type class
+//------------------------------------------------------------------------
+
+enum {
+ PLISTDATA_KEY = 0,
+ PLISTDATA_DICT,
+ PLISTDATA_INTEGER,
+ PLISTDATA_STRING,
+ PLISTDATA_DATE,
+ PLISTDATA_ARRAY,
+ PLISTDATA_REAL,
+ PLISTDATA_RAW,
+ PLISTDATA_BOOLEAN,
+};
+
+
+class plistData
+{
+public:
+ plistData(int _type) : type(_type) {}
+ plistData() : type(-1) {}
+ virtual ~plistData() {}
+ virtual int getType() const { return type; }
+ virtual void setType(int _type) { type = _type; }
+ virtual void setData(plistData *d)=0;
+ virtual const wchar_t *getString() const =0;
+ virtual const wchar_t *getTypeString() const =0;
+ virtual void setString(const wchar_t *str);
+private:
+ int type;
+};
+
+//------------------------------------------------------------------------
+// A key is a string attached to another piece of data
+//------------------------------------------------------------------------
+class plistKey : public plistData
+{
+public:
+ plistKey() : name(L""), data(NULL), plistData(PLISTDATA_KEY) {}
+ plistKey(const wchar_t *_name, plistData *_data=NULL) : name(_name), data(_data), plistData(PLISTDATA_KEY) {}
+ virtual ~plistKey() { delete data; }
+ const wchar_t *getName() const { return name; }
+ void setName(const wchar_t *_name) { name = _name; }
+ plistData *getData() const { return data; }
+ virtual void setData(plistData *d) { data = d; }
+ virtual const wchar_t *getString() const { return getName(); }
+ virtual const wchar_t *getTypeString() const { return L"key"; }
+private:
+ StringW name;
+ plistData *data;
+};
+
+
+class plistKeyholder
+{
+public:
+ virtual int addKey(plistKey *key) = 0;
+};
+//------------------------------------------------------------------------
+// A dictionary contains a list of keys
+//------------------------------------------------------------------------
+class plistDict : public plistData, public plistKeyholder
+{
+public:
+ plistDict() : plistData(PLISTDATA_DICT) {}
+ virtual ~plistDict() { keys.deleteAll(); }
+ int getNumKeys() const { return keys.getNumItems(); }
+ plistKey *enumKey(int n) const { return keys.enumItem(n); }
+ int addKey(plistKey *key) { if (!keys.haveItem(key)) keys.addItem(key); return keys.getNumItems(); }
+ virtual void setData(plistData *d) { if (d->getType() != PLISTDATA_KEY) return; keys.addItem((plistKey*)d); }
+ int delKey(const wchar_t *name, int dodelete=1) {
+ foreach(keys)
+ if (WCSCASEEQLSAFE(name, keys.getfor()->getName())) {
+ if (dodelete) delete keys.getfor();
+ keys.removeByPos(foreach_index);
+ break;
+ }
+ endfor;
+ return keys.getNumItems();
+ }
+ plistKey *getKey(const wchar_t *name) const {
+ foreach(keys)
+ if (WCSCASEEQLSAFE(name, keys.getfor()->getName())) {
+ return keys.getfor();
+ }
+ endfor;
+ return NULL;
+ }
+ virtual const wchar_t *getString() const { return L""; }
+ virtual const wchar_t *getTypeString() const { return L"dict"; }
+private:
+ PtrList<plistKey> keys;
+};
+
+//------------------------------------------------------------------------
+// An array contains a number of data entries
+//------------------------------------------------------------------------
+class plistArray : public plistData, public plistKeyholder
+{
+public:
+ plistArray() : plistData(PLISTDATA_ARRAY) {}
+ virtual ~plistArray() { items.deleteAll(); }
+ int getNumItems() const { return items.getNumItems(); }
+ plistData *enumItem(int n) const { return items.enumItem(n); }
+ virtual void setData(plistData *d) { items.addItem(d); }
+ int addKey(plistKey *key) { items.addItem(key); return items.getNumItems(); }
+ virtual const wchar_t *getString() const { return L"(array)"; }
+ virtual const wchar_t *getTypeString() const { return L"array"; }
+private:
+ PtrList<plistData> items;
+};
+
+//------------------------------------------------------------------------
+// Raw data
+//------------------------------------------------------------------------
+class plistRaw : public plistData {
+public:
+ plistRaw() : plistData(PLISTDATA_RAW) {}
+ virtual ~plistRaw() {}
+ virtual void *getMem(int *size) const { if (size) *size = mem.getSize(); return mem.getMemory(); }
+ virtual void setMem(void *m, int size) { mem.setSize(size); mem.setMemory((char *)m, size, 0); }
+ virtual void setData(plistData *d);
+ virtual const wchar_t *getString() const ;
+ virtual const wchar_t *getTypeString() const { return L"data"; }
+private:
+ mutable MemBlock<char> mem;
+ mutable StringW encoded;
+};
+
+//------------------------------------------------------------------------
+// Int
+//------------------------------------------------------------------------
+class plistInteger : public plistData {
+public:
+ plistInteger(int64_t _value) : value(_value), plistData(PLISTDATA_INTEGER) {}
+ plistInteger() : value(0), plistData(PLISTDATA_INTEGER) {}
+ virtual ~plistInteger() {}
+
+ virtual int64_t getValue() const { return value; }
+ virtual void setValue(int64_t _value) { value = _value; }
+
+ virtual void setData(plistData *d);
+
+ virtual const wchar_t *getString() const
+ {
+ static wchar_t s[64];
+#ifdef _MSC_VER
+ return _i64tow(getValue(), s, 10);
+#elif defined(__GCC__)
+ sprintf(s, L"%lld", getValue());
+ return s;
+#else
+#error define me!
+#endif
+ }
+ virtual const wchar_t *getTypeString() const { return L"integer"; }
+private:
+ int64_t value;
+};
+
+class plistBoolean : public plistData
+{
+public:
+ plistBoolean(bool _value) : value(_value), plistData(PLISTDATA_BOOLEAN) {}
+ plistBoolean() : value(0), plistData(PLISTDATA_BOOLEAN) {}
+ virtual ~plistBoolean() {}
+
+ virtual bool getValue() const { return value; }
+ virtual void setValue(bool _value) { value = _value; }
+ virtual void setData(plistData *d);
+
+ virtual const wchar_t *getString() const
+ {
+ if (value)
+ return L"true";
+ else
+ return L"false";
+ }
+ virtual const wchar_t *getTypeString() const { return L"boolean"; }
+private:
+ bool value;
+};
+
+//------------------------------------------------------------------------
+// String
+//------------------------------------------------------------------------
+class plistString : public plistData {
+public:
+ plistString(const wchar_t *_str) : str(_str), plistData(PLISTDATA_STRING) {}
+ plistString() : str(L""), plistData(PLISTDATA_STRING) {}
+ virtual ~plistString() {}
+ virtual const wchar_t *getString() const { return str; }
+ virtual void setString(const wchar_t *_str) { str = _str; }
+ virtual void setData(plistData *d);
+ virtual const wchar_t *getTypeString() const { return L"string"; }
+private:
+ StringW str;
+};
+
+//------------------------------------------------------------------------
+// Real
+//------------------------------------------------------------------------
+class plistReal : public plistData {
+public:
+ plistReal(int _value) : value(_value), plistData(PLISTDATA_REAL) {}
+ plistReal() : value(0), plistData(PLISTDATA_REAL) {}
+ virtual ~plistReal() {}
+ virtual double getValue() const { return value; }
+ virtual void setValue(double _value) { value = _value; }
+ virtual void setData(plistData *d);
+ virtual const wchar_t *getString() const { static StringW s; s.printf(L"%f", getValue()); return s; }
+ virtual const wchar_t *getTypeString() const { return L"real"; }
+private:
+ double value;
+};
+
+//------------------------------------------------------------------------
+// Date/Time
+//------------------------------------------------------------------------
+class plistDate : public plistData {
+public:
+ plistDate(time_t _when) : when(_when), plistData(PLISTDATA_DATE) {}
+ plistDate() : when(0), plistData(PLISTDATA_DATE) {}
+ virtual ~plistDate() {}
+ virtual time_t getDate() const { return when; }
+ virtual void setDate(time_t _when) { when = _when; }
+ virtual void setData(plistData *d);
+ virtual const wchar_t *getString() const {
+ struct tm *t = gmtime(&when);
+ if (t) {
+ static wchar_t time_format[256] = {0};
+ wcsftime(time_format, 256, L"%Y-%m-%dT%H:%M:%SZ", t);
+ return time_format;
+ }
+ return L"";
+ }
+ virtual void setString(const wchar_t *_str);
+ virtual const wchar_t *getTypeString() const { return L"date"; }
+private:
+ time_t when;
+};
+
+#endif
+
+//------------------------------------------------------------------------ \ No newline at end of file