Skip to content

Commit 6e5e987

Browse files
committed
Add BilibiliParser
1 parent 3dc310a commit 6e5e987

File tree

7 files changed

+155
-4
lines changed

7 files changed

+155
-4
lines changed

3rdparty/rapidxml

libwtfdanmaku.vcxproj

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@
1717
</PropertyGroup>
1818
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
1919
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
20-
<ConfigurationType>DynamicLibrary</ConfigurationType>
20+
<ConfigurationType>StaticLibrary</ConfigurationType>
2121
<UseDebugLibraries>true</UseDebugLibraries>
2222
<PlatformToolset>v120</PlatformToolset>
2323
<CharacterSet>Unicode</CharacterSet>
2424
</PropertyGroup>
2525
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
26-
<ConfigurationType>DynamicLibrary</ConfigurationType>
26+
<ConfigurationType>StaticLibrary</ConfigurationType>
2727
<UseDebugLibraries>false</UseDebugLibraries>
2828
<PlatformToolset>v120</PlatformToolset>
2929
<WholeProgramOptimization>true</WholeProgramOptimization>
@@ -67,6 +67,7 @@
6767
<IntrinsicFunctions>true</IntrinsicFunctions>
6868
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBWTFDANMAKU_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
6969
<SDLCheck>true</SDLCheck>
70+
<AdditionalIncludeDirectories>$(ProjectDir)3rdparty;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
7071
</ClCompile>
7172
<Link>
7273
<SubSystem>Windows</SubSystem>
@@ -78,11 +79,13 @@
7879
</ItemDefinitionGroup>
7980
<ItemGroup>
8081
<ClInclude Include="src\BaseDanmaku.hpp" />
82+
<ClInclude Include="src\BilibiliParser.hpp" />
8183
<ClInclude Include="src\DanmakusManager.hpp" />
8284
<ClInclude Include="src\Displayer.hpp" />
8385
<ClInclude Include="src\DisplayerImpl.hpp" />
8486
<ClInclude Include="src\GlobalConfig.hpp" />
8587
<ClInclude Include="src\ITimer.hpp" />
88+
<ClInclude Include="src\IParser.hpp" />
8689
<ClInclude Include="src\R2LDanmaku.hpp" />
8790
<ClInclude Include="src\Renderable.hpp" />
8891
<ClInclude Include="src\DanmakusRetainer.hpp" />
@@ -97,6 +100,7 @@
97100
<ClInclude Include="src\WinmmTimer.hpp" />
98101
</ItemGroup>
99102
<ItemGroup>
103+
<ClCompile Include="src\BilibiliParser.cpp" />
100104
<ClCompile Include="src\DisplayerImpl.cpp" />
101105
<ClCompile Include="src\dllmain.cpp">
102106
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>

libwtfdanmaku.vcxproj.filters

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,12 @@
6969
<ClInclude Include="src\Controller.hpp">
7070
<Filter>src</Filter>
7171
</ClInclude>
72+
<ClInclude Include="src\BilibiliParser.hpp">
73+
<Filter>src</Filter>
74+
</ClInclude>
75+
<ClInclude Include="src\IParser.hpp">
76+
<Filter>src</Filter>
77+
</ClInclude>
7278
</ItemGroup>
7379
<ItemGroup>
7480
<ClCompile Include="src\BaseDanmaku.cpp">
@@ -116,5 +122,8 @@
116122
<ClCompile Include="src\Controller.cpp">
117123
<Filter>src</Filter>
118124
</ClCompile>
125+
<ClCompile Include="src\BilibiliParser.cpp">
126+
<Filter>src</Filter>
127+
</ClCompile>
119128
</ItemGroup>
120129
</Project>

src/BaseDanmaku.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ using std::weak_ptr;
1313

