Initial community commit

This commit is contained in:
Jef 2024-09-24 14:54:57 +02:00
parent 537bcbc862
commit fc06254474
16440 changed files with 4239995 additions and 2 deletions

View file

@ -0,0 +1 @@
1.2

View file

@ -0,0 +1,350 @@
#include "nsid3v1.h"
#include "tag.h"
#include "foundation/error.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <new>
int NSID3v1_Header_Valid(const void *data, size_t len)
{
// return NErr_True or NErr_False depending on whether or not you detect that it's valid ID3v1
if (memcmp(data, "TAG", 3) == 0)
{
return NErr_True;
}
return NErr_False;
}
int NSID3v1_Tag_Create(const void *data, size_t len, nsid3v1_tag_t *out_tag)
{
ID3v1::Tag *tag = new (std::nothrow) ID3v1::Tag();
if (!tag)
return NErr_OutOfMemory;
int ret = tag->Parse(data, len);
if (ret != NErr_Success)
return ret;
*out_tag = (nsid3v1_tag_t)tag;
return NErr_Success;
}
int NSID3v1_Tag_New(nsid3v1_tag_t *out_tag)
{
ID3v1::Tag *tag = new (std::nothrow) ID3v1::Tag();
if (!tag)
return NErr_OutOfMemory;
tag->New();
*out_tag = (nsid3v1_tag_t)tag;
return NErr_Success;
}
int NSID3v1_Tag_Serialize(const nsid3v1_tag_t t, void *data, size_t len)
{
ID3v1::Tag *tag = (ID3v1::Tag *)t;
if (!tag)
return NErr_BadParameter;
return tag->Serialize(data, len);
}
int NSID3v1_Tag_Destroy(nsid3v1_tag_t t)
{
ID3v1::Tag *tag = (ID3v1::Tag *)t;
if (!tag)
return NErr_BadParameter;
delete tag;
return NErr_Success;
}
// Field getters
int NSID3v1_Field_Text_Get(const nsid3v1_tag_t t, const int field, nx_string_t *out_value)
{
const ID3v1::Tag *tag = (const ID3v1::Tag *)t;
char track_num[4] = { 0, 0, 0 };
if (tag)
{
switch (field)
{
case NSID3V1_TITLE:
return NSID3v1_Get_Title(t, out_value);
case NSID3V1_ARTIST:
return NSID3v1_Get_Artist(t, out_value);
case NSID3V1_ALBUM:
return NSID3v1_Get_Album(t, out_value);
case NSID3V1_YEAR:
return NSID3v1_Get_Year(t, out_value);
case NSID3V1_COMMENT:
return NSID3v1_Get_Comment(t, out_value);
case NSID3V1_TRACK:
return NSID3v1_Get_Track(t, out_value);
//case NSID3V1_GENRE:
//return NSID3v1_Get_Genre(t, out_value);
default:
return NErr_Unknown;
}
}
else
return NErr_Empty;
}
int NSID3v1_Get_Title(nsid3v1_tag_t t, nx_string_t *value)
{
const ID3v1::Tag *tag = (const ID3v1::Tag *)t;
if (tag)
{
size_t value_length = tag->GetTitleLength();
if (value_length > 0)
return NXStringCreateWithBytes(value, tag->GetTitle(), value_length, nx_charset_latin1);
else
return NErr_Empty;
return NErr_Success;
}
return NErr_Empty;
}
int NSID3v1_Get_Artist(nsid3v1_tag_t t, nx_string_t *value)
{
const ID3v1::Tag *tag = (const ID3v1::Tag *)t;
if (tag)
{
size_t value_length = tag->GetArtistLength();
if (value_length > 0)
return NXStringCreateWithBytes(value, tag->GetArtist(), value_length, nx_charset_latin1);
else
return NErr_Empty;
return NErr_Success;
}
return NErr_Empty;
}
int NSID3v1_Get_Album(nsid3v1_tag_t t, nx_string_t *value)
{
const ID3v1::Tag *tag = (const ID3v1::Tag *)t;
if (tag)
{
size_t value_length = tag->GetAlbumLength();
if (value_length > 0)
return NXStringCreateWithBytes(value, tag->GetAlbum(), value_length, nx_charset_latin1);
else
return NErr_Empty;
return NErr_Success;
}
return NErr_Empty;
}
int NSID3v1_Get_Year(nsid3v1_tag_t t, nx_string_t *value)
{
const ID3v1::Tag *tag = (const ID3v1::Tag *)t;
if (tag)
{
size_t value_length = tag->GetYearLength();
if (value_length > 0)
return NXStringCreateWithBytes(value, tag->GetYear(), value_length, nx_charset_latin1);
else
return NErr_Empty;
}
return NErr_Empty;
}
int NSID3v1_Get_Comment(nsid3v1_tag_t t, nx_string_t *value)
{
const ID3v1::Tag *tag = (const ID3v1::Tag *)t;
if (tag)
{
size_t value_length = tag->GetCommentLength();
if (value_length > 0)
return NXStringCreateWithBytes(value, tag->GetComment(), value_length, nx_charset_latin1);
else
return NErr_Empty;
}
return NErr_Empty;
}
int NSID3v1_Get_Track(nsid3v1_tag_t t, nx_string_t *value)
{
const ID3v1::Tag *tag = (const ID3v1::Tag *)t;
if (tag)
{
unsigned char track = tag->GetTrack();
if (track > 0)
return NXStringCreateWithUInt64(value, track);
else
return NErr_Empty;
return NErr_Success;
}
return NErr_Empty;
}
int NSID3v1_Int_Get_Year(nsid3v1_tag_t t, unsigned int *value)
{
const ID3v1::Tag *tag = (const ID3v1::Tag *)t;
if (tag)
{
char year[5];
memcpy(year, tag->GetYear(), 4);
year[4]=0;
*value = strtoul(year, 0, 10);
return NErr_Success;
}
return NErr_Empty;
}
int NSID3v1_Int_Get_Track(nsid3v1_tag_t t, uint8_t *value)
{
const ID3v1::Tag *tag = (const ID3v1::Tag *)t;
if (tag)
{
*value = tag->GetTrack();
return NErr_Success;
}
return NErr_Empty;
}
int NSID3v1_Int_Get_Genre(nsid3v1_tag_t t, uint8_t *value)
{
const ID3v1::Tag *tag = (const ID3v1::Tag *)t;
if (tag)
{
*value = tag->GetGenre();
return NErr_Success;
}
return NErr_Empty;
}
/* ================= setters ================= */
typedef void (ID3v1::Tag::*Setter)(const char *, size_t length);
template <size_t limit>
static int SetFromString(ID3v1::Tag *tag, Setter setter, nx_string_t value)
{
if (!value)
{
(tag->*setter)(0, 0);
return NErr_Success;
}
char temp[limit];
size_t bytes_copied;
int ret = NXStringGetBytes(&bytes_copied, value, temp, limit, nx_charset_latin1, 0);
if (ret != NErr_Success)
return ret;
(tag->*setter)(temp, bytes_copied);
return NErr_Success;
}
int NSID3v1_Set_Title(nsid3v1_tag_t t, nx_string_t value)
{
ID3v1::Tag *tag = (ID3v1::Tag *)t;
if (!t)
return NErr_BadParameter;
return SetFromString<30>(tag, &ID3v1::Tag::SetTitle, value);
}
int NSID3v1_Set_Artist(nsid3v1_tag_t t, nx_string_t value)
{
ID3v1::Tag *tag = (ID3v1::Tag *)t;
if (!t)
return NErr_BadParameter;
return SetFromString<30>(tag, &ID3v1::Tag::SetArtist, value);
}
int NSID3v1_Set_Album(nsid3v1_tag_t t, nx_string_t value)
{
ID3v1::Tag *tag = (ID3v1::Tag *)t;
if (!t)
return NErr_BadParameter;
return SetFromString<30>(tag, &ID3v1::Tag::SetAlbum, value);
}
int NSID3v1_Set_Year(nsid3v1_tag_t t, nx_string_t value)
{
ID3v1::Tag *tag = (ID3v1::Tag *)t;
if (!t)
return NErr_BadParameter;
return SetFromString<4>(tag, &ID3v1::Tag::SetYear, value);
}
int NSID3v1_Set_Comment(nsid3v1_tag_t t, nx_string_t value)
{
ID3v1::Tag *tag = (ID3v1::Tag *)t;
if (!t)
return NErr_BadParameter;
return SetFromString<28>(tag, &ID3v1::Tag::SetComment, value);
}
int NSID3v1_Set_Track(nsid3v1_tag_t t, nx_string_t value)
{
ID3v1::Tag *tag = (ID3v1::Tag *)t;
if (!t)
return NErr_BadParameter;
if (!value)
{
tag->SetTrack(0);
return NErr_Success;
}
int temp=0;
int ret = NXStringGetIntegerValue(value, &temp);
if (ret != NErr_Success)
return ret;
if (temp < 0 || temp > 255)
return NErr_ParameterOutOfRange;
tag->SetTrack((uint8_t)temp);
return NErr_Success;
}
int NSID3v1_Int_Set_Year(nsid3v1_tag_t t, unsigned int value)
{
ID3v1::Tag *tag = (ID3v1::Tag *)t;
if (!t)
return NErr_BadParameter;
if (value > 9999)
return NErr_ParameterOutOfRange;
char temp[5];
sprintf(temp, "%u", value);
tag->SetYear(temp, 4);
return NErr_Success;
}
int NSID3v1_Int_Set_Track(nsid3v1_tag_t t, uint8_t value)
{
ID3v1::Tag *tag = (ID3v1::Tag *)t;
if (!t)
return NErr_BadParameter;
tag->SetTrack(value);
return NErr_Success;
}
int NSID3v1_Int_Set_Genre(nsid3v1_tag_t t, uint8_t value)
{
ID3v1::Tag *tag = (ID3v1::Tag *)t;
if (!t)
return NErr_BadParameter;
tag->SetGenre(value);
return NErr_Success;
}

