|
From: <ny...@us...> - 2007-02-28 08:17:04
|
Revision: 401
http://svn.sourceforge.net/pmplib/?rev=401&view=rev
Author: nyaochi
Date: 2007-02-28 00:17:04 -0800 (Wed, 28 Feb 2007)
Log Message:
-----------
Added reader/dumper for "Play Count" file.
Modified Paths:
--------------
trunk/pmplib/lib/pmp_ipod/ipod.c
trunk/pmplib/lib/pmp_ipod/ipod.h
trunk/pmplib/lib/pmp_ipod/pmp_ipod.c
trunk/pmplib/lib/pmp_ipod/pmp_ipod.vcproj
Added Paths:
-----------
trunk/pmplib/lib/pmp_ipod/playcounts.c
trunk/pmplib/lib/pmp_ipod/playcounts.h
Modified: trunk/pmplib/lib/pmp_ipod/ipod.c
===================================================================
--- trunk/pmplib/lib/pmp_ipod/ipod.c 2007-02-27 15:20:57 UTC (rev 400)
+++ trunk/pmplib/lib/pmp_ipod/ipod.c 2007-02-28 08:17:04 UTC (rev 401)
@@ -39,6 +39,7 @@
#include "ipod.h"
#include "ipodprop.h"
#include "itunesdb.h"
+#include "playcounts.h"
#define COMP(a, b) ((a)>(b))-((a)<(b))
@@ -47,6 +48,7 @@
"apple_ipod", "Apple", "iPod", "UM",
"---", "---",
"iPod_Control\\iTunes\\iTunesDB",
+ "iPod_Control\\iTunes\\Play Counts",
".mp3\0.m4a\0",
{PMPCODEC_MPEGLAYER3, PMPCODEC_MPEG4AUDIO, 0, 0, 0, 0, 0, 0},
"iPod_Control", "iPod_Control\\Music", "Playlists",
@@ -56,6 +58,7 @@
NULL, NULL,
NULL,
NULL,
+ NULL,
{0, 0, 0, 0, 0, 0, 0, 0},
NULL, NULL, NULL,
},
@@ -155,19 +158,23 @@
void ipod_init(ipod_t* ipod)
{
- ipod->itunesdb = calloc(1, sizeof(itunesdb_chunk_t));
+ ipod->itunesdb = (itunesdb_chunk_t*)calloc(1, sizeof(itunesdb_chunk_t));
+ ipod->pcs = (playcounts_t*)calloc(1, sizeof(playcounts_t));
}
void ipod_finish(ipod_t* ipod)
{
+ playcounts_finish(ipod->pcs);
itunesdb_finish(ipod->itunesdb);
+ free(ipod->pcs);
free(ipod->itunesdb);
}
-result_t ipod_read(ipod_t* ipod, const ucs2char_t* itunesdb)
+result_t ipod_read(ipod_t* ipod, const ucs2char_t* itunesdb, const ucs2char_t* playcounts)
{
FILE *fp = NULL;
+ /* Read iTunesDB. */
fp = ucs2fopen(itunesdb, "rb");
if (fp) {
serializer_t sio;
@@ -179,12 +186,28 @@
serialize_init_read(&sio, buffer, (size_t)size);
itunesdb_read(ipod->itunesdb, &sio);
- serialize_finish(&sio);
+ serialize_finish(&sio); /* This will free the buffer. */
+ } else {
+ return 1;
+ }
- return 0;
+ /* Read "Play Counts". */
+ fp = ucs2fopen(playcounts, "rb");
+ if (fp) {
+ serializer_t sio;
+ uint8_t* buffer = NULL;
+ long size = 0;
+
+ fread_all(fp, &buffer, &size);
+ fclose(fp);
+
+ serialize_init_read(&sio, buffer, (size_t)size);
+ playcounts_serialize(ipod->pcs, &sio);
+ serialize_finish(&sio); /* This will free the buffer. */
} else {
return 1;
}
+ return 0;
}
result_t ipod_write(ipod_t* ipod, const ucs2char_t* itunesdb)
@@ -212,7 +235,15 @@
{
serializer_t sio;
serialize_init_dump(&sio, fpo, 2);
+
+ fprintf(fpo, "[iTunesDB]\n");
itunesdb_repr(ipod->itunesdb, 0, &sio);
+ fprintf(fpo, "\n");
+
+ fprintf(fpo, "[Play Counts]\n");
+ playcounts_serialize(ipod->pcs, &sio);
+ fprintf(fpo, "\n");
+
serialize_finish(&sio);
return 0;
}
Modified: trunk/pmplib/lib/pmp_ipod/ipod.h
===================================================================
--- trunk/pmplib/lib/pmp_ipod/ipod.h 2007-02-27 15:20:57 UTC (rev 400)
+++ trunk/pmplib/lib/pmp_ipod/ipod.h 2007-02-28 08:17:04 UTC (rev 401)
@@ -34,6 +34,7 @@
const char *min_version;
const char *max_version;
const char *itunesdb_filename;
+ const char *playcounts_filename;
const char *extensions;
uint32_t codecs[8];
const char *path_to_system;
@@ -44,8 +45,12 @@
struct tag_itunesdb_chunk;
typedef struct tag_itunesdb_chunk itunesdb_chunk_t;
+struct tag_playcounts;
+typedef struct tag_playcounts playcounts_t;
+
typedef struct {
itunesdb_chunk_t* itunesdb;
+ playcounts_t* pcs;
} ipod_t;
const ipod_descriptor_t* ipod_detect(const ucs2char_t* path_to_device, const char *id, pmp_device_information_t* ptr_info);
@@ -54,7 +59,7 @@
void ipod_init(ipod_t* ipod);
void ipod_finish(ipod_t* ipod);
result_t ipod_set(ipod_t* ipod, const pmp_music_record_t* records, int num_records, const pmp_playlist_t* playlists, int num_playlists);
-result_t ipod_read(ipod_t* ipod, const ucs2char_t* itunesdb);
+result_t ipod_read(ipod_t* ipod, const ucs2char_t* itunesdb, const ucs2char_t* playcounts);
result_t ipod_write(ipod_t* ipod, const ucs2char_t* itunesdb);
result_t ipod_dump(ipod_t* ipod, FILE *fpo);
Added: trunk/pmplib/lib/pmp_ipod/playcounts.c
===================================================================
--- trunk/pmplib/lib/pmp_ipod/playcounts.c (rev 0)
+++ trunk/pmplib/lib/pmp_ipod/playcounts.c 2007-02-28 08:17:04 UTC (rev 401)
@@ -0,0 +1,147 @@
+/*
+ * Reader and dumper for "Play Counts" file.
+ *
+ * Copyright (c) 2005-2007 Naoaki Okazaki
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+/* $Id:$ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif/*HAVE_CONFIG_H*/
+
+#include <os.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif/*HAVE_STRING_H*/
+#include <pmplib/ucs2char.h>
+
+#include "ipod.h"
+#include "serialize.h"
+#include "util.h"
+#include "playcounts.h"
+
+static void playcount_init(playcount_entry_t* entry)
+{
+ memset(entry, 0, sizeof(*entry));
+}
+
+static int playcount_serialize(playcount_entry_t* entry, const playcounts_t* pcs, serializer_t* sio)
+{
+ size_t begin = serialize_tell(sio);
+
+ if (serialize_uint32le(sio, "play_count", "%u", &entry->play_count)) return 1;
+ if (serialize_uint32le(sio, "last_played", "%u", &entry->last_played)) return 1;
+ if (serialize_uint32le(sio, "audio_bookmark", "%u", &entry->audio_bookmark)) return 1;
+
+ if (serialize_reading(sio) && begin + pcs->entry_size <= serialize_tell(sio)) return 0;
+ if (serialize_uint32le(sio, "rating", "%u", &entry->rating)) return 1;
+
+ if (serialize_reading(sio) && begin + pcs->entry_size <= serialize_tell(sio)) return 0;
+ if (serialize_uint32le(sio, "unknown", "%u", &entry->unknown)) return 1;
+
+ if (serialize_reading(sio) && begin + pcs->entry_size <= serialize_tell(sio)) return 0;
+ if (serialize_uint32le(sio, "skip_count", "%u", &entry->skip_count)) return 1;
+ if (serialize_uint32le(sio, "last_skipped", "%u", &entry->last_skipped)) return 1;
+
+ /* Padding data if any. */
+ if (serialize_reading(sio)) {
+ if (serialize_tell(sio) < begin + pcs->entry_size) {
+ entry->padding_size = pcs->entry_size - (serialize_tell(sio) - begin);
+ entry->padding = (uint8_t*)calloc(entry->padding_size, 1);
+ }
+ }
+ if (entry->padding) {
+ if (serialize_uint8_array(sio, "padding", "%02X ", entry->padding, entry->padding_size)) return 1;
+ }
+
+ return 0;
+}
+
+void playcounts_init(playcounts_t* pcs)
+{
+ memset(pcs, 0, sizeof(*pcs));
+ strncpy(pcs->id, "mhdp", 4);
+ pcs->header_size = 0x60;
+ pcs->entry_size = 0x1C;
+}
+
+void playcounts_finish(playcounts_t* pcs)
+{
+ free(pcs->entries);
+}
+
+int playcounts_serialize(playcounts_t* pcs, serializer_t* sio)
+{
+ uint32_t i;
+ size_t begin = serialize_tell(sio);
+
+ if (serialize_reading(sio)) {
+ if (serialize_uint8_array(sio, "id", "%c ", pcs->id, sizeof(pcs->id))) return 1;
+ } else if (serialize_dumping(sio)) {
+ serialize_indent(sio);
+ fprintf(sio->fp, "Chunk %c%c%c%c = {\n", pcs->id[0], pcs->id[1], pcs->id[2], pcs->id[3]);
+ }
+ serialize_indent_ascend(sio);
+
+ if (serialize_uint32le(sio, "header_size", "%u", &pcs->header_size)) return 1;
+ if (serialize_uint32le(sio, "entry_size", "%u", &pcs->entry_size)) return 1;
+ if (serialize_uint32le(sio, "num_entries", "%u", &pcs->num_entries)) return 1;
+
+ /* Padding data if any. */
+ if (serialize_reading(sio)) {
+ if (serialize_tell(sio) < begin + pcs->header_size) {
+ pcs->padding_size = pcs->header_size - (serialize_tell(sio) - begin);
+ pcs->padding = (uint8_t*)calloc(pcs->padding_size, 1);
+ }
+ }
+ if (pcs->padding) {
+ if (serialize_uint8_array(sio, "padding", "%02X ", pcs->padding, pcs->padding_size)) return 1;
+ }
+
+ if (serialize_reading(sio)) {
+ pcs->entries = (playcount_entry_t*)calloc(pcs->num_entries, sizeof(playcount_entry_t));
+ for (i = 0;i < pcs->num_entries;++i) {
+ playcount_init(&pcs->entries[i]);
+ }
+ }
+
+ for (i = 0;i < pcs->num_entries;++i) {
+ if (serialize_dumping(sio)) {
+ serialize_indent(sio);
+ fprintf(sio->fp, "entry (%d) = {\n", i);
+ serialize_indent_ascend(sio);
+ }
+ if (playcount_serialize(&pcs->entries[i], pcs, sio)) return 1;
+ if (serialize_dumping(sio)) {
+ serialize_indent_descend(sio);
+ serialize_indent(sio);
+ fprintf(sio->fp, "}\n");
+ }
+ }
+
+ serialize_indent_descend(sio);
+ if (serialize_dumping(sio)) {
+ serialize_indent(sio);
+ fprintf(sio->fp, "}\n");
+ }
+
+ return 0;
+}
Property changes on: trunk/pmplib/lib/pmp_ipod/playcounts.c
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: trunk/pmplib/lib/pmp_ipod/playcounts.h
===================================================================
--- trunk/pmplib/lib/pmp_ipod/playcounts.h (rev 0)
+++ trunk/pmplib/lib/pmp_ipod/playcounts.h 2007-02-28 08:17:04 UTC (rev 401)
@@ -0,0 +1,54 @@
+/*
+ * Reader and dumper for "Play Counts" file.
+ *
+ * Copyright (c) 2005-2007 Naoaki Okazaki
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+/* $Id:$ */
+
+#ifndef __PLAYCOUNTS_H__
+#define __PLAYCOUNTS_H__
+
+typedef struct {
+ uint32_t play_count;
+ uint32_t last_played;
+ uint32_t audio_bookmark;
+ uint32_t rating;
+ uint32_t unknown;
+ uint32_t skip_count;
+ uint32_t last_skipped;
+
+ int32_t padding_size;
+ uint8_t* padding;
+} playcount_entry_t;
+
+struct tag_playcounts {
+ int8_t id[4];
+ uint32_t header_size;
+ uint32_t entry_size;
+ uint32_t num_entries;
+ int32_t padding_size;
+ uint8_t* padding;
+ playcount_entry_t* entries;
+};
+
+void playcounts_init(playcounts_t* pcs);
+void playcounts_finish(playcounts_t* pcs);
+int playcounts_serialize(playcounts_t* pcs, serializer_t* sio);
+
+#endif/*__PLAYCOUNTS_H__*/
Property changes on: trunk/pmplib/lib/pmp_ipod/playcounts.h
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Modified: trunk/pmplib/lib/pmp_ipod/pmp_ipod.c
===================================================================
--- trunk/pmplib/lib/pmp_ipod/pmp_ipod.c 2007-02-27 15:20:57 UTC (rev 400)
+++ trunk/pmplib/lib/pmp_ipod/pmp_ipod.c 2007-02-28 08:17:04 UTC (rev 401)
@@ -145,16 +145,25 @@
memset(info, 0, sizeof(*info));
}
-static void set_filenames(ucs2char_t *itunesdb, pmp_t *pmp)
+static void set_filenames(ucs2char_t *itunesdb, ucs2char_t* playcounts, pmp_t *pmp)
{
ucs2char_t* ucs2 = NULL;
pmp_internal_t* pmpi = (pmp_internal_t*)pmp->instance;
- ucs2cpy(itunesdb, pmp->info.path_to_root);
- filepath_addslash(itunesdb);
- ucs2 = mbsdupucs2(pmpi->decl->itunesdb_filename);
- ucs2cat(itunesdb, ucs2);
- ucs2free(ucs2);
+ if (itunesdb) {
+ ucs2cpy(itunesdb, pmp->info.path_to_root);
+ filepath_addslash(itunesdb);
+ ucs2 = mbsdupucs2(pmpi->decl->itunesdb_filename);
+ ucs2cat(itunesdb, ucs2);
+ ucs2free(ucs2);
+ }
+ if (playcounts) {
+ ucs2cpy(playcounts, pmp->info.path_to_root);
+ filepath_addslash(playcounts);
+ ucs2 = mbsdupucs2(pmpi->decl->playcounts_filename);
+ ucs2cat(playcounts, ucs2);
+ ucs2free(ucs2);
+ }
}
@@ -404,13 +413,13 @@
result_t ret = 0;
pmp_t* pmp = music->pmp;
pmp_music_internal_t* pmpmi = (pmp_music_internal_t*)music->instance;
- ucs2char_t itunesdb[MAX_PATH];
+ ucs2char_t itunesdb[MAX_PATH], playcounts[MAX_PATH];
// Initialize ipod library.
ipod_init(&ipod);
// Read the music database.
- set_filenames(itunesdb, music->pmp);
+ set_filenames(itunesdb, playcounts, music->pmp);
if (pmp->flag & PMPOF_MUSIC_DB_WRITE) {
ipod_set(&ipod, pmpmi->records, pmpmi->num_records, pmpmi->playlists, pmpmi->num_playlists);
@@ -458,14 +467,14 @@
{
ipod_t ipod;
result_t ret = 0;
- ucs2char_t itunesdb[MAX_PATH];
+ ucs2char_t itunesdb[MAX_PATH], playcounts[MAX_PATH];
// Initialize IP3DB.
ipod_init(&ipod);
// Read the music database.
- set_filenames(itunesdb, music->pmp);
- ret = ipod_read(&ipod, itunesdb);
+ set_filenames(itunesdb, playcounts, music->pmp);
+ ret = ipod_read(&ipod, itunesdb, playcounts);
if (ret) {
goto exit_this;
}
Modified: trunk/pmplib/lib/pmp_ipod/pmp_ipod.vcproj
===================================================================
--- trunk/pmplib/lib/pmp_ipod/pmp_ipod.vcproj 2007-02-27 15:20:57 UTC (rev 400)
+++ trunk/pmplib/lib/pmp_ipod/pmp_ipod.vcproj 2007-02-28 08:17:04 UTC (rev 401)
@@ -186,6 +186,10 @@
>
</File>
<File
+ RelativePath=".\playcounts.c"
+ >
+ </File>
+ <File
RelativePath=".\pmp_ipod.c"
>
</File>
@@ -216,6 +220,10 @@
>
</File>
<File
+ RelativePath=".\playcounts.h"
+ >
+ </File>
+ <File
RelativePath=".\serialize.h"
>
</File>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|