#include <lightmediascanner_utils.h>
#include <ctype.h>
#include <stdlib.h>
+#include <string.h>
#include <alloca.h>
/**
}
}
+/**
+ * lms_string_size version of strdup().
+ *
+ * @param dst where to return the duplicated value.
+ * @param src pointer to lms_string_size to be duplicated.
+ *
+ * @return 1 on success, 0 on failure.
+ */
+int
+lms_string_size_dup(struct lms_string_size *dst, const struct lms_string_size *src)
+{
+ if (src->len == 0) {
+ dst->str = NULL;
+ dst->len = 0;
+ return 1;
+ }
+
+ dst->str = malloc(src->len + 1);
+ if (!dst->str) {
+ dst->len = 0;
+ return 0;
+ }
+
+ dst->len = src->len;
+ memcpy(dst->str, src->str, dst->len);
+ dst->str[dst->len] = '\0';
+ return 1;
+}
+
+/**
+ * Similar to lms_string_size_dup(), but from a simple string.
+ *
+ * @param dst where to return the duplicated value.
+ * @param src pointer to string to be duplicated.
+ * @param size size to copy or -1 to auto-calculate.
+ *
+ * @return 1 on success, 0 on failure.
+ */
+int
+lms_string_size_strndup(struct lms_string_size *dst, const char *src, int size)
+{
+ if (size < 0) {
+ if (!src)
+ size = 0;
+ else
+ size = strlen(src);
+ }
+
+ if (size == 0) {
+ dst->str = NULL;
+ dst->len = 0;
+ return 1;
+ }
+
+ dst->str = malloc(size + 1);
+ if (!dst->str) {
+ dst->len = 0;
+ return 0;
+ }
+
+ dst->len = size;
+ memcpy(dst->str, src, dst->len);
+ dst->str[dst->len] = '\0';
+ return 1;
+}
/**
* Find out which of the given extensions matches the given name.
API void lms_strstrip(char *str, unsigned int *p_len) GNUC_NON_NULL(1, 2);
API void lms_strstrip_and_free(char **p_str, unsigned int *p_len) GNUC_NON_NULL(1, 2);
API void lms_string_size_strip_and_free(struct lms_string_size *p) GNUC_NON_NULL(1);
+
+ API int lms_string_size_dup(struct lms_string_size *dst, const struct lms_string_size *src) GNUC_NON_NULL(1, 2);
+ API int lms_string_size_strndup(struct lms_string_size *dst, const char *src, int size) GNUC_NON_NULL(1);
+
API int lms_which_extension(const char *name, unsigned int name_len, const struct lms_string_size *exts, unsigned int exts_len) GNUC_NON_NULL(1, 3);
long ext_idx;
ext_idx = ((long)match) - 1;
- info.title.len = finfo->path_len - finfo->base - _exts[ext_idx].len;
- info.title.str = malloc((info.title.len + 1) * sizeof(char));
- memcpy(info.title.str, finfo->path + finfo->base, info.title.len);
- info.title.str[info.title.len] = '\0';
+ lms_string_size_strndup(&info.title, finfo->path + finfo->base,
+ finfo->path_len - finfo->base - _exts[ext_idx].len);
lms_charset_conv(ctxt->cs_conv, &info.title.str, &info.title.len);
info.id = finfo->id;
for (i = 0; i < tags->data.vorbis_comment.num_comments; i++) {
str = (char *) tags->data.vorbis_comment.comments[i].entry;
len = tags->data.vorbis_comment.comments[i].length;
- if (strncmp(str, "TITLE=", 6) == 0) {
- info.title.str = malloc((len - 6 + 1) * sizeof(char));
- strcpy(info.title.str, str + 6);
- info.title.len = len - 6;
- }
- else if (strncmp(str, "ARTIST=", 7) == 0) {
- info.artist.str = malloc((len - 7 + 1) * sizeof(char));
- strcpy(info.artist.str, str + 7);
- info.artist.len = len - 7;
- }
- else if (strncmp(str, "ALBUM=", 6) == 0) {
- info.album.str = malloc((len - 6 + 1) * sizeof(char));
- strcpy(info.album.str, str + 6);
- info.album.len = len - 6;
- }
- else if (strncmp(str, "GENRE=", 6) == 0) {
- info.genre.str = malloc((len - 6 + 1) * sizeof(char));
- strcpy(info.genre.str, str + 6);
- info.genre.len = len - 6;
- }
+ if (strncmp(str, "TITLE=", 6) == 0)
+ lms_string_size_strndup(&info.title, str + 6, len - 6);
+ else if (strncmp(str, "ARTIST=", 7) == 0)
+ lms_string_size_strndup(&info.artist, str + 7, len - 7);
+ else if (strncmp(str, "ALBUM=", 6) == 0)
+ lms_string_size_strndup(&info.album, str + 7, len - 7);
+ else if (strncmp(str, "GENRE=", 6) == 0)
+ lms_string_size_strndup(&info.genre, str + 6, len - 6);
else if (strncmp(str, "TRACKNUMBER=", 12) == 0)
info.trackno = atoi(str + 12);
}
finfo->path);
ext_idx = ((long)match) - 1;
- info.title.len = finfo->path_len - finfo->base - _exts[ext_idx].len;
- info.title.str = malloc((info.title.len + 1) * sizeof(char));
- memcpy(info.title.str, finfo->path + finfo->base, info.title.len);
- info.title.str[info.title.len] = '\0';
+ lms_string_size_strndup(&info.title, finfo->path + finfo->base,
+ finfo->path_len - finfo->base - _exts[ext_idx].len);
lms_charset_conv(ctxt->cs_conv, &info.title.str, &info.title.len);
info.id = finfo->id;
_get_video_codec(MP4FileHandle mp4_fh, MP4TrackId id)
{
const char *data_name = MP4GetTrackMediaDataName(mp4_fh, id);
- struct lms_string_size ret = {};
+ struct lms_string_size ret = {}, tmp;
char buf[256];
char ofmt[8] = {};
found: /* ugly, but h264 codec is composed in runtime */
- if (ret.str == NULL)
+ if (!lms_string_size_dup(&tmp, &ret))
return nullstr;
- else {
- struct lms_string_size tmp;
-
- tmp.str = malloc(ret.len + 1);
- if (!tmp.str)
- tmp.len = 0;
- else {
- tmp.len = ret.len;
- memcpy(tmp.str, ret.str, ret.len);
- tmp.str[tmp.len] = '\0';
- }
- return tmp;
- }
+ return tmp;
}
static struct lms_string_size
_get_lang(MP4FileHandle mp4_fh, MP4TrackId id)
{
- struct lms_string_size ret = { };
+ struct lms_string_size ret;
char buf[4];
if (!MP4GetTrackLanguage(mp4_fh, id, buf))
if (memcmp(buf, "und", 4) == 0)
return nullstr;
- buf[3] = '\0';
- ret.len = strlen(buf);
- ret.str = malloc(ret.len + 1);
- if (ret.str == NULL)
- ret.len = 0;
- else
- memcpy(ret.str, buf, 4);
+ if (!lms_string_size_strndup(&ret, buf, -1))
+ return nullstr;
return ret;
}
goto fail;
}
-#define STR_FIELD_FROM_TAG(_tags_field, _field) \
- do { \
- if (_tags_field) { \
- _field.len = strlen(_tags_field); \
- _field.str = malloc(_field.len); \
- memcpy(_field.str, _tags_field, _field.len + 1); \
- } \
- } while (0)
-
- STR_FIELD_FROM_TAG(tags->name, info.title);
- STR_FIELD_FROM_TAG(tags->artist, info.artist);
+ lms_string_size_strndup(&info.title, tags->name, -1);
+ lms_string_size_strndup(&info.artist, tags->artist, -1);
/* check if the file contains a video track */
num_tracks = MP4GetNumberOfTracks(mp4_fh, MP4_VIDEO_TRACK_TYPE, 0);
if (stream_type == LMS_STREAM_TYPE_AUDIO) {
MP4TrackId id;
- STR_FIELD_FROM_TAG(tags->album, info.album);
- STR_FIELD_FROM_TAG(tags->genre, info.genre);
+ lms_string_size_strndup(&info.album, tags->album, -1);
+ lms_string_size_strndup(&info.genre, tags->genre, -1);
if (tags->track)
info.trackno = tags->track->index;
static void
_set_lms_info(struct lms_string_size *info, const char *tag)
{
- int size;
-
- if (!info || !tag)
- return;
-
- size = strlen(tag);
-
- if (!size)
+ if (!info)
return;
- info->len = size;
- info->str = malloc(size * sizeof(char));
- memcpy(info->str, tag, size);
+ lms_string_size_strndup(info, tag, -1);
lms_string_size_strip_and_free(info);
}
}
ext_idx = ((long)match) - 1;
- info.title.len = finfo->path_len - finfo->base - _exts[ext_idx].len;
- info.title.str = malloc((info.title.len + 1) * sizeof(char));
- memcpy(info.title.str, finfo->path + finfo->base, info.title.len);
- info.title.str[info.title.len] = '\0';
+ lms_string_size_strndup(&info.title, finfo->path + finfo->base,
+ finfo->path_len - finfo->base - _exts[ext_idx].len);
lms_charset_conv(ctxt->cs_conv, &info.title.str, &info.title.len);
info.id = finfo->id;
long ext_idx;
ext_idx = ((long)match) - 1;
- info.title.len = finfo->path_len - finfo->base - _exts[ext_idx].len;
- info.title.str = malloc((info.title.len + 1) * sizeof(char));
- memcpy(info.title.str, finfo->path + finfo->base, info.title.len);
- info.title.str[info.title.len] = '\0';
+ lms_string_size_strndup(&info.title, finfo->path + finfo->base,
+ finfo->path_len - finfo->base - _exts[ext_idx].len);
lms_charset_conv(ctxt->cs_conv, &info.title.str, &info.title.len);
info.id = finfo->id;