vitunes
 All Data Structures
meta_info.h
1 /*
2  * Copyright (c) 2010, 2011 Ryan Flannery <ryan.flannery@gmail.com>
3  *
4  * Permission to use, copy, modify, and distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 #ifndef META_INFO_H
18 #define META_INFO_H
19 
20 #include "compat/compat.h"
21 
22 #include <ctype.h>
23 #include <limits.h>
24 #include <err.h>
25 #include <errno.h>
26 #include <stdbool.h>
27 #include <stdint.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <strings.h>
32 #include <time.h>
33 
34 /* non-baes includes (just TagLib) */
35 #include <tag_c.h>
36 
37 #include "debug.h"
38 #include "enums.h"
39 
40 /* the character-info fields. used for all meta-info that's shown */
41 #define MI_NUM_CINFO 8
42 #define MI_CINFO_ARTIST 0
43 #define MI_CINFO_ALBUM 1
44 #define MI_CINFO_TITLE 2
45 #define MI_CINFO_TRACK 3
46 #define MI_CINFO_YEAR 4
47 #define MI_CINFO_GENRE 5
48 #define MI_CINFO_LENGTH 6
49 #define MI_CINFO_COMMENT 7
50 
51 /* struct used to represent all meta information from a given file */
52 typedef struct {
53  char *filename; /* filename of file itself */
54  char *cinfo[MI_NUM_CINFO]; /* character meta info array */
55  int length; /* play length in seconds */
56  time_t last_updated; /* last time info was extracted */
57  bool is_url; /* if this is a url */
58 } meta_info;
59 
60 /*
61  * XXX Note in the above that the playlength is stored both numerically
62  * in the member 'length' and as a character string in the cinfo array
63  * in the form "hh:mm:ss"
64  */
65 
66 /* array of human-readable names of each CINFO member */
67 extern const char *MI_CINFO_NAMES[MI_NUM_CINFO];
68 
69 /* create/destroy meta_info structs */
70 meta_info *mi_new(void);
71 void mi_free(meta_info *info);
72 
73 /* read/write meta_info structs to a file */
74 void mi_fwrite(meta_info *mi, FILE *fout);
75 void mi_fread(meta_info *mi, FILE *fin);
76 
77 /* used to extract meta info from a media file */
78 meta_info* mi_extract(const char *filename);
79 
80 
81 /*****************************************************************************
82  * XXX Important Note XXX These functions are used to replace any
83  * non-printable characters in a string -or- any of the cinfo fields of a
84  * meta-info struct. This must be done as some files (sadly, some Aphex Twin)
85  * contain such characters in their meta info, and these characters correspond
86  * to ncurses control sequences, thus mucking-up the display when painted to
87  * the screen. See "vitunes -e help check" for details.
88  * This is NOT called explicitly during mi_extract, and MUST be done
89  * eleswhere (medialib_db_update, medialib_db_scan_dirs, ecmd_addurl, etc.)
90  * This is so that one may use the "check" e-command to see which files have
91  * such characters, and then tag them correctly.
92  ****************************************************************************/
93 
94 void str_sanitize(char *s);
95 void mi_sanitize(meta_info *mi);
96 
97 
98 /*****************************************************************************
99  * Functions used to query meta_info's (i.e. to match them against a given
100  * search/filter). It works by setting-up a global query description which
101  * contains a list of tokens in the search and whether or not each token
102  * should be matched positively/negatively.
103  *
104  * After the global query has been set, mi_match() can be used to compare a
105  * given meta_info against this global query description.
106  ****************************************************************************/
107 
108 /* structure used to describe what to match meta_info's against */
109 #define MI_MAX_QUERY_TOKENS 255
110 typedef struct {
111  char *tokens[MI_MAX_QUERY_TOKENS];
112  char match[MI_MAX_QUERY_TOKENS];
113  int ntokens;
114  char *raw; /* a copy of the original, un-tokenized query */
116 
117 /* flag to indicate if we should include filename when matching */
118 extern bool mi_query_match_filename;
119 
120 /* initialize, set, and clear global query description */
121 void mi_query_init();
122 bool mi_query_isset();
123 void mi_query_clear();
124 void mi_query_add_token(const char *token);
125 
126 void mi_query_setraw(const char *query);
127 const char *mi_query_getraw();
128 
129 /* match a given meta_info/string against the global query description */
130 bool mi_match(const meta_info *mi);
131 bool str_match_query(const char *s);
132 
133 
134 /*****************************************************************************
135  * Functions used to sort meta_info's. These work by setting-up a global
136  * sort description that includes the ordering of the CINFO items to sort and
137  * which, if any, to sort descending.
138  *
139  * Once the global sort description has been setup, mi_compare() can be used
140  * to compare two meta_info's in a way that works with qsort(3), heapsort(3),
141  * or mergesort(3).
142  ****************************************************************************/
143 
144 /* structure used to describe how to sort meta_info structs */
145 typedef struct {
146  int order[MI_NUM_CINFO];
147  bool descending[MI_NUM_CINFO];
148  int nfields;
150 
151 /* initialize, set, and clear global sort description */
152 void mi_sort_init();
153 void mi_sort_clear();
154 int mi_sort_set(const char *str, const char **errmsg);
155 
156 /* compare two meta_info's using the global sort description */
157 int mi_compare(const void *a, const void *b);
158 
159 
160 /*****************************************************************************
161  * Functions to control how to display meta_info's to the screen. These
162  * setup a global description of the display format, which includes an ordered
163  * list of the fields and the width of each field.
164  ****************************************************************************/
165 
166 /* structure used to describe how to display meta_info structs */
167 typedef struct {
168  int nfields;
169  int order[MI_NUM_CINFO];
170  int widths[MI_NUM_CINFO];
171  Direction align[MI_NUM_CINFO];
173 extern mi_display_description mi_display;
174 
175 /* initialize and set the global display description */
176 void mi_display_init();
177 int mi_display_set(const char *str, const char **errmsg);
178 void mi_display_reset();
179 
180 /* convert current display to a string */
181 char *mi_display_tostr();
182 
183 /* get total width of display */
184 int mi_display_getwidth();
185 
186 #endif