View file

@ -0,0 +1,67 @@
#pragma once
#include "nx/nxstring.h"
#ifdef __cplusplus
extern "C" {
#endif
#define NSID3V1_EXPORT
typedef struct nsid3v1_tag_struct_t { } *nsid3v1_tag_t;
// Basic methods
NSID3V1_EXPORT int NSID3v1_Header_Valid(const void *data, size_t len);
NSID3V1_EXPORT int NSID3v1_Tag_Create(const void *data, size_t len, nsid3v1_tag_t *out_tag);
NSID3V1_EXPORT int NSID3v1_Tag_New(nsid3v1_tag_t *out_tag);
// len must be >= 128. ALWAYS writes 128 bytes if successful
NSID3V1_EXPORT int NSID3v1_Tag_Serialize(const nsid3v1_tag_t t, void *data, size_t len);
NSID3V1_EXPORT int NSID3v1_Tag_Destroy(nsid3v1_tag_t t);
// Generic getters
//NSID3V1_EXPORT int NSID3v1_Field_Text_Get(const nsid3v1_tag_t *t, const int field, nx_string_t *out_value);
NSID3V1_EXPORT int NSID3v1_Field_Text_Get(const nsid3v1_tag_t t, const int field, nx_string_t *out_value);
// Specific field getters as text
NSID3V1_EXPORT int NSID3v1_Get_Title(const nsid3v1_tag_t t, nx_string_t *value);
NSID3V1_EXPORT int NSID3v1_Get_Artist(const nsid3v1_tag_t t, nx_string_t *value);
NSID3V1_EXPORT int NSID3v1_Get_Album(const nsid3v1_tag_t t, nx_string_t *value);
NSID3V1_EXPORT int NSID3v1_Get_Year(const nsid3v1_tag_t t, nx_string_t *value);
NSID3V1_EXPORT int NSID3v1_Get_Comment(const nsid3v1_tag_t t, nx_string_t *value);
NSID3V1_EXPORT int NSID3v1_Get_Track(const nsid3v1_tag_t t, nx_string_t *value);
// Specific field getters as integers
NSID3V1_EXPORT int NSID3v1_Int_Get_Year(const nsid3v1_tag_t t, unsigned int *value);
NSID3V1_EXPORT int NSID3v1_Int_Get_Track(const nsid3v1_tag_t t, uint8_t *value);
NSID3V1_EXPORT int NSID3v1_Int_Get_Genre(const nsid3v1_tag_t t, uint8_t *value);
// Specific field setters as text
NSID3V1_EXPORT int NSID3v1_Set_Title(nsid3v1_tag_t t, nx_string_t value);
NSID3V1_EXPORT int NSID3v1_Set_Artist(nsid3v1_tag_t t, nx_string_t value);
NSID3V1_EXPORT int NSID3v1_Set_Album(nsid3v1_tag_t t, nx_string_t value);
NSID3V1_EXPORT int NSID3v1_Set_Year(nsid3v1_tag_t t, nx_string_t value);
NSID3V1_EXPORT int NSID3v1_Set_Comment(nsid3v1_tag_t t, nx_string_t value);
NSID3V1_EXPORT int NSID3v1_Set_Track(nsid3v1_tag_t t, nx_string_t value);
// Specific field setters as integers
NSID3V1_EXPORT int NSID3v1_Int_Set_Year(nsid3v1_tag_t t, unsigned int value);
NSID3V1_EXPORT int NSID3v1_Int_Set_Track(nsid3v1_tag_t t, uint8_t value);
NSID3V1_EXPORT int NSID3v1_Int_Set_Genre(nsid3v1_tag_t t, uint8_t value);
// field types for ID3V1.0
enum
{
NSID3V1_TAG,
NSID3V1_TITLE,
NSID3V1_ARTIST,
NSID3V1_ALBUM,
NSID3V1_YEAR,
NSID3V1_COMMENT,
NSID3V1_TRACK, // ID3V1.1
NSID3V1_GENRE,
};
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,44 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29509.3
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nsid3v1", "nsid3v1.vcxproj", "{1BF331E2-00BE-4ACC-B491-8C5DA35FA716}"
ProjectSection(ProjectDependencies) = postProject
{F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915} = {F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nu", "..\nu\nu.vcxproj", "{F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915}"
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
{1BF331E2-00BE-4ACC-B491-8C5DA35FA716}.Debug|Win32.ActiveCfg = Debug|Win32
{1BF331E2-00BE-4ACC-B491-8C5DA35FA716}.Debug|Win32.Build.0 = Debug|Win32
{1BF331E2-00BE-4ACC-B491-8C5DA35FA716}.Debug|x64.ActiveCfg = Debug|x64
{1BF331E2-00BE-4ACC-B491-8C5DA35FA716}.Debug|x64.Build.0 = Debug|x64
{1BF331E2-00BE-4ACC-B491-8C5DA35FA716}.Release|Win32.ActiveCfg = Release|Win32
{1BF331E2-00BE-4ACC-B491-8C5DA35FA716}.Release|Win32.Build.0 = Release|Win32
{1BF331E2-00BE-4ACC-B491-8C5DA35FA716}.Release|x64.ActiveCfg = Release|x64
{1BF331E2-00BE-4ACC-B491-8C5DA35FA716}.Release|x64.Build.0 = Release|x64
{F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915}.Debug|Win32.ActiveCfg = Debug|Win32
{F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915}.Debug|Win32.Build.0 = Debug|Win32
{F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915}.Debug|x64.ActiveCfg = Debug|x64
{F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915}.Debug|x64.Build.0 = Debug|x64
{F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915}.Release|Win32.ActiveCfg = Release|Win32
{F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915}.Release|Win32.Build.0 = Release|Win32
{F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915}.Release|x64.ActiveCfg = Release|x64
{F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B1F650AF-5553-4512-9413-CCE4ACF1FB2F}
EndGlobalSection
EndGlobal

View file

@ -0,0 +1,171 @@
<?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>{1BF331E2-00BE-4ACC-B491-8C5DA35FA716}</ProjectGuid>
<RootNamespace>nsid3v1</RootNamespace>
</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>x86_Debug\</OutDir>
<IntDir>x86_Debug\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>x64_Debug\</OutDir>
<IntDir>x64_Debug\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>x86_Release\</OutDir>
<IntDir>x86_Release\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>x64_Release\</OutDir>
<IntDir>x64_Release\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Lib>
<OutputFile>$(ProjectDir)x86_Debug\$(ProjectName).lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN64;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Lib>
<OutputFile>$(ProjectDir)x64_Debug\$(ProjectName).lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>MinSpace</Optimization>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Lib>
<OutputFile>$(ProjectDir)x86_Release\$(ProjectName).lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<Optimization>MinSpace</Optimization>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN64;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Lib>
<OutputFile>$(ProjectDir)x64_Release\$(ProjectName).lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemGroup>
<ProjectReference Include="..\nu\nu.vcxproj">
<Project>{efc75a79-269f-44fc-bac5-d7d4fd4ec92c}</Project>
<CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies>
<ReferenceOutputAssembly>true</ReferenceOutputAssembly>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ClCompile Include="nsid3v1.cpp" />
<ClCompile Include="tag.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="nsid3v1.h" />
<ClInclude Include="precomp.h" />
<ClInclude Include="tag.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View file

@ -0,0 +1,18 @@
//
// precomp.h
// nsid3v1
//
#include "foundation/error.h"
#include "foundation/types.h"
#include "nu/ByteReader.h"
#include "nu/ByteWriter.h"
#include "nx/nxstring.h"
#include <limits.h>
#include <new>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

View file

@ -0,0 +1,177 @@
#include "tag.h"
#include <string.h> // for strnlen
#include "nsid3v1.h"
#include "foundation/error.h"
#include "nu/ByteReader.h"
#include "nu/ByteWriter.h"
#ifdef __APPLE__
inline static size_t id3v1_strnlen(const char *s, size_t n)
{
const char *p=(const char *)memchr(s, 0, n);
return p?p-s:n;
}
#else // __APPLE__
inline static size_t id3v1_strnlen(const char *s, size_t n)
{
return strnlen(s, n);
}
#endif
ID3v1::Tag::Tag()
{
}
void ID3v1::Tag::New()
{
header[0]='T';
header[1]='A';
header[2]='G';
memset(title, 0, 30);
memset(artist, 0, 30);
memset(album, 0, 30);
memset(year, 0, 30);
memset(comment, 0, 30);
track=0;
genre=0;
}
// Deprecated, bytereader class can now handle n-number of bytes
static void GetAndFillNumberOfBytes(bytereader_value_t byte_reader, int bytes, const void *data, char *destination)
{
for (int i = 0; i < bytes; i++)
{
destination[i] = bytereader_read_u8(&byte_reader);
}
}
const char *ID3v1::Tag::GetHeader(void) const { return header; }
const char *ID3v1::Tag::GetTitle(void) const { return title; }
const char *ID3v1::Tag::GetArtist(void) const { return artist; }
const char *ID3v1::Tag::GetAlbum(void) const { return album; }
const char *ID3v1::Tag::GetYear(void) const { return year; }
const char *ID3v1::Tag::GetComment(void) const { return comment; }
uint8_t ID3v1::Tag::GetTrack(void) const { return track; }
uint8_t ID3v1::Tag::GetGenre(void) const { return genre; }
//unsigned int ID3v1::Tag::GetTitleLength(void) { return ( strlen(title) <= 30 ) ? strlen(title) : 30; }
size_t ID3v1::Tag::GetHeaderLength(void) const { return id3v1_strnlen(header, 3); }
size_t ID3v1::Tag::GetTitleLength(void) const { return id3v1_strnlen(title, 30); }
size_t ID3v1::Tag::GetArtistLength(void) const { return id3v1_strnlen(artist, 30); }
size_t ID3v1::Tag::GetAlbumLength(void) const { return id3v1_strnlen(album, 30); }
size_t ID3v1::Tag::GetYearLength(void) const { return id3v1_strnlen(year, 4); }
size_t ID3v1::Tag::GetCommentLength(void) const { return id3v1_strnlen(comment, 30); }
int ID3v1::Tag::Parse(const void *data, size_t len)
{
if (len < 128)
return NErr_NeedMoreData;
bytereader_value_t byte_reader;
bytereader_init(&byte_reader, data, len);
// Get header
bytereader_read_n(&byte_reader, header, 3);
// Get title
bytereader_read_n(&byte_reader, title, 30);
// Get artist
bytereader_read_n(&byte_reader, artist, 30);
// Get album
bytereader_read_n(&byte_reader, album, 30);
// Get year
bytereader_read_n(&byte_reader, year, 4);
// Get comments
bytereader_read_n(&byte_reader, comment, 30);
// Get genre
genre = bytereader_read_u8(&byte_reader);
// Check for the presence of track # inside of the comments field at offset position 29 & 30
if (comment[28] == 0 && comment[29] != 0)
{
track = comment[29];
}
else
track = 0;
return NErr_Success;
}
/* copies source_bytes characters to destination, and fills up the remaining (up to destination_length) with null */
static void id3v1_strncpyn(char *destination, size_t destination_length, const char *source, size_t source_bytes)
{
// make sure we don't write too much
if (source_bytes > destination_length)
source_bytes = destination_length;
memcpy(destination, source, source_bytes);
memset(destination+source_bytes, 0, destination_length-source_bytes); // zero remainder of string
}
void ID3v1::Tag::SetTitle(const char *new_title, size_t length)
{
id3v1_strncpyn(title, 30, new_title, length);
}
void ID3v1::Tag::SetArtist(const char *new_artist, size_t length)
{
id3v1_strncpyn(artist, 30, new_artist, length);
}
void ID3v1::Tag::SetAlbum(const char *new_album, size_t length)
{
id3v1_strncpyn(album, 30, new_album, length);
}
void ID3v1::Tag::SetYear(const char *new_year, size_t length)
{
id3v1_strncpyn(year, 4, new_year, length);
}
void ID3v1::Tag::SetComment(const char *new_comment, size_t length)
{
id3v1_strncpyn(comment, 28, new_comment, length);
}
void ID3v1::Tag::SetTrack(uint8_t new_track)
{
track = new_track;
}
void ID3v1::Tag::SetGenre(uint8_t new_genre)
{
genre = new_genre;
}
int ID3v1::Tag::Serialize(void *data, size_t len)
{
if (len < 128)
return NErr_Insufficient;
bytewriter_s byte_writer;
bytewriter_init(&byte_writer, data, len);
bytewriter_write_n(&byte_writer, header, 3);
bytewriter_write_n(&byte_writer, title, 30);
bytewriter_write_n(&byte_writer, artist, 30);
bytewriter_write_n(&byte_writer, album, 30);
bytewriter_write_n(&byte_writer, year, 4);
bytewriter_write_n(&byte_writer, comment, 28);
bytewriter_write_u8(&byte_writer, 0);
bytewriter_write_u8(&byte_writer, track);
bytewriter_write_u8(&byte_writer, genre);
return NErr_Success;
}

View file

@ -0,0 +1,54 @@
#pragma once
#include "nsid3v1.h"
class nstest;
namespace ID3v1
{
class Tag
{
friend class nstest;
public:
Tag();
int Parse(const void *data, size_t len);
void New(); // creates an empty (but valid) tag
// Member value getters
const char *GetHeader(void) const;
const char *GetTitle(void) const;
const char *GetArtist(void) const;
const char *GetAlbum(void) const;
const char *GetYear(void) const;
const char *GetComment(void) const;
uint8_t GetTrack(void) const;
uint8_t GetGenre(void) const;
// Member length getters
size_t GetHeaderLength(void) const;
size_t GetTitleLength(void) const;
size_t GetArtistLength(void) const;
size_t GetAlbumLength(void) const;
size_t GetYearLength(void) const;
size_t GetCommentLength(void) const;
void SetTitle(const char *title, size_t length);
void SetArtist(const char *artist, size_t length);
void SetAlbum(const char *album, size_t length);
void SetYear(const char *year, size_t length);
void SetComment(const char *comment, size_t length);
void SetTrack(uint8_t track);
void SetGenre(uint8_t genre);
int Serialize(void *data, size_t len);
protected:
char header[3];
char title[30];
char artist[30];
char album[30];
char year[4];
char comment[30]; // Bytes 29 & 30 can contain 0 & genre respectivly, ID3V1.1
uint8_t track;
uint8_t genre;
};
}