Пример #1
0
Файл: cue.c Проект: ThreeGe/mpv
struct cue_file *mp_parse_cue(struct bstr data)
{
    struct cue_file *f = talloc_zero(NULL, struct cue_file);
    f->tags = talloc_zero(f, struct mp_tags);

    data = skip_utf8_bom(data);

    char *filename = NULL;
    // Global metadata, and copied into new tracks.
    struct cue_track proto_track = {0};
    struct cue_track *cur_track = NULL;

    while (data.len) {
        struct bstr param;
        int cmd = read_cmd(&data, &param);
        switch (cmd) {
        case CUE_ERROR:
            talloc_free(f);
            return NULL;
        case CUE_TRACK: {
            MP_TARRAY_GROW(f, f->tracks, f->num_tracks);
            f->num_tracks += 1;
            cur_track = &f->tracks[f->num_tracks - 1];
            *cur_track = proto_track;
            cur_track->tags = talloc_zero(f, struct mp_tags);
            break;
        }
        case CUE_TITLE:
        case CUE_PERFORMER: {
            static const char *metanames[] = {
                [CUE_TITLE] = "title",
                [CUE_PERFORMER] = "performer",
            };
            struct mp_tags *tags = cur_track ? cur_track->tags : f->tags;
            mp_tags_set_bstr(tags, bstr0(metanames[cmd]), param);
            break;
        }
        case CUE_INDEX: {
            int type = read_int_2(&param);
            double time = read_time(&param);
            if (cur_track) {
                if (type == 1) {
                    cur_track->start = time;
                    cur_track->filename = filename;
                } else if (type == 0) {
                    cur_track->pregap_start = time;
                }
            }
            break;
        }
        case CUE_FILE:
            // NOTE: FILE comes before TRACK, so don't use cur_track->filename
            filename = read_quoted(f, &param);
            break;
        }
    }

    return f;
}
Пример #2
0
pal::string_t fx_muxer_t::resolve_cli_version(const pal::string_t& global_json)
{
    trace::verbose(_X("--- Resolving CLI version from global json [%s]"), global_json.c_str());

    pal::string_t retval;
    if (!pal::file_exists(global_json))
    {
        trace::verbose(_X("[%s] does not exist"), global_json.c_str());
        return retval;
    }

    pal::ifstream_t file(global_json);
    if (!file.good())
    {
        trace::verbose(_X("[%s] could not be opened"), global_json.c_str());
        return retval;
    }

    if (skip_utf8_bom(&file))
    {
        trace::verbose(_X("UTF-8 BOM skipped while reading [%s]"), global_json.c_str());
    }

    try
    {
        const auto root = json_value::parse(file);
        const auto& json = root.as_object();
        const auto sdk_iter = json.find(_X("sdk"));
        if (sdk_iter == json.end() || sdk_iter->second.is_null())
        {
            trace::verbose(_X("CLI '/sdk/version' field not present/null in [%s]"), global_json.c_str());
            return retval;
        }

        const auto& sdk_obj = sdk_iter->second.as_object();
        const auto ver_iter = sdk_obj.find(_X("version"));
        if (ver_iter == sdk_obj.end() || ver_iter->second.is_null())
        {
            trace::verbose(_X("CLI 'sdk/version' field not present/null in [%s]"), global_json.c_str());
            return retval;
        }
        retval = ver_iter->second.as_string();
    }
    catch (const std::exception& je)
    {
        pal::string_t jes;
        (void) pal::utf8_palstring(je.what(), &jes);
        trace::error(_X("A JSON parsing exception occurred in [%s]: %s"), global_json.c_str(), jes.c_str());
    }
    trace::verbose(_X("CLI version is [%s] in global json file [%s]"), retval.c_str(), global_json.c_str());
    return retval;
}
Пример #3
0
/**
 * Resolve the hostpolicy version from deps.
 *  - Scan the deps file's libraries section and find the hostpolicy version in the file.
 */
