1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485
|
/*
* 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.
*/
struct tag_h10db_fd {
uint32_t id; /**< Field identifier. */
uint32_t field_type; /**< 1: UCS2-LE String; 2: uint32_t AFAIK. */
uint32_t max_length; /**< Maximum length of the field */
uint32_t unknown4;
uint32_t unknown5;
uint32_t has_index; /**< 1 if this field needs an index (*.idx), otherwise 0. */
uint32_t unknown6;
uint32_t unknown7;
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
*/
struct tag_h10db_hdr {
uint32_t unknown1; /**< 0 AFAIK */
uint32_t unknown2; /**< 0 AFAIK */
ucs2_char_t pathname_dat[H10DB_PATHLENGTH]; /**< Pathname of H10DB.dat file */
uint32_t unknown3; /**< 1 AFAIK */
ucs2_char_t pathname_hdr[H10DB_PATHLENGTH]; /**< Pathname of H10DB.hdr file */
uint32_t unknown4; /**< Version of the database specification? (0x0000042C) */
uint32_t num_dat_entries; /**< Number of entries in H10DB.DAT */
uint32_t num_dat_inactive_entries; /**< Number of inactive entries in H10DB.DAT */
uint32_t num_dat_fields; /**< H10DB_NUM_DAT_FIELDS (22) AFAIK */
h10db_fd_t fd[H10DB_NUM_DAT_FIELDS]; /**< Field descriptors. */
/**< 1032 bytes padding. */
uint32_t max_dat_field_size[H10DB_NUM_DAT_FIELDS];
uint32_t dat_size; /**< Size of H10DB.dat file */
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.
*/
struct tag_h10db_dat {
uint32_t status; /**< 0 if the element is active, otherwise 1. */
uint32_t unknown1; /**< 0 (Reserved?) */
/* The "field descriptor" in H10DB.hdr defines the following 22 members. */
uint32_t unknown2; /**< ??? */
ucs2_char_t *file_path; /**< Path to the music file. */
ucs2_char_t *file_name; /**< Name of the music file. */
uint32_t media_type; /**< 0: music, 1: picture */
ucs2_char_t *title; /**< Track title. */
ucs2_char_t *artist; /**< Artist name. */
ucs2_char_t *album; /**< Album name. */
ucs2_char_t *genre; /**< Genre. */
uint32_t rating; /**< Rating. (0 to 5) */
uint32_t revision; /**< Revision number. */
uint32_t recent_play; /**< Recent playback time (elapsed time in seconds from "Sat Jan 01 00:00:00 2000") */
uint32_t unknown4; /**< ??? */
uint32_t number; /**< Track number. */
uint32_t year; /**< Year. */
uint32_t filesize; /**< File size. */
uint32_t duration; /**< Duration in seconds (represented by UCS-2 string in H10DB.dat). */
uint32_t samplerate; /**< Sample rate in [Hz]. */
uint32_t bitrate; /**< Bitrate in [bps]. */
uint32_t unknown5; /**< ??? */
ucs2_char_t *unknown6; /**< ??? */
uint32_t unknown7; /**< ??? */
ucs2_char_t *unknown8; /**< ??? */
};
typedef struct tag_h10db_dat h10db_dat_t;
/**
* Structure of an index in H10DB_*.idx.
*/
struct tag_h10db_idx {
uint32_t status; /**< 0 if the element is active, otherwise 1. */
uint32_t index; /**< index number pointing to the entry in H10DB.dat. */
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__*/
|