Commit 39748e15 authored by Petri Hintukainen's avatar Petri Hintukainen

disc: add simple persistent storage

parent 526178b5
......@@ -113,6 +113,8 @@ libbluray_la_SOURCES = \
src/libbluray/disc/disc.h \
src/libbluray/disc/disc.c \
src/libbluray/disc/enc_info.h \
src/libbluray/disc/properties.h \
src/libbluray/disc/properties.c \
src/libbluray/hdmv/hdmv_insn.h \
src/libbluray/hdmv/hdmv_vm.h \
src/libbluray/hdmv/hdmv_vm.c \
......
......@@ -345,6 +345,11 @@ const uint8_t *dec_data(BD_DEC *dec, int type)
return NULL;
}
const uint8_t *dec_disc_id(BD_DEC *dec)
{
return dec_data(dec, BD_AACS_DISC_ID);
}
void dec_start(BD_DEC *dec, uint32_t num_titles)
{
if (num_titles == 0) {
......
......@@ -53,6 +53,7 @@ BD_PRIVATE void dec_close(BD_DEC **);
/* get decoder data */
BD_PRIVATE const uint8_t *dec_data(BD_DEC *, int type);
BD_PRIVATE const uint8_t *dec_disc_id(BD_DEC *);
/* status events from upper layers */
BD_PRIVATE void dec_start(BD_DEC *, uint32_t num_titles);
......
/*
* This file is part of libbluray
* Copyright (C) 2014 Petri Hintukainen <phintuka@users.sourceforge.net>
* Copyright (C) 2014-2017 Petri Hintukainen <phintuka@users.sourceforge.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
......@@ -24,6 +24,7 @@
#include "disc.h"
#include "dec.h"
#include "properties.h"
#include "util/logging.h"
#include "util/macro.h"
......@@ -31,8 +32,10 @@
#include "util/strutl.h"
#include "file/file.h"
#include "file/mount.h"
#include "file/dirs.h"
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#ifdef ENABLE_UDF
......@@ -41,6 +44,7 @@
struct bd_disc {
BD_MUTEX ovl_mutex; /* protect access to overlay root */
BD_MUTEX properties_mutex; /* protect access to properties file */
char *disc_root; /* disc filesystem root (if disc is mounted) */
char *overlay_root; /* overlay filesystem root (if set) */
......@@ -53,6 +57,7 @@ struct bd_disc {
void (*pf_fs_close)(void *);
const char *udf_volid;
char *properties_file; /* NULL if not yet used */
int8_t avchd; /* -1 - unknown. 0 - no. 1 - yes */
};
......@@ -265,6 +270,7 @@ static BD_DISC *_disc_init()
BD_DISC *p = calloc(1, sizeof(BD_DISC));
if (p) {
bd_mutex_init(&p->ovl_mutex);
bd_mutex_init(&p->properties_mutex);
/* default file access functions */
p->fs_handle = (void*)p;
......@@ -351,8 +357,10 @@ void disc_close(BD_DISC **pp)
}
bd_mutex_destroy(&p->ovl_mutex);
bd_mutex_destroy(&p->properties_mutex);
X_FREE(p->disc_root);
X_FREE(p->properties_file);
X_FREE(*pp);
}
}
......@@ -573,6 +581,84 @@ int disc_cache_bdrom_file(BD_DISC *p, const char *rel_path, const char *cache_pa
return 0;
}
/*
* persistent properties storage
*/
static char *_properties_file(BD_DISC *p)
{
const uint8_t *disc_id = NULL;
uint8_t pseudo_id[20];
char id_type, id_str[41];
char *cache_home;
char *properties_file;
cache_home = file_get_cache_home();
if (!cache_home) {
return NULL;
}
/* get disc ID */
if (p->dec) {
id_type = 'A';
disc_id = dec_disc_id(p->dec);
}
if (!disc_id) {
id_type = 'P';
disc_pseudo_id(p, pseudo_id);
disc_id = pseudo_id;
}
properties_file = str_printf("%s" DIR_SEP "bluray" DIR_SEP "properties" DIR_SEP "%c%s",
cache_home, id_type,
str_print_hex(id_str, disc_id, 20));
X_FREE(cache_home);
return properties_file;
}
static int _ensure_properties_file(BD_DISC *p)
{
bd_mutex_lock(&p->properties_mutex);
if (!p->properties_file) {
p->properties_file = _properties_file(p);
}
bd_mutex_unlock(&p->properties_mutex);
return p->properties_file ? 0 : -1;
}
int disc_property_put(BD_DISC *p, const char *property, const char *val)
{
int result;
if (_ensure_properties_file(p) < 0) {
return -1;
}
bd_mutex_lock(&p->properties_mutex);
result = properties_put(p->properties_file, property, val);
bd_mutex_unlock(&p->properties_mutex);
return result;
}
char *disc_property_get(BD_DISC *p, const char *property)
{
char *result;
if (_ensure_properties_file(p) < 0) {
return NULL;
}
bd_mutex_lock(&p->properties_mutex);
result = properties_get(p->properties_file, property);
bd_mutex_unlock(&p->properties_mutex);
return result;
}
/*
* streams
*/
......
......@@ -91,6 +91,17 @@ BD_PRIVATE struct bd_dir_s *disc_open_bdrom_dir(BD_DISC *disc, const char *path
BD_PRIVATE struct bd_file_s *disc_open_stream(BD_DISC *disc, const char *file);
/*
* Store / fetch persistent properties for disc.
* Data is stored in cache directory and persists between playback sessions.
*
* Property name is ASCII string. '=' or '\n' is not allowed in name.
* property data is UTF8 string without line feeds.
*/
BD_PRIVATE int disc_property_put(BD_DISC *disc, const char *property, const char *value);
BD_PRIVATE char *disc_property_get(BD_DISC *disc, const char *property);
/*
*
*/
......
/*
* This file is part of libbluray
* Copyright (C) 2017 Petri Hintukainen <phintuka@users.sourceforge.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <http://www.gnu.org/licenses/>.
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include "properties.h"
#include "file/file.h"
#include "util/logging.h"
#include "util/macro.h"
#include "util/strutl.h"
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#define MAX_PROP_FILE_SIZE (64*1024)
/*
* read / write file
*/
static int _read_prop_file(const char *file, char **data)
{
BD_FILE_H *fp;
int64_t size = -1;
*data = NULL;
if (file_path_exists(file) < 0) {
BD_DEBUG(DBG_FILE, "Properties file %s does not exist\n", file);
*data = str_dup("");
return 0;
}
fp = file_open(file, "rt");
if (!fp) {
goto unlink;
}
size = file_size(fp);
if (size < 1 || size > MAX_PROP_FILE_SIZE) {
goto unlink;
}
*data = malloc((size_t)size + 1);
if (!*data) {
file_close(fp);
return -1;
}
if (file_read(fp, *data, size) != (size_t)size) {
goto unlink;
}
file_close(fp);
(*data)[size] = 0;
return 0;
unlink:
BD_DEBUG(DBG_FILE | DBG_CRIT, "Removing invalid properties file %s (%"PRId64" bytes)\n", file, size);
X_FREE(*data);
if (fp) {
file_close(fp);
}
file_unlink(file);
*data = str_dup("");
return data ? 0 : -1;
}
static int _write_prop_file(const char *file, const char *data)
{
BD_FILE_H *fp;
size_t size;
int64_t written;
size = strlen(data);
if (size > MAX_PROP_FILE_SIZE) {
BD_DEBUG(DBG_FILE | DBG_CRIT, "Not writing too large properties file: %s is %zu bytes\n", file, size);
return -1;
}
if (file_mkdirs(file) < 0) {
return -1;
}
fp = file_open(file, "wt");
if (!fp) {
return -1;
}
written = fp->write(fp, (const void*)data, (int64_t)size);
file_close(fp);
if (written != (int64_t)size) {
file_unlink(file);
return -1;
}
return 0;
}
/*
*
*/
static char *_scan_prop(char *data, const char *key, size_t *data_size)
{
size_t key_size = strlen(key);
while (data) {
if (!strncmp(data, key, key_size)) {
data += key_size;
char *lf = strchr(data, '\n');
*data_size = lf ? (size_t)(lf - data) : strlen(data);
return data;
}
/* next line */
data = strchr(data, '\n');
if (data) {
data++;
}
}
return NULL;
}
char *properties_get(const char *file, const char *property)
{
char *key, *data;
size_t data_size;
char *result = NULL;
if (strchr(property, '\n') || strchr(property, '=')) {
BD_DEBUG(DBG_FILE | DBG_CRIT, "Ignoring invalid property '%s'\n", property);
return NULL;
}
if (_read_prop_file(file, &data) < 0) {
return NULL;
}
key = str_printf("%s=", property);
if (!key) {
X_FREE(data);
return NULL;
}
result = _scan_prop(data, key, &data_size);
if (result) {
result[data_size] = 0;
result = str_dup(result);
}
X_FREE(key);
X_FREE(data);
return result;
}
int properties_put(const char *file, const char *property, const char *val)
{
char *key = NULL, *old_data = NULL, *new_data = NULL;
char *old_val;
size_t old_size;
int result = -1;
if (strchr(property, '\n') || strchr(property, '=') || strchr(val, '\n')) {
BD_DEBUG(DBG_FILE | DBG_CRIT, "Ignoring invalid property '%s'='%s'\n", property, val);
goto out;
}
if (_read_prop_file(file, &old_data) < 0) {
goto out;
}
key = str_printf("%s=", property);
if (!key) {
goto out;
}
old_val = _scan_prop(old_data, key, &old_size);
if (!old_val) {
new_data = str_printf("%s%s%s\n", old_data, key, val);
} else {
*old_val = 0;
new_data = str_printf("%s%s%s", old_data, val, old_val + old_size);
}
if (!new_data) {
goto out;
}
result = _write_prop_file(file, new_data);
out:
X_FREE(old_data);
X_FREE(new_data);
X_FREE(key);
return result;
}
/*
* This file is part of libbluray
* Copyright (C) 2017 Petri Hintukainen <phintuka@users.sourceforge.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <http://www.gnu.org/licenses/>.
*
* Simple persistent storage for (key,value) pairs
*
*/
#ifndef _BD_PROPERTIES_H_
#define _BD_PROPERTIES_H_
#include "util/attributes.h"
/*
* property name: ASCII string, no '=' or '\n'
* property value: UTF-8 string, no '\n'
*/
/**
*
* Add / replace property value in file.
*
* @param file full path to properties file
* @param property property name
* @param val value for property
* @return 0 on success, -1 on error
*/
BD_PRIVATE int properties_put(const char *file, const char *property, const char *val);
/**
*
* Read property value from file.
*
* @param file full path to properties file
* @param property property name
* @return property value or NULL
*/
BD_PRIVATE char *properties_get(const char *file, const char *property);
#endif /* _BD_PROPERTIES_H_ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment