Initial community commit

This commit is contained in:
Jef
2024-09-24 14:54:57 +02:00
parent 537bcbc862
commit 20d28e80a5
16810 changed files with 4640254 additions and 2 deletions

169
Src/plist/loader.cpp Normal file
View File

@ -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

36
Src/plist/loader.h Normal file
View File

@ -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
//------------------------------------------------------------------------

30
Src/plist/plist.sln Normal file
View File

@ -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

217
Src/plist/plist.vcxproj Normal file
View File

@ -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>

View File

@ -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>

240
Src/plist/types.cpp Normal file
View File

@ -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?
}

262
Src/plist/types.h Normal file
View File

@ -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
//------------------------------------------------------------------------