From: <ny...@us...> - 2006-12-31 07:38:08
|
Revision: 230 http://svn.sourceforge.net/pmplib/?rev=230&view=rev Author: nyaochi Date: 2006-12-30 23:38:06 -0800 (Sat, 30 Dec 2006) Log Message: ----------- - Database update for iriver E10. - Playlist conversion for iriver E10. Modified Paths: -------------- trunk/pmplib/lib/pmp_iriverplus3/dat.c trunk/pmplib/lib/pmp_iriverplus3/dat.h trunk/pmplib/lib/pmp_iriverplus3/ip3db.c trunk/pmplib/lib/pmp_iriverplus3/ip3db.h trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.vcproj trunk/pmplib/lib/pmp_iriverplus3/util.c trunk/pmplib/lib/pmp_iriverplus3/util.h Added Paths: ----------- trunk/pmplib/lib/pmp_iriverplus3/playlist.c Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-29 15:59:14 UTC (rev 229) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-31 07:38:06 UTC (rev 230) @@ -47,6 +47,7 @@ #include "dat.h" #define PAGESIZE 0x00020000 +#define COMP(a, b) ((a)>(b))-((a)<(b)) typedef struct { uint32_t size; @@ -55,6 +56,11 @@ uint32_t next_page; } page_header_t; +struct tag_sort_index_t { + const void* base; + int index; +}; + static void dat_entry_init(dat_entry_t* entry, const dic_table_t* dic_list) { memset(entry, 0, sizeof(*entry)); @@ -292,9 +298,75 @@ +static int comp_object_uid(const void *__x, const void *__y) +{ + const sort_index_t* _x = (const sort_index_t*)__x; + const sort_index_t* _y = (const sort_index_t*)__y; + const dat_list_t* _xb = (const dat_list_t*)_x->base; + const dat_list_t* _yb = (const dat_list_t*)_y->base; + const ip3db_variant_t* x = _xb->entries[_x->index].fields; + const ip3db_variant_t* y = _yb->entries[_y->index].fields; + return COMP(x[IP3DBF_OBJECTS_UID].value.dword, y[IP3DBF_OBJECTS_UID].value.dword); +} + +static sort_index_t* dat_uidmap_create(dat_list_t* list) +{ + int i; + sort_index_t* si = (sort_index_t*)malloc(sizeof(sort_index_t) * list->num_entries); + + if (si) { + /* Sort UIDs. */ + for (i = 0;i < list->num_entries;++i) { + si[i].base = list; + si[i].index = i; + } + qsort(si, list->num_entries, sizeof(si[0]), comp_object_uid); + } + return si; +} + +static void dat_uidmap_finish(sort_index_t* si) +{ + free(si); +} + +static int dat_uidmap_get(sort_index_t* si, dat_list_t* list, uint32_t uid) +{ + int low = 0, high = list->num_entries-1; + + /* Binary search. */ + while (low <= high) { + int middle = (low + high) / 2; + int comp = COMP(uid, list->entries[si[middle].index].fields[IP3DBF_OBJECTS_UID].value.dword); + if (comp == 0) { + /* Found */ + return si[middle].index; + } else if (comp < 0) { + high = middle - 1; + } else { + low = middle + 1; + } + } + return -1; +} + +static ucs2char_t* ucs2append(const ucs2char_t* x, const ucs2char_t* y) +{ + ucs2char_t* ret = NULL; + size_t length = 0; + length += x ? ucs2len(x) : 0; + length += y ? ucs2len(y) : 0; + ret = ucs2calloc(sizeof(ucs2char_t) * (length+1)); + if (x) ucs2cat(ret, x); + if (y) ucs2cat(ret, y); + return ret; +} + + + dat_t* dat_new() { - dat_t* dat = (dat_t*)malloc(sizeof(dat_t)); + dat_t* dat = (dat_t*)calloc(1, sizeof(dat_t)); if (dat) { dat_list_init(&dat->objects); dat_list_init(&dat->musics); @@ -311,6 +383,7 @@ int dat_read(dat_t* dat, const dic_t* dic, FILE *fpi) { + uint32_t i = 0; page_header_t ph; long buffer_size = 0; uint8_t* buffer = NULL; @@ -330,6 +403,10 @@ dat_list_read(&dat->objects, &ph, &dic->objects, buffer, PAGESIZE * (ph.next_page - 1)); } + /* Construct Object UID -> dat->objects[i] mapping table. */ + dat_uidmap_finish(dat->objects_uidmap); + dat->objects_uidmap = dat_uidmap_create(&dat->objects); + /* Clear Music records. */ dat_list_finish(&dat->musics); @@ -339,6 +416,48 @@ dat_list_read(&dat->musics, &ph, &dic->music, buffer, PAGESIZE * (ph.next_page - 1)); } + /* Set filename and pathname fields. */ + for (i = 0;i < dat->musics.num_entries;++i) { + dat_entry_t* entry = &dat->musics.entries[i]; + int index = dat_uidmap_get(dat->objects_uidmap, &dat->objects, entry->fields[IP3DBF_MUSIC_UID].value.dword); + if (0 <= index) { + static const ucs2char_t ucs2cs_root[] = {'/',0}; + ucs2char_t* pathname = NULL; + ucs2char_t* tmp = NULL; + size_t length = 0; + + /* Set the filename. */ + ip3db_variant_set_str( + &entry->fields[IP3DBF_MUSIC_FILENAME], + dat->objects.entries[index].fields[IP3DBF_OBJECTS_OBJECTNAME].value.str + ); + + /* Obtain the pathname by tracing parent UIDs. */ + for (;;) { + uint32_t parent_uid = dat->objects.entries[index].fields[IP3DBF_OBJECTS_PARENTUID].value.dword; + if (parent_uid == 0xFFFFFFFF) { + break; + } + index = dat_uidmap_get(dat->objects_uidmap, &dat->objects, parent_uid); + if (index < 0) { + break; + } + tmp = ucs2append( + dat->objects.entries[index].fields[IP3DBF_OBJECTS_OBJECTNAME].value.str, + pathname + ); + ucs2free(pathname); + pathname = tmp; + } + + tmp = ucs2append(ucs2cs_root, pathname); + ucs2free(pathname); + pathname = tmp; + ip3db_variant_set_str(&entry->fields[IP3DBF_MUSIC_FILEPATH], pathname); + ucs2free(pathname); + } + } + free(buffer); return 0; } @@ -484,17 +603,14 @@ -typedef struct { - const ip3db_music_record_t* base; - int index; -} sort_index_t; - static int comp_pathname(const void *__x, const void *__y) { const sort_index_t* _x = (const sort_index_t*)__x; const sort_index_t* _y = (const sort_index_t*)__y; - const ip3db_variant_t* x = _x->base[_x->index]; - const ip3db_variant_t* y = _y->base[_y->index]; + const ip3db_music_record_t* _xb = (const ip3db_music_record_t*)_x->base; + const ip3db_music_record_t* _yb = (const ip3db_music_record_t*)_y->base; + const ip3db_variant_t* x = _xb[_x->index]; + const ip3db_variant_t* y = _yb[_y->index]; int ret = ucs2cmp(x[IP3DBF_MUSIC_FILEPATH].value.str, y[IP3DBF_MUSIC_FILEPATH].value.str); if (ret == 0) { return ucs2cmp(x[IP3DBF_MUSIC_FILENAME].value.str, y[IP3DBF_MUSIC_FILENAME].value.str); @@ -554,6 +670,7 @@ /* Clear all entries. */ dat_list_finish(dato); dat_list_finish(datm); + dat_uidmap_finish(dat->objects_uidmap); /* Append an entry for the root directory. */ entry = dat_list_expand(dato); @@ -638,4 +755,6 @@ } dircache_finish(&dc); + + dat->objects_uidmap = dat_uidmap_create(&dat->objects); } Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.h 2006-12-29 15:59:14 UTC (rev 229) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.h 2006-12-31 07:38:06 UTC (rev 230) @@ -35,9 +35,12 @@ dat_entry_t* entries; } dat_list_t; +struct tag_sort_index_t; typedef struct tag_sort_index_t sort_index_t; + struct tag_dat_t { dat_list_t objects; dat_list_t musics; + sort_index_t* objects_uidmap; }; dat_t* dat_new(); Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-29 15:59:14 UTC (rev 229) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-31 07:38:06 UTC (rev 230) @@ -220,6 +220,16 @@ return 0; } +int ip3db_num_records(ip3db_t* db) +{ + return (int)db->dat->musics.num_entries; +} + +ip3db_music_record_t* ip3db_get_record(ip3db_t* db, int i) +{ + return (ip3db_music_record_t*)db->dat->musics.entries[i].fields; +} + void ip3db_record_init(ip3db_t* db, ip3db_music_record_t* record) { int i; Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.h 2006-12-29 15:59:14 UTC (rev 229) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.h 2006-12-31 07:38:06 UTC (rev 230) @@ -181,7 +181,16 @@ result_t ip3db_read(ip3db_t* db, const ucs2char_t* datfn, const ucs2char_t* dicfn, const ucs2char_t* idxfn); result_t ip3db_write(ip3db_t* db, const ucs2char_t* datfn, const ucs2char_t* dicfn, const ucs2char_t* idxfn); result_t ip3db_set(ip3db_t* db, const ip3db_music_record_t* records, int num_records); +int ip3db_num_records(ip3db_t* db); +ip3db_music_record_t* ip3db_get_record(ip3db_t* db, int i); result_t ip3db_dump(ip3db_t* db, FILE *fpo); +int ip3db_playlist_write( + ip3db_t* db, + const ucs2char_t *filename, + ucs2char_t* const mediafiles[], + int num_mediafiles, + const ucs2char_t *path_to_root + ); void ip3db_record_init(ip3db_t* db, ip3db_music_record_t* record); Added: trunk/pmplib/lib/pmp_iriverplus3/playlist.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/playlist.c (rev 0) +++ trunk/pmplib/lib/pmp_iriverplus3/playlist.c 2006-12-31 07:38:06 UTC (rev 230) @@ -0,0 +1,120 @@ +/* + * Playlist reader/writer for iriver E10. + * + * Copyright (c) 2005-2006 Nyaochi + * + * 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 <ucs2char.h> +#include <filepath.h> + +#include "serialize.h" +#include "util.h" +#include "ip3db.h" +#include "dat.h" + +static uint32_t findfile(ip3db_t* db, const ucs2char_t *filename, const ucs2char_t *path_to_root) +{ + int i; + const ucs2char_t *filepart = filepath_skippath(filename); + const ucs2char_t *pathfile = filepath_skipdrive(filename, path_to_root); + ucs2char_t *pathname = alloca(sizeof(ucs2char_t) * (ucs2len(pathfile) + 1)); + + ucs2cpy(pathname, pathfile); + filepath_remove_filespec(pathname); + filepath_addslash(pathname); + filepath_slash(pathname); + + for (i = 0;i < db->dat->musics.num_entries;++i) { + dat_entry_t* entry = &db->dat->musics.entries[i]; + if (ucs2icmp(entry->fields[IP3DBF_MUSIC_FILENAME].value.str, filepart) == 0 && + ucs2icmp(entry->fields[IP3DBF_MUSIC_FILEPATH].value.str, pathname) == 0) { + return entry->fields[IP3DBF_MUSIC_UID].value.dword; + } + } + return 0; +} + +int ip3db_playlist_write( + ip3db_t* db, + const ucs2char_t *filename, + ucs2char_t* const mediafiles[], + int num_mediafiles, + const ucs2char_t *path_to_root + ) +{ + int i; + FILE *fp = NULL; + uint32_t* uids = NULL; + uint32_t num_uids = 0; + + for (i = 0;i < num_mediafiles;i++) { + if (mediafiles[i][0]) { + uint32_t uid = 0; + ucs2char_t mediafile[MAX_PATH]; + ucs2cpy(mediafile, mediafiles[i]); + + uid = findfile(db, mediafile, path_to_root); + if (uid <= 0) { + goto error_exit; + } + + uids = realloc(uids, sizeof(uint32_t) * (num_uids+1)); + if (!uids) { + goto error_exit; + } + uids[num_uids++] = uid; + } + } + + fp = ucs2fopen(filename, "wb"); + if (fp) { + size_t size = sizeof(uint32_t) + sizeof(uint32_t) * num_uids; + uint8_t* buffer = (uint8_t*)malloc(size); + uint8_t* p = buffer; + + if (!buffer) { + goto error_exit; + } + + p += serialize_uint32le(p, &num_uids, 1); + for (i = 0;i < (int)num_uids;++i) { + p += serialize_uint32le(p, &uids[i], 1); + } + fwrite(buffer, 1, size, fp); + free(buffer); + fclose(fp); + } else { + return -1; + } + + free(uids); + return 0; + +error_exit: + free(uids); + return -1; +} Property changes on: trunk/pmplib/lib/pmp_iriverplus3/playlist.c ___________________________________________________________________ Name: svn:keywords + Id Modified: trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c 2006-12-29 15:59:14 UTC (rev 229) +++ trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c 2006-12-31 07:38:06 UTC (rev 230) @@ -37,6 +37,7 @@ #include <pmphelp.h> #include "ip3db.h" +#include "util.h" #ifdef PMP_IRIVERPLUS3_EXPORTS #define PMPIRIVERPLUS3API __declspec(dllexport) @@ -62,8 +63,8 @@ static const ip3model_descriptor_t g_model_descriptions[] = { { - "iriver_e10_ums_1.04", "E10 UMS", "UM", - "1.04", "1.04", + "iriver_e10_ums_1.00-1.04", "E10 UMS", "UM", + "1.00", "1.04", "System\\E10.SYS", "System\\db.dat", "System\\db.dic", "System\\db.idx", "", "Playlists\\", ".plp", @@ -433,7 +434,30 @@ pmppl_internal_t* pmppli = NULL; *ptr_pmppl = 0; - return PMP_NOTIMPLIMENTED; + + pmppl = calloc(1, sizeof(pmppl_t)); + if (!pmppl) { + return PMPDBE_OUTOFMEMORY; + } + + pmppl->add_ref = pmppl_add_ref; + pmppl->release = pmppl_release; + pmppl->write = pmppl_write; + + pmppli = calloc(1, sizeof(pmppl_internal_t)); + if (!pmppli) { + free(pmppl); + return PMPDBE_OUTOFMEMORY; + } + ip3db_init(&pmppli->ip3db); + ip3db_read(&pmppli->ip3db, pmpi->env.dat_filename, pmpi->env.dic_filename, pmpi->env.idx_filename); + + pmppl->pmp = pmp; + pmppl->instance = pmppli; + + pmppl->add_ref(pmppl); + *ptr_pmppl = pmppl; + return 0; } @@ -515,38 +539,22 @@ return (path + length); } -static int _filepath_slash(ucs2char_t* path) -{ - while (*path) { - if (*path == 0x005C) { - *path = 0x002F; - } - path++; - } - return 0; -} - static result_t pmpdb_set(pmpdb_t* pmpdb, const pmp_record_t* records, uint32_t num_records) { int i; pmpdb_internal_t* pmpdbi = (pmpdb_internal_t*)pmpdb->instance; pmp_internal_t* pmpi = (pmp_internal_t*)pmpdb->pmp->instance; - ucs2char_t *path_to_root = alloca(sizeof(ucs2char_t) * (ucs2len(pmpi->env.path_to_root)+1)); - ip3db_music_record_t* array = (ip3db_music_record_t*)malloc(sizeof(ip3db_music_record_t) * num_records); - ucs2cpy(path_to_root, pmpi->env.path_to_root); - _filepath_removeslash(path_to_root); - for (i = 0;i < num_records;++i) { const pmp_record_t* src = &records[i]; ip3db_variant_t* dst = array[i]; ip3db_record_init(&pmpdbi->ip3db, &array[i]); - ip3db_variant_set_str(&dst[IP3DBF_MUSIC_FILEPATH], src->filename + ucs2len(path_to_root)); + ip3db_variant_set_str(&dst[IP3DBF_MUSIC_FILEPATH], filepath_skipdrive(src->filename, pmpi->env.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); + 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); @@ -567,21 +575,67 @@ } 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); } ip3db_set(&pmpdbi->ip3db, array, num_records); free(array); return 0; - //return ip2db_set(&pmpdbi->ip2db, records, num_records, pmpi->env.path_to_root); -} + } static result_t pmpdb_get(pmpdb_t* pmpdb, pmp_record_t* records, uint32_t* num_records) { pmpdb_internal_t* pmpdbi = (pmpdb_internal_t*)pmpdb->instance; pmp_internal_t* pmpi = (pmp_internal_t*)pmpdb->pmp->instance; - return PMP_NOTIMPLIMENTED; - //return ip2db_get(&pmpdbi->ip2db, records, num_records, pmpi->env.path_to_root); + ucs2char_t *path_to_root = alloca(sizeof(ucs2char_t) * (ucs2len(pmpi->env.path_to_root)+1)); + ip3db_t* db = &pmpdbi->ip3db; + int i, n = ip3db_num_records(db); + + if (!records) { + *num_records = (uint32_t)n; + return 0; + } + + for (i = 0;i < n;++i) { + const ip3db_variant_t* src = (const ip3db_variant_t*)ip3db_get_record(db, i); + pmp_record_t* dst = &records[i]; + size_t length = 0; + + pmp_record_init(dst); + + length = ucs2len(pmpi->env.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, pmpi->env.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; + } + return 0; } static result_t pmpdb_dump(pmpdb_t* pmpdb, FILE *fp, int level) @@ -618,11 +672,8 @@ { pmppl_internal_t* pmppli = (pmppl_internal_t*)pmppl->instance; pmp_internal_t* pmpi = (pmp_internal_t*)pmppl->pmp->instance; - return PMP_NOTIMPLIMENTED; - /* - if (ip2db_playlist_write(&pmppli->ip2db, filename, files, num_files, pmpi->env.path_to_root) != 0) { + if (ip3db_playlist_write(&pmppli->ip3db, filename, files, num_files, pmpi->env.path_to_root) != 0) { return PMPPLE_WRITE; } return 0; - */ } Modified: trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.vcproj =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.vcproj 2006-12-29 15:59:14 UTC (rev 229) +++ trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.vcproj 2006-12-31 07:38:06 UTC (rev 230) @@ -193,6 +193,10 @@ > </File> <File + RelativePath=".\playlist.c" + > + </File> + <File RelativePath=".\pmp_iriverplus3.c" > </File> Modified: trunk/pmplib/lib/pmp_iriverplus3/util.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/util.c 2006-12-29 15:59:14 UTC (rev 229) +++ trunk/pmplib/lib/pmp_iriverplus3/util.c 2006-12-31 07:38:06 UTC (rev 230) @@ -148,3 +148,24 @@ *ptr_size = size; return 0; } + +void filepath_slash(ucs2char_t* path) +{ + while (*path) { + if (*path == 0x005C) { + *path = 0x002F; + } + path++; + } +} + +void filepath_backslash(ucs2char_t* path) +{ + while (*path) { + if (*path == 0x002F) { + *path = 0x005C; + } + path++; + } +} + Modified: trunk/pmplib/lib/pmp_iriverplus3/util.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/util.h 2006-12-29 15:59:14 UTC (rev 229) +++ trunk/pmplib/lib/pmp_iriverplus3/util.h 2006-12-31 07:38:06 UTC (rev 230) @@ -35,4 +35,7 @@ int fread_all(FILE *fp, uint8_t** ptr_buffer, long* ptr_size); +void filepath_slash(ucs2char_t* path); +void filepath_backslash(ucs2char_t* path); + #endif/*__IP3DB_UTIL_H__*/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |