|
From: <ny...@us...> - 2007-02-21 15:56:22
|
Revision: 382
http://svn.sourceforge.net/pmplib/?rev=382&view=rev
Author: nyaochi
Date: 2007-02-21 07:56:22 -0800 (Wed, 21 Feb 2007)
Log Message:
-----------
Started to support Apple iPod in PMPlib. New driver module pmp_ipod was added. The code is in the very early stage
of the development: only reading/dumping iTunesDB is working.
Modified Paths:
--------------
trunk/pmplib/include/pmplib/os_types.h
trunk/pmplib/pmp.sln
Added Paths:
-----------
trunk/pmplib/lib/pmp_ipod/
trunk/pmplib/lib/pmp_ipod/ipod.c
trunk/pmplib/lib/pmp_ipod/ipod.h
trunk/pmplib/lib/pmp_ipod/itunesdb.c
trunk/pmplib/lib/pmp_ipod/itunesdb.h
trunk/pmplib/lib/pmp_ipod/pmp_ipod.c
trunk/pmplib/lib/pmp_ipod/pmp_ipod.vcproj
trunk/pmplib/lib/pmp_ipod/serialize.c
trunk/pmplib/lib/pmp_ipod/serialize.h
trunk/pmplib/lib/pmp_ipod/util.c
trunk/pmplib/lib/pmp_ipod/util.h
Modified: trunk/pmplib/include/pmplib/os_types.h
===================================================================
--- trunk/pmplib/include/pmplib/os_types.h 2007-02-20 15:40:10 UTC (rev 381)
+++ trunk/pmplib/include/pmplib/os_types.h 2007-02-21 15:56:22 UTC (rev 382)
@@ -31,10 +31,12 @@
#include <sys/types.h>
#else
-typedef unsigned char uint8_t;
-typedef unsigned int uint32_t;
-typedef int int32_t;
-typedef unsigned short uint16_t;
+typedef char int8_t;
+typedef unsigned char uint8_t;
+typedef unsigned int uint32_t;
+typedef int int32_t;
+typedef unsigned short uint16_t;
+typedef unsigned __int64 uint64_t;
#endif
Added: trunk/pmplib/lib/pmp_ipod/ipod.c
===================================================================
--- trunk/pmplib/lib/pmp_ipod/ipod.c (rev 0)
+++ trunk/pmplib/lib/pmp_ipod/ipod.c 2007-02-21 15:56:22 UTC (rev 382)
@@ -0,0 +1,81 @@
+/*
+ * iPod
+ *
+ * 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 "serialize.h"
+#include "util.h"
+#include "ipod.h"
+#include "itunesdb.h"
+
+void ipod_init(ipod_t* ipod)
+{
+ ipod->itunesdb = calloc(1, sizeof(itunesdb_chunk_t));
+}
+
+void ipod_finish(ipod_t* ipod)
+{
+
+}
+
+result_t ipod_read(ipod_t* ipod, const ucs2char_t* itunesdb)
+{
+ FILE *fp = NULL;
+
+ fp = ucs2fopen(itunesdb, "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);
+ itunesdb_read(ipod->itunesdb, &sio);
+ serialize_finish(&sio);
+
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+result_t ipod_dump(ipod_t* ipod, FILE *fpo)
+{
+ serializer_t sio;
+ serialize_init_dump(&sio, fpo, 2);
+ itunesdb_repr(ipod->itunesdb, 0, &sio);
+ serialize_finish(&sio);
+ return 0;
+}
Property changes on: trunk/pmplib/lib/pmp_ipod/ipod.c
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: trunk/pmplib/lib/pmp_ipod/ipod.h
===================================================================
--- trunk/pmplib/lib/pmp_ipod/ipod.h (rev 0)
+++ trunk/pmplib/lib/pmp_ipod/ipod.h 2007-02-21 15:56:22 UTC (rev 382)
@@ -0,0 +1,16 @@
+#ifndef __IPOD_H__
+#define __IPOD_H__
+
+struct tag_itunesdb_chunk;
+typedef struct tag_itunesdb_chunk itunesdb_chunk_t;
+
+typedef struct {
+ itunesdb_chunk_t* itunesdb;
+} ipod_t;
+
+void ipod_init(ipod_t* ipod);
+void ipod_finish(ipod_t* ipod);
+result_t ipod_read(ipod_t* ipod, const ucs2char_t* itunesdb);
+result_t ipod_dump(ipod_t* ipod, FILE *fpo);
+
+#endif/*__IPOD_H__*/
Property changes on: trunk/pmplib/lib/pmp_ipod/ipod.h
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: trunk/pmplib/lib/pmp_ipod/itunesdb.c
===================================================================
--- trunk/pmplib/lib/pmp_ipod/itunesdb.c (rev 0)
+++ trunk/pmplib/lib/pmp_ipod/itunesdb.c 2007-02-21 15:56:22 UTC (rev 382)
@@ -0,0 +1,526 @@
+/*
+ * iTunesDB
+ *
+ * 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 "itunesdb.h"
+
+static int mhbd_serialize(itunesdb_chunk_t* chunk, serializer_t* sio)
+{
+ chunk_mhbd_t* mhbd = (chunk_mhbd_t*)chunk->data;
+
+ if (serialize_uint32le(sio, "unknown1", "%d", &mhbd->unknown1)) return 1;
+ if (serialize_uint32le(sio, "version", "%d", &mhbd->version)) return 1;
+ if (serialize_uint32le(sio, "num_children", "%d", &mhbd->num_children)) return 1;
+ if (serialize_uint64le(sio, "identifier", "%lX", &mhbd->identifier)) return 1;
+ if (serialize_uint16le(sio, "unkonwn2", "%d", &mhbd->unknown2)) return 1;
+ if (serialize_uint16le(sio, "unkonwn3", "%d", &mhbd->unknown3)) return 1;
+ if (serialize_uint64le(sio, "unknown4", "%lX", &mhbd->unknown4)) return 1;
+ if (serialize_uint8_array(sio, "unknown5", "%02X ", mhbd->unknown5, sizeof(mhbd->unknown5))) return 1;
+ if (serialize_uint8_array(sio, "language", "%c ", mhbd->language, sizeof(mhbd->language))) return 1;
+ if (serialize_uint8_array(sio, "unknown6", "%02X ", mhbd->unknown6, sizeof(mhbd->unknown6))) return 1;
+
+ return 0;
+}
+
+static int mhsd_serialize(itunesdb_chunk_t* chunk, serializer_t* sio)
+{
+ chunk_mhsd_t* mhsd = (chunk_mhsd_t*)chunk->data;
+
+ if (serialize_uint32le(sio, "type", "%d", &mhsd->type)) return 1;
+ if (serialize_uint8_array(sio, "unknown1", "%02X ", mhsd->unknown1, sizeof(mhsd->unknown1))) return 1;
+
+ return 0;
+}
+
+static int mhlt_serialize(itunesdb_chunk_t* chunk, serializer_t* sio)
+{
+ chunk_mhlt_t* mhlt = (chunk_mhlt_t*)chunk->data;
+
+ if (serialize_uint8_array(sio, "unknown1", "%02X ", mhlt->unknown1, sizeof(mhlt->unknown1))) return 1;
+
+ return 0;
+}
+
+static int mhit_serialize(itunesdb_chunk_t* chunk, serializer_t* sio)
+{
+ chunk_mhit_t* mhit = (chunk_mhit_t*)chunk->data;
+
+ if (serialize_uint32le(sio, "num_children", "%u", &mhit->num_children)) return 1;
+ if (serialize_uint32le(sio, "uid", "%u", &mhit->uid)) return 1;
+ if (serialize_uint32le(sio, "visible", "%u", &mhit->visible)) return 1;
+ if (serialize_uint32le(sio, "filetype", "%08X", &mhit->filetype)) return 1;
+ if (serialize_uint8(sio, "type1", "%02X", &mhit->type1)) return 1;
+ if (serialize_uint8(sio, "type2", "%02X", &mhit->type2)) return 1;
+ if (serialize_uint8(sio, "compilation", "%u", &mhit->compilation)) return 1;
+ if (serialize_uint8(sio, "rating", "%u", &mhit->type1)) return 1;
+ if (serialize_uint32le(sio, "last_modified", "%u", &mhit->last_modified)) return 1;
+ if (serialize_uint32le(sio, "filesize", "%u", &mhit->filesize)) return 1;
+ if (serialize_uint32le(sio, "duration", "%u", &mhit->duration)) return 1;
+ if (serialize_uint32le(sio, "track_number", "%u", &mhit->track_number)) return 1;
+ if (serialize_uint32le(sio, "total_tracks", "%u", &mhit->total_tracks)) return 1;
+ if (serialize_uint32le(sio, "year", "%u", &mhit->year)) return 1;
+ if (serialize_uint32le(sio, "bitrate", "%u", &mhit->bitrate)) return 1;
+ if (serialize_uint16le(sio, "unknown1", "%u", &mhit->unknown1)) return 1;
+ if (serialize_uint16le(sio, "samplerate", "%u", &mhit->samplerate)) return 1;
+ if (serialize_int32le(sio, "volume", "%d", &mhit->volume)) return 1;
+ if (serialize_uint32le(sio, "start_time", "%u", &mhit->start_time)) return 1;
+ if (serialize_uint32le(sio, "stop_time", "%u", &mhit->stop_time)) return 1;
+ if (serialize_uint32le(sio, "sound_check", "%u", &mhit->sound_check)) return 1;
+ if (serialize_uint32le(sio, "play_count", "%u", &mhit->play_count)) return 1;
+ if (serialize_uint32le(sio, "play_count2", "%u", &mhit->play_count2)) return 1;
+ if (serialize_uint32le(sio, "last_played", "%u", &mhit->last_played)) return 1;
+ if (serialize_uint32le(sio, "disc_number", "%u", &mhit->disc_number)) return 1;
+ if (serialize_uint32le(sio, "total_discs", "%u", &mhit->total_discs)) return 1;
+ if (serialize_uint32le(sio, "user_id", "%u", &mhit->user_id)) return 1;
+ if (serialize_uint32le(sio, "date_added", "%u", &mhit->date_added)) return 1;
+ if (serialize_uint32le(sio, "bookmark_time", "%u", &mhit->bookmark_time)) return 1;
+ if (serialize_uint64le(sio, "dbid", "%X", &mhit->dbid)) return 1;
+ if (serialize_uint8(sio, "is_checked", "%u", &mhit->is_checked)) return 1;
+ if (serialize_uint8(sio, "rating_itunes", "%u", &mhit->rating_itunes)) return 1;
+ if (serialize_uint16le(sio, "bpm", "%u", &mhit->bpm)) return 1;
+ if (serialize_uint16le(sio, "num_artworks", "%u", &mhit->num_artworks)) return 1;
+ if (serialize_uint16le(sio, "unk9", "%u", &mhit->unk9)) return 1;
+ if (serialize_uint32le(sio, "artwork_size", "%u", &mhit->artwork_size)) return 1;
+ if (serialize_uint32le(sio, "unk11", "%u", &mhit->unk11)) return 1;
+ if (serialize_uint32le(sio, "samplerate2", "%u", &mhit->samplerate2)) return 1;
+ if (serialize_uint32le(sio, "disc_released", "%u", &mhit->disc_released)) return 1;
+ if (serialize_uint16le(sio, "unk14_1", "%u", &mhit->unk14_1)) return 1;
+ if (serialize_uint16le(sio, "unk14_2", "%u", &mhit->unk14_2)) return 1;
+ if (serialize_uint32le(sio, "unk15", "%u", &mhit->unk15)) return 1;
+ if (serialize_uint32le(sio, "unk16", "%u", &mhit->unk16)) return 1;
+ if (serialize_uint32le(sio, "skip_count", "%u", &mhit->skip_count)) return 1;
+ if (serialize_uint32le(sio, "last_skipped", "%u", &mhit->last_skipped)) return 1;
+ if (serialize_uint8(sio, "has_artwork", "%u", &mhit->has_artwork)) return 1;
+ if (serialize_uint8(sio, "skip_when_shuffling", "%u", &mhit->skip_when_shuffling)) return 1;
+ if (serialize_uint8(sio, "remember_playback_position", "%u", &mhit->remember_playback_position)) return 1;
+ if (serialize_uint8(sio, "flag4", "%u", &mhit->flag4)) return 1;
+ if (serialize_uint64le(sio, "dbid2", "%X", &mhit->dbid2)) return 1;
+ if (serialize_uint8(sio, "has_lyrics", "%u", &mhit->has_lyrics)) return 1;
+ if (serialize_uint8(sio, "is_movie", "%u", &mhit->is_movie)) return 1;
+ if (serialize_uint8(sio, "is_played", "%u", &mhit->is_played)) return 1;
+ if (serialize_uint8(sio, "unk17", "%u", &mhit->unk17)) return 1;
+ if (serialize_uint32le(sio, "unk21", "%u", &mhit->unk21)) return 1;
+ if (serialize_int32le(sio, "encoder_delay", "%d", &mhit->encoder_delay)) return 1;
+ if (serialize_uint64le(sio, "num_samples", "%u", &mhit->num_samples)) return 1;
+ if (serialize_uint32le(sio, "unk25", "%u", &mhit->unk25)) return 1;
+ if (serialize_int32le(sio, "padding_samples", "%d", &mhit->padding_samples)) return 1;
+ if (serialize_uint32le(sio, "unk27", "%u", &mhit->unk27)) return 1;
+ if (serialize_uint32le(sio, "media_type", "%u", &mhit->media_type)) return 1;
+ if (serialize_uint32le(sio, "season_number", "%u", &mhit->season_number)) return 1;
+ if (serialize_uint32le(sio, "episode_number", "%u", &mhit->episode_number)) return 1;
+ if (serialize_uint32le(sio, "unk31", "%u", &mhit->unk31)) return 1;
+ if (serialize_uint32le(sio, "unk32", "%u", &mhit->unk32)) return 1;
+ if (serialize_uint32le(sio, "unk33", "%u", &mhit->unk33)) return 1;
+ if (serialize_uint32le(sio, "unk34", "%u", &mhit->unk34)) return 1;
+ if (serialize_uint32le(sio, "unk35", "%u", &mhit->unk35)) return 1;
+ if (serialize_uint32le(sio, "unk36", "%u", &mhit->unk36)) return 1;
+ if (serialize_uint32le(sio, "unk37", "%u", &mhit->unk37)) return 1;
+ if (serialize_uint32le(sio, "offset_last8th_frame", "%u", &mhit->offset_last8th_frame)) return 1;
+ if (serialize_uint32le(sio, "unk38", "%u", &mhit->unk38)) return 1;
+ if (serialize_uint16le(sio, "gapless_track", "%u", &mhit->gapless_track)) return 1;
+ if (serialize_uint16le(sio, "gapless_album", "%u", &mhit->gapless_album)) return 1;
+
+ return 0;
+}
+
+static int mhlp_serialize(itunesdb_chunk_t* chunk, serializer_t* sio)
+{
+ chunk_mhlp_t* mhlp = (chunk_mhlp_t*)chunk->data;
+
+ if (serialize_uint8_array(sio, "unknown1", "%02X ", mhlp->unknown1, sizeof(mhlp->unknown1))) return 1;
+
+ return 0;
+}
+
+static int mhyp_serialize(itunesdb_chunk_t* chunk, serializer_t* sio)
+{
+ chunk_mhyp_t* mhyp = (chunk_mhyp_t*)chunk->data;
+
+ if (serialize_uint32le(sio, "num_mhod", "%u", &mhyp->num_mhod)) return 1;
+ if (serialize_uint32le(sio, "num_mhip", "%u", &mhyp->num_mhip)) return 1;
+ if (serialize_uint8(sio, "flag_master", "%u", &mhyp->flag_master)) return 1;
+ if (serialize_uint8(sio, "flag_unkonwn1", "%u", &mhyp->flag_unkonwn1)) return 1;
+ if (serialize_uint8(sio, "flag_unkonwn2", "%u", &mhyp->flag_unkonwn2)) return 1;
+ if (serialize_uint8(sio, "flag_unkonwn3", "%u", &mhyp->flag_unkonwn3)) return 1;
+ if (serialize_uint32le(sio, "timestamp", "%u", &mhyp->timestamp)) return 1;
+ if (serialize_uint64le(sio, "id", "%u", &mhyp->id)) return 1;
+ if (serialize_uint32le(sio, "unk3", "%u", &mhyp->unk3)) return 1;
+ if (serialize_uint16le(sio, "unk4", "%u", &mhyp->unk4)) return 1;
+ if (serialize_uint16le(sio, "flag_podcast", "%u", &mhyp->flag_podcast)) return 1;
+ if (serialize_uint32le(sio, "sort_order", "%u", &mhyp->sort_order)) return 1;
+ if (serialize_uint8_array(sio, "padding", "%02X ", mhyp->padding, sizeof(mhyp->padding))) return 1;
+
+ return 0;
+}
+
+static int mhip_serialize(itunesdb_chunk_t* chunk, serializer_t* sio)
+{
+ chunk_mhip_t* mhyp = (chunk_mhip_t*)chunk->data;
+
+ if (serialize_uint32le(sio, "num_mhod", "%u", &mhyp->num_mhod)) return 1;
+ if (serialize_uint32le(sio, "flag_podcast_group", "%X", &mhyp->flag_podcast_group)) return 1;
+ if (serialize_uint32le(sio, "group_id", "%u", &mhyp->group_id)) return 1;
+ if (serialize_uint32le(sio, "track_id", "%u", &mhyp->track_id)) return 1;
+ if (serialize_uint32le(sio, "timestamp", "%u", &mhyp->timestamp)) return 1;
+ if (serialize_uint32le(sio, "podcast_parent", "%u", &mhyp->podcast_parent)) return 1;
+
+ return 0;
+}
+
+static int mhod_string_serialize(itunesdb_chunk_t* chunk, const char *name, serializer_t* sio)
+{
+ chunk_mhod_string_t* string = &((chunk_mhod_t*)chunk->data)->data.str;
+
+ if (serialize_uint32le(sio, "unk1", "%u", &string->unk1)) return 1;
+ if (serialize_uint32le(sio, "unk2", "%u", &string->unk2)) return 1;
+ if (serialize_uint32le(sio, "position", "%u", &string->position)) return 1;
+ if (serialize_uint32le(sio, "size", "%u", &string->size)) return 1;
+ if (serialize_uint32le(sio, "unknown", "%u", &string->unknown)) return 1;
+ if (serialize_uint32le(sio, "unk4", "%u", &string->unk4)) return 1;
+ if (serialize_ucs2lestr_fixed(sio, name, "%s", &string->value, string->size / sizeof(ucs2char_t))) return 1;
+
+ return 0;
+}
+
+static int mhod_url_serialize(itunesdb_chunk_t* chunk, const char *name, serializer_t* sio)
+{
+ chunk_mhod_t* mhod = (chunk_mhod_t*)chunk->data;
+ chunk_mhod_url_t* url = &mhod->data.url;
+
+ if (serialize_uint32le(sio, "unk1", "%u", &url->unk1)) return 1;
+ if (serialize_uint32le(sio, "unk2", "%u", &url->unk2)) return 1;
+ if (serialize_utf8str_fixed(sio, name, "%s", &url->value, chunk->data_size - chunk->chunk_size)) return 1;
+
+ return 0;
+}
+
+static int mhod_index_serialize(itunesdb_chunk_t* chunk, const char *name, serializer_t* sio)
+{
+ uint32_t i;
+ chunk_mhod_t* mhod = (chunk_mhod_t*)chunk->data;
+ chunk_mhod_index_t* index = &mhod->data.index;
+
+ if (serialize_uint32le(sio, "unk1", "%u", &index->unk1)) return 1;
+ if (serialize_uint32le(sio, "unk2", "%u", &index->unk2)) return 1;
+ if (serialize_uint32le(sio, "type", "%u", &index->type)) return 1;
+ if (serialize_uint32le(sio, "num_entries", "%u", &index->num_entries)) return 1;
+ if (serialize_uint8_array(sio, "padding", "%02X ", index->padding, sizeof(index->padding))) return 1;
+
+ /* Allocate array when reading. */
+ if (serialize_reading(sio)) {
+ index->entries = calloc(index->num_entries, sizeof(uint32_t));
+ if (!index->entries) {
+ return 1;
+ }
+ }
+
+ for (i = 0;i < index->num_entries;++i) {
+ char fieldname[128];
+ sprintf(fieldname, "entries[%d]", i);
+ if (serialize_uint32le(sio, fieldname, "%u", &index->entries[i])) return 1;
+ }
+
+ return 0;
+}
+
+static int mhod_playlist_column_serialize(itunesdb_chunk_t* chunk, const char *name, serializer_t* sio)
+{
+ uint32_t i;
+ chunk_mhod_t* mhod = (chunk_mhod_t*)chunk->data;
+ chunk_mhod_playlist_column_t* pc = &mhod->data.pc;
+
+ if (serialize_uint32le(sio, "unk1", "%u", &pc->unk1)) return 1;
+ if (serialize_uint32le(sio, "unk2", "%u", &pc->unk2)) return 1;
+ if (serialize_uint32le(sio, "unk3", "%u", &pc->unk3)) return 1;
+ if (serialize_uint64le(sio, "unk4", "%u", &pc->unk4)) return 1;
+ if (serialize_uint32le(sio, "unk8", "%u", &pc->unk8)) return 1;
+ if (serialize_uint16le(sio, "unk9", "%u", &pc->unk9)) return 1;
+ if (serialize_uint16le(sio, "unk10", "%u", &pc->unk10)) return 1;
+ if (serialize_uint32le(sio, "sort_type", "%u", &pc->sort_type)) return 1;
+ if (serialize_uint32le(sio, "num_columns", "%u", &pc->num_columns)) return 1;
+ if (serialize_uint32le(sio, "unknown", "%u", &pc->unknown)) return 1;
+
+ /* Allocate array when reading. */
+ if (serialize_reading(sio)) {
+ pc->columns = (chunk_mhod_playlist_column_definition_t*)calloc(
+ pc->num_columns, sizeof(chunk_mhod_playlist_column_definition_t));
+ if (!pc->columns) {
+ return 1;
+ }
+ }
+
+ for (i = 0;i < pc->num_columns;++i) {
+ char fieldname[128];
+ chunk_mhod_playlist_column_definition_t* def = &pc->columns[i];
+
+ sprintf(fieldname, "columns[%d].id", i);
+ if (serialize_uint16le(sio, fieldname, "%u", &def->id)) return 1;
+ sprintf(fieldname, "columns[%d].width", i);
+ if (serialize_uint16le(sio, fieldname, "%u", &def->width)) return 1;
+ sprintf(fieldname, "columns[%d].sort_direction", i);
+ if (serialize_uint32le(sio, fieldname, "%u", &def->sort_direction)) return 1;
+ sprintf(fieldname, "columns[%d].padding", i);
+ if (serialize_uint64le(sio, fieldname, "%u", &def->padding)) return 1;
+ }
+
+ return 0;
+}
+
+static int mhod_playlist_order_serialize(itunesdb_chunk_t* chunk, const char *name, serializer_t* sio)
+{
+ chunk_mhod_t* mhod = (chunk_mhod_t*)chunk->data;
+ chunk_mhod_playlist_order_t* po = &mhod->data.po;
+
+ if (serialize_uint32le(sio, "unk1", "%u", &po->unk1)) return 1;
+ if (serialize_uint32le(sio, "unk2", "%u", &po->unk2)) return 1;
+ if (serialize_uint32le(sio, "position", "%u", &po->position)) return 1;
+ if (serialize_uint8_array(sio, "padding", "%02X ", po->padding, sizeof(po->padding))) return 1;
+
+ return 0;
+}
+
+static const itunesdb_mhoddecl_t* find_mhoddecl(itunesdb_chunk_t* chunk)
+{
+ static const itunesdb_mhoddecl_t mds[] = {
+ {1, "title", 0, mhod_string_serialize},
+ {2, "location", 0, mhod_string_serialize},
+ {3, "album", 0, mhod_string_serialize},
+ {4, "artist", 0, mhod_string_serialize},
+ {5, "genre", 0, mhod_string_serialize},
+ {6, "filetype", 0, mhod_string_serialize},
+ {7, "EQ setting", 0, mhod_string_serialize},
+ {8, "comment", 0, mhod_string_serialize},
+ {9, "category", 0, mhod_string_serialize},
+ {12, "composer", 0, mhod_string_serialize},
+ {13, "grouping", 0, mhod_string_serialize},
+ {14, "description", 0, mhod_string_serialize},
+ {15, "podcast_enclosure_url", 0, mhod_url_serialize},
+ {16, "podcast_rss_url", 0, mhod_url_serialize},
+ {52, "index", 0, mhod_index_serialize},
+ {100, "playlist_column", 0x288, mhod_playlist_column_serialize},
+ {100, "playlist_order", 0x2C, mhod_playlist_order_serialize},
+ {0, NULL, 0, NULL},
+ };
+ const itunesdb_mhoddecl_t* decl = mds;
+ chunk_mhod_t* mhod = (chunk_mhod_t*)chunk->data;
+
+ while (decl->name) {
+ if (decl->type == mhod->type) {
+ if (decl->chunk_size == 0 || decl->chunk_size == chunk->chunk_size) {
+ return decl;
+ }
+ }
+ ++decl;
+ }
+ return NULL;
+}
+
+static int mhod_serialize(itunesdb_chunk_t* chunk, serializer_t* sio)
+{
+ chunk_mhod_t* mhod = (chunk_mhod_t*)chunk->data;
+ const itunesdb_mhoddecl_t* decl = NULL;
+
+ if (serialize_uint32le(sio, "type", "%u", &mhod->type)) return 1;
+
+ decl = find_mhoddecl(chunk);
+ if (decl) {
+ if (decl->serialize(chunk, decl->name, sio)) return 1;
+ } else {
+ if (serialize_dumping(sio)) {
+ serialize_indent(sio);
+ fprintf(sio->fp, "!unknown_mhod_type!\n");
+ }
+ }
+
+ return 0;
+}
+
+
+static const itunesdb_chunkdecl_t* find_chunkdecl(itunesdb_chunk_t* chunk)
+{
+ static const itunesdb_chunkdecl_t cds[] = {
+ {"mhbd", sizeof(chunk_mhbd_t), mhbd_serialize},
+ {"mhsd", sizeof(chunk_mhsd_t), mhsd_serialize},
+ {"mhlt", sizeof(chunk_mhlt_t), mhlt_serialize},
+ {"mhit", sizeof(chunk_mhit_t), mhit_serialize},
+ {"mhlp", sizeof(chunk_mhlp_t), mhlp_serialize},
+ {"mhyp", sizeof(chunk_mhyp_t), mhyp_serialize},
+ {"mhip", sizeof(chunk_mhip_t), mhip_serialize},
+ {"mhod", sizeof(chunk_mhod_t), mhod_serialize},
+ {NULL, 0, NULL},
+ };
+ const itunesdb_chunkdecl_t* decl = cds;
+
+ while (decl->name) {
+ if (strncmp(decl->name, chunk->id, 4) == 0) {
+ return decl;
+ }
+ ++decl;
+ }
+ return NULL;
+}
+
+int itunesdb_repr(itunesdb_chunk_t* chunk, size_t index, serializer_t* sio)
+{
+ uint32_t i;
+ itunesdb_chunk_t* child = NULL;
+ const itunesdb_chunkdecl_t* decl = NULL;
+
+ /* Start of a chunk */
+ serialize_indent(sio);
+ fprintf(sio->fp, "Chunk %c%c%c%c (%d) = {\n", chunk->id[0], chunk->id[1], chunk->id[2], chunk->id[3], index);
+ serialize_indent_ascend(sio);
+
+ /* Show information of the chunk header */
+ serialize_indent(sio);
+ fprintf(sio->fp, "offset: %08X\n", chunk->offset);
+ serialize_indent(sio);
+ fprintf(sio->fp, "data_size: %d\n", chunk->data_size);
+ serialize_indent(sio);
+ fprintf(sio->fp, "chunk_size: %d\n", chunk->chunk_size);
+
+ /* Show fields in the chunk data */
+ decl = find_chunkdecl(chunk);
+ if (decl) {
+ decl->serialize(chunk, sio);
+ } else {
+ serialize_indent(sio);
+ fprintf(sio->fp, "!unknown_chunk!\n");
+ }
+
+ /* Show number of children */
+ serialize_indent(sio);
+ fprintf(sio->fp, "#children: %d\n", chunk->num_children);
+
+ /* Descend to children */
+ for (i = 0;i < chunk->num_children;++i) {
+ fputc('\n', sio->fp);
+ itunesdb_repr(&chunk->childlen[i], i, sio);
+ }
+
+ /* End of the chunk */
+ serialize_indent_descend(sio);
+ serialize_indent(sio);
+ fprintf(sio->fp, "}\n");
+
+ return 0;
+}
+
+int itunesdb_read(itunesdb_chunk_t* chunk, serializer_t* sio)
+{
+ uint32_t i;
+ size_t begin = serialize_tell(sio);
+ const itunesdb_chunkdecl_t* decl = NULL;
+
+ /* Read the chunk ID and header information */
+ chunk->offset = begin;
+ if (serialize_uint8_array(sio, "id", "%c ", chunk->id, sizeof(chunk->id))) return 1;
+ if (serialize_uint32le(sio, "data_size", "%d", &chunk->data_size)) return 1;
+ if (serialize_uint32le(sio, "chunk_size", "%d", &chunk->chunk_size)) return 1;
+
+ /* Read the chunk data if this chunk is 'known' */
+ decl = find_chunkdecl(chunk);
+ if (decl) {
+ chunk->data = calloc(1, decl->data_size);
+ if (chunk->data) {
+ if (decl->serialize(chunk, sio)) return 1;
+ }
+ }
+
+ if (strncmp(chunk->id, "mhod", 4) == 0) {
+ uint32_t next = begin + chunk->chunk_size;
+ if (next < serialize_tell(sio)) {
+ fprintf(stderr, "WARNING: backward seeking.\n");
+ }
+ serialize_seek(sio, next);
+ } else {
+ uint32_t next = begin + chunk->data_size;
+ if (next < serialize_tell(sio)) {
+ fprintf(stderr, "WARNING: backward seeking.\n");
+ }
+ serialize_seek(sio, next);
+ }
+
+ /* Read children for this chunk. */
+ if (strncmp(chunk->id, "mhlt", 4) == 0 || strncmp(chunk->id, "mhlp", 4) == 0) {
+ /* chunk->chunk_size represents the number of children for "mhlt" and "mhlp" chunks */
+ chunk->num_children = chunk->chunk_size;
+ chunk->childlen = (itunesdb_chunk_t*)calloc(chunk->num_children, sizeof(itunesdb_chunk_t));
+ for (i = 0;i < chunk->num_children;++i) {
+ itunesdb_read(&chunk->childlen[i], sio);
+ }
+ } else {
+ /* chunk->chunk_size represents the size in bytes of this chunk */
+ chunk->num_children = 0;
+ chunk->childlen = NULL;
+ while (sio->offset - begin < chunk->chunk_size) {
+ chunk->num_children;
+ chunk->childlen = realloc(chunk->childlen, sizeof(itunesdb_chunk_t) * (chunk->num_children + 1));
+ memset(&chunk->childlen[chunk->num_children], 0, sizeof(itunesdb_chunk_t));
+ itunesdb_read(&chunk->childlen[chunk->num_children], sio);
+ ++chunk->num_children;
+ }
+ }
+
+ return 0;
+}
+
+#if 0
+int main(int argc, char *argv[])
+{
+ FILE *fp = fopen("C:\\pmplib\\ipod_nano\\iPod_Control\\iTunes\\iTunesDB", "rb");
+ if (fp) {
+ serializer_t sio;
+ uint8_t* buffer = NULL;
+ long size = 0;
+ itunesdb_chunk_t root;
+
+ fread_all(fp, &buffer, &size);
+ fclose(fp);
+
+ serialize_init_read(&sio, buffer, (size_t)size);
+ chunk_read(&root, &sio);
+ serialize_finish(&sio);
+
+ serialize_init_dump(&sio, stdout, 2);
+ chunk_repr(&root, 0, &sio);
+ serialize_finish(&sio);
+ }
+
+ return 0;
+}
+#endif
\ No newline at end of file
Property changes on: trunk/pmplib/lib/pmp_ipod/itunesdb.c
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: trunk/pmplib/lib/pmp_ipod/itunesdb.h
===================================================================
--- trunk/pmplib/lib/pmp_ipod/itunesdb.h (rev 0)
+++ trunk/pmplib/lib/pmp_ipod/itunesdb.h 2007-02-21 15:56:22 UTC (rev 382)
@@ -0,0 +1,247 @@
+/*
+ * iTunesDB
+ *
+ * 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 __ITUNESDB_H__
+#define __ITUNESDB_H__
+
+typedef struct {
+ uint32_t unknown1; /* always set to 1. */
+ uint32_t version;
+ uint32_t num_children;
+ uint64_t identifier;
+ uint16_t unknown2; /* always set to 2. */
+ uint16_t unknown3; /* 0x0263 */
+ uint64_t unknown4;
+ uint8_t unknown5[26]; /* zero padded. */
+ uint8_t language[2]; /* e.g., "en", "ja" */
+ uint8_t unknown6[32]; /* zero padded. */
+} chunk_mhbd_t;
+
+typedef struct {
+ uint32_t type; /* 1 (track list), 2 (playlist list), or 3 (podcast list). */
+ uint8_t unknown1[16*5]; /* zero padded. */
+} chunk_mhsd_t;
+
+typedef struct {
+ uint8_t unknown1[16*5]; /* zero padded. */
+} chunk_mhlt_t;
+
+typedef struct {
+ uint32_t num_children;
+ uint32_t uid;
+ uint32_t visible;
+ uint32_t filetype;
+ uint8_t type1;
+ uint8_t type2;
+ uint8_t compilation;
+ uint8_t rating;
+ uint32_t last_modified;
+ uint32_t filesize;
+ uint32_t duration;
+ uint32_t track_number;
+ uint32_t total_tracks;
+ uint32_t year;
+ uint32_t bitrate; /* in [kbps] */
+ uint16_t unknown1;
+ uint16_t samplerate; /* in [Hz] */
+ int32_t volume;
+ uint32_t start_time;
+ uint32_t stop_time;
+ uint32_t sound_check;
+ uint32_t play_count;
+ uint32_t play_count2;
+ uint32_t last_played;
+ uint32_t disc_number;
+ uint32_t total_discs;
+ uint32_t user_id;
+ uint32_t date_added;
+ uint32_t bookmark_time;
+ uint64_t dbid;
+ uint8_t is_checked;
+ uint8_t rating_itunes;
+ uint16_t bpm;
+ uint16_t num_artworks;
+ uint16_t unk9;
+ uint32_t artwork_size;
+ uint32_t unk11;
+ uint32_t samplerate2;
+ uint32_t disc_released;
+ uint16_t unk14_1;
+ uint16_t unk14_2;
+ uint32_t unk15;
+ uint32_t unk16;
+ uint32_t skip_count;
+ uint32_t last_skipped;
+ uint8_t has_artwork;
+ uint8_t skip_when_shuffling;
+ uint8_t remember_playback_position;
+ uint8_t flag4;
+ uint64_t dbid2;
+ uint8_t has_lyrics;
+ uint8_t is_movie;
+ uint8_t is_played;
+ uint8_t unk17;
+ uint32_t unk21;
+ int32_t encoder_delay;
+ uint64_t num_samples;
+ uint32_t unk25;
+ int32_t padding_samples;
+ uint32_t unk27;
+ uint32_t media_type;
+ uint32_t season_number;
+ uint32_t episode_number;
+ uint32_t unk31;
+ uint32_t unk32;
+ uint32_t unk33;
+ uint32_t unk34;
+ uint32_t unk35;
+ uint32_t unk36;
+ uint32_t unk37;
+ uint32_t offset_last8th_frame;
+ uint32_t unk38;
+ uint16_t gapless_track;
+ uint16_t gapless_album;
+} chunk_mhit_t;
+
+typedef struct {
+ uint8_t unknown1[16*5]; /* zero padded. */
+} chunk_mhlp_t;
+
+typedef struct {
+ uint32_t num_mhod;
+ uint32_t num_mhip;
+ uint8_t flag_master;
+ uint8_t flag_unkonwn1;
+ uint8_t flag_unkonwn2;
+ uint8_t flag_unkonwn3;
+ uint32_t timestamp;
+ uint64_t id;
+ uint32_t unk3;
+ uint16_t unk4;
+ uint16_t flag_podcast;
+ uint32_t sort_order;
+ uint8_t padding[0x3C];
+} chunk_mhyp_t;
+
+typedef struct {
+ uint32_t num_mhod;
+ uint32_t flag_podcast_group;
+ uint32_t group_id;
+ uint32_t track_id;
+ uint32_t timestamp;
+ uint32_t podcast_parent;
+} chunk_mhip_t;
+
+typedef struct {
+ uint32_t unk1;
+ uint32_t unk2;
+ uint32_t position;
+ uint32_t size;
+ uint32_t unknown;
+ uint32_t unk4;
+ ucs2char_t* value;
+} chunk_mhod_string_t;
+
+typedef struct {
+ uint32_t unk1;
+ uint32_t unk2;
+ char* value;
+} chunk_mhod_url_t;
+
+typedef struct {
+ uint32_t unk1;
+ uint32_t unk2;
+ uint32_t type;
+ uint32_t num_entries;
+ uint8_t padding[40];
+ uint32_t* entries;
+} chunk_mhod_index_t;
+
+typedef struct {
+ uint16_t id;
+ uint16_t width;
+ uint32_t sort_direction;
+ uint64_t padding;
+} chunk_mhod_playlist_column_definition_t;
+
+typedef struct {
+ uint32_t unk1;
+ uint32_t unk2;
+ uint32_t unk3;
+ uint64_t unk4;
+ uint32_t unk8;
+ uint16_t unk9;
+ uint16_t unk10;
+ uint32_t sort_type;
+ uint32_t num_columns;
+ uint32_t unknown;
+ chunk_mhod_playlist_column_definition_t* columns;
+} chunk_mhod_playlist_column_t;
+
+typedef struct {
+ uint32_t unk1;
+ uint32_t unk2;
+ uint32_t position;
+ uint8_t padding[16];
+} chunk_mhod_playlist_order_t;
+
+typedef struct {
+ uint32_t type;
+ union {
+ chunk_mhod_string_t str;
+ chunk_mhod_url_t url;
+ chunk_mhod_index_t index;
+ chunk_mhod_playlist_column_t pc;
+ chunk_mhod_playlist_order_t po;
+ } data;
+} chunk_mhod_t;
+
+
+struct tag_itunesdb_chunk {
+ int8_t id[4];
+ uint32_t data_size;
+ uint32_t chunk_size;
+
+ void* data;
+ uint32_t num_children; /* This field does not exist in iTunesDB. */
+ struct tag_itunesdb_chunk* childlen;
+ uint32_t offset; /* This field does not exist in iTunesDB. */
+};
+
+typedef struct {
+ uint32_t type;
+ const char* name;
+ size_t chunk_size;
+ int (*serialize)(itunesdb_chunk_t* chunk, const char *name, serializer_t* sio);
+} itunesdb_mhoddecl_t;
+
+typedef struct {
+ const char* name;
+ size_t data_size;
+ int (*serialize)(itunesdb_chunk_t* chunk, serializer_t* sio);
+} itunesdb_chunkdecl_t;
+
+int itunesdb_repr(itunesdb_chunk_t* chunk, size_t index, serializer_t* sio);
+int itunesdb_read(itunesdb_chunk_t* chunk, serializer_t* sio);
+
+#endif/*__ITUNESDB_H__*/
Property changes on: trunk/pmplib/lib/pmp_ipod/itunesdb.h
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: trunk/pmplib/lib/pmp_ipod/pmp_ipod.c
===================================================================
--- trunk/pmplib/lib/pmp_ipod/pmp_ipod.c (rev 0)
+++ trunk/pmplib/lib/pmp_ipod/pmp_ipod.c 2007-02-21 15:56:22 UTC (rev 382)
@@ -0,0 +1,625 @@
+/*
+ * PMP library implementation for Apple iPod series.
+ *
+ * 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 <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif/*HAVE_STRING_H*/
+#include <pmplib/ucs2char.h>
+#include <pmplib/filepath.h>
+#include <pmplib/pmp.h>
+
+#include "util.h"
+#include "ipod.h"
+
+#ifdef PMP_IPOD_EXPORTS
+#define PMPIPODAPI __declspec(dllexport)
+#else
+#define PMPIPODAPI
+#endif
+
+
+typedef struct {
+ const char *id;
+ const char *manufacturer;
+ const char *name;
+ const char *mode;
+ const char *min_version;
+ const char *max_version;
+ const char *itunesdb_filename;
+ const char *extensions;
+ uint32_t codecs[8];
+ const char *path_to_system;
+ const char *path_to_music;
+ const char *path_to_playlist;
+} ipod_descriptor_t;
+
+static const ipod_descriptor_t g_model_descriptions[] = {
+ {
+ "ipod", "Apple", "iPod", "UM",
+ "---", "---",
+ "iPod_Control\\iTunes\\iTunesDB",
+ ".mp3\0",
+ {PMPCODEC_MPEGLAYER3, 0, 0, 0, 0, 0, 0, 0},
+ "iPod_Control", "iPod_Control\\Music", "Playlists",
+ },
+ {
+ NULL, NULL, NULL, NULL,
+ NULL, NULL,
+ NULL,
+ NULL,
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ NULL, NULL, NULL,
+ },
+};
+
+typedef struct {
+ const ipod_descriptor_t* decl;
+} pmp_internal_t;
+
+typedef struct {
+ pmp_music_record_t* records;
+ int num_records;
+ pmp_playlist_t* playlists;
+ int num_playlists;
+} pmp_music_internal_t;
+
+static uint32_t pmp_add_ref(pmp_t* pmp);
+static uint32_t pmp_release(pmp_t* pmp);
+static result_t pmp_open(pmp_t* pmp, uint32_t flag);
+static result_t pmp_close(pmp_t* pmp);
+static result_t pmp_create_instance_music(pmp_t* pmp, pmp_music_t** ptr_pmpdb);
+
+static uint32_t pmpmusic_release(pmp_music_t* music);
+static uint32_t pmpmusic_open(pmp_music_t* music);
+static uint32_t pmpmusic_close(pmp_music_t* music);
+static result_t pmpmusic_set_records(pmp_music_t* music, const pmp_music_record_t* records, uint32_t num_records);
+static result_t pmpmusic_get_records(pmp_music_t* music, pmp_music_record_t* records, uint32_t* num_records);
+static result_t pmpmusic_dump(pmp_music_t* music, FILE *fp, int level);
+static result_t pmpmusic_set_playlists(pmp_music_t* music, const pmp_playlist_t* playlists, uint32_t num_playlists);
+
+
+#define COMP(a, b) ((a)>(b))-((a)<(b))
+
+static char* strip(char *str)
+{
+ char *p = str + strlen(str) - 1;
+ while (*str && isspace(*str)) {
+ str++;
+ }
+ while (str <= p && isspace(*p)) {
+ *p-- = 0;
+ }
+ return str;
+}
+
+static const char *strcpy_if_empty(char *dst, const char *src)
+{
+ return *dst ? dst : strcpy(dst, src);
+}
+
+static void set_device_info(
+ const char *id,
+ const ucs2char_t* path_to_device,
+ const ipod_descriptor_t* md,
+ pmp_device_information_t* info
+ )
+{
+ uint32_t n;
+ const char *p = NULL;
+ ucs2char_t* ucs2 = NULL;
+ pmp_device_description_t* decl = (pmp_device_description_t*)&info->decl;
+
+ strcpy_if_empty(decl->id, id);
+ strcpy_if_empty(decl->manufacturer, md->manufacturer);
+ strcpy_if_empty(decl->name, md->name);
+ strcpy_if_empty(decl->mode, md->mode);
+ strcpy_if_empty(decl->min_version, md->min_version);
+ strcpy_if_empty(decl->max_version, md->max_version);
+
+ ucs2cpy(info->path_to_root, path_to_device);
+
+ ucs2 = mbsdupucs2(md->path_to_system);
+ ucs2cpy(info->path_to_system, ucs2);
+ ucs2free(ucs2);
+
+ ucs2 = mbsdupucs2(md->path_to_music);
+ ucs2cpy(info->path_to_music, ucs2);
+ ucs2free(ucs2);
+
+ ucs2 = mbsdupucs2(md->path_to_playlist);
+ ucs2cpy(info->path_to_playlist, ucs2);
+ ucs2free(ucs2);
+
+ info->music_flag = PMPMF_SUPPORT | PMPMF_RECURSIVE;
+ info->playlist_flag = PMPPF_SUPPORT;
+
+ // Audio codecs.
+ for (n = 0;md->codecs[n];++n) ;
+ info->num_audio_codecs = n;
+ info->audio_codecs = (uint32_t*)ucs2malloc(sizeof(uint32_t) * info->num_audio_codecs);
+ for (n = 0;n < info->num_audio_codecs;++n) {
+ info->audio_codecs[n] = md->codecs[n];
+ }
+
+ // Obtain the number of extensions separated by '\0' characters.
+ for (n = 0, p = md->extensions;*p;p += (strlen(p)+1)) {
+ n++;
+ }
+ info->num_audio_extensions = n;
+ info->audio_extensions = (ucs2char_t**)ucs2malloc(sizeof(ucs2char_t*) * info->num_audio_extensions);
+ for (n = 0, p = md->extensions;*p;p += (strlen(p)+1)) {
+ info->audio_extensions[n++] = mbsdupucs2(p);
+ }
+}
+
+static void free_device_info(pmp_device_information_t* info)
+{
+ uint32_t i;
+ for (i = 0;i < info->num_audio_extensions;++i) {
+ ucs2free(info->audio_extensions[i]);
+ }
+ ucs2free(info->audio_codecs);
+ ucs2free(info->audio_extensions);
+ memset(info, 0, sizeof(*info));
+}
+
+static void set_filenames(ucs2char_t *itunesdb, 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);
+}
+
+
+static int compare_version(const char *x, const char *y)
+{
+ char *p = NULL, *q = NULL;
+
+ for (;;) {
+ long a = strtol(x, &p, 10);
+ long b = strtol(y, &q, 10);
+ int value = COMP(a, b);
+ if (value != 0) {
+ return value;
+ }
+ if (!*p || !*q || *p != *q) {
+ return COMP(*p, *q);
+ }
+ x = p+1;
+ y = q+1;
+ }
+}
+
+
+
+PMPIPODAPI result_t pmp_enumerate_devid(pmplib_enumerate_devid_callback_t callback, void *instance)
+{
+ const ipod_descriptor_t* md = g_model_descriptions;
+ for (;md->id;++md) {
+ callback(instance, md->id);
+ }
+ return 0;
+}
+
+PMPIPODAPI result_t pmp_create(pmp_t** ptr_pmp, const ucs2char_t* path_to_device, const char *id)
+{
+ result_t ret = 0;
+ pmp_t* pmp = NULL;
+ pmp_internal_t* pmpi = NULL;
+ const ipod_descriptor_t* md = NULL;
+ pmp_device_information_t info;
+
+ // Initialize device information.
+ memset(&info, 0, sizeof(info));
+
+ // Return a NULL pointer by default.
+ *ptr_pmp = 0;
+
+ // Find a suitable model for the device.
+ md = g_model_descriptions;
+ for (;md->id;++md) {
+ if (id && *id) {
+ // Match the device identifier.
+ if (strcmp(md->id, id) == 0) {
+ // This will fill some members in decl.
+ //detect_model(path_to_device, md, &info);
+ set_device_info(id, path_to_device, md, &info);
+ break;
+ }
+ }
+ }
+
+ if (!md->id) {
+ return PMPERR_DEVICENOTFOUND;
+ }
+
+ // Allocate PMP class instance.
+ pmp = (pmp_t*)calloc(1, sizeof(pmp_t));
+ if (!pmp) {
+ return PMPERR_INSUFFICIENTMEMORY;
+ }
+
+ pmp->add_ref = pmp_add_ref;
+ pmp->release = pmp_release;
+ pmp->open = pmp_open;
+ pmp->close = pmp_close;
+ pmp->add_ref(pmp);
+
+ // Allocate the internal variables.
+ pmpi = (pmp_internal_t*)calloc(1, sizeof(pmp_internal_t));
+ if (!pmpi) {
+ free(pmp);
+ return PMPERR_INSUFFICIENTMEMORY;
+ }
+ pmpi->decl = md;
+
+ // Initialize the internal variables.
+ pmp->instance = pmpi;
+ memcpy((pmp_device_information_t*)&pmp->info, &info, sizeof(info));
+
+ // Create music instance.
+ ret = pmp_create_instance_music(pmp, &pmp->music);
+ if (ret != 0) {
+ pmp_release(pmp);
+ return ret;
+ }
+
+ // Prepare
+ *ptr_pmp = pmp;
+ return 0;
+}
+
+static uint32_t pmp_add_ref(pmp_t* pmp)
+{
+ return pmplib_interlocked_increment(&pmp->ref_count);
+}
+
+static uint32_t pmp_release(pmp_t* pmp)
+{
+ uint32_t count = pmplib_interlocked_decrement(&pmp->ref_count);
+ if (count == 0) {
+ pmpmusic_release(pmp->music);
+ free_device_info(&pmp->info);
+ free(pmp->instance);
+ free(pmp);
+ }
+ return count;
+}
+
+static result_t pmp_open(pmp_t* pmp, uint32_t flag)
+{
+ result_t ret = 0;
+
+ // Set the open flag.
+ pmp->flag = flag;
+
+ // Open the music database.
+ ret = pmpmusic_open(pmp->music);
+ if (ret) {
+ return ret;
+ }
+
+ return 0;
+}
+
+static result_t pmp_close(pmp_t* pmp)
+{
+ result_t ret = 0;
+
+ // Close the music database.
+ ret = pmpmusic_close(pmp->music);
+ if (ret) {
+ return ret;
+ }
+
+ return 0;
+}
+
+static result_t pmp_create_instance_music(pmp_t* pmp, pmp_music_t** ptr_music)
+{
+ pmp_music_t* music = NULL;
+ pmp_internal_t* pmpi = (pmp_internal_t*)pmp->instance;
+ pmp_music_internal_t* pmpmi = NULL;
+
+ *ptr_music = 0;
+
+ music = calloc(1, sizeof(pmp_music_t));
+ if (!music) {
+ return PMPERR_INSUFFICIENTMEMORY;
+ }
+
+ pmpmi = calloc(1, sizeof(pmp_music_internal_t));
+ if (!pmpmi) {
+ free(music);
+ return PMPERR_INSUFFICIENTMEMORY;
+ }
+
+ music->set_records = pmpmusic_set_records;
+ music->get_records = pmpmusic_get_records;
+ music->dump = pmpmusic_dump;
+ music->set_playlists = pmpmusic_set_playlists;
+ music->pmp = pmp;
+ music->instance = pmpmi;
+
+ *ptr_music = music;
+ return 0;
+}
+
+
+
+
+static uint32_t pmpmusic_release(pmp_music_t* music)
+{
+ pmp_music_internal_t* pmpmi = (pmp_music_internal_t*)music->instance;
+ pmplib_records_finish(pmpmi->records, pmpmi->num_records);
+ pmplib_playlists_finish(pmpmi->playlists, pmpmi->num_playlists);
+ free(pmpmi);
+ free(music);
+ return 0;
+}
+
+static uint32_t pmpmusic_open(pmp_music_t* music)
+{
+ //ip3db_t ip3db;
+ result_t ret = 0;
+ pmp_t* pmp = music->pmp;
+ pmp_music_internal_t* pmpmi = (pmp_music_internal_t*)music->instance;
+
+ /*
+ // Initialize IP3DB.
+ ip3db_init(&ip3db);
+
+ // Free the existing records.
+ pmplib_records_finish(pmpmi->records, pmpmi->num_records);
+ pmpmi->records = 0;
+ pmpmi->num_records = 0;
+
+ // Open the music database if necessary.
+ if (pmp->flag & PMPOF_MUSIC_DB_READ) {
+ int i;
+ ucs2char_t dat[MAX_PATH], dic[MAX_PATH], idx[MAX_PATH];
+ pmp_music_internal_t* pmpmi = (pmp_music_internal_t*)pmp->music->instance;
+
+ // Read the music database.
+ set_filenames(dat, dic, idx, pmp);
+ ret = ip3db_read(&ip3db, dat, dic, idx);
+ if (ret) {
+ goto exit_this;
+ }
+
+ // The number of music records.
+ pmpmi->num_records = ip3db_num_records(&ip3db);
+
+ // Allocate an array of the records.
+ pmpmi->records = (pmp_music_record_t*)malloc(sizeof(pmp_music_record_t) * pmpmi->num_records);
+
+ // Convert IP3DB records to a pmp_music_record_t array.
+ for (i = 0;i < pmpmi->num_records;++i) {
+ const ip3db_variant_t* src = (const ip3db_variant_t*)ip3db_get_record(&ip3db, i);
+ pmp_music_record_t* dst = &pmpmi->records[i];
+ size_t length = 0;
+
+ pmplib_record_init(dst);
+
+ length = ucs2len(pmp->info.path_to_root);
+ length += ucs2len(src[IP3DBF_MUSIC_FILEPATH].value.str);
+ length += ucs2len(src[IP3DBF_MUSIC_FILENAME].value.str);
+ dst->filename = (ucs2char_t*)ucs2malloc(sizeof(ucs2char_t) * (length+1));
+ ucs2cpy(dst->filename, pmp->info.path_to_root);
+ ucs2cat(dst->filename, src[IP3DBF_MUSIC_FILEPATH].value.str+1);
+ ucs2cat(dst->filename, src[IP3DBF_MUSIC_FILENAME].value.str);
+ filepath_backslash(dst->filename);
+
+ dst->title = ucs2dup(src[IP3DBF_MUSIC_TITLE].value.str);
+ dst->artist = ucs2dup(src[IP3DBF_MUSIC_ARTIST].value.str);
+ dst->album = ucs2dup(src[IP3DBF_MUSIC_ALBUM].value.str);
+ dst->genre = ucs2dup(src[IP3DBF_MUSIC_GENRE].value.str);
+ dst->date = ucs2dup(src[IP3DBF_MUSIC_ORGRELEASEDATE].value.str);
+ switch (src[IP3DBF_MUSIC_FILEFORMAT].value.word) {
+ case 0:
+ dst->codec = PMPCODEC_MPEGLAYER3;
+ break;
+ case 3:
+ dst->codec = PMPCODEC_VORBIS;
+ break;
+ case 5:
+ dst->codec = PMPCODEC_WMA;
+ break;
+ }
+ dst->track_number = src[IP3DBF_MUSIC_TRACKNUMBER].value.word;
+ dst->bitrate = src[IP3DBF_MUSIC_BITRATE].value.dword;
+ dst->duration = src[IP3DBF_MUSIC_DURATION].value.dword;
+ dst->ts_update = src[IP3DBF_MUSIC_CLUSA].value.dword;
+ dst->rating = src[IP3DBF_MUSIC_RATING].value.word;
+ }
+ }
+ */
+
+exit_this:
+ //ip3db_finish(&ip3db);
+ return ret;
+}
+
+static uint32_t pmpmusic_close(pmp_music_t* music)
+{
+ //ip3db_t ip3db;
+ result_t ret = 0;
+ pmp_t* pmp = music->pmp;
+ pmp_music_internal_t* pmpmi = (pmp_music_internal_t*)music->instance;
+
+ /*
+ // Initialize IP3DB.
+ ip3db_init(&ip3db);
+
+ if (pmp->flag & PMPOF_MUSIC_DB_WRITE) {
+ int i;
+ ucs2char_t dat[MAX_PATH], dic[MAX_PATH], idx[MAX_PATH];
+ ip3db_music_record_t* records = NULL;
+
+ // Allocate an array of music records.
+ records = (ip3db_music_record_t*)malloc(sizeof(ip3db_music_record_t) * pmpmi->num_records);
+
+ // Build an array of IP3DB records.
+ for (i = 0;i < pmpmi->num_records;++i) {
+ const pmp_music_record_t* src = &pmpmi->records[i];
+ ip3db_variant_t* dst = records[i];
+
+ ip3db_record_init(&ip3db, &records[i]);
+ ip3db_variant_set_str(&dst[IP3DBF_MUSIC_FILEPATH], filepath_changeroot(src->filename, pmp->info.path_to_root));
+ filepath_remove_filespec(dst[IP3DBF_MUSIC_FILEPATH].value.str);
+ filepath_addslash(dst[IP3DBF_MUSIC_FILEPATH].value.str);
+ filepath_slash(dst[IP3DBF_MUSIC_FILEPATH].value.str);
+ ip3db_variant_set_str(&dst[IP3DBF_MUSIC_FILENAME], filepath_skippath(src->filename));
+ ip3db_variant_set_str(&dst[IP3DBF_MUSIC_ARTIST], src->artist);
+ ip3db_variant_set_str(&dst[IP3DBF_MUSIC_ALBUM], src->album);
+ ip3db_variant_set_str(&dst[IP3DBF_MUSIC_GENRE], src->genre);
+ ip3db_variant_set_str(&dst[IP3DBF_MUSIC_TITLE], src->title);
+ ip3db_variant_set_dword(&dst[IP3DBF_MUSIC_DURATION], src->duration);
+ ip3db_variant_set_word(&dst[IP3DBF_MUSIC_RATING], (uint16_t)src->rating);
+ switch (src->codec) {
+ case PMPCODEC_MPEGLAYER3:
+ ip3db_variant_set_word(&dst[IP3DBF_MUSIC_FILEFORMAT], 0);
+ break;
+ case PMPCODEC_VORBIS:
+ ip3db_variant_set_word(&dst[IP3DBF_MUSIC_FILEFORMAT], 3);
+ break;
+ case PMPCODEC_WMA:
+ ip3db_variant_set_word(&dst[IP3DBF_MUSIC_FILEFORMAT], 5);
+ break;
+ }
+ ip3db_variant_set_word(&dst[IP3DBF_MUSIC_TRACKNUMBER], (uint16_t)src->track_number);
+ ip3db_variant_set_dword(&dst[IP3DBF_MUSIC_BITRATE], src->bitrate);
+ ip3db_variant_set_dword(&dst[IP3DBF_MUSIC_CLUSA], src->ts_update);
+ ip3db_variant_set_dword(&dst[IP3DBF_MUSIC_UID], (uint32_t)i+1);
+ }
+
+ // Register records (and playlists) to the database.
+ if (pmp->flag & PMPOF_MUSIC_PL_WRITE) {
+ ip3db_set(
+ &ip3db,
+ (const ip3db_music_record_t*)records,
+ pmpmi->num_records,
+ pmpmi->playlists,
+ pmpmi->num_playlists
+ );
+ } else {
+ ip3db_set(
+ &ip3db,
+ (const ip3db_music_record_t*)records,
+ pmpmi->num_records,
+ NULL,
+ 0
+ );
+ }
+
+ // Write out the music database.
+ set_filenames(dat, dic, idx, pmp);
+ ret = ip3db_write(&ip3db, dat, dic, idx);
+
+ // Free IP3DB records.
+ for (i = 0;i < pmpmi->num_records;++i) {
+ ip3db_record_finish(&ip3db, &records[i]);
+ }
+ free(records);
+ }
+
+ ip3db_finish(&ip3db);
+ */
+ return ret;
+}
+
+static result_t pmpmusic_set_records(pmp_music_t* music, const pmp_music_record_t* records, uint32_t num_records)
+{
+ pmp_t* pmp = music->pmp;
+ pmp_music_internal_t* pmpmi = (pmp_music_internal_t*)music->instance;
+
+ /* Free records attached to pmpmi. */
+ pmplib_records_finish(pmpmi->records, pmpmi->num_records);
+
+ /* Allocate new records. */
+ pmpmi->records = (pmp_music_record_t*)ucs2malloc(sizeof(pmp_music_record_t) * num_records);
+ pmpmi->num_records = num_records;
+ pmplib_records_clone(pmpmi->records, records, num_records);
+
+ return 0;
+ }
+
+static result_t pmpmusic_get_records(pmp_music_t* music, pmp_music_record_t* records, uint32_t* num_records)
+{
+ pmp_t* pmp = music->pmp;
+ pmp_music_internal_t* pmpmi = (pmp_music_internal_t*)music->instance;
+
+ if (!records) {
+ *num_records = pmpmi->num_records;
+ return 0;
+ } else if (*num_records == pmpmi->num_records) {
+ pmplib_records_clone(records, pmpmi->records, pmpmi->num_records);
+ return 0;
+ } else {
+ return PMPERR_INSUFFICIENTMEMORY;
+ }
+}
+
+static result_t pmpmusic_dump(pmp_music_t* music, FILE *fp, int level)
+{
+ ipod_t ipod;
+ result_t ret = 0;
+ ucs2char_t itunesdb[MAX_PATH];
+
+ // Initialize IP3DB.
+ ipod_init(&ipod);
+
+ // Read the music database.
+ set_filenames(itunesdb, music->pmp);
+ ret = ipod_read(&ipod, itunesdb);
+ if (ret) {
+ goto exit_this;
+ }
+
+ ret = ipod_dump(&ipod, fp);
+ if (ret) {
+ goto exit_this;
+ }
+
+exit_this:
+ ipod_finish(&ipod);
+ return ret;
+}
+
+static result_t pmpmusic_set_playlists(pmp_music_t* music, const pmp_playlist_t* playlists, uint32_t num_playlists)
+{
+ return PMPERR_NOTIMPLIMENTED;
+}
Property changes on: trunk/pmplib/lib/pmp_ipod/pmp_ipod.c
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: trunk/pmplib/lib/pmp_ipod/pmp_ipod.vcproj
===================================================================
--- trunk/pmplib/lib/pmp_ipod/pmp_ipod.vcproj (rev 0)
+++ trunk/pmplib/lib/pmp_ipod/pmp_ipod.vcproj 2007-02-21 15:56:22 UTC (rev 382)
@@ -0,0 +1,231 @@
+<?xml version="1.0" encoding="shift_jis"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="pmp_ipod"
+ ProjectGUID="{529F5BE9-291E-4BCF-BE90-5E64B780340F}"
+ RootNamespace="pmp_ipod"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)debug"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(SolutionDir)include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;PMP_IPOD_EXPORTS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)release"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="$(SolutionDir)include"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_USRDLL;PMP_IPOD_EXPORTS"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="\x83\\x81[\x83X \x83t\x83@\x83C\x83\x8B"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\ipod.c"
+ >
+ </File>
+ <File
+ RelativePath=".\itunesdb.c"
+ >
+ </File>
+ <File
+ RelativePath=".\pmp_ipod.c"
+ >
+ </File>
+ <File
+ RelativePath=".\serialize.c"
+ >
+ </File>
+ <File
+ RelativePath=".\util.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="\x83w\x83b\x83_\x81[ \x83t\x83@\x83C\x83\x8B"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\ipod.h"
+ >
+ </File>
+ <File
+ RelativePath=".\itunesdb.h"
+ >
+ </File>
+ <File
+ RelativePath=".\serialize.h"
+ >
+ </File>
+ <File
+ RelativePath=".\util.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="\x83\x8A\x83\\x81[\x83X \x83t\x83@\x83C\x83\x8B"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
Added: trunk/pmplib/lib/pmp_ipod/serialize.c
===================================================================
--- trunk/pmplib/lib/pmp_ipod/serialize.c (rev 0)
+++ trunk/pmplib/lib/pmp_ipod/serialize.c 2007-02-21 15:56:22 UTC (rev 382)
@@ -0,0 +1,303 @@
+/*
+ * Data serializer (with byte-order consideration).
+ *
+ * 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>
+#include <string.h>
+#include <pmplib/ucs2char.h>
+
+#include "util.h"
+#include "serialize.h"
+
+static int check(serializer_t* sio, size_t size)
+{
+ if (0 < sio->mode) {
+ if (sio->size < sio->offset + size) {
+ sio->size += sio->unit;
+ sio->base = (uint8_t*)realloc(sio->base, sio->size);
+ if (!sio->base) {
+ return 1;
+ }
+ }
+ } else if (sio->mode < 0) {
+ if (sio->limit < sio->offset + size) {
+ return 1;
+ }
+ if (sio->size < sio->offset + size) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+void serialize_init_read(serializer_t* sio, uint8_t* base, size_t size)
+{
+ memset(sio, 0, sizeof(*sio));
+ sio->base = base;
+ sio->size = size;
+ sio->limit = size;
+ sio->mode = -1;
+}
+
+void serialize_init_write(serializer_t* sio, size_t unit)
+{
+ memset(sio, 0, sizeof(*sio));
+ sio->unit = unit;
+ sio->mode = 1;
+}
+
+void serialize_init_dump(serializer_t* sio, FILE *fp, size_t unit)
+{
+ memset(sio, 0, sizeof(*sio));
+ sio->fp = fp;
+ sio->unit = unit;
+ sio->mode = 0;
+}
+
+void serialize_finish(serializer_t* sio)
+{
+ if (0 < sio->mode) {
+ free(sio->base);
+ }
+ memset(sio, 0, sizeof(*sio));
+}
+
+
+int serialize_uint8(serializer_t* sio, const char *name, const char *format, uint8_t* value)
+{
+ if (check(sio, sizeof(uint8_t))) return 1;
+
+ if (0 < sio->mode) {
+ sio->base[sio->offset++] = *value;
+ } else if (sio->mode < 0) {
+ *value = sio->base[sio->offset++];
+ } else {
+ serialize_indent(sio);
+ fprintf(sio->fp, "%s: ", name);
+ fprintf(sio->fp, format, *value);
+ fputc('\n', sio->fp);
+ }
+ return 0;
+}
+
+int serialize_uint8_array(serializer_t* sio, const char *name, const char *format, uint8_t* array, size_t length)
+{
+ size_t i;
+
+ if (check(sio, length)) return 1;
+
+ if (0 < sio->mode) {
+ for (i = 0;i < length;++i) {
+ sio->base[sio->offset++] = array[i];
+ }
+ } else if (sio->mode < 0) {
+ for (i = 0;i < length;++i) {
+ array[i] = sio->base[sio->offset++];
+ }
+ } else {
+ serialize_indent(sio);
+ fprintf(sio->fp, "%s: ", name);
+ for (i = 0;i < length;++i) {
+ fprintf(sio->fp, format, array[i]);
+ }
+ fputc('\n', sio->fp);
+ }
+ return 0;
+}
+
+int serialize_uint16le(serializer_t* sio, const char *name, const char *format, uint16_t* value)
+{
+ if (check(sio, sizeof(uint16_t))) return 1;
+
+ if (0 < sio->mode) {
+ sio->base[sio->offset++] = (uint8_t)(*value & 0xFF);
+ sio->base[sio->offset++] = (uint8_t)(*value >> 8);
+ } else if (sio->mode < 0) {
+ *value = ((uint16_t)sio->base[sio->offset++]);
+ *value |= ((uint16_t)sio->base[sio->offset++] << 8);
+ } else {
+ serialize_indent(sio);
+ fprintf(sio->fp, "%s: ", name);
+ fprintf(sio->fp, format, *value);
+ fputc('\n', sio->fp);
+ }
+ return 0;
+}
+
+int serialize_uint32le(serializer_t* sio, const char *name, const char *format, uint32_t* value)
+{
+ if (check(sio, sizeof(uint32_t))) return 1;
+
+ if (0 < sio->mode) {
+ sio->base[sio->offset++] = (uint8_t)(*value & 0xFF);
+ sio->base[sio->offset++] = (uint8_t)(*value >> 8);
+ sio->base[sio->offset++] = (uint8_t)(*value >> 16);
+ sio->base[sio->offset++] = (uint8_t)(*value >> 24);
+ } else if (sio->mode < 0) {
+ *value = ((uint32_t)sio->base[sio->offset++]);
+ *value |= ((uint32_t)sio->base[sio->offset++] << 8);
+ *value |= ((uint32_t)sio->base[sio->offset++] << 16);
+ *value |= ((uint32_t)sio->base[sio->offset++] << 24);
+ } else {
+ serialize_indent(sio);
+ fprintf(sio->fp, "%s: ", name);
+ fprintf(sio->fp, format, *value);
+ fputc('\n', sio->fp);
+ }
+ return 0;
+}
+
+int serialize_int32le(serializer_t* sio, const char *name, const char *format, int32_t* value)
+{
+ return serialize_uint32le(sio, name, format, (uint32_t*)value);
+}
+
+int serialize_uint64le(serializer_t* sio, const char *name, const char *format, uint64_t* value)
+{
+ if ...
[truncated message content] |