2 * "THE BEER-WARE LICENSE" (Revision 42):
3 * <tobias.rehbein@web.de> wrote this file. As long as you retain this notice
4 * you can do whatever you want with this stuff. If we meet some day, and you
5 * think this stuff is worth it, you can buy me a beer in return.
15 #include <vorbis/vorbisfile.h>
19 #define SAFE_STRNCPY(dst, src, len) do { \
20 strncpy(dst, src, (len)-1); \
21 dst[(len)-1] = '\0'; \
28 static int fill_comments(struct ogg_context
*ctx
, struct ogg_oggfile
*ogg
);
29 static void do_iconv(struct ogg_context
*ctx
, char *in
, char *out
, size_t outlen
);
32 ogg_oggfile_create(struct ogg_context
*ctx
, struct ogg_oggfile
*ogg
, char *filename
)
36 assert(filename
!= NULL
);
38 SAFE_STRNCPY(ogg
->filename
, filename
, sizeof(ogg
->filename
));
39 if (fill_comments(ctx
, ogg
) != 0)
46 fill_comments(struct ogg_context
*ctx
, struct ogg_oggfile
*ogg
)
56 if (ov_fopen(ogg
->filename
, &ovf
) != 0) {
57 warnx("could not open file: %s", ogg
->filename
);
60 if ((ovc
= ov_comment(&ovf
, -1)) == NULL
) {
61 warnx("could not read comments for file: %s", ogg
->filename
);
64 for (i
= 0; i
< ovc
->comments
; i
++) {
65 value
= ovc
->user_comments
[i
];
66 key
= strsep(&value
, "=");
67 if (strcasecmp(key
, "artist") == 0)
68 do_iconv(ctx
, value
, ogg
->artist
, sizeof(ogg
->artist
));
69 else if (strcasecmp(key
, "album") == 0)
70 do_iconv(ctx
, value
, ogg
->album
, sizeof(ogg
->album
));
71 else if (strcasecmp(key
, "title") == 0)
72 do_iconv(ctx
, value
, ogg
->title
, sizeof(ogg
->title
));
73 if (ogg
->artist
== NULL
|| ogg
->album
== NULL
|| ogg
->title
== NULL
) {
74 warnx("insufficient comments for file: %s", ogg
->filename
);
79 if (ov_clear(&ovf
) != 0)
80 warnx("could not close file: %s", ogg
->filename
);
88 struct ogg_context
*ctx
;
91 if ((cd
= iconv_open("char", "UTF-8")) == (iconv_t
) (-1))
93 if ((ctx
= malloc(sizeof(*ctx
))) == NULL
)
102 ogg_context_close(struct ogg_context
*ctx
)
106 if (iconv_close(ctx
->cd
) == -1)
114 do_iconv(struct ogg_context
*ctx
, char *in
, char *out
, size_t outlen
)
118 size_t inlen
= strlen(in
);
128 if (iconv(ctx
->cd
, NULL
, NULL
, outp
, &outlen
) == (size_t) (-1))
129 errx(EX_SOFTWARE
, "could not set initial conversion state");
132 if (iconv(ctx
->cd
, (const char **)inp
, &inlen
, outp
, &outlen
) == (size_t) (-1))
133 errx(EX_SOFTWARE
, "string conversion failed");