Logo Search packages:      
Sourcecode: easyh10 version File versions  Download package

h10db.h

/*
 *      H10 database parser/writer.
 *
 *      Copyright (c) 2005 Nyaochi
 *          Copyright (c) 2005 Toby Corkindale (iRiver.pm).
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit
 * http://www.gnu.org/copyleft/gpl.html .
 *
 */

/* $Id: h10db.h,v 1.21 2006/02/07 00:47:53 nyaochi Exp $ */

#ifndef     __H10DB_H__
#define     __H10DB_H__

#include <time.h>

#ifdef      __cplusplus
extern "C" {
#endif/*__cplusplus*/


#define     H10DB_PATHLENGTH        0x100       /**< Maximum length of path/file name. */
#define     H10DB_NUM_DAT_FIELDS    22                /**< The number of fields in h10db_dat excluding status and unknown1. */

struct bfile;

/**
 * Structure of field descriptor.
 */
00044 struct tag_h10db_fd {
00045       uint32_t    id;                     /**< Field identifier. */
00046       uint32_t    field_type;       /**< 1: UCS2-LE String; 2: uint32_t AFAIK. */
00047       uint32_t    max_length;       /**< Maximum length of the field */
      uint32_t    unknown4;
      uint32_t    unknown5;
00050       uint32_t    has_index;        /**< 1 if this field needs an index (*.idx), otherwise 0. */
      uint32_t    unknown6;
      uint32_t    unknown7;
00053       ucs2_char_t index_pathname[H10DB_PATHLENGTH];   /**< Pathname of the index file */
};
typedef struct tag_h10db_fd h10db_fd_t;



/**
 * Field offset array.
 */
typedef uint16_t h10db_field_offsets_t[H10DB_NUM_DAT_FIELDS];



/**
 * Structure of H10DB.hdr
 */
00069 struct tag_h10db_hdr {
00070       uint32_t    unknown1;                                       /**< 0 AFAIK */
00071       uint32_t    unknown2;                                       /**< 0 AFAIK */
00072       ucs2_char_t pathname_dat[H10DB_PATHLENGTH];           /**< Pathname of H10DB.dat file */
00073       uint32_t    unknown3;                                       /**< 1 AFAIK */
00074       ucs2_char_t pathname_hdr[H10DB_PATHLENGTH];           /**< Pathname of H10DB.hdr file */
00075       uint32_t    unknown4;                                       /**< Version of the database specification? (0x0000042C) */
00076       uint32_t    num_dat_entries;                          /**< Number of entries in H10DB.DAT */
00077       uint32_t    num_dat_inactive_entries;                 /**< Number of inactive entries in H10DB.DAT */
00078       uint32_t    num_dat_fields;                                 /**< H10DB_NUM_DAT_FIELDS (22) AFAIK */
00079       h10db_fd_t  fd[H10DB_NUM_DAT_FIELDS];                 /**< Field descriptors. */
                                                                              /**< 1032 bytes padding. */
      uint32_t    max_dat_field_size[H10DB_NUM_DAT_FIELDS];
00082       uint32_t    dat_size;                                       /**< Size of H10DB.dat file */
00083       uint32_t    unknown5;                                       /**< 1 AFAIK (This field exists only in 20GB MTP 2.50) */
      h10db_field_offsets_t *dat_field_offset;        /* [H10DB_MAX_ENTRY] */
      uint32_t    *dat_entry_offset;                              /* [H10DB_MAX_ENTRY+1] */

      /* These fields are not serizlied in H10DB.hdr */
      uint32_t    max_entries;
      uint32_t    padding_size;
      uint32_t    has_unknown5;
};
typedef struct tag_h10db_hdr h10db_hdr_t;



/**
 * Structure of an entry in H10DB.dat.
 */
00099 struct tag_h10db_dat {
00100       uint32_t    status;                 /**< 0 if the element is active, otherwise 1. */
00101       uint32_t    unknown1;         /**< 0 (Reserved?) */

      /* The "field descriptor" in H10DB.hdr defines the following 22 members. */
00104       uint32_t    unknown2;         /**< ??? */
00105       ucs2_char_t *file_path;       /**< Path to the music file. */
00106       ucs2_char_t *file_name;       /**< Name of the music file. */
00107       uint32_t    media_type;       /**< 0: music, 1: picture */
00108       ucs2_char_t *title;                 /**< Track title. */
00109       ucs2_char_t *artist;          /**< Artist name. */
00110       ucs2_char_t *album;                 /**< Album name. */
00111       ucs2_char_t *genre;                 /**< Genre. */
00112       uint32_t    rating;                 /**< Rating. (0 to 5) */
00113       uint32_t    revision;         /**< Revision number. */
00114       uint32_t    recent_play;      /**< Recent playback time (elapsed time in seconds from "Sat Jan 01 00:00:00 2000") */
00115       uint32_t    unknown4;         /**< ??? */
00116       uint32_t    number;                 /**< Track number. */
00117       uint32_t    year;             /**< Year. */
00118       uint32_t    filesize;         /**< File size. */
00119       uint32_t    duration;         /**< Duration in seconds (represented by UCS-2 string in H10DB.dat). */
00120       uint32_t    samplerate;       /**< Sample rate in [Hz]. */
00121       uint32_t    bitrate;          /**< Bitrate in [bps]. */
00122       uint32_t    unknown5;         /**< ??? */
00123       ucs2_char_t *unknown6;        /**< ??? */
00124       uint32_t    unknown7;         /**< ??? */
00125       ucs2_char_t *unknown8;        /**< ??? */
};
typedef struct tag_h10db_dat h10db_dat_t;



/**
 * Structure of an index in H10DB_*.idx.
 */
00134 struct tag_h10db_idx {
00135       uint32_t status;        /**< 0 if the element is active, otherwise 1. */
00136       uint32_t index;               /**< index number pointing to the entry in H10DB.dat. */
00137       uint32_t check_value;   /**< check value of the relevant field in the H10DB.dat entry. */
};
typedef struct tag_h10db_idx h10db_idx_t;



struct tag_h10db_type {
      uint16_t    version;
      uint16_t    model;
      uint16_t    fw_major_min;
      uint16_t    fw_minor_min;
      uint16_t    fw_major_max;
      uint16_t    fw_minor_max;
};
typedef struct tag_h10db_type h10db_type_t;

int h10db_model_findchunk(struct bfile *bfp, const char *chunk_name, uint32_t* chunk_size);
int h10db_model_writechunk(struct bfile *bfp, const char *chunk_name, uint32_t chunk_size, long* offset);
int h10db_model_writechunksize(struct bfile *bfp, long offset, uint32_t chunk_size);

uint32_t h10db_model_get_padding(h10db_type_t* type);
uint32_t h10db_model_get_maxentries(h10db_type_t* type);
uint32_t h10db_model_has_hdr_unknown5(h10db_type_t* type);

void h10db_type_init(h10db_type_t* type, uint32_t h10db_flag);
int h10db_type_read(struct bfile *bfp, h10db_type_t* type);
int h10db_type_write(struct bfile *bfp, h10db_type_t* type);





/*
 * H10DB.hdr
 */
void h10db_hdr_init(h10db_hdr_t* hdr, uint32_t max_entries, uint32_t padding_size, uint32_t has_unknown5);
void h10db_hdr_finish(h10db_hdr_t* hdr);
int h10db_hdr_serialize(struct bfile *bfp, h10db_hdr_t* hdr, int is_storing, int is_template);
void h10db_hdr_repr(FILE *fp, const h10db_hdr_t* hdr);



/*
 * Field descriptor in H10DB.hdr
 */
void h10db_fd_init(h10db_fd_t* hdr_idx);
void h10db_fd_finish(h10db_fd_t* hdr_idx);
int h10db_fd_serialize(struct bfile *bfp, h10db_fd_t* hdr_idx, int is_storing);



/*
 * H10DB.dat
 */
void h10db_dat_init(h10db_dat_t* item);
void h10db_dat_finish(h10db_dat_t* item);
int h10db_dat_serialize(struct bfile *bfp, h10db_dat_t* item, h10db_field_offsets_t offsets, h10db_fd_t* fd, int is_storing);
void h10db_dat_swap(h10db_dat_t* x, h10db_dat_t* y);
void h10db_dat_repr(FILE *fp, const h10db_dat_t* item);
void h10db_dat_validate(FILE *fp, const h10db_dat_t* item);
uint32_t h10db_dat_calculate_checkvalue(const h10db_dat_t* item, int field_index);
int h10db_dat_read(struct bfile *bfp, h10db_dat_t** array_ptr, uint32_t* num_ptr, const h10db_hdr_t* hdr);
int h10db_dat_write(struct bfile *bfp, const h10db_dat_t* array, int num, h10db_hdr_t* hdr);
void h10db_dat_delete(h10db_dat_t* array, int num);



/**
 * \defgroup IDXLowLevel      Low level interface for H10DB_*.idx.
 */
/*@{*/

void h10db_idx_init(h10db_idx_t* item);
int h10db_idx_serialize(struct bfile *bfp, h10db_idx_t* item, int is_storing);
void h10db_idx_swap(h10db_idx_t* x, h10db_idx_t* y);
void h10db_idx_repr(FILE *fp, const h10db_idx_t* item);
int h10db_idx_read(struct bfile *bfp, h10db_idx_t** array_ptr, int* num_ptr);
int h10db_idx_write(struct bfile *bfp, const h10db_idx_t* array, int num);

/*@}*/




/*
 * H10DB.upd
 */
struct tag_h10db_upd_entry {
      uint32_t crc;
      time_t ft;
};
typedef struct tag_h10db_upd_entry h10db_upd_entry_t;

struct tag_h10db_upd {
      uint32_t num;
      h10db_upd_entry_t *array;
};
typedef struct tag_h10db_upd h10db_upd_t;

int h10db_upd_read(h10db_upd_t* upd, struct bfile *bfp);
int h10db_upd_is_updated(h10db_upd_t* upd, uint32_t entry, h10db_dat_t* item, const ucs2_char_t *filename);
int h10db_upd_write(const h10db_upd_t* upd, struct bfile *bfp);


/**
 * \defgroup HighLevelInterface     High Level Interface for H10DB.
 */
/*@{*/

enum {
      H10DB_PROGRESS_NONE = 0,

      H10DB_PROGRESS_IDX_COUNT,

      H10DB_PROGRESS_READ_START,                /* progress: 0, max_progress: 0 */
      H10DB_PROGRESS_READ_END,                  /* progress: 0, max_progress: 0 */
      H10DB_PROGRESS_UPDATE_START,
      H10DB_PROGRESS_UPDATE_END,
      H10DB_PROGRESS_WRITE_START,
      H10DB_PROGRESS_WRITE_END,

      H10DB_PROGRESS_READ_HDR,
      H10DB_PROGRESS_PARSE_HDR,
      H10DB_PROGRESS_READ_DAT,      
      H10DB_PROGRESS_PARSE_DAT,
      H10DB_PROGRESS_READ_IDX,
      H10DB_PROGRESS_PARSE_IDX,
      H10DB_PROGRESS_READ_UPD,
      H10DB_PROGRESS_PARSE_UPD,

      H10DB_PROGRESS_UPDATE_CLEAN,
      H10DB_PROGRESS_UPDATE_IDX,

      H10DB_PROGRESS_GENERATE_IDX,
      H10DB_PROGRESS_WRITE_IDX,
      H10DB_PROGRESS_GENERATE_DAT,
      H10DB_PROGRESS_WRITE_DAT,
      H10DB_PROGRESS_GENERATE_HDR,
      H10DB_PROGRESS_WRITE_HDR,
      H10DB_PROGRESS_GENERATE_UPD,
      H10DB_PROGRESS_WRITE_UPD,

      H10DB_PROGRESS_READ_TEMPLATE,
      H10DB_PROGRESS_WRITE_TEMPLATE,
};


typedef int (*h10db_progress_callback)(void *instance, int msg, int progress, int max_progress);
typedef int (*h10db_error_callback)(void *instance, int code, const char *msg);

struct tag_h10db {
      h10db_type_t*     type;
      h10db_hdr_t*      hdr;
      h10db_dat_t*      dat;
      h10db_idx_t**     idx;
      h10db_upd_t*      upd;

      int flags;

      h10db_progress_callback progress_func;
      h10db_error_callback error_func;
      void *instance;
      int msg;
};
typedef struct tag_h10db h10db_t;

enum {
      H10DB_SUCCESS = 0,
      H10DBE_OUTOFMEMORY,
      H10DBE_DBINCONSISTENCY,

      H10DBE_HDR_OPENR,
      H10DBE_HDR_OPENW,
      H10DBE_HDR_READ,
      H10DBE_HDR_WRITE,

      H10DBE_DAT_OPENR,
      H10DBE_DAT_OPENW,
      H10DBE_DAT_READ,
      H10DBE_DAT_WRITE,
      H10DBE_DAT_ENTRYOFFSET,
      H10DBE_DAT_FIELDOFFSET,

      H10DBE_IDX_OPENR,
      H10DBE_IDX_OPENW,
      H10DBE_IDX_READ,
      H10DBE_IDX_WRITE,

      H10DBE_UPD_OPENR,
      H10DBE_UPD_OPENW,
      H10DBE_UPD_READ,
      H10DBE_UPD_WRITE,

      H10DBE_MODEL_OPENR,
      H10DBE_MODEL_OPENW,
      H10DBE_MODEL_READ,
      H10DBE_MODEL_WRITE,
      H10DBE_MODEL_FINDCHUNK,
};

enum {
      H10DB_UPDATEF_NONE =                            0x00000000,
      H10DB_UPDATEF_CLEAN =                           0x00010000,
      H10DB_FLAG_INCREMENTAL =                        0x00100000,

      H10DB_FIRMWARE_UMS =                            0x00000001,
      H10DB_FIRMWARE_MTP =                            0x00000002,
      H10DB_FIRMWARE_MTP_2_50 =                       0x00000003,
      H10DB_FIRMWARE_MASK =                           0xFFFFFFF0,
      H10DB_FIRMWARE_UNMASK =                         0x0000000F,

      H10DB_CAPACITY_1GB =                            0x00000100,
      H10DB_CAPACITY_2GB =                            0x00000200,
      H10DB_CAPACITY_5GB =                            0x00000500,
      H10DB_CAPACITY_6GB =                            0x00000600,
      H10DB_CAPACITY_20GB =                           0x00001400,
      H10DB_CAPACITY_MASK =                           0xFFFF00FF,
      H10DB_CAPACITY_UNMASK =                         0x0000FF00,
};


/**
 * Create an instance of h10db_t.
 *    @param      flags             The flags.
 *    @return                             The pointer to the instance if succeeded, otherwise NULL.
 */
h10db_t* h10db_new(int flags);

/**
 * Delete an h10db_t instance.
 *    @param      h10db             The pointer to the h10db_t instance.
 */
void h10db_delete(h10db_t* h10db);

/**
 * Set the instance value for callback.
 *    @param      h10db             The pointer to the h10db_t instance.
 *    @param      instance          The instance value that is to be sent to the callback function.
 */
void h10db_set_instance(h10db_t* h10db, void *instance);

/**
 * Register a callback function for progress notification.
 *    @param      h10db             The pointer to the h10db_t instance.
 *    @param      pfn                     The pointer to a function that receives progress notification.
 */
void h10db_set_progress_callback(h10db_t* h10db, h10db_progress_callback pfn);

/**
 * Read an existing H10 database.
 *    @param      h10db             The pointer to the h10db_t instance.
 *    @param      path              The path to the H10 database.
 *    @return                             0 if succeeded, otherwise -1.
 */
int h10db_read(h10db_t* h10db, const ucs2_char_t *path);

/**
 * Write an H10 database.
 *    @param      h10db             The pointer to the h10db_t instance.
 *    @param      path              The path to the H10 database.
 *    @return                             0 if succeeded, otherwise -1.
 */
int h10db_write(h10db_t* h10db, const ucs2_char_t *path);

int h10db_load_model(h10db_t* h10db, const ucs2_char_t *filename);
h10db_type_t* h10db_access_type(h10db_t* h10db);
int h10db_store_model(h10db_t* h10db, const ucs2_char_t *filename);

/**
 * Update the H10 database.
 *    @param      h10db             The pointer to the h10db_t instance.
 *    @param      flags             The operation flags.
 *    @return                             0 if succeeded, otherwise -1.
 */
int h10db_update(h10db_t* h10db, int flags);

int h10db_is_updated_item(h10db_t* h10db, int index, const ucs2_char_t *filename);

/**
 * Get the number of entries in H10 database.
 *    @param      h10db             The pointer to the h10db_t instance.
 *    @return                             The number of entries.
 */
int h10db_get_size(h10db_t* h10db);

/**
 * Resize the array of entries in H10 database.
 *    @param      h10db             The pointer to the h10db_t instance.
 *    @param      size              The number of entries that the H10 database should store.
 *    @return                             The nuw nunber of entries.
 */
int h10db_resize(h10db_t* h10db, int size);

/* Obsolute: delete this function in future. */
h10db_dat_t* h10db_access_item(h10db_t* h10db, int index);

int h10db_set_filepath(h10db_t* h10db, int index, const ucs2_char_t* value);
int h10db_set_filename(h10db_t* h10db, int index, const ucs2_char_t* value);
int h10db_set_title(h10db_t* h10db, int index, const ucs2_char_t* value);
int h10db_set_artist(h10db_t* h10db, int index, const ucs2_char_t* value);
int h10db_set_album(h10db_t* h10db, int index, const ucs2_char_t* value);
int h10db_set_genre(h10db_t* h10db, int index, const ucs2_char_t* value);
int h10db_set_unknown6(h10db_t* h10db, int index, const ucs2_char_t* value);
int h10db_set_unknown8(h10db_t* h10db, int index, const ucs2_char_t* value);
int h10db_set_tracknumber(h10db_t* h10db, int index, uint32_t tracknumber);
int h10db_set_year(h10db_t* h10db, int index, uint32_t year);
int h10db_set_filesize(h10db_t* h10db, int index, uint32_t filesize);
int h10db_set_duration(h10db_t* h10db, int index, uint32_t duration);
int h10db_set_samplerate(h10db_t* h10db, int index, uint32_t samplerate);
int h10db_set_bitrate(h10db_t* h10db, int index, uint32_t bitrate);
int h10db_set_unknown4(h10db_t* h10db, int index, uint32_t value);
int h10db_set_unknown5(h10db_t* h10db, int index, uint32_t value);

const ucs2_char_t* h10db_get_filepath(h10db_t* h10db, int index);
const ucs2_char_t* h10db_get_filename(h10db_t* h10db, int index);
const ucs2_char_t* h10db_get_title(h10db_t* h10db, int index);
const ucs2_char_t* h10db_get_artist(h10db_t* h10db, int index);
const ucs2_char_t* h10db_get_album(h10db_t* h10db, int index);
const ucs2_char_t* h10db_get_genre(h10db_t* h10db, int index);
const ucs2_char_t* h10db_get_unknown6(h10db_t* h10db, int index);
const ucs2_char_t* h10db_get_unknown8(h10db_t* h10db, int index);
uint32_t h10db_get_tracknumber(h10db_t* h10db, int index);
uint32_t h10db_get_year(h10db_t* h10db, int index);
uint32_t h10db_get_filesize(h10db_t* h10db, int index);
uint32_t h10db_get_duration(h10db_t* h10db, int index);
uint32_t h10db_get_samplerate(h10db_t* h10db, int index);
uint32_t h10db_get_bitrate(h10db_t* h10db, int index);
uint32_t h10db_get_unknown4(h10db_t* h10db, int index);
uint32_t h10db_get_unknown5(h10db_t* h10db, int index);

void h10db_fit_fields(h10db_t* h10db, int index);
void h10db_righttoleft_encode_fields(h10db_t* h10db, int index);
void h10db_righttoleft_decode_fields(h10db_t* h10db, int index);

uint16_t h10db_get_model(h10db_t* h10db);
uint16_t h10db_get_capacity(h10db_t* h10db);
uint16_t h10db_get_type(h10db_t* h10db);
uint16_t h10db_get_fw_major_min(h10db_t* h10db);
uint16_t h10db_get_fw_minor_min(h10db_t* h10db);
uint16_t h10db_get_fw_major_max(h10db_t* h10db);
uint16_t h10db_get_fw_minor_max(h10db_t* h10db);

/*@}*/

#ifdef      __cplusplus
}
#endif/*__cplusplus*/

#endif/*__H10DB_H__*/

Generated by  Doxygen 1.6.0   Back to index