summaryrefslogtreecommitdiffstats
path: root/src/db-parse-context.c
diff options
context:
space:
mode:
authorJorg Schuler <jcsjcs@users.sourceforge.net>2005-09-19 10:30:50 +0000
committerJorg Schuler <jcsjcs@users.sourceforge.net>2005-09-19 10:30:50 +0000
commit7278b29a031119ce8da1ea6022de8b70b49ee577 (patch)
treeb98944ba47d504e70fdb04bf7f858c7be365b4d7 /src/db-parse-context.c
parentdb92f98a83f98715538b6c91c0dfd6694d9ef079 (diff)
downloadlibgpod-7278b29a031119ce8da1ea6022de8b70b49ee577.tar.gz
libgpod-7278b29a031119ce8da1ea6022de8b70b49ee577.tar.xz
libgpod-7278b29a031119ce8da1ea6022de8b70b49ee577.zip
* applied patch provided by Christophe Fergeau <teuf at gnome.org>
for artwork database support (read-only). git-svn-id: https://gtkpod.svn.sf.net/svnroot/gtkpod/libgpod/trunk@1093 f01d2545-417e-4e96-918e-98f8d0dbbcb6
Diffstat (limited to 'src/db-parse-context.c')
-rw-r--r--src/db-parse-context.c196
1 files changed, 196 insertions, 0 deletions
diff --git a/src/db-parse-context.c b/src/db-parse-context.c
new file mode 100644
index 0000000..4f4264e
--- /dev/null
+++ b/src/db-parse-context.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2005 Christophe Fergeau
+ *
+ *
+ * The code contained in this file 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 file 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 code; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * iTunes and iPod are trademarks of Apple
+ *
+ * This product is not supported/written/published by Apple!
+ *
+ */
+
+
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <glib.h>
+
+#include "db-parse-context.h"
+#include "db-itunes-parser.h"
+
+DBParseContext *
+db_parse_context_new (const unsigned char *buffer, off_t len)
+{
+ DBParseContext *result;
+
+ result = g_new0 (DBParseContext, 1);
+ if (result == NULL) {
+ return NULL;
+ }
+
+ result->buffer = buffer;
+ result->cur_pos = buffer;
+ result->total_len = len;
+
+ return result;
+}
+
+
+static void
+db_parse_context_set_header_len (DBParseContext *ctx, off_t len)
+{
+ /* FIXME: this can probably happen in malformed itunesdb files,
+ * don't g_assert on this, only output a warning
+ */
+ g_assert ((ctx->cur_pos - ctx->buffer) <= len);
+ g_assert (len <= ctx->total_len);
+ ctx->header_len = len;
+}
+
+void
+db_parse_context_set_total_len (DBParseContext *ctx, off_t len)
+{
+ /* FIXME: this can probably happen in malformed itunesdb files,
+ * don't g_assert on this, only output a warning
+ */
+ g_assert ((ctx->cur_pos - ctx->buffer) <= len);
+ if (ctx->header_len != 0) {
+ g_assert (len >= ctx->header_len);
+ }
+ ctx->total_len = len;
+}
+
+
+off_t
+db_parse_context_get_remaining_length (DBParseContext *ctx)
+{
+ if (ctx->header_len != 0) {
+ return ctx->header_len - (ctx->cur_pos - ctx->buffer);
+ } else {
+ return ctx->total_len - (ctx->cur_pos - ctx->buffer);
+ }
+}
+
+DBParseContext *
+db_parse_context_get_sub_context (DBParseContext *ctx, off_t offset)
+{
+ if (offset >= ctx->total_len) {
+ return NULL;
+ }
+ return db_parse_context_new (&ctx->buffer[offset],
+ ctx->total_len - offset);
+}
+
+
+DBParseContext *
+db_parse_context_get_next_child (DBParseContext *ctx)
+{
+ if (ctx->header_len == 0) {
+ return NULL;
+ }
+ if (ctx->header_len >= ctx->total_len) {
+ return NULL;
+ }
+
+ return db_parse_context_get_sub_context (ctx, ctx->header_len);
+}
+
+void *
+db_parse_context_get_m_header_internal (DBParseContext *ctx, const char *id, off_t size)
+{
+ MHeader *h;
+
+ if (db_parse_context_get_remaining_length (ctx) < 8) {
+ return NULL;
+ }
+
+ h = (MHeader *)ctx->cur_pos;
+ if (strncmp (id, (char *)h->header_id, 4) != 0) {
+ return NULL;
+ }
+
+ /* FIXME: this test sucks for compat: if a field is smaller than
+ * expected, we probably should create a buffer of the appropriate
+ * size inited to 0, copy the data that is available in it and use
+ * that buffer in the rest of the code (maybe it's harmful to have
+ * some fields at 0 in some headers though...)
+ */
+ if (GINT_FROM_LE (h->header_len) < size) {
+ return NULL;
+ }
+
+ db_parse_context_set_header_len (ctx, GINT_FROM_LE (h->header_len));
+
+ return h;
+}
+
+DBParseContext *
+db_parse_context_new_from_file (const char *filename)
+{
+ int fd;
+ struct stat stat_buf;
+ int result;
+ unsigned char *buffer;
+ DBParseContext *ctx;
+
+ buffer = NULL;
+ ctx = NULL;
+
+ fd = open (filename, O_RDONLY);
+ if (fd == -1) {
+ g_print ("Failed to open %s: %s\n",
+ filename, strerror (errno));
+ return NULL;
+ }
+
+ result = fstat (fd, &stat_buf);
+ if (result == -1) {
+ g_print ("Failed to read %s size: %s\n",
+ filename, strerror (errno));
+ goto error;
+ }
+
+ if (!S_ISREG (stat_buf.st_mode)) {
+ g_print ("%s is not a regular file\n", filename);
+ goto error;
+ }
+
+ if (stat_buf.st_size > ITUNESDB_MAX_SIZE) {
+ g_print ("%s is too big to be an buffer file\n", filename);
+ goto error;
+ }
+
+ buffer = mmap (NULL, stat_buf.st_size, PROT_READ, MAP_SHARED, fd, 0);
+
+ if (buffer == MAP_FAILED) {
+ g_print ("Error while mmap'ing %s: %s\n",
+ filename, strerror (errno));
+ goto error;
+ }
+
+ ctx = db_parse_context_new (buffer, stat_buf.st_size);
+ if (ctx == NULL) {
+ munmap (buffer, stat_buf.st_size);
+ }
+ error:
+ close (fd);
+ return ctx;
+}