pal::string_t resolve_hostpolicy_version_from_deps(const pal::string_t& deps_json)
{
    trace::verbose(_X("--- Resolving %s version from deps json [%s]"), LIBHOSTPOLICY_NAME, deps_json.c_str());

    pal::string_t retval;
    if (!pal::file_exists(deps_json))
    {
        trace::verbose(_X("Dependency manifest [%s] does not exist"), deps_json.c_str());
        return retval;
    }

    pal::ifstream_t file(deps_json);
    if (!file.good())
    {
        trace::verbose(_X("Dependency manifest [%s] could not be opened"), deps_json.c_str());
        return retval;
    }

    if (skip_utf8_bom(&file))
    {
        trace::verbose(_X("UTF-8 BOM skipped while reading [%s]"), deps_json.c_str());
    }

    try
    {
        const auto root = json_value::parse(file);
        const auto& json = root.as_object();
        const auto& libraries = json.at(_X("libraries")).as_object();

        // Look up the root package instead of the "runtime" package because we can't do a full rid resolution.
        // i.e., look for "Microsoft.NETCore.DotNetHostPolicy/" followed by version.
        pal::string_t prefix = _X("Microsoft.NETCore.DotNetHostPolicy/");
        for (const auto& library : libraries)
        {
            if (starts_with(library.first, prefix, false))
            {
                // Extract the version information that occurs after '/'
                retval = library.first.substr(prefix.size());
                break;
            }
        }
    }
    catch (const std::exception& je)
    {
        pal::string_t jes;
        (void)pal::utf8_palstring(je.what(), &jes);
        trace::error(_X("A JSON parsing exception occurred in [%s]: %s"), deps_json.c_str(), jes.c_str());
    }
    trace::verbose(_X("Resolved version %s from dependency manifest file [%s]"), retval.c_str(), deps_json.c_str());
    return retval;
}
Пример #4
0
Файл: cue.c Проект: ThreeGe/mpv
// Check if the text in data is most likely CUE data. This is used by the
// demuxer code to check the file type.
// data is the start of the probed file, possibly cut off at a random point.
bool mp_probe_cue(struct bstr data)
{
    bool valid = false;
    data = skip_utf8_bom(data);
    for (;;) {
        enum cue_command cmd = read_cmd(&data, NULL);
        // End reached. Since the line was most likely cut off, don't use the
        // result of the last parsing call.
        if (data.len == 0)
            break;
        if (cmd == CUE_ERROR)
            return false;
        if (cmd != CUE_EMPTY)
            valid = true;
    }
    return valid;
}
Пример #5
0
// -----------------------------------------------------------------------------
// Load the deps file and parse its "entry" lines which contain the "fields" of
// the entry. Populate an array of these entries.
//
bool deps_json_t::load(bool portable, const pal::string_t& deps_path, const rid_fallback_graph_t& rid_fallback_graph)
{
    m_file_exists = pal::file_exists(deps_path);

    // If file doesn't exist, then assume parsed.
    if (!m_file_exists)
    {
        trace::verbose(_X("Could not locate the dependencies manifest file [%s]. Some libraries may fail to resolve."), deps_path.c_str());
        return true;
    }

    // Somehow the file stream could not be opened. This is an error.
    pal::ifstream_t file(deps_path);
    if (!file.good())
    {
        trace::error(_X("Could not open dependencies manifest file [%s]"), deps_path.c_str());
        return false;
    }

    if (skip_utf8_bom(&file))
    {
        trace::verbose(_X("UTF-8 BOM skipped while reading [%s]"), deps_path.c_str());
    }

    try
    {
        const auto json = json_value::parse(file);

        const auto& runtime_target = json.at(_X("runtimeTarget"));

        const pal::string_t& name = runtime_target.is_string()?
            runtime_target.as_string():
            runtime_target.at(_X("name")).as_string();

        trace::verbose(_X("Loading deps file... %s as portable=[%d]"), deps_path.c_str(), portable);

        return (portable) ? load_portable(json, name, rid_fallback_graph) : load_standalone(json, name);
    }
    catch (const std::exception& je)
    {
        pal::string_t jes;
        (void) pal::utf8_palstring(je.what(), &jes);
        trace::error(_X("A JSON parsing exception occurred in [%s]: %s"), deps_path.c_str(), jes.c_str());
        return false;
    }
}
Пример #6
0
static struct attr_stack *read_attr_from_file(const char *path, int macro_ok)
{
	FILE *fp = fopen_or_warn(path, "r");
	struct attr_stack *res;
	char buf[2048];
	int lineno = 0;