1414
namespace WTFDanmaku {
1515

16-
enum DanmakuType {
16+
enum DanmakuType : int {
1717
kNull = 0,
1818
kScrolling = 1,
1919
kBottom = 4,

src/BilibiliParser.cpp

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
#include <clocale>
2+
#include <codecvt>
3+
#include "../3rdparty/rapidxml/rapidxml.hpp"
4+
#include "../3rdparty/rapidxml/rapidxml_utils.hpp"
5+
#include "DanmakuFactory.hpp"
6+
#include "BilibiliParser.hpp"
7+
8+
using namespace rapidxml;
9+
10+
namespace WTFDanmaku {
11+
12+
BilibiliParser::BilibiliParser() {
13+
mDanmakus = std::move(std::unique_ptr<std::vector<DanmakuRef>>(new std::vector<DanmakuRef>));
14+
}
15+
16+
bool BilibiliParser::ParseStringSource(const char* str) {
17+
return ParseXml(str);
18+
}
19+
20+
bool BilibiliParser::ParseFileSource(const char* filePath) {
21+
file<> xmlFile(filePath);
22+
return ParseXml(xmlFile.data());
23+
}
24+
25+
bool BilibiliParser::ParseXml(const char* data) {
26+
if (mDanmakus.get() == nullptr)
27+
return false;
28+
29+
int bufferSize = strlen(data) + 1;
30+
char* buf = new char[bufferSize];
31+
std::unique_ptr<char> buffer(buf);
32+
memset(buf, 0, bufferSize);
33+
strcpy_s(buf, bufferSize, data);
34+
35+
xml_document<> doc;
36+
doc.parse<0>(buf);
37+
38+
xml_node<char>* root = doc.first_node("i");
39+
if (root == nullptr)
40+
return false;
41+
42+
for (auto node = root->first_node("d"); node != nullptr; node = node->next_sibling()) {
43+
const char* attr = node->first_attribute("p")->value();
44+
auto attributes = SplitString(attr, ',');
45+
46+
if (attributes.size() >= 8) {
47+
time_t time = static_cast<time_t>(std::stod(attributes[0]) * 1000);
48+
DanmakuType type = static_cast<DanmakuType>(std::stoi(attributes[1]));
49+
int textSize = static_cast<int>(std::stof(attributes[2]));
50+
int textColor = std::stoi(attributes[3]) | 0xFF000000;
51+
time_t timestamp = std::stoull(attributes[4]);
52+
int danmakuId = std::stoi(attributes[7]);
53+
std::wstring comment = UTF8ToWideString(node->value());
54+
55+
DanmakuRef danmaku = DanmakuFactory::CreateDanmaku(type, time, comment, textSize, textColor, timestamp, danmakuId);
56+
if (danmaku != nullptr) {
57+
mDanmakus->push_back(danmaku);
58+
}
59+
}
60+
}
61+
return true;
62+
}
63+
64+
std::unique_ptr<std::vector<DanmakuRef>> BilibiliParser::GetDanmakus() {
65+
return std::move(mDanmakus);
66+
}
67+
68+
std::vector<std::string> BilibiliParser::SplitString(const char* input, char delimiter) {
69+
std::vector<std::string> fragments;
70+
while (auto next = strchr(input, delimiter)) {
71+
fragments.push_back(std::string(input, next));
72+
input = next + 1;
73+
}
74+
fragments.push_back(std::string(input));
75+
return fragments;
76+
}
77+
78+
std::wstring BilibiliParser::UTF8ToWideString(const char* input) {
79+
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> u8to16conv;
80+
std::wstring wide = u8to16conv.from_bytes(input);
81+
return wide;
82+
}
83+
84+
}

src/BilibiliParser.hpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#ifndef _WTF_BILIBILI_PARSER_HPP
2+
#define _WTF_BILIBILI_PARSER_HPP
3+
4+
#include "IParser.hpp"
5+
6+
namespace WTFDanmaku {
7+
8+
class BilibiliParser : public IParser {
9+
public:
10+
static inline ParserRef Create() {
11+
return std::make_shared<BilibiliParser>();
12+
}
13+
public:
14+
explicit BilibiliParser();
15+
virtual ~BilibiliParser() = default;
16+
virtual bool ParseStringSource(const char* str) override;
17+
virtual bool ParseFileSource(const char* filePath) override;
18+
virtual std::unique_ptr<std::vector<DanmakuRef>> GetDanmakus() override;
19+
private:
20+
bool ParseXml(const char* data);
21+
static std::vector<std::string> BilibiliParser::SplitString(const char* input, char delimiter);
22+
static std::wstring UTF8ToWideString(const char* input);
23+
private:
24+
std::unique_ptr<std::vector<DanmakuRef>> mDanmakus;
25+
};
26+
27+
}
28+
29+
#endif // _WTF_BILIBILI_PARSER_HPP

src/IParser.hpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#ifndef _WTF_IPARSER_HPP
2+
#define _WTF_IPARSER_HPP
3+
4+
#include <cstdint>
5+
#include <vector>
6+
#include <memory>
7+
#include "BaseDanmaku.hpp"
8+
#include "Noncopyable.hpp"
9+
10+
namespace WTFDanmaku {
11+
12+
class IParser : public Noncopyable {
13+
public:
14+
explicit IParser() = default;
15+
virtual ~IParser() = default;
16+
virtual bool ParseStringSource(const char* str) = 0;
17+
virtual bool ParseFileSource(const char* filePath) = 0;
18+
virtual std::unique_ptr<std::vector<DanmakuRef>> GetDanmakus() = 0;
19+
};
20+
21+
typedef std::shared_ptr<IParser> ParserRef;
22+
23+
}
24+
25+
#endif // _WTF_IPARSER_HPP

0 commit comments

Comments
 (0)