annotate foosdk/sdk/foobar2000/helpers/cue_parser.cpp @ 1:20d02a178406 default tip

*: check in everything else yay
author Paper <paper@tflc.us>
date Mon, 05 Jan 2026 02:15:46 -0500
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1 #include "StdAfx.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
2 #include "cue_parser.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
3
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
4
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
5 #define maximumCueTrackNumber 999
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
6
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
7 namespace {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
8 PFC_DECLARE_EXCEPTION(exception_cue,pfc::exception,"Invalid cuesheet");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
9 PFC_DECLARE_EXCEPTION(exception_cue_tracktype, exception_cue, "Not an audio track")
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
10 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
11
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
12 [[noreturn]] static void cue_fail(const char* msg) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
13 pfc::throw_exception_with_message< exception_cue >(msg);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
14 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
15
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
16 static bool is_numeric(char c) {return c>='0' && c<='9';}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
17
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
18
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
19 static bool is_spacing(char c)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
20 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
21 return c == ' ' || c == '\t';
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
22 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
23
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
24 static bool is_linebreak(char c)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
25 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
26 return c == '\n' || c == '\r';
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
27 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
28
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
29 static void validate_file_type(const char * p_type,t_size p_type_length) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
30 const char* const allowedTypes[] = {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
31 "WAVE", "MP3", "AIFF", // standard typers
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
32 "APE", "FLAC", "WV", "WAVPACK", "MP4", // common user-entered types
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
33 "BINARY" // BINARY
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
34 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
35 for (auto walk : allowedTypes) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
36 if (pfc::stringEqualsI_ascii_ex(p_type, p_type_length, walk, SIZE_MAX)) return;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
37 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
38 pfc::throw_exception_with_message< exception_cue >(PFC_string_formatter() << "expected WAVE, MP3 or AIFF, got : \"" << pfc::string_part(p_type,p_type_length) << "\"");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
39 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
40
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
41 namespace {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
42
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
43 class NOVTABLE cue_parser_callback
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
44 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
45 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
46 virtual void on_file(const char * p_file,t_size p_file_length,const char * p_type,t_size p_type_length) = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
47 virtual void on_track(unsigned p_index,const char * p_type,t_size p_type_length) = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
48 virtual void on_pregap(unsigned p_value) = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
49 virtual void on_index(unsigned p_index,unsigned p_value) = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
50 virtual void on_title(const char * p_title,t_size p_title_length) = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
51 virtual void on_performer(const char * p_performer,t_size p_performer_length) = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
52 virtual void on_songwriter(const char * p_songwriter,t_size p_songwriter_length) = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
53 virtual void on_isrc(const char * p_isrc,t_size p_isrc_length) = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
54 virtual void on_catalog(const char * p_catalog,t_size p_catalog_length) = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
55 virtual void on_comment(const char * p_comment,t_size p_comment_length) = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
56 virtual void on_flags(const char * p_flags,t_size p_flags_length) = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
57 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
58
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
59 class NOVTABLE cue_parser_callback_meta : public cue_parser_callback
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
60 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
61 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
62 virtual void on_file(const char * p_file,t_size p_file_length,const char * p_type,t_size p_type_length) = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
63 virtual void on_track(unsigned p_index,const char * p_type,t_size p_type_length) = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
64 virtual void on_pregap(unsigned p_value) = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
65 virtual void on_index(unsigned p_index,unsigned p_value) = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
66 virtual void on_meta(const char * p_name,t_size p_name_length,const char * p_value,t_size p_value_length) = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
67 protected:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
68 static bool is_known_meta(const char * p_name,t_size p_length)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
69 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
70 static const char * metas[] = {"genre","date","discid","comment","replaygain_track_gain","replaygain_track_peak","replaygain_album_gain","replaygain_album_peak", "discnumber", "totaldiscs"};
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
71 for (const char* m : metas) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
72 if (!stricmp_utf8_ex(p_name, p_length, m, SIZE_MAX)) return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
73 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
74 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
75 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
76
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
77 void on_comment(const char * p_comment,t_size p_comment_length)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
78 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
79 unsigned ptr = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
80 while(ptr < p_comment_length && !is_spacing(p_comment[ptr])) ptr++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
81 if (is_known_meta(p_comment, ptr))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
82 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
83 unsigned name_length = ptr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
84 while(ptr < p_comment_length && is_spacing(p_comment[ptr])) ptr++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
85 if (ptr < p_comment_length)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
86 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
87 if (p_comment[ptr] == '\"')
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
88 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
89 ptr++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
90 unsigned value_base = ptr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
91 while(ptr < p_comment_length && p_comment[ptr] != '\"') ptr++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
92 if (ptr == p_comment_length) pfc::throw_exception_with_message<exception_cue>("invalid REM syntax");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
93 if (ptr > value_base) on_meta(p_comment,name_length,p_comment + value_base,ptr - value_base);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
94 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
95 else
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
96 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
97 unsigned value_base = ptr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
98 while(ptr < p_comment_length /*&& !is_spacing(p_comment[ptr])*/) ptr++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
99 if (ptr > value_base) on_meta(p_comment,name_length,p_comment + value_base,ptr - value_base);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
100 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
101 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
102 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
103 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
104 void on_title(const char * p_title,t_size p_title_length)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
105 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
106 on_meta("title",pfc_infinite,p_title,p_title_length);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
107 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
108 void on_songwriter(const char * p_songwriter,t_size p_songwriter_length) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
109 on_meta("songwriter",pfc_infinite,p_songwriter,p_songwriter_length);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
110 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
111 void on_performer(const char * p_performer,t_size p_performer_length)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
112 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
113 on_meta("artist",pfc_infinite,p_performer,p_performer_length);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
114 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
115
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
116 void on_isrc(const char * p_isrc,t_size p_isrc_length)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
117 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
118 on_meta("isrc",pfc_infinite,p_isrc,p_isrc_length);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
119 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
120 void on_catalog(const char * p_catalog,t_size p_catalog_length)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
121 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
122 on_meta("catalog",pfc_infinite,p_catalog,p_catalog_length);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
123 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
124 void on_flags(const char * p_flags,t_size p_flags_length) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
125 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
126
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
127
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
128 class cue_parser_callback_retrievelist : public cue_parser_callback
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
129 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
130 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
131 cue_parser_callback_retrievelist(cue_parser::t_cue_entry_list& p_out) : m_out(p_out) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
132
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
133 void on_file(const char * p_file,t_size p_file_length,const char * p_type,t_size p_type_length)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
134 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
135 validate_file_type(p_type,p_type_length);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
136 m_file.set_string(p_file,p_file_length);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
137 m_fileType.set_string(p_type, p_type_length);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
138 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
139
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
140 void on_track(unsigned p_index,const char * p_type,t_size p_type_length)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
141 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
142 finalize_track(); // finalize previous track
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
143
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
144 m_trackIsAudio = stricmp_utf8_ex(p_type,p_type_length,"audio",pfc_infinite) == 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
145 if (m_file.is_empty()) pfc::throw_exception_with_message<exception_cue>("declaring a track with no file set");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
146 m_trackfile = m_file;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
147 m_trackFileType = m_fileType;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
148 m_track = p_index;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
149 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
150
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
151 void on_pregap(unsigned p_value) {m_pregap = (double) p_value / 75.0;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
152
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
153 void on_index(unsigned p_index,unsigned p_value)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
154 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
155 if (p_index < t_cuesheet_index_list::count)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
156 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
157 switch(p_index)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
158 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
159 case 0: m_index0_set = true; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
160 case 1: m_index1_set = true; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
161 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
162 m_index_list.m_positions[p_index] = (double) p_value / 75.0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
163 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
164 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
165
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
166 void on_title(const char * p_title,t_size p_title_length) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
167 void on_performer(const char * p_performer,t_size p_performer_length) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
168 void on_songwriter(const char * p_songwriter,t_size p_songwriter_length) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
169 void on_isrc(const char * p_isrc,t_size p_isrc_length) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
170 void on_catalog(const char * p_catalog,t_size p_catalog_length) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
171 void on_comment(const char * p_comment,t_size p_comment_length) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
172 void on_flags(const char * p_flags,t_size p_flags_length) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
173
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
174 void finalize()
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
175 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
176 finalize_track(); // finalize last track
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
177 sanity();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
178 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
179
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
180 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
181 void sanity() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
182 int trk = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
183 for (auto& iter : m_out) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
184 int i = iter.m_track_number;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
185 if (i <= trk) cue_fail("incorrect track numbering");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
186 trk = i;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
187 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
188 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
189 void finalize_track()
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
190 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
191 if ( m_track != 0 && m_trackIsAudio ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
192 if (!m_index1_set) cue_fail("INDEX 01 not set");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
193 if (!m_index0_set) m_index_list.m_positions[0] = m_index_list.m_positions[1] - m_pregap;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
194 if (!m_index_list.is_valid()) cue_fail("invalid index list");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
195
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
196 cue_parser::t_cue_entry_list::iterator iter;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
197 iter = m_out.insert_last();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
198 if (m_trackfile.is_empty()) cue_fail("track has no file assigned");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
199 iter->m_file = m_trackfile;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
200 iter->m_fileType = m_trackFileType;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
201 iter->m_track_number = m_track;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
202 iter->m_indexes = m_index_list;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
203 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
204
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
205 m_index_list.reset();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
206 m_index0_set = false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
207 m_index1_set = false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
208 m_pregap = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
209
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
210 m_track = 0; m_trackIsAudio = false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
211 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
212
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
213 bool m_index0_set = false,m_index1_set = false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
214 t_cuesheet_index_list m_index_list;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
215 double m_pregap = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
216 unsigned m_track = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
217 bool m_trackIsAudio = false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
218 pfc::string8 m_file,m_fileType,m_trackfile,m_trackFileType;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
219 cue_parser::t_cue_entry_list & m_out;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
220 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
221
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
222 class cue_parser_callback_retrieveinfo : public cue_parser_callback_meta
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
223 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
224 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
225 cue_parser_callback_retrieveinfo(file_info & p_out,unsigned p_wanted_track) : m_out(p_out), m_wanted_track(p_wanted_track), m_track(0), m_is_va(false), m_index0_set(false), m_index1_set(false), m_pregap(0), m_totaltracks(0) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
226
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
227 void on_file(const char * p_file,t_size p_file_length,const char * p_type,t_size p_type_length) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
228
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
229 void on_track(unsigned p_index,const char * p_type,t_size p_type_length)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
230 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
231 if (p_index == 0) cue_fail("invalid TRACK index");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
232 if (p_index == m_wanted_track)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
233 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
234 if (stricmp_utf8_ex(p_type,p_type_length,"audio",pfc_infinite)) throw exception_cue_tracktype();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
235 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
236 m_track = p_index;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
237 m_totaltracks++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
238 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
239
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
240 void on_pregap(unsigned p_value) {if (m_track == m_wanted_track) m_pregap = (double) p_value / 75.0;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
241
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
242 void on_index(unsigned p_index,unsigned p_value)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
243 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
244 if (m_track == m_wanted_track && p_index < t_cuesheet_index_list::count)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
245 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
246 switch(p_index)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
247 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
248 case 0: m_index0_set = true; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
249 case 1: m_index1_set = true; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
250 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
251 m_indexes.m_positions[p_index] = (double) p_value / 75.0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
252 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
253 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
254
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
255
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
256 void on_meta(const char * p_name,t_size p_name_length,const char * p_value,t_size p_value_length)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
257 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
258 t_meta_list::iterator iter;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
259 if (m_track == 0) //globals
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
260 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
261 //convert global title to album
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
262 if (!stricmp_utf8_ex(p_name,p_name_length,"title",pfc_infinite))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
263 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
264 p_name = "album";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
265 p_name_length = 5;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
266 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
267 else if (!stricmp_utf8_ex(p_name,p_name_length,"artist",pfc_infinite))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
268 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
269 m_album_artist.set_string(p_value,p_value_length);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
270 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
271
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
272 iter = m_globals.insert_last();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
273 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
274 else
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
275 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
276 if (!m_is_va)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
277 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
278 if (!stricmp_utf8_ex(p_name,p_name_length,"artist",pfc_infinite))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
279 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
280 if (!m_album_artist.is_empty())
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
281 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
282 if (stricmp_utf8_ex(p_value,p_value_length,m_album_artist,m_album_artist.length())) m_is_va = true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
283 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
284 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
285 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
286
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
287 if (m_track == m_wanted_track) //locals
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
288 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
289 iter = m_locals.insert_last();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
290 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
291 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
292 if (iter.is_valid())
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
293 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
294 iter->m_name.set_string(p_name,p_name_length);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
295 iter->m_value.set_string(p_value,p_value_length);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
296 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
297 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
298
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
299 void _meta_set(const char* key, const pfc::string8 & value) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
300 if ( value.length() > 0 ) m_out.meta_set( key, value );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
301 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
302
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
303 void finalize()
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
304 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
305 if (!m_index1_set) pfc::throw_exception_with_message< exception_cue > ("INDEX 01 not set");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
306 if (!m_index0_set) m_indexes.m_positions[0] = m_indexes.m_positions[1] - m_pregap;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
307 m_indexes.to_infos(m_out);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
308
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
309 replaygain_info rg;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
310 rg.reset();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
311 t_meta_list::const_iterator iter;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
312
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
313 if (m_is_va)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
314 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
315 //clean up VA mess
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
316
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
317 t_meta_list::const_iterator iter_global,iter_local;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
318
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
319 iter_global = find_first_field(m_globals,"artist");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
320 iter_local = find_first_field(m_locals,"artist");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
321 if (iter_global.is_valid())
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
322 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
323 _meta_set("album artist",iter_global->m_value);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
324 if (iter_local.is_valid()) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
325 _meta_set("artist",iter_local->m_value);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
326 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
327 _meta_set("artist",iter_global->m_value);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
328 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
329 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
330 else
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
331 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
332 if (iter_local.is_valid()) _meta_set("artist",iter_local->m_value);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
333 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
334
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
335
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
336 wipe_field(m_globals,"artist");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
337 wipe_field(m_locals,"artist");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
338
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
339 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
340
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
341 for(iter=m_globals.first();iter.is_valid();iter++)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
342 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
343 if (!rg.set_from_meta(iter->m_name,iter->m_value))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
344 _meta_set(iter->m_name,iter->m_value);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
345 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
346 for(iter=m_locals.first();iter.is_valid();iter++)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
347 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
348 if (!rg.set_from_meta(iter->m_name,iter->m_value))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
349 _meta_set(iter->m_name,iter->m_value);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
350 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
351 m_out.meta_set("tracknumber",PFC_string_formatter() << m_wanted_track);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
352 m_out.meta_set("totaltracks", PFC_string_formatter() << m_totaltracks);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
353 m_out.set_replaygain(rg);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
354
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
355 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
356 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
357 struct t_meta_entry {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
358 pfc::string8 m_name,m_value;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
359 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
360 typedef pfc::chain_list_v2_t<t_meta_entry> t_meta_list;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
361
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
362 static t_meta_list::const_iterator find_first_field(t_meta_list const & p_list,const char * p_field)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
363 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
364 t_meta_list::const_iterator iter;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
365 for(iter=p_list.first();iter.is_valid();++iter)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
366 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
367 if (!stricmp_utf8(p_field,iter->m_name)) return iter;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
368 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
369 return t_meta_list::const_iterator();//null iterator
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
370 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
371
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
372 static void wipe_field(t_meta_list & p_list,const char * p_field)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
373 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
374 t_meta_list::iterator iter;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
375 for(iter=p_list.first();iter.is_valid();)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
376 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
377 if (!stricmp_utf8(p_field,iter->m_name))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
378 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
379 t_meta_list::iterator temp = iter;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
380 ++temp;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
381 p_list.remove_single(iter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
382 iter = temp;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
383 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
384 else
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
385 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
386 ++iter;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
387 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
388 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
389 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
390
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
391 t_meta_list m_globals,m_locals;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
392 file_info & m_out;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
393 unsigned m_wanted_track, m_track,m_totaltracks;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
394 pfc::string8 m_album_artist;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
395 bool m_is_va;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
396 t_cuesheet_index_list m_indexes;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
397 bool m_index0_set,m_index1_set;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
398 double m_pregap;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
399 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
400
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
401 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
402
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
403 static pfc::string_part_ref cue_line_argument( const char * base, size_t length ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
404 const char * end = base + length;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
405 while(base < end && is_spacing(base[0]) ) ++base;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
406 while(base < end && is_spacing(end[-1]) ) --end;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
407 if ( base + 1 < end ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
408 if ( base[0] == '\"' && end[-1] == '\"' ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
409 ++base; --end;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
410 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
411 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
412 return pfc::string_part(base, end-base);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
413 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
414
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
415 static void g_parse_cue_line(const char * p_line,t_size p_line_length,cue_parser_callback & p_callback)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
416 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
417 t_size ptr = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
418 while(ptr < p_line_length && !is_spacing(p_line[ptr])) ptr++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
419 if (!stricmp_utf8_ex(p_line,ptr,"file",pfc_infinite))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
420 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
421 while(ptr < p_line_length && is_spacing(p_line[ptr])) ptr++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
422 t_size file_base,file_length, type_base,type_length;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
423
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
424 if (p_line[ptr] == '\"')
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
425 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
426 ptr++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
427 file_base = ptr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
428 while(ptr < p_line_length && p_line[ptr] != '\"') ptr++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
429 if (ptr == p_line_length) pfc::throw_exception_with_message< exception_cue > ("invalid FILE syntax");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
430 file_length = ptr - file_base;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
431 ptr++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
432 while(ptr < p_line_length && is_spacing(p_line[ptr])) ptr++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
433 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
434 else
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
435 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
436 file_base = ptr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
437 while(ptr < p_line_length && !is_spacing(p_line[ptr])) ptr++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
438 file_length = ptr - file_base;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
439 while(ptr < p_line_length && is_spacing(p_line[ptr])) ptr++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
440 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
441
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
442 type_base = ptr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
443 while(ptr < p_line_length && !is_spacing(p_line[ptr])) ptr++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
444 type_length = ptr - type_base;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
445 while(ptr < p_line_length && is_spacing(p_line[ptr])) ptr++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
446
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
447 if (ptr != p_line_length || file_length == 0 || type_length == 0) pfc::throw_exception_with_message< exception_cue > ("invalid FILE syntax");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
448
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
449 p_callback.on_file(p_line + file_base, file_length, p_line + type_base, type_length);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
450 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
451 else if (!stricmp_utf8_ex(p_line,ptr,"track",pfc_infinite))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
452 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
453 while(ptr < p_line_length && is_spacing(p_line[ptr])) ptr++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
454
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
455 t_size track_base = ptr, track_length;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
456 while(ptr < p_line_length && !is_spacing(p_line[ptr]))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
457 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
458 if (!is_numeric(p_line[ptr])) pfc::throw_exception_with_message< exception_cue > ("invalid TRACK syntax");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
459 ptr++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
460 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
461 track_length = ptr - track_base;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
462 while(ptr < p_line_length && is_spacing(p_line[ptr])) ptr++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
463
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
464 t_size type_base = ptr, type_length;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
465 while(ptr < p_line_length && !is_spacing(p_line[ptr])) ptr++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
466 type_length = ptr - type_base;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
467
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
468 while(ptr < p_line_length && is_spacing(p_line[ptr])) ptr++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
469 if (ptr != p_line_length || type_length == 0) pfc::throw_exception_with_message< exception_cue > ("invalid TRACK syntax");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
470 unsigned track = pfc::atoui_ex(p_line+track_base,track_length);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
471 if (track < 1 || track > maximumCueTrackNumber) pfc::throw_exception_with_message< exception_cue > ("invalid track number");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
472
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
473 p_callback.on_track(track,p_line + type_base, type_length);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
474 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
475 else if (!stricmp_utf8_ex(p_line,ptr,"index",pfc_infinite))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
476 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
477 while(ptr < p_line_length && is_spacing(p_line[ptr])) ptr++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
478
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
479 t_size index_base,index_length, time_base,time_length;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
480 index_base = ptr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
481 while(ptr < p_line_length && !is_spacing(p_line[ptr]))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
482 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
483 if (!is_numeric(p_line[ptr])) pfc::throw_exception_with_message< exception_cue > ("invalid INDEX syntax" );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
484 ptr++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
485 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
486 index_length = ptr - index_base;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
487
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
488 while(ptr < p_line_length && is_spacing(p_line[ptr])) ptr++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
489 time_base = ptr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
490 while(ptr < p_line_length && !is_spacing(p_line[ptr]))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
491 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
492 if (!is_numeric(p_line[ptr]) && p_line[ptr] != ':')
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
493 pfc::throw_exception_with_message< exception_cue > ("invalid INDEX syntax");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
494 ptr++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
495 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
496 time_length = ptr - time_base;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
497
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
498 while(ptr < p_line_length && is_spacing(p_line[ptr])) ptr++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
499
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
500 if (ptr != p_line_length || index_length == 0 || time_length == 0)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
501 pfc::throw_exception_with_message< exception_cue > ("invalid INDEX syntax");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
502
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
503 unsigned index = pfc::atoui_ex(p_line+index_base,index_length);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
504 if (index > maximumCueTrackNumber) pfc::throw_exception_with_message< exception_cue > ("invalid INDEX syntax");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
505 unsigned time = cuesheet_parse_index_time_ticks_e(p_line + time_base,time_length);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
506
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
507 p_callback.on_index(index,time);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
508 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
509 else if (!stricmp_utf8_ex(p_line,ptr,"pregap",pfc_infinite))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
510 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
511 while(ptr < p_line_length && is_spacing(p_line[ptr])) ptr++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
512
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
513 t_size time_base, time_length;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
514 time_base = ptr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
515 while(ptr < p_line_length && !is_spacing(p_line[ptr]))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
516 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
517 if (!is_numeric(p_line[ptr]) && p_line[ptr] != ':')
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
518 pfc::throw_exception_with_message< exception_cue > ("invalid PREGAP syntax");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
519 ptr++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
520 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
521 time_length = ptr - time_base;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
522
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
523 while(ptr < p_line_length && is_spacing(p_line[ptr])) ptr++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
524
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
525 if (ptr != p_line_length || time_length == 0)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
526 pfc::throw_exception_with_message< exception_cue > ("invalid PREGAP syntax");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
527
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
528 unsigned time = cuesheet_parse_index_time_ticks_e(p_line + time_base,time_length);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
529
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
530 p_callback.on_pregap(time);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
531 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
532 else if (!stricmp_utf8_ex(p_line,ptr,"title",pfc_infinite))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
533 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
534 auto arg = cue_line_argument(p_line+ptr, p_line_length-ptr);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
535 if ( arg.m_len > 0 ) p_callback.on_title( arg.m_ptr, arg.m_len );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
536 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
537 else if (!stricmp_utf8_ex(p_line,ptr,"performer",pfc_infinite))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
538 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
539 auto arg = cue_line_argument(p_line + ptr, p_line_length - ptr);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
540 // 2021-01 fix: allow blank performer
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
541 /*if (arg.m_len > 0)*/ p_callback.on_performer(arg.m_ptr, arg.m_len);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
542 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
543 else if (!stricmp_utf8_ex(p_line,ptr,"songwriter",pfc_infinite))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
544 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
545 auto arg = cue_line_argument(p_line + ptr, p_line_length - ptr);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
546 if (arg.m_len > 0) p_callback.on_songwriter(arg.m_ptr, arg.m_len);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
547 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
548 else if (!stricmp_utf8_ex(p_line,ptr,"isrc",pfc_infinite))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
549 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
550 while(ptr < p_line_length && is_spacing(p_line[ptr])) ptr++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
551 t_size length = p_line_length - ptr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
552 if (length == 0) pfc::throw_exception_with_message< exception_cue > ("invalid ISRC syntax");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
553 p_callback.on_isrc(p_line+ptr,length);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
554 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
555 else if (!stricmp_utf8_ex(p_line,ptr,"catalog",pfc_infinite))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
556 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
557 while(ptr < p_line_length && is_spacing(p_line[ptr])) ptr++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
558 t_size length = p_line_length - ptr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
559 if (length == 0) pfc::throw_exception_with_message< exception_cue > ("invalid CATALOG syntax");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
560 p_callback.on_catalog(p_line+ptr,length);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
561 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
562 else if (!stricmp_utf8_ex(p_line,ptr,"flags",pfc_infinite))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
563 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
564 while(ptr < p_line_length && is_spacing(p_line[ptr])) ptr++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
565 if (ptr < p_line_length)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
566 p_callback.on_flags(p_line + ptr, p_line_length - ptr);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
567 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
568 else if (!stricmp_utf8_ex(p_line,ptr,"rem",pfc_infinite))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
569 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
570 while(ptr < p_line_length && is_spacing(p_line[ptr])) ptr++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
571 if (ptr < p_line_length)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
572 p_callback.on_comment(p_line + ptr, p_line_length - ptr);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
573 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
574 else if (!stricmp_utf8_ex(p_line,ptr,"postgap",pfc_infinite)) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
575 pfc::throw_exception_with_message< exception_cue > ("POSTGAP is not supported");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
576 } else if (!stricmp_utf8_ex(p_line,ptr,"cdtextfile",pfc_infinite)) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
577 //do nothing
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
578 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
579 else pfc::throw_exception_with_message< exception_cue > ("unknown cuesheet item");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
580 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
581
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
582 static void g_parse_cue(const char * p_cuesheet,cue_parser_callback & p_callback)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
583 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
584 const char * parseptr = p_cuesheet;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
585 t_size lineidx = 1;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
586 while(*parseptr)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
587 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
588 while(is_spacing(*parseptr)) parseptr++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
589 if (*parseptr)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
590 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
591 t_size length = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
592 while(parseptr[length] && !is_linebreak(parseptr[length])) length++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
593 if (length > 0) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
594 try {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
595 g_parse_cue_line(parseptr,length,p_callback);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
596 } catch(exception_cue const & e) {//rethrow with line info
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
597 pfc::throw_exception_with_message< exception_cue > (PFC_string_formatter() << e.what() << " (line " << (unsigned)lineidx << ")");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
598 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
599 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
600 parseptr += length;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
601 while(is_linebreak(*parseptr)) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
602 if (*parseptr == '\n') lineidx++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
603 parseptr++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
604 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
605 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
606 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
607 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
608
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
609 void cue_parser::parse(const char *p_cuesheet,t_cue_entry_list & p_out) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
610 try {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
611 cue_parser_callback_retrievelist callback(p_out);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
612 g_parse_cue(p_cuesheet,callback);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
613 callback.finalize();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
614 } catch(exception_cue const & e) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
615 pfc::throw_exception_with_message<exception_bad_cuesheet>(PFC_string_formatter() << "Error parsing cuesheet: " << e.what());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
616 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
617 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
618 void cue_parser::parse_info(const char * p_cuesheet,file_info & p_info,unsigned p_index) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
619 try {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
620 cue_parser_callback_retrieveinfo callback(p_info,p_index);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
621 g_parse_cue(p_cuesheet,callback);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
622 callback.finalize();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
623 } catch(exception_cue const & e) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
624 pfc::throw_exception_with_message< exception_bad_cuesheet > (PFC_string_formatter() << "Error parsing cuesheet: " << e.what());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
625 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
626 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
627
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
628 namespace {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
629
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
630 class cue_parser_callback_retrievecount : public cue_parser_callback
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
631 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
632 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
633 cue_parser_callback_retrievecount() : m_count(0) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
634 unsigned get_count() const {return m_count;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
635 void on_file(const char * p_file,t_size p_file_length,const char * p_type,t_size p_type_length) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
636 void on_track(unsigned p_index,const char * p_type,t_size p_type_length) {m_count++;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
637 void on_pregap(unsigned p_value) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
638 void on_index(unsigned p_index,unsigned p_value) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
639 void on_title(const char * p_title,t_size p_title_length) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
640 void on_performer(const char * p_performer,t_size p_performer_length) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
641 void on_isrc(const char * p_isrc,t_size p_isrc_length) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
642 void on_catalog(const char * p_catalog,t_size p_catalog_length) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
643 void on_comment(const char * p_comment,t_size p_comment_length) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
644 void on_flags(const char * p_flags,t_size p_flags_length) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
645 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
646 unsigned m_count;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
647 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
648
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
649 class cue_parser_callback_retrievecreatorentries : public cue_parser_callback
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
650 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
651 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
652 cue_parser_callback_retrievecreatorentries(cue_creator::t_entry_list & p_out) : m_out(p_out), m_track(0), m_pregap(0), m_index0_set(false), m_index1_set(false) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
653
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
654 void on_file(const char * p_file,t_size p_file_length,const char * p_type,t_size p_type_length) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
655 validate_file_type(p_type,p_type_length);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
656 m_file.set_string(p_file,p_file_length);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
657 m_fileType.set_string(p_type, p_type_length);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
658 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
659
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
660 void on_track(unsigned p_index,const char * p_type,t_size p_type_length)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
661 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
662 finalize_track();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
663
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
664 m_trackType.set_string( p_type, p_type_length );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
665
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
666 //if (p_index != m_track + 1) throw exception_cue("cuesheet tracks out of order",0);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
667
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
668 if (m_file.is_empty()) pfc::throw_exception_with_message< exception_cue > ("declaring a track with no file set");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
669 m_trackfile = m_file;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
670 m_trackFileType = m_fileType;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
671 m_track = p_index;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
672 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
673
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
674 void on_pregap(unsigned p_value)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
675 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
676 m_pregap = (double) p_value / 75.0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
677 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
678
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
679 void on_index(unsigned p_index,unsigned p_value)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
680 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
681 if (p_index < t_cuesheet_index_list::count)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
682 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
683 switch(p_index)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
684 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
685 case 0: m_index0_set = true; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
686 case 1: m_index1_set = true; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
687 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
688 m_indexes.m_positions[p_index] = (double) p_value / 75.0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
689 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
690 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
691 void on_title(const char * p_title,t_size p_title_length) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
692 void on_performer(const char * p_performer,t_size p_performer_length) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
693 void on_songwriter(const char * p_performer,t_size p_performer_length) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
694 void on_isrc(const char * p_isrc,t_size p_isrc_length) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
695 void on_catalog(const char * p_catalog,t_size p_catalog_length) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
696 void on_comment(const char * p_comment,t_size p_comment_length) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
697 void finalize()
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
698 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
699 finalize_track();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
700 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
701 void on_flags(const char * p_flags,t_size p_flags_length) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
702 m_flags.set_string(p_flags,p_flags_length);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
703 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
704 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
705 void finalize_track()
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
706 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
707 if ( m_track != 0 ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
708 if (m_track < 1 || m_track > maximumCueTrackNumber) pfc::throw_exception_with_message< exception_cue > ("track number out of range");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
709 if (!m_index1_set) pfc::throw_exception_with_message< exception_cue > ("INDEX 01 not set");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
710 if (!m_index0_set) m_indexes.m_positions[0] = m_indexes.m_positions[1] - m_pregap;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
711 if (!m_indexes.is_valid()) pfc::throw_exception_with_message< exception_cue > ("invalid index list");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
712
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
713 cue_creator::t_entry_list::iterator iter;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
714 iter = m_out.insert_last();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
715 iter->m_track_number = m_track;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
716 iter->m_file = m_trackfile;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
717 iter->m_fileType = m_trackFileType;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
718 iter->m_index_list = m_indexes;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
719 iter->m_flags = m_flags;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
720 iter->m_trackType = m_trackType;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
721 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
722 m_pregap = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
723 m_indexes.reset();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
724 m_index0_set = m_index1_set = false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
725 m_flags.reset();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
726 m_trackType.reset();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
727 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
728
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
729 bool m_index0_set,m_index1_set;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
730 double m_pregap;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
731 unsigned m_track;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
732 cue_creator::t_entry_list & m_out;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
733 pfc::string8 m_file, m_fileType,m_trackfile, m_trackFileType, m_flags, m_trackType;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
734 t_cuesheet_index_list m_indexes;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
735 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
736 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
737
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
738 void cue_parser::parse_full(const char * p_cuesheet,cue_creator::t_entry_list & p_out) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
739 try {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
740 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
741 cue_parser_callback_retrievecreatorentries callback(p_out);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
742 g_parse_cue(p_cuesheet,callback);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
743 callback.finalize();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
744 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
745
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
746 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
747 cue_creator::t_entry_list::iterator iter;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
748 for(iter=p_out.first();iter.is_valid();++iter) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
749 if ( iter->isTrackAudio() ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
750 cue_parser_callback_retrieveinfo callback(iter->m_infos,iter->m_track_number);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
751 g_parse_cue(p_cuesheet,callback);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
752 callback.finalize();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
753 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
754 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
755 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
756 } catch(exception_cue const & e) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
757 pfc::throw_exception_with_message< exception_bad_cuesheet > (PFC_string_formatter() << "Error parsing cuesheet: " << e.what());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
758 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
759 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
760
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
761 namespace file_info_record_helper {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
762 namespace {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
763 class __file_info_record__info__enumerator {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
764 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
765 __file_info_record__info__enumerator(file_info & p_out) : m_out(p_out) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
766 void operator() (const char * p_name, const char * p_value) { m_out.__info_add_unsafe(p_name, p_value); }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
767 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
768 file_info & m_out;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
769 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
770
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
771 class __file_info_record__meta__enumerator {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
772 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
773 __file_info_record__meta__enumerator(file_info & p_out) : m_out(p_out) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
774 template<typename t_value> void operator() (const char * p_name, const t_value & p_value) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
775 t_size index = ~0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
776 for (typename t_value::const_iterator iter = p_value.first(); iter.is_valid(); ++iter) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
777 if (index == ~0) index = m_out.__meta_add_unsafe(p_name, *iter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
778 else m_out.meta_add_value(index, *iter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
779 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
780 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
781 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
782 file_info & m_out;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
783 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
784 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
785
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
786 void file_info_record::from_info(const file_info & p_info) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
787 reset();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
788 m_length = p_info.get_length();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
789 m_replaygain = p_info.get_replaygain();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
790 from_info_overwrite_meta(p_info);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
791 from_info_overwrite_info(p_info);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
792 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
793 void file_info_record::to_info(file_info & p_info) const {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
794 p_info.reset();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
795 p_info.set_length(m_length);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
796 p_info.set_replaygain(m_replaygain);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
797
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
798 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
799 __file_info_record__info__enumerator e(p_info);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
800 m_info.enumerate(e);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
801 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
802 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
803 __file_info_record__meta__enumerator e(p_info);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
804 m_meta.enumerate(e);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
805 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
806 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
807
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
808 void file_info_record::reset() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
809 m_meta.remove_all(); m_info.remove_all();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
810 m_length = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
811 m_replaygain = replaygain_info_invalid;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
812 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
813
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
814 void file_info_record::from_info_overwrite_info(const file_info & p_info) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
815 for (t_size infowalk = 0, infocount = p_info.info_get_count(); infowalk < infocount; ++infowalk) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
816 m_info.set(p_info.info_enum_name(infowalk), p_info.info_enum_value(infowalk));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
817 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
818 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
819 void file_info_record::from_info_overwrite_meta(const file_info & p_info) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
820 for (t_size metawalk = 0, metacount = p_info.meta_get_count(); metawalk < metacount; ++metawalk) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
821 const t_size valuecount = p_info.meta_enum_value_count(metawalk);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
822 if (valuecount > 0) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
823 t_meta_value & entry = m_meta.find_or_add(p_info.meta_enum_name(metawalk));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
824 entry.remove_all();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
825 for (t_size valuewalk = 0; valuewalk < valuecount; ++valuewalk) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
826 entry.add_item(p_info.meta_enum_value(metawalk, valuewalk));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
827 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
828 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
829 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
830 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
831
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
832 void file_info_record::from_info_overwrite_rg(const file_info & p_info) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
833 m_replaygain = replaygain_info::g_merge(m_replaygain, p_info.get_replaygain());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
834 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
835
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
836 void file_info_record::merge_overwrite(const file_info & p_info) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
837 from_info_overwrite_info(p_info);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
838 from_info_overwrite_meta(p_info);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
839 from_info_overwrite_rg(p_info);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
840 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
841
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
842 void file_info_record::transfer_meta_entry(const char * p_name, const file_info & p_info, t_size p_index) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
843 const t_size count = p_info.meta_enum_value_count(p_index);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
844 if (count == 0) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
845 m_meta.remove(p_name);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
846 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
847 t_meta_value & val = m_meta.find_or_add(p_name);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
848 val.remove_all();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
849 for (t_size walk = 0; walk < count; ++walk) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
850 val.add_item(p_info.meta_enum_value(p_index, walk));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
851 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
852 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
853 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
854
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
855 void file_info_record::meta_set(const char * p_name, const char * p_value) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
856 m_meta.find_or_add(p_name).set_single(p_value);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
857 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
858
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
859 const file_info_record::t_meta_value * file_info_record::meta_query_ptr(const char * p_name) const {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
860 return m_meta.query_ptr(p_name);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
861 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
862 size_t file_info_record::meta_value_count(const char* name) const {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
863 auto v = meta_query_ptr(name);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
864 if (v == nullptr) return 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
865 return v->get_count();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
866 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
867
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
868
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
869 void file_info_record::from_info_set_meta(const file_info & p_info) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
870 m_meta.remove_all();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
871 from_info_overwrite_meta(p_info);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
872 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
873
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
874 }