	if (!fp)
		return NULL;
	res = xcalloc(1, sizeof(*res));
	while (fgets(buf, sizeof(buf), fp)) {
		char *bufp = buf;
		if (!lineno)
			skip_utf8_bom(&bufp, strlen(bufp));
		handle_attr_line(res, bufp, path, ++lineno, macro_ok);
	}
	fclose(fp);
	return res;
}
Пример #7
0
int add_excludes_from_file_to_list(const char *fname,
				   const char *base,
				   int baselen,
				   struct exclude_list *el,
				   int check_index)
{
	struct stat st;
	int fd, i, lineno = 1;
	size_t size = 0;
	char *buf, *entry;

	fd = open(fname, O_RDONLY);
	if (fd < 0 || fstat(fd, &st) < 0) {
		if (errno != ENOENT)
			warn_on_inaccessible(fname);
		if (0 <= fd)
			close(fd);
		if (!check_index ||
		    (buf = read_skip_worktree_file_from_index(fname, &size)) == NULL)
			return -1;
		if (size == 0) {
			free(buf);
			return 0;
		}
		if (buf[size-1] != '\n') {
			buf = xrealloc(buf, size+1);
			buf[size++] = '\n';
		}
	} else {
		size = xsize_t(st.st_size);
		if (size == 0) {
			close(fd);
			return 0;
		}
		buf = xmalloc(size+1);
		if (read_in_full(fd, buf, size) != size) {
			free(buf);
			close(fd);
			return -1;
		}
		buf[size++] = '\n';
		close(fd);
	}

	el->filebuf = buf;

	if (skip_utf8_bom(&buf, size))
		size -= buf - el->filebuf;

	entry = buf;

	for (i = 0; i < size; i++) {
		if (buf[i] == '\n') {
			if (entry != buf + i && entry[0] != '#') {
				buf[i - (i && buf[i-1] == '\r')] = 0;
				trim_trailing_spaces(entry);
				add_exclude(entry, base, baselen, el, lineno);
			}
			lineno++;
			entry = buf + i + 1;
		}
	}
	return 0;
}
Пример #8
0
Dict* dict_text_new(const char* filename) {
  TextDict* text_dictionary;

  text_dictionary = (TextDict*)malloc(sizeof(TextDict));
  text_dictionary->entry_count = INITIAL_DICTIONARY_SIZE;
  text_dictionary->max_length = 0;
  text_dictionary->lexicon = (TextEntry*)malloc(
    sizeof(TextEntry) * text_dictionary->entry_count);
  text_dictionary->word_buff = NULL;

  static char buff[ENTRY_BUFF_SIZE];

  FILE* fp = fopen(filename, "r");

  if (fp == NULL) {
    dict_text_delete((Dict*)text_dictionary);
    return (Dict*)-1;
  }
  skip_utf8_bom(fp);

  size_t i = 0;

  while (fgets(buff, ENTRY_BUFF_SIZE, fp)) {
    if (i >= text_dictionary->entry_count) {
      text_dictionary->entry_count += text_dictionary->entry_count;
      text_dictionary->lexicon = (TextEntry*)realloc(
        text_dictionary->lexicon,
        sizeof(TextEntry) * text_dictionary->entry_count
        );
    }

    if (parse_entry(buff, text_dictionary->lexicon + i) == -1) {
      text_dictionary->entry_count = i;
      dict_text_delete((Dict*)text_dictionary);
      return (Dict*)-1;
    }

    size_t length = ucs4len(text_dictionary->lexicon[i].key);

    if (length > text_dictionary->max_length) {
      text_dictionary->max_length = length;
    }

    i++;
  }

  fclose(fp);

  text_dictionary->entry_count = i;
  text_dictionary->lexicon = (TextEntry*)realloc(
    text_dictionary->lexicon,
    sizeof(TextEntry) * text_dictionary->entry_count
    );
  text_dictionary->word_buff = (ucs4_t*)
                               malloc(sizeof(ucs4_t) *
                                      (text_dictionary->max_length + 1));

  qsort(text_dictionary->lexicon,
        text_dictionary->entry_count,
        sizeof(text_dictionary->lexicon[0]),
        qsort_entry_cmp
        );

  return (Dict*)text_dictionary;
}
Пример #9
0
void build_cue_timeline(struct MPContext *mpctx)
{
    void *ctx = talloc_new(NULL);

    struct bstr data = mpctx->demuxer->file_contents;
    data = skip_utf8_bom(data);

    struct cue_track *tracks = NULL;
    size_t track_count = 0;

    struct bstr filename = {0};
    // Global metadata, and copied into new tracks.
    struct cue_track proto_track = {0};
    struct cue_track *cur_track = &proto_track;

    while (data.len) {
        struct bstr param;
        switch (read_cmd(&data, &param)) {
        case CUE_ERROR:
            mp_msg(MSGT_CPLAYER, MSGL_ERR, "CUE: error parsing input file!\n");
            goto out;
        case CUE_TRACK: {
            track_count++;
            tracks = talloc_realloc(ctx, tracks, struct cue_track, track_count);
            cur_track = &tracks[track_count - 1];
            *cur_track = proto_track;
            break;
        }
        case CUE_TITLE:
            cur_track->title = read_quoted(&param);
            break;
        case CUE_INDEX: {
            int type = read_int_2(&param);
            double time = read_time(&param);
            if (type == 1) {
                cur_track->start = time;
                cur_track->filename = filename;
            } else if (type == 0) {
                cur_track->pregap_start = time;
            }
            break;
        }
        case CUE_FILE:
            // NOTE: FILE comes before TRACK, so don't use cur_track->filename
            filename = read_quoted(&param);
            break;
        }
    }

    if (track_count == 0) {
        mp_msg(MSGT_CPLAYER, MSGL_ERR, "CUE: no tracks found!\n");
        goto out;
    }

    // Remove duplicate file entries. This might be too sophisticated, since
    // CUE files usually use either separate files for every single track, or
    // only one file for all tracks.

    struct bstr *files = 0;
    size_t file_count = 0;

    for (size_t n = 0; n < track_count; n++) {
        struct cue_track *track = &tracks[n];
        track->source = -1;
        for (size_t file = 0; file < file_count; file++) {
            if (bstrcmp(files[file], track->filename) == 0) {
                track->source = file;
                break;
            }
        }
        if (track->source == -1) {
            file_count++;
            files = talloc_realloc(ctx, files, struct bstr, file_count);
            files[file_count - 1] = track->filename;
            track->source = file_count - 1;
        }
    }
Пример #10
0
static struct bstr read_quoted(struct bstr *data)
{
    *data = bstr_lstrip(*data);
    if (!eat_char(data, '"'))
        return (struct bstr) {0};
    int end = bstrchr(*data, '"');
    if (end < 0)
        return (struct bstr) {0};
    struct bstr res = bstr_splice(*data, 0, end);
    *data = bstr_cut(*data, end + 1);
    return res;
}

// Read a 2 digit unsigned decimal integer.
// Return -1 on failure.
static int read_int_2(struct bstr *data)
{
    *data = bstr_lstrip(*data);
    if (data->len && data->start[0] == '-')
        return -1;
    struct bstr s = *data;
    int res = (int)bstrtoll(s, &s, 10);
    if (data->len == s.len || data->len - s.len > 2)
        return -1;
    *data = s;
    return res;
}

static double read_time(struct bstr *data)
{
    struct bstr s = *data;
    bool ok = true;
    double t1 = read_int_2(&s);
    ok = eat_char(&s, ':') && ok;
    double t2 = read_int_2(&s);
    ok = eat_char(&s, ':') && ok;
    double t3 = read_int_2(&s);
    ok = ok && t1 >= 0 && t2 >= 0 && t3 >= 0;
    return ok ? t1 * 60.0 + t2 + t3 * SECS_PER_CUE_FRAME : 0;
}

static struct bstr skip_utf8_bom(struct bstr data)
{
    return bstr_startswith0(data, "\xEF\xBB\xBF") ? bstr_cut(data, 3) : data;
}

// Check if the text in data is most likely CUE data. This is used by the
// demuxer code to check the file type.
// data is the start of the probed file, possibly cut off at a random point.
bool mp_probe_cue(struct bstr data)
{
    bool valid = false;
    data = skip_utf8_bom(data);
    for (;;) {
        enum cue_command cmd = read_cmd(&data, NULL);
        // End reached. Since the line was most likely cut off, don't use the
        // result of the last parsing call.
        if (data.len == 0)
            break;
        if (cmd == CUE_ERROR)
            return false;
        if (cmd != CUE_EMPTY)
            valid = true;
    }
    return valid;
}