1
+ #include <stdio.h>
2
+ #include <string.h>
3
+
4
+ #define ST_HEADER 0
5
+ #define ST_TITLE 1
6
+ #define ST_ARTIST 2
7
+ #define ST_ALBUM 3
8
+ #define ST_YEAR 4
9
+ #define ST_COMMENT 5
10
+ #define ST_BYTE_ZERO 6
11
+ #define ST_NUMBER 7
12
+ #define ST_GENRE 8
13
+
14
+ #define LEN_HEADER 3
15
+ #define LEN_TITLE 30
16
+ #define LEN_ARTIST 30
17
+ #define LEN_ALBUM 30
18
+ #define LEN_YEAR 4
19
+ #define LEN_COMMENT 30
20
+ #define POS_BYTE_ZERO 28
21
+ #define POS_NUMBER 29
22
+
23
+ const char GENRE_LIST [126 ][32 ] =
24
+ {
25
+ "Blues" ,
26
+ "Classic Rock" ,
27
+ "Country" ,
28
+ "Dance" ,
29
+ "Disco" ,
30
+ "Funk" ,
31
+ "Grunge" ,
32
+ "Hip-Hop" ,
33
+ "Jazz" ,
34
+ "Metal" ,
35
+ "New Age" ,
36
+ "Oldies" ,
37
+ "Other" ,
38
+ "Pop" ,
39
+ "R&B" ,
40
+ "Rap" ,
41
+ "Reggae" ,
42
+ "Rock" ,
43
+ "Techno" ,
44
+ "Industrial" ,
45
+ "Alternative" ,
46
+ "Ska" ,
47
+ "Death Metal" ,
48
+ "Pranks" ,
49
+ "Soundtrack" ,
50
+ "Euro-Techno" ,
51
+ "Ambient" ,
52
+ "Trip-Hop" ,
53
+ "Vocal" ,
54
+ "Jazz+Funk" ,
55
+ "Fusion" ,
56
+ "Trance" ,
57
+ "Classical" ,
58
+ "Instrumental" ,
59
+ "Acid" ,
60
+ "House" ,
61
+ "Game" ,
62
+ "Sound Clip" ,
63
+ "Gospel" ,
64
+ "Noise" ,
65
+ "AlternRock" ,
66
+ "Bass" ,
67
+ "Soul" ,
68
+ "Punk" ,
69
+ "Space" ,
70
+ "Meditative" ,
71
+ "Instrumental Pop" ,
72
+ "Instrumental Rock" ,
73
+ "Ethnic" ,
74
+ "Gothic" ,
75
+ "Darkwave" ,
76
+ "Techno-Industrial" ,
77
+ "Electronic" ,
78
+ "Pop-Folk" ,
79
+ "Eurodance" ,
80
+ "Dream" ,
81
+ "Southern Rock" ,
82
+ "Comedy" ,
83
+ "Cult" ,
84
+ "Gangsta" ,
85
+ "Top 40" ,
86
+ "Christian Rap" ,
87
+ "Pop/Funk" ,
88
+ "Jungle" ,
89
+ "Native American" ,
90
+ "Cabaret" ,
91
+ "New Wave" ,
92
+ "Psychadelic" ,
93
+ "Rave" ,
94
+ "Showtunes" ,
95
+ "Trailer" ,
96
+ "Lo-Fi" ,
97
+ "Tribal" ,
98
+ "Acid Punk" ,
99
+ "Acid Jazz" ,
100
+ "Polka" ,
101
+ "Retro" ,
102
+ "Musical" ,
103
+ "Rock & Roll" ,
104
+ "Hard Rock" ,
105
+ };
106
+
107
+
108
+ int main (int argc , char * * argv ){
109
+ FILE * file ;
110
+ char header [LEN_HEADER + 1 ], title [LEN_TITLE + 1 ], artist [LEN_ARTIST + 1 ],
111
+ album [LEN_ALBUM + 1 ], year [LEN_YEAR + 1 ],comment [LEN_COMMENT + 1 ], genre [32 ];
112
+
113
+ unsigned char byte_zero , number , genre_byte ;
114
+
115
+ // open the file for reading
116
+ file = fopen (argv [1 ], "r" );
117
+ if (!file )
118
+ {
119
+ printf ("Erro a abrir %s\n" , argv [1 ]);
120
+ return -1 ;
121
+ }
122
+
123
+ // jump to the last 128 bytes of the file
124
+ fseek (file , -128 , SEEK_END );
125
+
126
+ // read metadata
127
+ int state = ST_HEADER , n_read ;
128
+ switch (state )
129
+ {
130
+ case ST_HEADER :
131
+ n_read = fread (header , 1 , LEN_HEADER , file );
132
+ if (n_read != LEN_HEADER )
133
+ {
134
+ printf ("%d: leitura inválida, %d/%d bytes lidos\n" ,
135
+ state , n_read , LEN_HEADER );
136
+ return -1 ;
137
+ }
138
+ header [LEN_HEADER ] = '\0' ;
139
+ if (strcmp (header , "TAG" ))
140
+ {
141
+ printf ("Cabeçalho inválido, %s\n" , header );
142
+ return -1 ;
143
+ }
144
+ else state = ST_TITLE ;
145
+
146
+ case ST_TITLE :
147
+ n_read = fread (title , 1 , LEN_TITLE , file );
148
+ if (n_read != LEN_TITLE )
149
+ {
150
+ printf ("%d: leitura inválida, %d/%d bytes lidos\n" ,
151
+ state , n_read , LEN_TITLE );
152
+ return -1 ;
153
+ }
154
+ title [LEN_TITLE ] = '\0' ;
155
+ state = ST_ARTIST ;
156
+
157
+ case ST_ARTIST :
158
+ n_read = fread (artist , 1 , LEN_ARTIST , file );
159
+ if (n_read != LEN_ARTIST )
160
+ {
161
+ printf ("%d: leitura inválida, %d/%d bytes lidos\n" ,
162
+ state , n_read , LEN_ARTIST );
163
+ return -1 ;
164
+ }
165
+ artist [LEN_ARTIST ] = '\0' ;
166
+ state = ST_ALBUM ;
167
+
168
+ case ST_ALBUM :
169
+ n_read = fread (album , 1 , LEN_ALBUM , file );
170
+ if (n_read != LEN_ALBUM )
171
+ {
172
+ printf ("%d: leitura inválida, %d/%d bytes lidos\n" ,
173
+ state , n_read , LEN_ALBUM );
174
+ return -1 ;
175
+ }
176
+ album [LEN_ALBUM ] = '\0' ;
177
+ state = ST_YEAR ;
178
+
179
+ case ST_YEAR :
180
+ n_read = fread (year , 1 , LEN_YEAR , file );
181
+ if (n_read != LEN_YEAR )
182
+ {
183
+ printf ("%d: leitura inválida, %d/%d bytes lidos\n" ,
184
+ state , n_read , LEN_YEAR );
185
+ return -1 ;
186
+ }
187
+ year [LEN_YEAR ] = '\0' ;
188
+ state = ST_COMMENT ;
189
+
190
+ case ST_COMMENT :
191
+ n_read = fread (comment , 1 , LEN_COMMENT , file );
192
+ if (n_read != LEN_COMMENT )
193
+ {
194
+ printf ("%d: leitura inválida, %d/%d bytes lidos\n" ,
195
+ state , n_read , LEN_COMMENT );
196
+ return -1 ;
197
+ }
198
+ state = ST_BYTE_ZERO ;
199
+
200
+ case ST_BYTE_ZERO :
201
+ byte_zero = comment [POS_BYTE_ZERO ];
202
+ if (!(int )byte_zero )
203
+ {
204
+ comment [POS_BYTE_ZERO ] = '\0' ;
205
+ state = ST_NUMBER ;
206
+ }
207
+ else
208
+ {
209
+ comment [LEN_COMMENT ] = '\0' ;
210
+ state = ST_GENRE ;
211
+ }
212
+
213
+ case ST_NUMBER :
214
+ number = comment [POS_NUMBER ];
215
+ state = ST_GENRE ;
216
+
217
+ case ST_GENRE :
218
+ n_read = fread (& genre_byte , 1 , 1 , file );
219
+ if (n_read != 1 )
220
+ {
221
+ printf ("%d: leitura inválida, %d/%d bytes lidos\n" ,
222
+ state , n_read , 1 );
223
+ return -1 ;
224
+ }
225
+ strcpy (genre , GENRE_LIST [(int )genre_byte ]);
226
+ break ;
227
+
228
+ default :
229
+ printf ("Default case reached\n" );
230
+ return -1 ;
231
+ }
232
+ fclose (file );
233
+
234
+ printf ("Título: %s\n" , title );
235
+ printf ("Artista: %s\n" , artist );
236
+ printf ("Álbum: %s\n" , album );
237
+ printf ("Ano: %s\n" , year );
238
+ printf ("Comentário: %s\n" , comment );
239
+ if (!(int )byte_zero )
240
+ printf ("Número: %d\n" , (int )number );
241
+ printf ("Género: %s\n" , genre );
242
+
243
+ return 0 ;
244
+ }
0 commit comments