metalink_parse_update (3) Linux Manual Page
NAME
metalink_parse_update, metalink_parse_final, metalink_parser_context_new, metalink_parse_context_delete – Parse Metalink file and create metalink_t object.
SYNOPSIS
#include <metalink/metalink_parser.h>
metalink_error_t metalink_parse_update(metalink_parser_context_t *ctx, buf, size_t len);
metalink_error_t metalink_parse_final(metalink_parser_context_t *ctx, buf, size_t len, metalink_t **res);
metalink_parser_context_t* metalink_parser_context_new();
void metalink_parser_context_delete(metalink_parser_context_t *ctx);
DESCRIPTION
These functions privide a push interface for parsing Metalink XML files.
Before calling metalink_parse_update() and metalink_parse_final(), metalink_parse_context_t has to be created by metalink_parser_context_new().
In each call of metalink_parse_update(), len bytes of buf are processed. At the last piece of data, call metalink_parse_final() to get metalink_t(3) structure as a result. Giving 0 as len is permitted.
metalink_parse_final() calls metalink_parser_context_delete() internally to deallocate the memory for passed metalink_parser_context_t. Therefore you don’t have to call metlaink_parser_context_delete() if you call metalink_parse_final(). Otherwise call metalink_parser_context_delete() to free the allocated resource.
You don’t have to allocate memory for metalink_t(3) structure. metalink_parse_final() take the pointer of metalink_t(3) pointer and allocate memory for that pointer.
The caller must free the memory allocated for metalink_t(3) structure using metalink_delete(3) if it is no longer used.
RETURN VALUE
metalink_parse_update(), metalink_parse_final() return 0 for success. When error occurred, non-zero value error code is returned. If error occurred, metalink_parse_final() does not allocate memory for metalink_t. The error codes are described in metalink_error.h.
In case of success, metalink_parser_context_new() allocates memory for metalink_parser_context_t() and returns the pointer to it. In case of failure, metalink_parser_context_new() returns NULL.
metalink_parser_context_delete() returns no value.
EXAMPLE
#include <errno.h>
#include <fcntl.h>
#include <metalink/metalink_parser.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char **argv)
{
metalink_error_t r;
metalink_t *metalink;
metalink_file_t *file;
metalink_checksum_t **checksums;
metalink_parser_context_t *context;
int fd;
char buf[BUFSIZ];
ssize_t length;
context = metalink_parser_context_new();
if (context == NULL) {
fprintf(stderr,
"ERROR: failed to create metalink_parser_context_t
");
exit(EXIT_FAILURE);
}
fd = open("sample.metalink", O_RDONLY);
if (fd == -1) {
fprintf(stderr, "ERROR: open():%s
", strerror(errno));
exit(EXIT_FAILURE);
}
while ((length = TEMP_FAILURE_RETRY(read(fd, buf, sizeof(buf)))) != 0) {
r = metalink_parse_update(context, buf, length);
if (r != 0) {
fprintf(stderr, "ERROR: code=%d
", r);
metalink_parser_context_delete(context);
exit(EXIT_FAILURE);
}
}
if (length == -1) {
fprintf(stderr, "ERROR: read():%s
", strerror(errno));
metalink_parser_context_delete(context);
exit(EXIT_FAILURE);
}
r = metalink_parse_final(context, NULL, 0, &metalink);
if (r != 0) {
fprintf(stderr, "ERROR: code=%d
", r);
exit(EXIT_FAILURE);
}
TEMP_FAILURE_RETRY(close(fd));
file = metalink->files[0];
printf("name: %s
", file->name);
printf("size: %lld
", file->size);
printf("os : %s
", file->os);
if (file->checksums) {
checksums = file->checksums;
while (*checksums) {
printf("hash: %s %s
", (*checksums)->type, (*checksums)->hash);
++checksums;
}
}
if (file->chunk_checksum) {
size_t count = 0;
metalink_piece_hash_t **piece_hashes;
printf("chunk checksum: size=%d, type=%s
",
file->chunk_checksum->length,
file->chunk_checksum->type);
printf("first 5 piece hashes...
");
piece_hashes = file->chunk_checksum->piece_hashes;
while (*piece_hashes && count < 5) {
printf("piece=%d, hash=%s
", (*piece_hashes)->piece,
(*piece_hashes)->hash);
++piece_hashes;
++count;
}
printf("...
");
}
if (file->resources) {
size_t count = 0;
metalink_resource_t **resources;
printf("first 5 resources...
");
resources = file->resources;
while (*resources && count < 5) {
printf("type=%s, location=%s, preference=%d, url=%s
",
(*resources)->type, (*resources)->location,
(*resources)->preference, (*resources)->url);
++resources;
++count;
}
printf("...
");
}
/* delete metalink_t */
metalink_delete(metalink);
return EXIT_SUCCESS;
}
SEE ALSO
metalink_delete(3), metalink_parse_file(3), metalink_t(3)
