1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
|
/*
* Copyright 2003-2017 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef MPD_CUE_PARSER_HXX
#define MPD_CUE_PARSER_HXX
#include "check.h"
#include "song/DetachedSong.hxx"
#include "tag/Builder.hxx"
#include "util/Compiler.h"
#include <string>
#include <memory>
class CueParser {
enum {
/**
* Parsing the CUE header.
*/
HEADER,
/**
* Parsing a "FILE ... WAVE".
*/
WAVE,
/**
* Ignore everything until the next "FILE".
*/
IGNORE_FILE,
/**
* Parsing a "TRACK ... AUDIO".
*/
TRACK,
/**
* Ignore everything until the next "TRACK".
*/
IGNORE_TRACK,
} state = HEADER;
/**
* Tags read from the CUE header.
*/
TagBuilder header_tag;
/**
* Tags read for the current song (attribute #current). When
* #current gets moved to #previous, TagBuilder::Commit() will
* be called.
*/
TagBuilder song_tag;
std::string filename;
/**
* The song currently being edited.
*/
std::unique_ptr<DetachedSong> current;
/**
* The previous song. It is remembered because its end_time
* will be set to the current song's start time.
*/
std::unique_ptr<DetachedSong> previous;
/**
* A song that is completely finished and can be returned to
* the caller via Get().
*/
std::unique_ptr<DetachedSong> finished;
/**
* Ignore "INDEX" lines? Only up the first one after "00" is
* used. If there is a pregap (INDEX 00..01), it is assigned
* to the previous song.
*/
bool ignore_index;
/**
* Tracks whether Finish() has been called. If true, then all
* remaining (partial) results will be delivered by Get().
*/
bool end = false;
public:
/**
* Feed a text line from the CUE file into the parser. Call
* Get() after this to see if a song has been finished.
*/
void Feed(const char *line) noexcept;
/**
* Tell the parser that the end of the file has been reached. Call
* Get() after this to see if a song has been finished.
* This procedure must be done twice!
*/
void Finish() noexcept;
/**
* Check if a song was finished by the last Feed() or Finish()
* call.
*
* @return a song object that must be freed by the caller, or NULL if
* no song was finished at this time
*/
std::unique_ptr<DetachedSong> Get() noexcept;
private:
gcc_pure
TagBuilder *GetCurrentTag() noexcept;
/**
* Commit the current song. It will be moved to "previous",
* so the next song may soon edit its end time (using the next
* song's start time).
*/
void Commit() noexcept;
void Feed2(char *p) noexcept;
};
#endif
|