You can subscribe to this list here.
2006 |
Jan
|
Feb
|
Mar
(2) |
Apr
(4) |
May
(6) |
Jun
(56) |
Jul
(101) |
Aug
(14) |
Sep
|
Oct
(1) |
Nov
|
Dec
(40) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2007 |
Jan
(66) |
Feb
(106) |
Mar
(1) |
Apr
(2) |
May
(2) |
Jun
|
Jul
|
Aug
|
Sep
(10) |
Oct
(7) |
Nov
|
Dec
|
2008 |
Jan
(1) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <ny...@us...> - 2006-12-29 06:27:47
|
Revision: 225 http://svn.sourceforge.net/pmplib/?rev=225&view=rev Author: nyaochi Date: 2006-12-28 22:27:47 -0800 (Thu, 28 Dec 2006) Log Message: ----------- - EasyPMP [Win32 GUI] is now compatible with MSVC2005. - Removed a reference to the manifest file from the resource. Modified Paths: -------------- trunk/pmplib/frontend/easypmp/win32gui/easypmp_win32gui.rc trunk/pmplib/frontend/easypmp/win32gui/easypmp_win32gui.vcproj trunk/pmplib/frontend/easypmp/win32gui/preference.h trunk/pmplib/frontend/easypmp/win32gui/processingdlg.h trunk/pmplib/frontend/easypmp/win32gui/stdafx.h Modified: trunk/pmplib/frontend/easypmp/win32gui/easypmp_win32gui.rc =================================================================== --- trunk/pmplib/frontend/easypmp/win32gui/easypmp_win32gui.rc 2006-12-29 04:51:14 UTC (rev 224) +++ trunk/pmplib/frontend/easypmp/win32gui/easypmp_win32gui.rc 2006-12-29 06:27:47 UTC (rev 225) @@ -343,7 +343,7 @@ // // Generated from the TEXTINCLUDE 3 resource. // -CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "res\\easypmp_win32gui.exe.manifest" +//CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "res\\easypmp_win32gui.exe.manifest" ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED Modified: trunk/pmplib/frontend/easypmp/win32gui/easypmp_win32gui.vcproj =================================================================== --- trunk/pmplib/frontend/easypmp/win32gui/easypmp_win32gui.vcproj 2006-12-29 04:51:14 UTC (rev 224) +++ trunk/pmplib/frontend/easypmp/win32gui/easypmp_win32gui.vcproj 2006-12-29 06:27:47 UTC (rev 225) @@ -269,26 +269,6 @@ > </File> <File - RelativePath=".\res\easypmp_win32gui.exe.manifest" - > - <FileConfiguration - Name="Debug|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - </File> - <File RelativePath=".\res\easypmp_win32gui.ico" > </File> Modified: trunk/pmplib/frontend/easypmp/win32gui/preference.h =================================================================== --- trunk/pmplib/frontend/easypmp/win32gui/preference.h 2006-12-29 04:51:14 UTC (rev 224) +++ trunk/pmplib/frontend/easypmp/win32gui/preference.h 2006-12-29 06:27:47 UTC (rev 225) @@ -199,7 +199,7 @@ USES_CONVERSION; if (pmp) { - strPlayerLocation = W2CT(pmp->env.path_to_root.path); + strPlayerLocation = UCS2CT(pmp->env.path_to_root.path); strPlayerIdentifier = A2CT(pmp->env.id); strPlayerDescription = A2CT(pmp->env.name); strPlayerDescription += _T(""); @@ -228,7 +228,7 @@ strPlayerIdentifier = _T(""); strPlayerDescription = _T(""); - res = pmphelp_create(pmphelp, &pmp, T2CW(szLocation), NULL); + res = pmphelp_create(pmphelp, &pmp, T2CUCS(szLocation), NULL); if (res == 0 && pmp) { setPlayerInformation(pmp); pmp->release(pmp); Modified: trunk/pmplib/frontend/easypmp/win32gui/processingdlg.h =================================================================== --- trunk/pmplib/frontend/easypmp/win32gui/processingdlg.h 2006-12-29 04:51:14 UTC (rev 224) +++ trunk/pmplib/frontend/easypmp/win32gui/processingdlg.h 2006-12-29 06:27:47 UTC (rev 225) @@ -268,7 +268,8 @@ // Set words to be stripped from artist names. if (!m_preference.strStripWords.IsEmpty()) { - easypmp_set_strip_words(&opt, CT2CW(m_preference.strStripWords)); + LPCWSTR lpwszStripWords = CT2CW(m_preference.strStripWords); + easypmp_set_strip_words(&opt, CW2CUCS(lpwszStripWords)); opt.media_info_source |= GMIF_STRIP_ARTIST; } @@ -285,14 +286,16 @@ // Set path to the root folder. m_preference.GetPathToPlayerRoot(str); - ucs2cpy(opt.path_to_root, T2CW(str)); + ucs2cpy(opt.path_to_root, T2CUCS(str)); // Set path to the include folder. - ::GetModuleFileNameW(_Module.GetModuleInstance(), opt.path_to_include, MAX_PATH); - ::PathRemoveFileSpecW(opt.path_to_include); - ::PathAddBackslashW(opt.path_to_include); - ucs2cat(opt.path_to_include, A2W("jspl")); - ::PathAddBackslashW(opt.path_to_include); + TCHAR jspl_include[MAX_PATH]; + ::GetModuleFileName(_Module.GetModuleInstance(), jspl_include, MAX_PATH); + ::PathRemoveFileSpec(jspl_include); + ::PathAddBackslash(jspl_include); + ::lstrcat(jspl_include, A2W("jspl")); + ::PathAddBackslash(jspl_include); + ucs2cpy(opt.path_to_include, T2CUCS(jspl_include)); // Set model if (!m_preference.strPlayerIdentifier.IsEmpty()) { @@ -470,10 +473,10 @@ CString str; USES_CONVERSION; CProcessingDlg* dlg = (CProcessingDlg*)instance; - str.Format(_T("(%d) %s"), n, W2CT(file)); + str.Format(_T("(%d) %s"), n, UCS2CT(file)); dlg->setProgress(PHASE_ENUMERATE_MUSIC, str); - str = W2CT(path); - str += W2CT(file); + str = UCS2CT(path); + str += UCS2CT(file); dlg->write_log(LL_TRACE, _T("[%d] %s"), n, str); return (dlg->m_bCancel) ? -1 : 0; } @@ -489,10 +492,10 @@ CString str; USES_CONVERSION; CProcessingDlg* dlg = (CProcessingDlg*)instance; - str.Format(_T("(%d) %s"), n, W2CT(file)); + str.Format(_T("(%d) %s"), n, UCS2CT(file)); dlg->setProgress(PHASE_ENUMERATE_PLAYLIST, str); - str = W2CT(path); - str += W2CT(file); + str = UCS2CT(path); + str += UCS2CT(file); dlg->write_log(LL_TRACE, _T("[%d] %s"), n, str); return (dlg->m_bCancel) ? -1 : 0; } @@ -543,10 +546,10 @@ dlg->write_log(LL_TRACE, _T("[Obtaining media information]")); break; case EASYPMPDBP_GMI|EASYPMPSP_PROGRESS: - str.Format(_T("(%d) %s"), param_int+1, W2CT(filepath_skippath(param_str))); + str.Format(_T("(%d) %s"), param_int+1, UCS2CT(filepath_skippath(param_str))); dlg->m_ctrlProgress.SetText(str); dlg->m_ctrlProgress.SetPos(param_int); - dlg->write_log(LL_TRACE, _T("%s"), W2CT(param_str)); + dlg->write_log(LL_TRACE, _T("%s"), UCS2CT(param_str)); break; case EASYPMPDBP_GMI|EASYPMPSP_END: dlg->m_ctrlProgress.ShowWindow(SW_HIDE); @@ -590,27 +593,27 @@ dlg->write_log(LL_TRACE, _T("[Playlist conversion]")); break; case EASYPMPPLP_CONVERT|EASYPMPSP_PROGRESS: - str.Format(_T("(%d) %s"), param_int+1, W2CT(filepath_skippath(param_str))); + str.Format(_T("(%d) %s"), param_int+1, UCS2CT(filepath_skippath(param_str))); dlg->m_ctrlProgress.SetText(str); dlg->m_ctrlProgress.SetPos(param_int); - dlg->write_log(LL_TRACE, _T("%s"), W2CT(param_str)); + dlg->write_log(LL_TRACE, _T("%s"), UCS2CT(param_str)); break; case EASYPMPPLP_CONVERT|EASYPMPSP_WARN_PLAYLIST: dlg->m_bFailed = TRUE; - dlg->write_log(LL_WARNING, _T("WARNING: %s"), W2CT(param_str)); + dlg->write_log(LL_WARNING, _T("WARNING: %s"), UCS2CT(param_str)); break; case EASYPMPPLP_CONVERT|EASYPMPSP_SKIP_PLAYLIST: dlg->m_bFailed = TRUE; - dlg->write_log(LL_ERROR, _T("ERROR: %s"), W2CT(param_str)); + dlg->write_log(LL_ERROR, _T("ERROR: %s"), UCS2CT(param_str)); break; case EASYPMPPLP_CONVERT|EASYPMPSP_MISSING_MEDIA: - dlg->write_log(LL_INFO, _T(" %s"), W2CT(param_str)); + dlg->write_log(LL_INFO, _T(" %s"), UCS2CT(param_str)); break; case EASYPMPPLP_CONVERT|EASYPMPSP_JSPL_ERROR: - dlg->write_log(LL_ERROR, _T("JSPL(ERROR): %s"), W2CT(param_str)); + dlg->write_log(LL_ERROR, _T("JSPL(ERROR): %s"), UCS2CT(param_str)); break; case EASYPMPPLP_CONVERT|EASYPMPSP_JSPL_OUTPUT: - dlg->write_log(LL_INFO, _T("JSPL: %s"), W2CT(param_str)); + dlg->write_log(LL_INFO, _T("JSPL: %s"), UCS2CT(param_str)); break; case EASYPMPPLP_CONVERT|EASYPMPSP_END: dlg->m_ctrlProgress.ShowWindow(SW_HIDE); @@ -672,10 +675,10 @@ write_log(LL_TRACE, _T("Firmware mode: %s"), A2CT(pmp->env.mode)); write_log(LL_INFO, _T("Firmware version: %s"), A2CT(pmp->env.version)); write_log(LL_TRACE, _T("Default language: %s"), A2CT(pmp->env.language)); - write_log(LL_TRACE, _T("Root directory: %s"), W2CT(pmp->env.path_to_root.path)); - write_log(LL_TRACE, _T("Music directory: %s"), W2CT(pmp->env.path_to_music.path)); - write_log(LL_TRACE, _T("Playlist directory: %s"), W2CT(pmp->env.path_to_playlist.path)); - write_log(LL_TRACE, _T("Playlist extension: %s"), W2CT(pmp->env.playlist_ext)); + write_log(LL_TRACE, _T("Root directory: %s"), UCS2CT(pmp->env.path_to_root.path)); + write_log(LL_TRACE, _T("Music directory: %s"), UCS2CT(pmp->env.path_to_music.path)); + write_log(LL_TRACE, _T("Playlist directory: %s"), UCS2CT(pmp->env.path_to_playlist.path)); + write_log(LL_TRACE, _T("Playlist extension: %s"), UCS2CT(pmp->env.playlist_ext)); write_log(LL_INFO, _T("")); } Modified: trunk/pmplib/frontend/easypmp/win32gui/stdafx.h =================================================================== --- trunk/pmplib/frontend/easypmp/win32gui/stdafx.h 2006-12-29 04:51:14 UTC (rev 224) +++ trunk/pmplib/frontend/easypmp/win32gui/stdafx.h 2006-12-29 06:27:47 UTC (rev 225) @@ -5,12 +5,18 @@ #pragma once +#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"") + // Change these values to use different versions #define WINVER 0x0410 #define _WIN32_WINNT 0x0500 #define _WIN32_IE 0x0500 #define _RICHEDIT_VER 0x0100 +#if _MSC_VER >= 1400 +#define _CRT_SECURE_NO_DEPRECATE 1 /* Use 'unsafe' CRT routines. */ +#endif/*_MSC_VER*/ + #include <atlbase.h> #if _ATL_VER >= 0x0700 #include <atlcoll.h> @@ -33,3 +39,9 @@ #include <atlddx.h> #include <imagehlp.h> + +#define UCS2CT(x) W2CT(reinterpret_cast<LPCWSTR>(x)) +#define CW2CUCS(x) reinterpret_cast<const ucs2char_t*>(x) +#define T2CUCS(x) reinterpret_cast<const ucs2char_t*>(T2CW(x)) +#define UCS2W(x) reinterpret_cast<LPWSTR>(x) +#define UCS2CW(x) reinterpret_cast<LPCWSTR>(x) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2006-12-29 04:51:13
|
Revision: 224 http://svn.sourceforge.net/pmplib/?rev=224&view=rev Author: nyaochi Date: 2006-12-28 20:51:14 -0800 (Thu, 28 Dec 2006) Log Message: ----------- Fixed a critical bug in ucs2incmp() Modified Paths: -------------- trunk/pmplib/lib/ucs2/ucs2char.c Modified: trunk/pmplib/lib/ucs2/ucs2char.c =================================================================== --- trunk/pmplib/lib/ucs2/ucs2char.c 2006-12-29 03:02:59 UTC (rev 223) +++ trunk/pmplib/lib/ucs2/ucs2char.c 2006-12-29 04:51:14 UTC (rev 224) @@ -208,7 +208,7 @@ x++; y++; } - return COMP(a, b); + return COMP(ucs2upper(*x), ucs2upper(*y)); } int ucs2memcmp(const ucs2char_t* buf1, const ucs2char_t* buf2, size_t count) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2006-12-29 03:02:59
|
Revision: 223 http://svn.sourceforge.net/pmplib/?rev=223&view=rev Author: nyaochi Date: 2006-12-28 19:02:59 -0800 (Thu, 28 Dec 2006) Log Message: ----------- Skip articles ('a', 'an', 'the') when sorting strings. This is the required specification for the comparison function in AVL trees. Modified Paths: -------------- trunk/pmplib/lib/pmp_iriverplus3/idx.c Modified: trunk/pmplib/lib/pmp_iriverplus3/idx.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-29 01:59:32 UTC (rev 222) +++ trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-29 03:02:59 UTC (rev 223) @@ -320,12 +320,34 @@ return COMP(*x, *y); } +static const ucs2char_t* skip_prefix(const ucs2char_t* str) +{ + int i = 0; + static const ucs2char_t ucs2cs_a[] = {'a',' ',0}; + static const ucs2char_t ucs2cs_an[] = {'a','n',' ',0}; + static const ucs2char_t ucs2cs_the[] = {'t','h','e',' ',0}; + static const ucs2char_t *prefix[] = { + ucs2cs_a, ucs2cs_an, ucs2cs_the, NULL, + }; + + while (prefix[i]) { + if (ucs2incmp(str, prefix[i], ucs2len(prefix[i])) == 0) { + return str + ucs2len(prefix[i]); + } + ++i; + } + return str; +} + static int avl_comp_ucs2string(avl_t* avl, uint32_t _x, uint32_t _y) { - ucs2char_t* x = (ucs2char_t*)(avl->buffer + _x); - ucs2char_t* y = (ucs2char_t*)(avl->buffer + _y); ucs2char_t a, b; + const ucs2char_t* x = (const ucs2char_t*)(avl->buffer + _x); + const ucs2char_t* y = (const ucs2char_t*)(avl->buffer + _y); + x = skip_prefix(x); + y = skip_prefix(y); + do { a = ucs2upper(*x); b = ucs2upper(*y); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2006-12-29 01:59:31
|
Revision: 222 http://svn.sourceforge.net/pmplib/?rev=222&view=rev Author: nyaochi Date: 2006-12-28 17:59:32 -0800 (Thu, 28 Dec 2006) Log Message: ----------- Some bug fixes: - Avoid id3_file_fdopen() since it will close files multiple times with fclose() and id_file_close(id3file) - Initialize new memory blocks allocated for db.dat - Avoid crossing a page boundary in db.idx - Change the algorithm to sort strings in db.idx to case-insensitive. Modified Paths: -------------- trunk/pmplib/lib/gmi/gmi_mp3.c trunk/pmplib/lib/pmp_iriverplus3/dat.c trunk/pmplib/lib/pmp_iriverplus3/idx.c Modified: trunk/pmplib/lib/gmi/gmi_mp3.c =================================================================== --- trunk/pmplib/lib/gmi/gmi_mp3.c 2006-12-28 17:40:06 UTC (rev 221) +++ trunk/pmplib/lib/gmi/gmi_mp3.c 2006-12-29 01:59:32 UTC (rev 222) @@ -334,16 +334,11 @@ ucs2char_t* ucs2 = NULL; struct id3_file *id3file = NULL; struct id3_tag *id3tag = NULL; + char* pathname = ucs2dupmbs(filename); - /* Open the file with UNICODE filename. This is for better compatibility. */ - fp = ucs2fopen(filename, "rb"); - if (!fp) { - return -1; - } - /* Open with libid3tag */ - /*id3file = id3_file_open(pathname, ID3_FILE_MODE_READONLY);*/ - id3file = id3_file_fdopen(fileno(fp), ID3_FILE_MODE_READONLY); + id3file = id3_file_open(pathname, ID3_FILE_MODE_READONLY); + ucs2free(pathname); if (!id3file) { fclose(fp); return -1; Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-28 17:40:06 UTC (rev 221) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-29 01:59:32 UTC (rev 222) @@ -364,6 +364,7 @@ uint32_t page = ph.next_page++; buffer_size = PAGESIZE * page; buffer = (uint8_t*)realloc(buffer, sizeof(uint8_t) * buffer_size); + memset(buffer + PAGESIZE * (page - 1), 0, PAGESIZE); i += ph.num_entries; dat_list_write(&dat->objects, i, &ph, buffer, PAGESIZE * (page - 1)); dic->header.num_dat_pages += 1; @@ -386,6 +387,7 @@ uint32_t page = ph.next_page++; buffer_size = PAGESIZE * page; buffer = (uint8_t*)realloc(buffer, sizeof(uint8_t) * buffer_size); + memset(buffer + PAGESIZE * (page - 1), 0, PAGESIZE); i += ph.num_entries; dat_list_write(&dat->musics, i, &ph, buffer, PAGESIZE * (page - 1)); dic->header.num_dat_pages += 1; Modified: trunk/pmplib/lib/pmp_iriverplus3/idx.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-28 17:40:06 UTC (rev 221) +++ trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-29 01:59:32 UTC (rev 222) @@ -117,6 +117,10 @@ memset(avl->buffer + avl->size, 0, PAGESIZE); avl->offset = avl->size + sizeof(header_t); avl->size = newsize; + } else if (((avl->offset + size) / PAGESIZE) != (avl->offset / PAGESIZE)) { + /* Avoid crossing a page boundary. */ + uint32_t page = (avl->offset + size) / PAGESIZE; + avl->offset = PAGESIZE * page + sizeof(header_t); } /* Allocate a memory block. */ @@ -320,11 +324,18 @@ { ucs2char_t* x = (ucs2char_t*)(avl->buffer + _x); ucs2char_t* y = (ucs2char_t*)(avl->buffer + _y); - while (*x && *y && *x == *y) { + ucs2char_t a, b; + + do { + a = ucs2upper(*x); + b = ucs2upper(*y); + if (!*x || !*y) { + break; + } x++; y++; - } - return COMP(*x, *y); + } while (a == b); + return COMP(a, b); } static int avl_insert_key(avl_t* avl, const ip3db_variant_t* key, int type, uint32_t* offset, uint32_t* root) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2006-12-28 17:40:06
|
Revision: 221 http://svn.sourceforge.net/pmplib/?rev=221&view=rev Author: nyaochi Date: 2006-12-28 09:40:06 -0800 (Thu, 28 Dec 2006) Log Message: ----------- Fixed a bug in db.dat generator. Modified Paths: -------------- trunk/pmplib/lib/pmp_iriverplus3/dat.c Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-28 17:19:09 UTC (rev 220) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-28 17:40:06 UTC (rev 221) @@ -379,6 +379,7 @@ /* Write Music page(s) */ i = 0; + ph.next_page = dic->header.num_dat_pages + 2; dat_list_write(&dat->musics, i, &ph, buffer, PAGESIZE * 1); dic->header.num_dat_pages += 1; while (ph.next_page) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2006-12-28 17:19:12
|
Revision: 220 http://svn.sourceforge.net/pmplib/?rev=220&view=rev Author: nyaochi Date: 2006-12-28 09:19:09 -0800 (Thu, 28 Dec 2006) Log Message: ----------- Fixed a bug. Pointers might be invalid after a realloc() call. Modified Paths: -------------- trunk/pmplib/lib/pmp_iriverplus3/idx.c trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c Modified: trunk/pmplib/lib/pmp_iriverplus3/idx.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-28 16:56:01 UTC (rev 219) +++ trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-28 17:19:09 UTC (rev 220) @@ -743,11 +743,23 @@ int type = dictbl->fields[field].type; int ret = avl_insert_key(idx->avl, &entry->fields[field], type, &offset, root); if (level+1 < IP3DBIDX_MAX_KEYLEVEL && dictbl->indices[index].fields[level+1] != -1) { + /* The following code does not work since we cannot guarantee that node->tail + * is valid after idx_insert_dat() call, which may move the memory block to + * expand it (realloc). + * avlnode_t* node = avlnode(idx->avl, offset); + * idx_insert_dat(idx, dictbl, &node->tail, entry, index, level+1); + * Therefore, we need to update node->tail after idx_insert_dat() call. + */ avlnode_t* node = avlnode(idx->avl, offset); - idx_insert_dat(idx, dictbl, &node->tail, entry, index, level+1); + uint32_t child = node->tail; + idx_insert_dat(idx, dictbl, &child, entry, index, level+1); + node = avlnode(idx->avl, offset); + node->tail = child; } else { + /* The same here. We must obtain the pointer to the node after avltail_new() call. + */ + uint32_t offset_tail = avltail_new(idx->avl); avlnode_t* node = avlnode(idx->avl, offset); - uint32_t offset_tail = avltail_new(idx->avl); avltail_t* tail = (avltail_t*)avlnode(idx->avl, offset_tail); tail->data = entry->offset; tail->next = node->tail; Modified: trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c 2006-12-28 16:56:01 UTC (rev 219) +++ trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c 2006-12-28 17:19:09 UTC (rev 220) @@ -65,7 +65,7 @@ "iriver_e10_ums_1.04", "E10 UMS", "UM", "1.04", "1.04", "System\\E10.SYS", "System\\db.dat", "System\\db.dic", "System\\db.idx", - "Music2\\", "Playlists\\", + "", "Playlists\\", ".plp", }, { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2006-12-28 16:56:02
|
Revision: 219 http://svn.sourceforge.net/pmplib/?rev=219&view=rev Author: nyaochi Date: 2006-12-28 08:56:01 -0800 (Thu, 28 Dec 2006) Log Message: ----------- Do not cross a page boundary with AVL node and key. Modified Paths: -------------- trunk/pmplib/lib/pmp_iriverplus3/dat.c trunk/pmplib/lib/pmp_iriverplus3/idx.c Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-28 16:22:43 UTC (rev 218) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-28 16:56:01 UTC (rev 219) @@ -369,7 +369,15 @@ dic->header.num_dat_pages += 1; } - /* Read Music page(s) */ + /* Clear filepath and filename */ + for (i = 0;i < dat->musics.num_entries;++i) { + static const ucs2char_t empty[] = {0}; + dat_entry_t* entry = &dat->musics.entries[i]; + ip3db_variant_set_str(&entry->fields[IP3DBF_MUSIC_FILEPATH], empty); + ip3db_variant_set_str(&entry->fields[IP3DBF_MUSIC_FILENAME], empty); + } + + /* Write Music page(s) */ i = 0; dat_list_write(&dat->musics, i, &ph, buffer, PAGESIZE * 1); dic->header.num_dat_pages += 1; @@ -378,7 +386,7 @@ buffer_size = PAGESIZE * page; buffer = (uint8_t*)realloc(buffer, sizeof(uint8_t) * buffer_size); i += ph.num_entries; - dat_list_write(&dat->objects, i, &ph, buffer, PAGESIZE * (page - 1)); + dat_list_write(&dat->musics, i, &ph, buffer, PAGESIZE * (page - 1)); dic->header.num_dat_pages += 1; } Modified: trunk/pmplib/lib/pmp_iriverplus3/idx.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-28 16:22:43 UTC (rev 218) +++ trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-28 16:56:01 UTC (rev 219) @@ -142,9 +142,9 @@ avl->offset = offset; } -static uint32_t avlnode_new(avl_t* avl) +static uint32_t avlnode_new(avl_t* avl, size_t keysize) { - uint32_t offset = avl_allocate(avl, sizeof(avlnode_t)); + uint32_t offset = avl_allocate(avl, sizeof(avlnode_t) + keysize); avlnode_t* a = avlnode(avl, offset); a->left = 0; a->right = 0; @@ -332,25 +332,28 @@ int ret = 0; static avl_comp_t comp[] = {NULL, avl_comp_ucs2string, avl_comp_byte, avl_comp_word, avl_comp_dword}; uint32_t offset_prev = avl_current(avl); - uint32_t offset_this = avlnode_new(avl); - size_t size = 0; + uint32_t offset_this = 0; uint32_t offset_key = 0; switch (type) { case IP3DBVT_BYTE: - offset_key = avl_allocate(avl, sizeof(uint8_t)); + offset_this = avlnode_new(avl, sizeof(uint8_t)); + offset_key = offset_this + sizeof(avlnode_t); *((uint8_t*)avlnode(avl, offset_key)) = key->value.byte; break; case IP3DBVT_WORD: - offset_key = avl_allocate(avl, sizeof(uint16_t)); + offset_this = avlnode_new(avl, sizeof(uint16_t)); + offset_key = offset_this + sizeof(avlnode_t); *((uint16_t*)avlnode(avl, offset_key)) = key->value.word; break; case IP3DBVT_DWORD: - offset_key = avl_allocate(avl, sizeof(uint32_t)); + offset_this = avlnode_new(avl, sizeof(uint32_t)); + offset_key = offset_this + sizeof(avlnode_t); *((uint32_t*)avlnode(avl, offset_key)) = key->value.dword; break; case IP3DBVT_STRING: - offset_key = avl_allocate(avl, sizeof(ucs2char_t) * (ucs2len(key->value.str) + 1)); + offset_this = avlnode_new(avl, sizeof(ucs2char_t) * (ucs2len(key->value.str) + 1)); + offset_key = offset_this + sizeof(avlnode_t); ucs2cpy((ucs2char_t*)avlnode(avl, offset_key), key->value.str); break; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2006-12-28 16:22:45
|
Revision: 218 http://svn.sourceforge.net/pmplib/?rev=218&view=rev Author: nyaochi Date: 2006-12-28 08:22:43 -0800 (Thu, 28 Dec 2006) Log Message: ----------- Continued effort to support large database. Implemented writing routine. This revision still has some bugs. Modified Paths: -------------- trunk/pmplib/lib/pmp_iriverplus3/dat.c trunk/pmplib/lib/pmp_iriverplus3/dat.h trunk/pmplib/lib/pmp_iriverplus3/idx.c trunk/pmplib/lib/pmp_iriverplus3/idx.h trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-28 14:52:13 UTC (rev 217) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-28 16:22:43 UTC (rev 218) @@ -309,25 +309,6 @@ free(dat); } -static size_t dat_serialize(dat_t* dat, const dic_t* dic, uint8_t* buffer, int is_storing) -{ - if (is_storing) { - /* For writing a music chunk only. - * Empty filepath and filename fields as iriver plus 3 does. - */ - int i; - for (i = 0;i < dat->musics.num_entries;++i) { - static const ucs2char_t empty[] = {0}; - dat_entry_t* entry = &dat->musics.entries[i]; - ip3db_variant_set_str(&entry->fields[IP3DBF_MUSIC_FILEPATH], empty); - ip3db_variant_set_str(&entry->fields[IP3DBF_MUSIC_FILENAME], empty); - } - } - dat_list_serialize(&dat->objects, &dic->objects, buffer, 0, is_storing); - dat_list_serialize(&dat->musics, &dic->music, buffer, 0x00020000, is_storing); - return 0; -} - int dat_read(dat_t* dat, const dic_t* dic, FILE *fpi) { page_header_t ph; @@ -362,7 +343,7 @@ return 0; } -int dat_write(dat_t* dat, const dic_t* dic, FILE *fpo) +int dat_write(dat_t* dat, dic_t* dic, FILE *fpo) { uint32_t i = 0; page_header_t ph; @@ -378,23 +359,27 @@ memset(&ph, 0, sizeof(ph)); ph.next_page = 3; dat_list_write(&dat->objects, i, &ph, buffer, PAGESIZE * 0); + dic->header.num_dat_pages = 1; while (ph.next_page) { uint32_t page = ph.next_page++; buffer_size = PAGESIZE * page; buffer = (uint8_t*)realloc(buffer, sizeof(uint8_t) * buffer_size); i += ph.num_entries; dat_list_write(&dat->objects, i, &ph, buffer, PAGESIZE * (page - 1)); + dic->header.num_dat_pages += 1; } /* Read Music page(s) */ i = 0; dat_list_write(&dat->musics, i, &ph, buffer, PAGESIZE * 1); + dic->header.num_dat_pages += 1; while (ph.next_page) { uint32_t page = ph.next_page++; buffer_size = PAGESIZE * page; buffer = (uint8_t*)realloc(buffer, sizeof(uint8_t) * buffer_size); i += ph.num_entries; dat_list_write(&dat->objects, i, &ph, buffer, PAGESIZE * (page - 1)); + dic->header.num_dat_pages += 1; } if (fwrite(buffer, 1, buffer_size, fpo) != buffer_size) { Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.h 2006-12-28 14:52:13 UTC (rev 217) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.h 2006-12-28 16:22:43 UTC (rev 218) @@ -44,7 +44,7 @@ dat_t* dat_new(); void dat_finish(dat_t* dat); int dat_read(dat_t* dat, const dic_t* dic, FILE *fpi); -int dat_write(dat_t* dat, const dic_t* dic, FILE *fpo); +int dat_write(dat_t* dat, dic_t* dic, FILE *fpo); void dat_dump(dat_t* dat, const dic_t* dic, FILE *fp); void dat_set(dat_t* dat, dic_t* dic, const ip3db_music_record_t* records, int num_records); Modified: trunk/pmplib/lib/pmp_iriverplus3/idx.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-28 14:52:13 UTC (rev 217) +++ trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-28 16:22:43 UTC (rev 218) @@ -55,8 +55,17 @@ #include "dat.h" #include "idx.h" +#define PAGESIZE 0x00020000 + #define COMP(a, b) ((a)>(b))-((a)<(b)) +struct tag_header_t { + uint32_t size; + uint32_t unknown1; + uint32_t unknown2; +}; +typedef struct tag_header_t header_t; + struct tag_avlnode_t { uint32_t left; uint32_t right; @@ -80,6 +89,17 @@ typedef int (*avl_comp_t)(avl_t* avl, uint32_t x, uint32_t y); +static avl_t* avl_new() +{ + return (avl_t*)calloc(1, sizeof(avl_t)); +} + +static void avl_finish(avl_t* avl) +{ + free(avl->buffer); + free(avl); +} + static uint32_t avl_current(avl_t* avl) { return avl->offset; @@ -87,8 +107,27 @@ static uint32_t avl_allocate(avl_t* avl, uint32_t size) { - uint32_t offset = avl->offset; + header_t* header = NULL; + uint32_t base = 0, offset = 0; + + /* Expand the memory block if necessary. */ + if (avl->size < avl->offset + size) { + uint32_t newsize = avl->size + PAGESIZE; + avl->buffer = (uint8_t*)realloc(avl->buffer, sizeof(uint8_t) * newsize); + memset(avl->buffer + avl->size, 0, PAGESIZE); + avl->offset = avl->size + sizeof(header_t); + avl->size = newsize; + } + + /* Allocate a memory block. */ + offset = avl->offset; avl->offset += size; + + /* Store the size of the current page. */ + base = avl->size - PAGESIZE; + header = (header_t*)(avl->buffer + base); + header->size = avl->offset - base; + return offset; } @@ -595,37 +634,33 @@ idx_t *idx_new() { - idx_t* idx = (idx_t*)malloc(sizeof(idx_t)); - idx->max_size = 0x00020000; - idx->buffer = (uint8_t*)malloc(idx->max_size); - idx->size = 0; - idx->avl = (avl_t*)malloc(sizeof(avl_t)); - idx->avl->buffer = idx->buffer; - idx->avl->offset = sizeof(idx_header_t); - idx->avl->size = idx->max_size; + idx_t* idx = (idx_t*)calloc(1, sizeof(idx_t)); + idx->avl = avl_new(); return idx; } void idx_finish(idx_t* idx) { - free(idx->avl); - free(idx->buffer); + avl_finish(idx->avl); free(idx); } int idx_read(idx_t* idx, dic_t* dic, FILE *fpi) { int i; - idx_header_t* header = (idx_header_t*)idx->buffer; + uint32_t offset = 0; /* Read the whole data at a time. */ - fread_all(fpi, &idx->buffer, &idx->max_size); - idx->avl->buffer = idx->buffer; + fread_all(fpi, &idx->avl->buffer, &idx->avl->size); /* Convert the byte order of the header from big endian to the native one. */ - from_uint32be(&header->size); - from_uint32be(&header->unknown1); - from_uint32be(&header->unknown2); + while (offset < idx->avl->size) { + idx_header_t* header = (idx_header_t*)(idx->avl->buffer + offset); + from_uint32be(&header->size); + from_uint32be(&header->unknown1); + from_uint32be(&header->unknown2); + offset += PAGESIZE; + } /* Convert the byte order of values in AVL trees. */ for (i = 0;i < dic->music.num_indices;++i) { @@ -642,15 +677,16 @@ result_t idx_write(idx_t* idx, dic_t* dic, FILE *fpo) { int i; - idx_header_t* header = (idx_header_t*)idx->buffer; + uint32_t offset = 0; - /* The size fo db.idx equals to the maximum offset of the AVL trees. */ - header->size = idx->avl->offset; - /* Convert the byte order of the header to big endian from the native one. */ - to_uint32be(&header->size); - to_uint32be(&header->unknown1); - to_uint32be(&header->unknown2); + while (offset < idx->avl->size) { + idx_header_t* header = (idx_header_t*)(idx->avl->buffer + offset); + to_uint32be(&header->size); + to_uint32be(&header->unknown1); + to_uint32be(&header->unknown2); + offset += PAGESIZE; + } /* Convert the byte order of values in AVL trees. */ for (i = 0;i < dic->music.num_indices;++i) { @@ -663,25 +699,20 @@ } /* Read the whole data at a time. */ - if (fwrite(idx->buffer, 1, idx->max_size, fpo) != idx->max_size) { + if (fwrite(idx->avl->buffer, 1, idx->avl->size, fpo) != idx->avl->size) { return 1; } + dic->header.num_idx_pages = (idx->avl->size / PAGESIZE); return 0; } result_t idx_dump(idx_t* idx, dic_t* dic, FILE *fpo) { int i; - idx_header_t* header = (idx_header_t*)idx->buffer; fprintf(fpo, "===== db.idx =====\n"); - /* Dump the header. */ - fprintf(fpo, "size: 0x%08X\n", header->size); - fprintf(fpo, "unknown1: 0x%08X\n", header->unknown1); - fprintf(fpo, "unknown2: 0x%08X\n", header->unknown2); - /* Dump the binary search trees. */ for (i = 0;i < dic->music.num_indices;++i) { uint32_t idx_root = dic_get_idxroot(dic, IP3DBIDX_MUSIC, i); @@ -735,10 +766,8 @@ { int index; - memset(idx->buffer, 0, idx->max_size); - idx->avl->buffer = idx->buffer; - idx->avl->offset = sizeof(idx_header_t); - idx->avl->size = idx->max_size; + avl_finish(idx->avl); + idx->avl = avl_new(); for (index = 0;index < dic->music.num_indices;++index) { uint32_t root = 0; Modified: trunk/pmplib/lib/pmp_iriverplus3/idx.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/idx.h 2006-12-28 14:52:13 UTC (rev 217) +++ trunk/pmplib/lib/pmp_iriverplus3/idx.h 2006-12-28 16:22:43 UTC (rev 218) @@ -27,9 +27,6 @@ struct tag_avl_t; typedef struct tag_avl_t avl_t; struct tag_idx_t { - uint8_t* buffer; - uint32_t size; - uint32_t max_size; avl_t* avl; }; typedef struct tag_idx_t idx_t; Modified: trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c 2006-12-28 14:52:13 UTC (rev 217) +++ trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c 2006-12-28 16:22:43 UTC (rev 218) @@ -65,7 +65,7 @@ "iriver_e10_ums_1.04", "E10 UMS", "UM", "1.04", "1.04", "System\\E10.SYS", "System\\db.dat", "System\\db.dic", "System\\db.idx", - "", "Playlists\\", + "Music2\\", "Playlists\\", ".plp", }, { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2006-12-28 14:52:17
|
Revision: 217 http://svn.sourceforge.net/pmplib/?rev=217&view=rev Author: nyaochi Date: 2006-12-28 06:52:13 -0800 (Thu, 28 Dec 2006) Log Message: ----------- An extended game: db.idx and db.dat do not have a fixed size. These files are found to be (n*0x00020000) bytes long if the database has a large number of entries. This commit fixes database dump. The fix for database writer follows later. Modified Paths: -------------- trunk/pmplib/lib/pmp_iriverplus3/dat.c trunk/pmplib/lib/pmp_iriverplus3/dat.h trunk/pmplib/lib/pmp_iriverplus3/dic.c trunk/pmplib/lib/pmp_iriverplus3/dic.h trunk/pmplib/lib/pmp_iriverplus3/idx.c trunk/pmplib/lib/pmp_iriverplus3/ip3db.c trunk/pmplib/lib/pmp_iriverplus3/ip3db.h Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-28 05:46:51 UTC (rev 216) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-28 14:52:13 UTC (rev 217) @@ -46,6 +46,15 @@ #include "dic.h" #include "dat.h" +#define PAGESIZE 0x00020000 + +typedef struct { + uint32_t size; + uint32_t num_entries; + uint32_t unknown1; + uint32_t next_page; +} page_header_t; + static void dat_entry_init(dat_entry_t* entry, const dic_table_t* dic_list) { memset(entry, 0, sizeof(*entry)); @@ -71,6 +80,30 @@ } } +static size_t dat_entry_size(dat_entry_t* entry) +{ + int i; + size_t size = 0; + for (i = 0;i < entry->num_fields;++i) { + ip3db_variant_t* var = &entry->fields[i]; + switch (var->type) { + case IP3DBVT_STRING: + size += var->value.str ? sizeof(ucs2char_t) * (ucs2len(var->value.str) + 1) : sizeof(ucs2char_t); + break; + case IP3DBVT_BYTE: + size += sizeof(uint8_t); + break; + case IP3DBVT_WORD: + size += sizeof(uint16_t); + break; + case IP3DBVT_DWORD: + size += sizeof(uint32_t); + break; + } + } + return size; +} + static size_t dat_entry_serialize(dat_entry_t* entry, uint8_t* block, uint8_t* q, uint32_t start, int is_storing) { int i; @@ -177,62 +210,78 @@ return &list->entries[list->num_entries++]; } -static size_t dat_list_serialize(dat_list_t* list, const dic_table_t* dic_list, uint8_t* buffer, uint32_t start, int is_storing) +static size_t dat_list_read(dat_list_t* list, page_header_t* header, const dic_table_t* dic_list, uint8_t* buffer, uint32_t start) { uint32_t i; uint8_t *p = buffer + start; - uint8_t *q = buffer + start + 0x00020000 - sizeof(uint32_t); + uint8_t *q = buffer + start + PAGESIZE - sizeof(uint32_t); - if (!is_storing) { - /* Read the header. */ - p += serialize_uint32be(p, &list->size, is_storing); - p += serialize_uint32be(p, &list->num_entries, is_storing); - p += serialize_uint32be(p, &list->unknown1, is_storing); - p += serialize_uint32be(p, &list->unknown2, is_storing); - } else { - /* Skip the header for now when writing. */ - p += sizeof(uint32_t) * 4; + /* Read the header. */ + p += serialize_uint32be(p, &header->size, 0); + p += serialize_uint32be(p, &header->num_entries, 0); + p += serialize_uint32be(p, &header->unknown1, 0); + p += serialize_uint32be(p, &header->next_page, 0); + + /* Expand the array of records. */ + list->entries = (dat_entry_t*)realloc(list->entries, sizeof(dat_entry_t) * (list->num_entries + header->num_entries)); + for (i = 0;i < header->num_entries;++i) { + dat_entry_init(&list->entries[list->num_entries+i], dic_list); } - /* Initialize fields according to db.dic when reading. */ - if (!is_storing) { - free(list->entries); - list->entries = (dat_entry_t*)calloc(list->num_entries, sizeof(dat_entry_t)); - for (i = 0;i < list->num_entries;++i) { - dat_entry_init(&list->entries[i], dic_list); - } + /* Read the new records. */ + for (i = 0;i < header->num_entries;++i) { + dat_entry_t* entry = &list->entries[list->num_entries+i]; + entry->offset = (uint32_t)(p - buffer); /* compute the current offset address */ + p += dat_entry_serialize(entry, p, q, start, 0); + q -= sizeof(uint32_t); } - /* Serialize entries in this table. */ - for (i = 0;i < list->num_entries;++i) { + list->num_entries += header->num_entries; + return (size_t)(header->size); +} + +static size_t dat_list_write(dat_list_t* list, uint32_t i, page_header_t* header, uint8_t* buffer, uint32_t start) +{ + uint8_t *p = buffer + start; + uint8_t *q = buffer + start + PAGESIZE - sizeof(uint32_t); + + header->size = 0; + header->num_entries = 0; + + /* Skip the header for now when writing. */ + p += sizeof(uint32_t) * 4; + + /* Write records. */ + while (i < list->num_entries) { + size_t free_space = (size_t)(q-p); dat_entry_t* entry = &list->entries[i]; + if (free_space < dat_entry_size(entry)) { + break; + } entry->offset = (uint32_t)(p - buffer); /* compute the current offset address */ - p += dat_entry_serialize(entry, p, q, start, is_storing); + p += dat_entry_serialize(entry, p, q, start, 1); q -= sizeof(uint32_t); + header->num_entries++; + i++; } - if (is_storing) { - /* Compute the block size and write the header. */ - list->size = (uint32_t)(p - (buffer + start)); - p = buffer + start; - p += serialize_uint32be(p, &list->size, is_storing); - p += serialize_uint32be(p, &list->num_entries, is_storing); - p += serialize_uint32be(p, &list->unknown1, is_storing); - p += serialize_uint32be(p, &list->unknown2, is_storing); + /* Compute the block size and write the header. */ + header->size = (uint32_t)(p - (buffer + start)); + if (list->num_entries <= i) { + header->next_page = 0; } - return (size_t)(list->size); + p = buffer + start; + p += serialize_uint32be(p, &header->size, 1); + p += serialize_uint32be(p, &header->num_entries, 1); + p += serialize_uint32be(p, &header->unknown1, 1); + p += serialize_uint32be(p, &header->next_page, 1); + return header->size; } static void dat_list_dump(dat_list_t* list, const dic_table_t* dic_list, FILE *fp) { uint32_t i; - - fprintf(fp, " size: 0x%08X\n", list->size); - fprintf(fp, " num_entries: %d\n", list->num_entries); - fprintf(fp, " unknown1: 0x%08X\n", list->unknown1); - fprintf(fp, " unknown2: 0x%08X\n", list->unknown2); - for (i = 0;i < list->num_entries;++i) { dat_entry_t* entry = &list->entries[i]; fprintf(fp, " ENTRY %d (0x%08X) = {\n", i, entry->offset); @@ -281,37 +330,73 @@ int dat_read(dat_t* dat, const dic_t* dic, FILE *fpi) { + page_header_t ph; long buffer_size = 0; uint8_t* buffer = NULL; + /* Read the whole image. */ fread_all(fpi, &buffer, &buffer_size); if (!buffer) { return 1; } - if (dat_serialize(dat, dic, buffer, 0) != 0) { - free(buffer); - return 1; + /* Clear Object records. */ + dat_list_finish(&dat->objects); + + /* Read Objects page(s) */ + dat_list_read(&dat->objects, &ph, &dic->objects, buffer, PAGESIZE * 0); + while (ph.next_page) { + dat_list_read(&dat->objects, &ph, &dic->objects, buffer, PAGESIZE * (ph.next_page - 1)); } + /* Clear Music records. */ + dat_list_finish(&dat->musics); + + /* Read Music page(s) */ + dat_list_read(&dat->musics, &ph, &dic->music, buffer, PAGESIZE * 1); + while (ph.next_page) { + dat_list_read(&dat->musics, &ph, &dic->music, buffer, PAGESIZE * (ph.next_page - 1)); + } + free(buffer); return 0; } int dat_write(dat_t* dat, const dic_t* dic, FILE *fpo) { - long buffer_size = 0x00040000; + uint32_t i = 0; + page_header_t ph; + long buffer_size = PAGESIZE * 2; uint8_t* buffer = (uint8_t*)calloc(buffer_size, sizeof(uint8_t)); if (!buffer) { return 1; } - if (dat_serialize(dat, dic, buffer, 1) != 0) { - free(buffer); - return 1; + /* Write Objects page(s) */ + i = 0; + memset(&ph, 0, sizeof(ph)); + ph.next_page = 3; + dat_list_write(&dat->objects, i, &ph, buffer, PAGESIZE * 0); + while (ph.next_page) { + uint32_t page = ph.next_page++; + buffer_size = PAGESIZE * page; + buffer = (uint8_t*)realloc(buffer, sizeof(uint8_t) * buffer_size); + i += ph.num_entries; + dat_list_write(&dat->objects, i, &ph, buffer, PAGESIZE * (page - 1)); } + /* Read Music page(s) */ + i = 0; + dat_list_write(&dat->musics, i, &ph, buffer, PAGESIZE * 1); + while (ph.next_page) { + uint32_t page = ph.next_page++; + buffer_size = PAGESIZE * page; + buffer = (uint8_t*)realloc(buffer, sizeof(uint8_t) * buffer_size); + i += ph.num_entries; + dat_list_write(&dat->objects, i, &ph, buffer, PAGESIZE * (page - 1)); + } + if (fwrite(buffer, 1, buffer_size, fpo) != buffer_size) { free(buffer); return 1; Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.h 2006-12-28 05:46:51 UTC (rev 216) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.h 2006-12-28 14:52:13 UTC (rev 217) @@ -31,10 +31,7 @@ } dat_entry_t; typedef struct { - uint32_t size; uint32_t num_entries; - uint32_t unknown1; - uint32_t unknown2; dat_entry_t* entries; } dat_list_t; Modified: trunk/pmplib/lib/pmp_iriverplus3/dic.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dic.c 2006-12-28 05:46:51 UTC (rev 216) +++ trunk/pmplib/lib/pmp_iriverplus3/dic.c 2006-12-28 14:52:13 UTC (rev 217) @@ -194,7 +194,13 @@ { int i; uint32_t next = 0; - + uint8_t* p = buffer; + + p += serialize_uint32be(p, &dic->header.size, is_storing); + p += serialize_uint32be(p, &dic->header.num_dat_pages, is_storing); + p += serialize_uint32be(p, &dic->header.num_idx_pages, is_storing); + p += serialize_uint32be(p, &dic->header.unknown1, is_storing); + next = 0x0000003C; for (i = 0;i < dic->music.num_fields;++i) { dic_field_serialize(buffer + next, &dic->music.fields[i], is_storing); Modified: trunk/pmplib/lib/pmp_iriverplus3/dic.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dic.h 2006-12-28 05:46:51 UTC (rev 216) +++ trunk/pmplib/lib/pmp_iriverplus3/dic.h 2006-12-28 14:52:13 UTC (rev 217) @@ -25,6 +25,13 @@ #define __IP3DB_DIC_H__ typedef struct { + uint32_t size; + uint32_t num_dat_pages; + uint32_t num_idx_pages; + uint32_t unknown1; +} dic_header_t; + +typedef struct { uint32_t next; uint32_t type; uint32_t idx_root; @@ -45,8 +52,9 @@ } dic_table_t; struct tag_dic_t { - dic_table_t music; - dic_table_t objects; + dic_header_t header; + dic_table_t music; + dic_table_t objects; uint8_t* buffer; long size; Modified: trunk/pmplib/lib/pmp_iriverplus3/idx.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-28 05:46:51 UTC (rev 216) +++ trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-28 14:52:13 UTC (rev 217) @@ -619,9 +619,8 @@ idx_header_t* header = (idx_header_t*)idx->buffer; /* Read the whole data at a time. */ - if (fread(idx->buffer, 1, idx->max_size, fpi) != idx->max_size) { - return 1; - } + fread_all(fpi, &idx->buffer, &idx->max_size); + idx->avl->buffer = idx->buffer; /* Convert the byte order of the header from big endian to the native one. */ from_uint32be(&header->size); Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-28 05:46:51 UTC (rev 216) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-28 14:52:13 UTC (rev 217) @@ -78,7 +78,7 @@ { var->type = IP3DBVT_STRING; ucs2free(var->value.str); - var->value.str = ucs2dup(val); + var->value.str = val ? ucs2dup(val) : ucs2calloc(sizeof(ucs2char_t)); } void ip3db_variant_clone(ip3db_variant_t* dst, const ip3db_variant_t* src) Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.h 2006-12-28 05:46:51 UTC (rev 216) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.h 2006-12-28 14:52:13 UTC (rev 217) @@ -116,8 +116,10 @@ * Fields chunks in db.dat. */ enum { + IP3DBIDX_NONE = -1, IP3DBIDX_MUSIC = 0, IP3DBIDX_OBJECTS, + IP3DBIDX_LAST, }; /** This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2006-12-28 05:46:52
|
Revision: 216 http://svn.sourceforge.net/pmplib/?rev=216&view=rev Author: nyaochi Date: 2006-12-27 21:46:51 -0800 (Wed, 27 Dec 2006) Log Message: ----------- - Fixed a bug in dircache. - Set proper FileFormat IDs for MP3, OggVorbis, and WMA. Modified Paths: -------------- trunk/pmplib/lib/pmp_iriverplus3/dat.c trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-28 05:09:07 UTC (rev 215) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-28 05:46:51 UTC (rev 216) @@ -350,6 +350,15 @@ memset(dc, 0, sizeof(*dc)); } +static void dircache_finish(dircache_t* dc) +{ + int i; + for (i = 0;i < dc->max_elems;++i) { + ucs2free(dc->elems[i].path); + } + free(dc->elems); +} + static void dircache_push(dircache_t* dc, const ucs2char_t* path, uint32_t uid) { dircache_element_t* elem = NULL; @@ -368,11 +377,12 @@ static void dircache_pop(dircache_t* dc, int i) { - ++i; + int n = ++i; for (;i < dc->num_elems;++i) { ucs2free(dc->elems[i].path); memset(&dc->elems[i], 0, sizeof(dc->elems[0])); } + dc->num_elems = n; } static int dircache_findprefix(dircache_t* dc, const ucs2char_t* path) @@ -490,13 +500,13 @@ const ip3db_variant_t* record = records[si[i].index]; const ucs2char_t* path = record[IP3DBF_MUSIC_FILEPATH].value.str; const ucs2char_t* file = record[IP3DBF_MUSIC_FILENAME].value.str; - int i = dircache_findprefix(&dc, path); - const dircache_element_t* com = dircache_get(&dc, i); + int k = dircache_findprefix(&dc, path); + const dircache_element_t* com = dircache_get(&dc, k); const ucs2char_t* p = path + ucs2len(com->path); /* the prefix */ uint32_t puid = com->uid; /* the UID of the parent directory of the postfix */ /* Discard directory portions that do not share a prefix with the target. */ - dircache_pop(&dc, i); + dircache_pop(&dc, k); /* Create objects one by one for the directory portions in the postfix. */ while (p && *p) { @@ -545,4 +555,6 @@ } ip3db_variant_set_dword(&entry->fields[IP3DBF_MUSIC_UID], uid); } + + dircache_finish(&dc); } Modified: trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c 2006-12-28 05:09:07 UTC (rev 215) +++ trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c 2006-12-28 05:46:51 UTC (rev 216) @@ -554,10 +554,21 @@ 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); - ip3db_variant_set_word(&dst[IP3DBF_MUSIC_FILEFORMAT], 3); + 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_UID], (uint32_t)i+1); + } ip3db_set(&pmpdbi->ip3db, array, num_records); free(array); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2006-12-28 05:09:07
|
Revision: 215 http://svn.sourceforge.net/pmplib/?rev=215&view=rev Author: nyaochi Date: 2006-12-27 21:09:07 -0800 (Wed, 27 Dec 2006) Log Message: ----------- Fixed a crash when parsing MP3 files. Modified Paths: -------------- trunk/pmplib/lib/gmi/gmi.vcproj trunk/pmplib/lib/gmi/gmi_mp3.c Modified: trunk/pmplib/lib/gmi/gmi.vcproj =================================================================== --- trunk/pmplib/lib/gmi/gmi.vcproj 2006-12-28 04:54:57 UTC (rev 214) +++ trunk/pmplib/lib/gmi/gmi.vcproj 2006-12-28 05:09:07 UTC (rev 215) @@ -61,7 +61,7 @@ /> <Tool Name="VCLinkerTool" - AdditionalDependencies=".\contrib\id3tag\win32\libid3tagd.lib .\contrib\id3tag\win32\zlibd.lib .\contrib\ogg\win32\ogg_static_d.lib .\contrib\vorbis\win32\vorbisfile_static_d.lib" + AdditionalDependencies=".\contrib\id3tag\win32\libid3tagd.lib .\contrib\id3tag\win32\zlibd.lib .\contrib\ogg\win32\ogg_static_d.lib .\contrib\vorbis\win32\vorbis_static_d.lib .\contrib\vorbis\win32\vorbisfile_static_d.lib" OutputFile="$(OutDir)/gmi.dll" LinkIncremental="2" GenerateDebugInformation="true" @@ -139,7 +139,7 @@ /> <Tool Name="VCLinkerTool" - AdditionalDependencies=".\contrib\id3tag\win32\libid3tag.lib .\contrib\id3tag\win32\zlib.lib .\contrib\ogg\win32\ogg_static.lib .\contrib\vorbis\win32\vorbisfile_static.lib" + AdditionalDependencies=".\contrib\id3tag\win32\libid3tag.lib .\contrib\id3tag\win32\zlib.lib .\contrib\ogg\win32\ogg_static.lib .\contrib\vorbis\win32\vorbis_static.lib .\contrib\vorbis\win32\vorbisfile_static.lib" OutputFile="$(OutDir)/gmi.dll" LinkIncremental="1" GenerateDebugInformation="true" Modified: trunk/pmplib/lib/gmi/gmi_mp3.c =================================================================== --- trunk/pmplib/lib/gmi/gmi_mp3.c 2006-12-28 04:54:57 UTC (rev 214) +++ trunk/pmplib/lib/gmi/gmi_mp3.c 2006-12-28 05:09:07 UTC (rev 215) @@ -486,8 +486,7 @@ info->duration = mp3header.duration; } - id3_file_close(id3file); - fclose(fp); + id3_file_close(id3file); /* This will call fclose(fp); */ info->codec = PMPCODEC_MPEGLAYER3; return 0; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2006-12-28 04:54:58
|
Revision: 214 http://svn.sourceforge.net/pmplib/?rev=214&view=rev Author: nyaochi Date: 2006-12-27 20:54:57 -0800 (Wed, 27 Dec 2006) Log Message: ----------- Libraries and DLLs are built with MSVC2005. - zlib 1.2.3 - libid3tag 0.15.1b - libogg 1.1.3 - libvorbis 1.1.2 - js 1.5 Modified Paths: -------------- trunk/pmplib/lib/gmi/contrib/id3tag/id3tag.h trunk/pmplib/lib/gmi/contrib/id3tag/win32/libid3tag.lib trunk/pmplib/lib/gmi/contrib/id3tag/win32/libid3tagd.lib trunk/pmplib/lib/gmi/contrib/id3tag/win32/zlib.lib trunk/pmplib/lib/gmi/contrib/id3tag/win32/zlibd.lib trunk/pmplib/lib/gmi/contrib/ogg/win32/ogg_static.lib trunk/pmplib/lib/gmi/contrib/ogg/win32/ogg_static_d.lib trunk/pmplib/lib/gmi/contrib/vorbis/win32/vorbis_static.lib trunk/pmplib/lib/gmi/contrib/vorbis/win32/vorbis_static_d.lib trunk/pmplib/lib/gmi/contrib/vorbis/win32/vorbisfile_static.lib trunk/pmplib/lib/gmi/contrib/vorbis/win32/vorbisfile_static_d.lib trunk/pmplib/lib/playlist/contrib/js/win32/js32.lib trunk/pmplib/lib/playlist/contrib/js/win32/js32d.lib Added Paths: ----------- trunk/pmplib/lib/playlist/contrib/js/win32/debug/ trunk/pmplib/lib/playlist/contrib/js/win32/debug/js32.dll trunk/pmplib/lib/playlist/contrib/js/win32/release/ trunk/pmplib/lib/playlist/contrib/js/win32/release/js32.dll Modified: trunk/pmplib/lib/gmi/contrib/id3tag/id3tag.h =================================================================== --- trunk/pmplib/lib/gmi/contrib/id3tag/id3tag.h 2006-12-28 03:48:26 UTC (rev 213) +++ trunk/pmplib/lib/gmi/contrib/id3tag/id3tag.h 2006-12-28 04:54:57 UTC (rev 214) @@ -248,13 +248,8 @@ struct id3_file *id3_file_fdopen(int, enum id3_file_mode); int id3_file_close(struct id3_file *); -id3_length_t id3_file_content_offset(struct id3_file const *file); - struct id3_tag *id3_file_tag(struct id3_file const *); -struct id3_tag *id3_file_gettag(struct id3_file const *, int); -int id3_file_getnumtag(struct id3_file const *); - int id3_file_update(struct id3_file *); /* tag interface */ Modified: trunk/pmplib/lib/gmi/contrib/id3tag/win32/libid3tag.lib =================================================================== (Binary files differ) Modified: trunk/pmplib/lib/gmi/contrib/id3tag/win32/libid3tagd.lib =================================================================== (Binary files differ) Modified: trunk/pmplib/lib/gmi/contrib/id3tag/win32/zlib.lib =================================================================== (Binary files differ) Modified: trunk/pmplib/lib/gmi/contrib/id3tag/win32/zlibd.lib =================================================================== (Binary files differ) Modified: trunk/pmplib/lib/gmi/contrib/ogg/win32/ogg_static.lib =================================================================== (Binary files differ) Modified: trunk/pmplib/lib/gmi/contrib/ogg/win32/ogg_static_d.lib =================================================================== (Binary files differ) Modified: trunk/pmplib/lib/gmi/contrib/vorbis/win32/vorbis_static.lib =================================================================== (Binary files differ) Modified: trunk/pmplib/lib/gmi/contrib/vorbis/win32/vorbis_static_d.lib =================================================================== (Binary files differ) Modified: trunk/pmplib/lib/gmi/contrib/vorbis/win32/vorbisfile_static.lib =================================================================== (Binary files differ) Modified: trunk/pmplib/lib/gmi/contrib/vorbis/win32/vorbisfile_static_d.lib =================================================================== (Binary files differ) Added: trunk/pmplib/lib/playlist/contrib/js/win32/debug/js32.dll =================================================================== (Binary files differ) Property changes on: trunk/pmplib/lib/playlist/contrib/js/win32/debug/js32.dll ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Modified: trunk/pmplib/lib/playlist/contrib/js/win32/js32.lib =================================================================== (Binary files differ) Modified: trunk/pmplib/lib/playlist/contrib/js/win32/js32d.lib =================================================================== (Binary files differ) Added: trunk/pmplib/lib/playlist/contrib/js/win32/release/js32.dll =================================================================== (Binary files differ) Property changes on: trunk/pmplib/lib/playlist/contrib/js/win32/release/js32.dll ___________________________________________________________________ Name: svn:mime-type + application/octet-stream This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2006-12-28 03:48:25
|
Revision: 213 http://svn.sourceforge.net/pmplib/?rev=213&view=rev Author: nyaochi Date: 2006-12-27 19:48:26 -0800 (Wed, 27 Dec 2006) Log Message: ----------- Fixed a crash bug. Modified Paths: -------------- trunk/pmplib/lib/pmp_iriverplus3/dat.c Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-28 03:20:31 UTC (rev 212) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-28 03:48:26 UTC (rev 213) @@ -61,12 +61,14 @@ static void dat_entry_finish(dat_entry_t* entry) { - int i; - for (i = 0;i < entry->num_fields;++i) { - ip3db_variant_finish(&entry->fields[i]); + if (entry) { + int i; + for (i = 0;i < entry->num_fields;++i) { + ip3db_variant_finish(&entry->fields[i]); + } + free(entry->fields); + memset(entry, 0, sizeof(*entry)); } - free(entry->fields); - memset(entry, 0, sizeof(*entry)); } static size_t dat_entry_serialize(dat_entry_t* entry, uint8_t* block, uint8_t* q, uint32_t start, int is_storing) @@ -157,12 +159,16 @@ static void dat_list_finish(dat_list_t* list) { - uint32_t i; - for (i = 0;i < list->num_entries;++i) { - dat_entry_finish(&list->entries[i]); + if (list) { + if (list->entries) { + uint32_t i; + for (i = 0;i < list->num_entries;++i) { + dat_entry_finish(&list->entries[i]); + } + free(list->entries); + } + memset(list, 0, sizeof(*list)); } - free(list->entries); - memset(list, 0, sizeof(*list)); } static dat_entry_t *dat_list_expand(dat_list_t* list) @@ -190,7 +196,7 @@ /* Initialize fields according to db.dic when reading. */ if (!is_storing) { - dat_list_finish(list); + free(list->entries); list->entries = (dat_entry_t*)calloc(list->num_entries, sizeof(dat_entry_t)); for (i = 0;i < list->num_entries;++i) { dat_entry_init(&list->entries[i], dic_list); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2006-12-28 03:20:31
|
Revision: 212 http://svn.sourceforge.net/pmplib/?rev=212&view=rev Author: nyaochi Date: 2006-12-27 19:20:31 -0800 (Wed, 27 Dec 2006) Log Message: ----------- Add more comments. Modified Paths: -------------- trunk/pmplib/lib/pmp_iriverplus3/dic.c trunk/pmplib/lib/pmp_iriverplus3/idx.c trunk/pmplib/lib/pmp_iriverplus3/ip3db.c Modified: trunk/pmplib/lib/pmp_iriverplus3/dic.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dic.c 2006-12-27 19:22:33 UTC (rev 211) +++ trunk/pmplib/lib/pmp_iriverplus3/dic.c 2006-12-28 03:20:31 UTC (rev 212) @@ -23,7 +23,7 @@ /* Some important findings from db.dic: -- This file seems to define field names/types in a database. +- This file defines field names/types in a database. - This file stores offset addresses of root nodes in db.idx. */ Modified: trunk/pmplib/lib/pmp_iriverplus3/idx.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-27 19:22:33 UTC (rev 211) +++ trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-28 03:20:31 UTC (rev 212) @@ -23,12 +23,19 @@ /* Brief summary of db.idx structure: -- This file seems to have 12-bytes header +- This file has 12-bytes header - Indices consist of multiple binary search trees -- The offset addresses to the root nodes are specified in db.dic +- The offset addresses to the root nodes are described in db.dic Implementation note: -- The AVL trees are +- The byte order of values (such as offset address, key values, etc) + in AVL trees depends on the CPU architecture on which this code runs. + Since values in db.idx are written in big-endian, the functions + from_be_avltree() and to_be_avltree() convert the byte order from/to + big endian to the native byte-order on memory. +- The balance field of an AVL node stores values -1, 0, or 1 although + the field stores the height of a node in db.idx. This conversion + will take place in the function to_be_avltree(). */ #ifdef HAVE_CONFIG_H Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-27 19:22:33 UTC (rev 211) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-28 03:20:31 UTC (rev 212) @@ -121,7 +121,10 @@ { FILE *fp = 0; - /* Read db.dic */ + /* + * Read db.dic first since this file describes the structure of a database + * (e.g., field type and the offset values to the root nodes in db.idx). + */ fp = ucs2fopen(dicfn, "rb"); if (!fp) { ip3db_finish(db); @@ -155,7 +158,11 @@ { FILE *fp = 0; - /* Write db.dat. This will allocate offset values of the records. */ + /* + * Write db.dat. The function dat_write() also stores offset addresses + * (db->dat->objects.entries[i].offset and db->dat->music.entries[i].offset) + * where records are stored in the file. + */ fp = ucs2fopen(datfn, "wb"); if (!fp) { return 1; @@ -163,9 +170,18 @@ dat_write(db->dat, db->dic, fp); fclose(fp); - /* Construct db.idx and update db.dic. */ + /* + * Construct binary search trees from records in db->dat. The root offset + * of each search tree will be stored in db->dic. + */ idx_construct(db->idx, db->dic, db->dat); + /* + * Write db.idx. The function idx_write() converts values in the search trees + * from native byte-order to big endian. The byte-order conversion will take + * place in memory. Therefore, do not use db->idx after calling idx_write() + * function. + */ fp = ucs2fopen(idxfn, "wb"); if (!fp) { return 1; @@ -173,6 +189,7 @@ idx_write(db->idx, db->dic, fp); fclose(fp); + /* Write db.dic. */ fp = ucs2fopen(dicfn, "wb"); if (!fp) { return 1; @@ -198,7 +215,7 @@ result_t ip3db_set(ip3db_t* db, const ip3db_music_record_t* records, int num_records) { - /* Set music records to dat_t. */ + /* Construct records in db->dat from the records. */ dat_set(db->dat, db->dic, records, num_records); return 0; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2006-12-27 19:22:37
|
Revision: 211 http://svn.sourceforge.net/pmplib/?rev=211&view=rev Author: nyaochi Date: 2006-12-27 11:22:33 -0800 (Wed, 27 Dec 2006) Log Message: ----------- Source code clean-up for idx.c Modified Paths: -------------- trunk/pmplib/lib/pmp_iriverplus3/idx.c Modified: trunk/pmplib/lib/pmp_iriverplus3/idx.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-27 19:11:11 UTC (rev 210) +++ trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-27 19:22:33 UTC (rev 211) @@ -26,6 +26,9 @@ - This file seems to have 12-bytes header - Indices consist of multiple binary search trees - The offset addresses to the root nodes are specified in db.dic + +Implementation note: +- The AVL trees are */ #ifdef HAVE_CONFIG_H @@ -47,12 +50,6 @@ #define COMP(a, b) ((a)>(b))-((a)<(b)) -typedef struct { - uint32_t size; - uint32_t unknown1; - uint32_t unknown2; -} idx_header_t; - struct tag_avlnode_t { uint32_t left; uint32_t right; @@ -312,7 +309,6 @@ break; } - memcpy(avlnode(avl, offset_key), key, size); ret = avl_insert(avl, root, &offset_this, comp[type]); if (ret != -1) { /* A new key. */ @@ -326,19 +322,8 @@ } } -static int avl_insert_keydata(avl_t* avl, const void* key, int type, uint32_t data, uint32_t* root) -{ - uint32_t offset = 0; - int ret = avl_insert_key(avl, key, type, &offset, root); - avlnode_t* node = avlnode(avl, offset); - uint32_t offset_tail = avltail_new(avl); - avltail_t* tail = (avltail_t*)avlnode(avl, offset_tail); - tail->data = data; - tail->next = node->tail; - node->tail = offset_tail; - return ret; -} + static void from_uint16be(uint16_t* value) { uint8_t* src = (uint8_t*)value; @@ -514,6 +499,9 @@ return height; } + + + static void fprinti(FILE *fp, int n) { while (n--) fputc(' ', fp); @@ -590,36 +578,13 @@ } } -void avl_walk2(avl_t* avl, uint32_t offr, avl_comp_t comp) -{ - wchar_t* key = 0; - avlnode_t* root = avlnode(avl, offr); - avltail_t* tail = (avltail_t*)avlnode(avl, root->tail); - if (root->left) avl_walk2(avl, root->left, comp); - key = (wchar_t*)avlnode(avl, offr + sizeof(avlnode_t)); - printf("%S: ", key); - for (;;) { - printf("%d ", tail->data); - if (!tail->next) { - break; - } - tail = (avltail_t*)avlnode(avl, tail->next); - } - printf("\n"); - if (root->right) avl_walk2(avl, root->right, comp); -} -void avl_walk(avl_t* avl, uint32_t offr, avl_comp_t comp) -{ - wchar_t* key = 0; - avlnode_t* root = avlnode(avl, offr); - if (root->left) avl_walk(avl, root->left, comp); - key = (wchar_t*)avlnode(avl, offr + sizeof(avlnode_t)); - printf("%S: ", key); - avl_walk2(avl, root->tail, comp); - if (root->right) avl_walk(avl, root->right, comp); -} +typedef struct { + uint32_t size; + uint32_t unknown1; + uint32_t unknown2; +} idx_header_t; idx_t *idx_new() { @@ -656,7 +621,7 @@ from_uint32be(&header->unknown1); from_uint32be(&header->unknown2); - /* Convert the byte order of AVL trees. */ + /* Convert the byte order of values in AVL trees. */ for (i = 0;i < dic->music.num_indices;++i) { uint32_t idx_root = dic_get_idxroot(dic, IP3DBIDX_MUSIC, i); from_be_avltree(idx->avl, idx_root, &dic->music, i, 0); @@ -673,14 +638,15 @@ int i; idx_header_t* header = (idx_header_t*)idx->buffer; + /* The size fo db.idx equals to the maximum offset of the AVL trees. */ header->size = idx->avl->offset; - /* Convert the byte order of the header from big endian to the native one. */ + /* Convert the byte order of the header to big endian from the native one. */ to_uint32be(&header->size); to_uint32be(&header->unknown1); to_uint32be(&header->unknown2); - /* Convert the byte order of AVL trees. */ + /* Convert the byte order of values in AVL trees. */ for (i = 0;i < dic->music.num_indices;++i) { uint32_t idx_root = dic_get_idxroot(dic, IP3DBIDX_MUSIC, i); to_be_avltree(idx->avl, idx_root, &dic->music, i, 0); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2006-12-27 19:11:11
|
Revision: 210 http://svn.sourceforge.net/pmplib/?rev=210&view=rev Author: nyaochi Date: 2006-12-27 11:11:11 -0800 (Wed, 27 Dec 2006) Log Message: ----------- Trivial comments in dat.c Modified Paths: -------------- trunk/pmplib/lib/pmp_iriverplus3/dat.c Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-27 19:04:23 UTC (rev 209) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-27 19:11:11 UTC (rev 210) @@ -522,6 +522,7 @@ p = q; } + /* Create a new object for the file name (FileType = 2). */ uid = dato->num_entries; entry = dat_list_expand(dato); dat_entry_init(entry, &dic->objects); @@ -530,6 +531,7 @@ ip3db_variant_set_word(&entry->fields[IP3DBF_OBJECTS_FILETYPE], 2); ip3db_variant_set_str(&entry->fields[IP3DBF_OBJECTS_OBJECTNAME], file); + /* Create a music record with UID referring to the file name. */ entry = dat_list_expand(datm); dat_entry_init(entry, &dic->music); for (j = 0;j < entry->num_fields;++j) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2006-12-27 19:04:23
|
Revision: 209 http://svn.sourceforge.net/pmplib/?rev=209&view=rev Author: nyaochi Date: 2006-12-27 11:04:23 -0800 (Wed, 27 Dec 2006) Log Message: ----------- More source code clean-up. Added comments in dat.c Modified Paths: -------------- trunk/pmplib/lib/pmp_iriverplus3/dat.c trunk/pmplib/lib/pmp_iriverplus3/dat.h trunk/pmplib/lib/pmp_iriverplus3/ip3db.c Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-27 17:24:52 UTC (rev 208) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-27 19:04:23 UTC (rev 209) @@ -75,7 +75,11 @@ uint8_t *p = block; uint32_t offset; - /* Serialize offset address of this entry. */ + /* + * Serialize offset address of this entry. + * entry->offset: The offset address in the whole db.dat buffer (e.g., 0x00020123) + * offset (written in db.dat): The one within the chunk (e.g., 0x00000123) + */ if (is_storing) { offset = entry->offset - start; q -= serialize_uint32be(q, &offset, is_storing); @@ -151,12 +155,6 @@ memset(list, 0, sizeof(*list)); } -static dat_entry_t *dat_list_expand(dat_list_t* list) -{ - list->entries = (dat_entry_t*)realloc(list->entries, sizeof(dat_entry_t) * (list->num_entries+1)); - return &list->entries[list->num_entries++]; -} - static void dat_list_finish(dat_list_t* list) { uint32_t i; @@ -164,28 +162,35 @@ dat_entry_finish(&list->entries[i]); } free(list->entries); - dat_list_init(list); + memset(list, 0, sizeof(*list)); } +static dat_entry_t *dat_list_expand(dat_list_t* list) +{ + list->entries = (dat_entry_t*)realloc(list->entries, sizeof(dat_entry_t) * (list->num_entries+1)); + return &list->entries[list->num_entries++]; +} + static size_t dat_list_serialize(dat_list_t* list, const dic_table_t* dic_list, uint8_t* buffer, uint32_t start, int is_storing) { uint32_t i; uint8_t *p = buffer + start; uint8_t *q = buffer + start + 0x00020000 - sizeof(uint32_t); - /* Serialize the header (with a dummy size for writing). */ if (!is_storing) { + /* Read the header. */ p += serialize_uint32be(p, &list->size, is_storing); p += serialize_uint32be(p, &list->num_entries, is_storing); p += serialize_uint32be(p, &list->unknown1, is_storing); p += serialize_uint32be(p, &list->unknown2, is_storing); } else { + /* Skip the header for now when writing. */ p += sizeof(uint32_t) * 4; } - /* Initialize fields when reading. */ + /* Initialize fields according to db.dic when reading. */ if (!is_storing) { - free(list->entries); + dat_list_finish(list); list->entries = (dat_entry_t*)calloc(list->num_entries, sizeof(dat_entry_t)); for (i = 0;i < list->num_entries;++i) { dat_entry_init(&list->entries[i], dic_list); @@ -201,6 +206,7 @@ } if (is_storing) { + /* Compute the block size and write the header. */ list->size = (uint32_t)(p - (buffer + start)); p = buffer + start; p += serialize_uint32be(p, &list->size, is_storing); @@ -208,6 +214,7 @@ p += serialize_uint32be(p, &list->unknown1, is_storing); p += serialize_uint32be(p, &list->unknown2, is_storing); } + return (size_t)(list->size); } @@ -250,9 +257,12 @@ static size_t dat_serialize(dat_t* dat, const dic_t* dic, uint8_t* buffer, int is_storing) { if (is_storing) { + /* For writing a music chunk only. + * Empty filepath and filename fields as iriver plus 3 does. + */ int i; - ucs2char_t empty[] = {0}; for (i = 0;i < dat->musics.num_entries;++i) { + static const ucs2char_t empty[] = {0}; dat_entry_t* entry = &dat->musics.entries[i]; ip3db_variant_set_str(&entry->fields[IP3DBF_MUSIC_FILEPATH], empty); ip3db_variant_set_str(&entry->fields[IP3DBF_MUSIC_FILENAME], empty); @@ -316,24 +326,7 @@ fprintf(fp, "}\n"); } -typedef struct { - const ip3db_music_record_t* base; - int index; -} ip3db_sort_index_t; -static int comp_pathname(const void *__x, const void *__y) -{ - const ip3db_sort_index_t* _x = (const ip3db_sort_index_t*)__x; - const ip3db_sort_index_t* _y = (const ip3db_sort_index_t*)__y; - const ip3db_variant_t* x = _x->base[_x->index]; - const ip3db_variant_t* y = _y->base[_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); - } else { - return ret; - } -} typedef struct { ucs2char_t* path; @@ -392,15 +385,62 @@ return &dc->elems[i]; } + + +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]; + 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); + } else { + return ret; + } +} + + + static const ucs2char_t* skip_one_directory(const ucs2char_t* path) { ucs2char_t* p = ucs2chr(path, '/'); return p ? p+1 : NULL; } +void dat_set(dat_t* dat, dic_t* dic, const ip3db_music_record_t* records, int num_records) +{ + /* Procedure: + * 1) Construct the object chunk and attach music records with Object UIDs. + * Because the object chunk stores a tree structure of path names, we need to + * split a path name to elements and allocate an Object UID to each element. + * For example, the path name "/Music/Beatles/Love/01_love.ogg" will generate + * five objects each of which links to the object of the parent directory: + * - UID=0xFFFFFFFF: "/a/" (root directory; FileType = 0) + * - UID=1 : "Music/" (FileType = 1) + * - UID=2 : "Beatles/" (FileType = 1) + * - UID=3 : "Love/" (FileType = 1) + * - UID=4 : "01_love.ogg" (FileType = 2) + * In order to convert a list of path names to the tree structure, this + * implementation sorts the path names in alphabetical order and finds new + * path elements by using a directory queue (dircache_t). + * + * 3) Attach Object UIDs for file names (FileType = 2) to music records. + * These UIDs are stored in records in the music chunk so that the player + * can refer to the path/file name of a music track quickly. + * + * 4) Construct the music chunk by basically duplicating the records. + * + * Now the content of db.dat is ready. Note that the path character in db.dat + * is not '\\' but '/'. + */ -void dat_construct(dat_t* dat, dic_t* dic, const ip3db_music_record_t* records, int num_records) -{ int i, j; dat_entry_t* entry; uint32_t uid = 0; @@ -409,8 +449,8 @@ static const ucs2char_t ucs2cs_root[] = {'/', 0}; dat_list_t* dato = &dat->objects; dat_list_t* datm = &dat->musics; + sort_index_t *si = (sort_index_t*)malloc(sizeof(sort_index_t) * num_records); dircache_t dc; - ip3db_sort_index_t *si = (ip3db_sort_index_t*)malloc(sizeof(ip3db_sort_index_t) * num_records); dircache_init(&dc); @@ -427,31 +467,42 @@ /* Register the root node to the directory cache. */ dircache_push(&dc, ucs2cs_root, uid_root); + /* Sort the records in alphabetical order of their path names. */ for (i = 0;i < num_records;++i) { si[i].base = records; si[i].index = i; } qsort(si, num_records, sizeof(si[0]), comp_pathname); + /* Loop for the records. */ for (i = 0;i < num_records;++i) { + /* + * Split a path name into two parts: a prefix that have already been + * registered in the Object table: and a postfix that is being registered + * as Object records. + */ const ip3db_variant_t* record = records[si[i].index]; const ucs2char_t* path = record[IP3DBF_MUSIC_FILEPATH].value.str; const ucs2char_t* file = record[IP3DBF_MUSIC_FILENAME].value.str; int i = dircache_findprefix(&dc, path); const dircache_element_t* com = dircache_get(&dc, i); - const ucs2char_t* p = path + ucs2len(com->path); - uint32_t puid = com->uid; + const ucs2char_t* p = path + ucs2len(com->path); /* the prefix */ + uint32_t puid = com->uid; /* the UID of the parent directory of the postfix */ + /* Discard directory portions that do not share a prefix with the target. */ dircache_pop(&dc, i); + /* Create objects one by one for the directory portions in the postfix. */ while (p && *p) { ucs2char_t tmp[MAX_PATH]; const ucs2char_t* q = skip_one_directory(p); uid = dato->num_entries; + /* A directory element (e.g., "Beatles/") */ ucs2ncpy(tmp, p, q-p); tmp[q-p] = 0; + /* Create a new object. */ entry = dat_list_expand(dato); dat_entry_init(entry, &dic->objects); ip3db_variant_set_dword(&entry->fields[IP3DBF_OBJECTS_UID], uid); @@ -459,11 +510,15 @@ ip3db_variant_set_word(&entry->fields[IP3DBF_OBJECTS_FILETYPE], 1); ip3db_variant_set_str(&entry->fields[IP3DBF_OBJECTS_OBJECTNAME], tmp); + /* Register the fullpath (e.g., "/Music/eatles/" in the dircache. */ ucs2ncpy(tmp, path, q-path); tmp[q-path] = 0; dircache_push(&dc, tmp, uid); + /* Store the current UID for children. */ puid = uid; + + /* Move to the next portion. */ p = q; } Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.h 2006-12-27 17:24:52 UTC (rev 208) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.h 2006-12-27 19:04:23 UTC (rev 209) @@ -49,6 +49,6 @@ int dat_read(dat_t* dat, const dic_t* dic, FILE *fpi); int dat_write(dat_t* dat, const dic_t* dic, FILE *fpo); void dat_dump(dat_t* dat, const dic_t* dic, FILE *fp); -void dat_construct(dat_t* dat, dic_t* dic, const ip3db_music_record_t* records, int num_records); +void dat_set(dat_t* dat, dic_t* dic, const ip3db_music_record_t* records, int num_records); #endif/*__IP3DB_DAT_H__*/ Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-27 17:24:52 UTC (rev 208) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-27 19:04:23 UTC (rev 209) @@ -198,8 +198,8 @@ result_t ip3db_set(ip3db_t* db, const ip3db_music_record_t* records, int num_records) { - /* Construct Objects table in db.dat */ - dat_construct(db->dat, db->dic, records, num_records); + /* Set music records to dat_t. */ + dat_set(db->dat, db->dic, records, num_records); return 0; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2006-12-27 17:24:51
|
Revision: 208 http://svn.sourceforge.net/pmplib/?rev=208&view=rev Author: nyaochi Date: 2006-12-27 09:24:52 -0800 (Wed, 27 Dec 2006) Log Message: ----------- Source code clean-up: make dic_t manage the buffer for db.dic. Modified Paths: -------------- trunk/pmplib/lib/pmp_iriverplus3/dic.c trunk/pmplib/lib/pmp_iriverplus3/dic.h trunk/pmplib/lib/pmp_iriverplus3/ip3db.c trunk/pmplib/lib/pmp_iriverplus3/ip3db.h Modified: trunk/pmplib/lib/pmp_iriverplus3/dic.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dic.c 2006-12-27 17:07:29 UTC (rev 207) +++ trunk/pmplib/lib/pmp_iriverplus3/dic.c 2006-12-27 17:24:52 UTC (rev 208) @@ -64,6 +64,7 @@ {0, 0x0ACE, {IP3DBF_OBJECTS_FILETYPE, IP3DBF_OBJECTS_PARENTUID, IP3DBF_OBJECTS_PROPERTIES}}, }; +static int dic_serialize(dic_t* dic, uint8_t* buffer, int is_storing); static void dic_field_init(dic_field_t* entry) { @@ -129,6 +130,7 @@ dic_t* dic_new() { + uint8_t* dic_template = NULL; dic_t* dic = (dic_t*)malloc(sizeof(dic_t)); if (dic) { dic_table_init(&dic->music); @@ -141,6 +143,14 @@ dic->objects.fields = (dic_field_t*)calloc(dic->objects.num_fields, sizeof(dic_field_t)); dic->objects.num_indices = sizeof(objects_indices) / sizeof(objects_indices[0]); dic->objects.indices = objects_indices; + + /* Read the database description, which rules everything in a database. */ + dic_template = dic_get_template(&dic->size); + dic->buffer = (uint8_t*)malloc(dic->size); + if (dic->buffer) { + memcpy(dic->buffer, dic_template, dic->size); + dic_serialize(dic, dic->buffer, 0); + } } return dic; } @@ -150,12 +160,38 @@ if (dic) { dic_table_finish(&dic->music); dic_table_finish(&dic->objects); + free(dic->buffer); free(dic); } } -int dic_serialize(dic_t* dic, uint8_t* buffer, int is_storing) +int dic_read(dic_t* dic, FILE *fpi) { + free(dic->buffer); + dic->size = 0; + + fread_all(fpi, &dic->buffer, &dic->size); + + /* Parse db.dic */ + if (dic_serialize(dic, dic->buffer, 0) != 0) { + return 1; + } + return 0; +} + +int dic_write(dic_t* dic, FILE *fpo) +{ + if (dic_serialize(dic, dic->buffer, 1) != 0) { + return 1; + } + + fwrite(dic->buffer, 1, dic->size, fpo); + + return 0; +} + +static int dic_serialize(dic_t* dic, uint8_t* buffer, int is_storing) +{ int i; uint32_t next = 0; Modified: trunk/pmplib/lib/pmp_iriverplus3/dic.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dic.h 2006-12-27 17:07:29 UTC (rev 207) +++ trunk/pmplib/lib/pmp_iriverplus3/dic.h 2006-12-27 17:24:52 UTC (rev 208) @@ -47,12 +47,16 @@ struct tag_dic_t { dic_table_t music; dic_table_t objects; + + uint8_t* buffer; + long size; }; typedef struct tag_dic_t dic_t; dic_t* dic_new(); void dic_finish(dic_t* dic); -int dic_serialize(dic_t* dic, uint8_t* buffer, int is_storing); +int dic_read(dic_t* dic, FILE *fpi); +int dic_write(dic_t* dic, FILE *fpo); void dic_dump(dic_t* dic, FILE *fp); uint32_t dic_get_idxroot(dic_t* dic, int table, int index); void dic_set_idxroot(dic_t* dic, int table, int index, uint32_t root); Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-27 17:07:29 UTC (rev 207) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-27 17:24:52 UTC (rev 208) @@ -102,21 +102,11 @@ void ip3db_init(ip3db_t* db) { - uint8_t *dic_template = NULL; - /* Construct db->dat, db->dic, and db->idx */ memset(db, 0, sizeof(*db)); db->dat = dat_new(); db->dic = dic_new(); db->idx = idx_new(); - - /* Initialize db->dic, which rules everything in a database. */ - dic_template = dic_get_template(&db->dic_size); - db->dic_buffer = (uint8_t*)malloc(db->dic_size); - if (db->dic_buffer) { - memcpy(db->dic_buffer, dic_template, db->dic_size); - dic_serialize(db->dic, db->dic_buffer, 0); - } } void ip3db_finish(ip3db_t* db) @@ -124,7 +114,6 @@ dic_finish(db->dic); dat_finish(db->dat); idx_finish(db->idx); - free(db->dic_buffer); memset(db, 0, sizeof(*db)); } @@ -138,15 +127,9 @@ ip3db_finish(db); return 1; } - fread_all(fp, &db->dic_buffer, &db->dic_size); + dic_read(db->dic, fp); fclose(fp); - /* Parse db.dic */ - if (dic_serialize(db->dic, db->dic_buffer, 0) != 0) { - ip3db_finish(db); - return 1; - } - /* Read db.dat */ fp = ucs2fopen(datfn, "rb"); if (!fp) { @@ -156,7 +139,7 @@ dat_read(db->dat, db->dic, fp); fclose(fp); - /* Read and parse db.idx */ + /* Read db.idx */ fp = ucs2fopen(idxfn, "rb"); if (!fp) { ip3db_finish(db); @@ -190,16 +173,11 @@ idx_write(db->idx, db->dic, fp); fclose(fp); - if (dic_serialize(db->dic, db->dic_buffer, 1) != 0) { - ip3db_finish(db); - return 1; - } - fp = ucs2fopen(dicfn, "wb"); if (!fp) { return 1; } - fwrite(db->dic_buffer, 1, db->dic_size, fp); + dic_write(db->dic, fp); fclose(fp); return 0; Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.h 2006-12-27 17:07:29 UTC (rev 207) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.h 2006-12-27 17:24:52 UTC (rev 208) @@ -161,13 +161,9 @@ struct tag_idx_t; typedef struct tag_idx_t idx_t; typedef struct { - uint8_t* dic_buffer; - long dic_size; - dat_t* dat; dic_t* dic; idx_t* idx; - } ip3db_t; void ip3db_variant_init(ip3db_variant_t* var, int type); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2006-12-27 17:07:29
|
Revision: 207 http://svn.sourceforge.net/pmplib/?rev=207&view=rev Author: nyaochi Date: 2006-12-27 09:07:29 -0800 (Wed, 27 Dec 2006) Log Message: ----------- Source code clean-up. The ip3db_t structure does not hold the entire memory block for db.dat any more. 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 Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-27 16:38:53 UTC (rev 206) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-27 17:07:29 UTC (rev 207) @@ -247,7 +247,7 @@ free(dat); } -size_t dat_serialize(dat_t* dat, const dic_t* dic, uint8_t* buffer, int is_storing) +static size_t dat_serialize(dat_t* dat, const dic_t* dic, uint8_t* buffer, int is_storing) { if (is_storing) { int i; @@ -263,6 +263,48 @@ return 0; } +int dat_read(dat_t* dat, const dic_t* dic, FILE *fpi) +{ + long buffer_size = 0; + uint8_t* buffer = NULL; + + fread_all(fpi, &buffer, &buffer_size); + if (!buffer) { + return 1; + } + + if (dat_serialize(dat, dic, buffer, 0) != 0) { + free(buffer); + return 1; + } + + free(buffer); + return 0; +} + +int dat_write(dat_t* dat, const dic_t* dic, FILE *fpo) +{ + long buffer_size = 0x00040000; + uint8_t* buffer = (uint8_t*)calloc(buffer_size, sizeof(uint8_t)); + + if (!buffer) { + return 1; + } + + if (dat_serialize(dat, dic, buffer, 1) != 0) { + free(buffer); + return 1; + } + + if (fwrite(buffer, 1, buffer_size, fpo) != buffer_size) { + free(buffer); + return 1; + } + + free(buffer); + return 0; +} + void dat_dump(dat_t* dat, const dic_t* dic, FILE *fp) { fprintf(fp, "===== db.dat =====\n"); Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.h 2006-12-27 16:38:53 UTC (rev 206) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.h 2006-12-27 17:07:29 UTC (rev 207) @@ -46,9 +46,9 @@ dat_t* dat_new(); void dat_finish(dat_t* dat); -size_t dat_serialize(dat_t* dat, const dic_t* dic, uint8_t* buffer, int is_storing); +int dat_read(dat_t* dat, const dic_t* dic, FILE *fpi); +int dat_write(dat_t* dat, const dic_t* dic, FILE *fpo); void dat_dump(dat_t* dat, const dic_t* dic, FILE *fp); - void dat_construct(dat_t* dat, dic_t* dic, const ip3db_music_record_t* records, int num_records); #endif/*__IP3DB_DAT_H__*/ Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-27 16:38:53 UTC (rev 206) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-27 17:07:29 UTC (rev 207) @@ -95,11 +95,7 @@ break; case IP3DBVT_STRING: ucs2free(dst->value.str); - if (src->value.str) { - dst->value.str = ucs2dup(src->value.str); - } else { - dst->value.str = 0; - } + dst->value.str = src->value.str ? ucs2dup(src->value.str) : 0; break; } } @@ -108,15 +104,19 @@ { uint8_t *dic_template = NULL; + /* Construct db->dat, db->dic, and db->idx */ memset(db, 0, sizeof(*db)); db->dat = dat_new(); db->dic = dic_new(); db->idx = idx_new(); + /* Initialize db->dic, which rules everything in a database. */ dic_template = dic_get_template(&db->dic_size); db->dic_buffer = (uint8_t*)malloc(db->dic_size); - memcpy(db->dic_buffer, dic_template, db->dic_size); - dic_serialize(db->dic, db->dic_buffer, 0); + if (db->dic_buffer) { + memcpy(db->dic_buffer, dic_template, db->dic_size); + dic_serialize(db->dic, db->dic_buffer, 0); + } } void ip3db_finish(ip3db_t* db) @@ -124,9 +124,8 @@ dic_finish(db->dic); dat_finish(db->dat); idx_finish(db->idx); - free(db->dat_buffer); free(db->dic_buffer); - ip3db_init(db); + memset(db, 0, sizeof(*db)); } result_t ip3db_read(ip3db_t* db, const ucs2char_t* datfn, const ucs2char_t* dicfn, const ucs2char_t* idxfn) @@ -154,15 +153,9 @@ ip3db_finish(db); return 1; } - fread_all(fp, &db->dat_buffer, &db->dat_size); + dat_read(db->dat, db->dic, fp); fclose(fp); - /* Parse db.dat */ - if (dat_serialize(db->dat, db->dic, db->dat_buffer, 0) != 0) { - ip3db_finish(db); - return 1; - } - /* Read and parse db.idx */ fp = ucs2fopen(idxfn, "rb"); if (!fp) { @@ -179,21 +172,12 @@ { FILE *fp = 0; - free(db->dat_buffer); - - db->dat_size = 0x00040000; - db->dat_buffer = (uint8_t*)calloc(db->dat_size, sizeof(uint8_t)); - - if (dat_serialize(db->dat, db->dic, db->dat_buffer, 1) != 0) { - ip3db_finish(db); - return 1; - } - + /* Write db.dat. This will allocate offset values of the records. */ fp = ucs2fopen(datfn, "wb"); if (!fp) { return 1; } - fwrite(db->dat_buffer, 1, db->dat_size, fp); + dat_write(db->dat, db->dic, fp); fclose(fp); /* Construct db.idx and update db.dic. */ Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.h 2006-12-27 16:38:53 UTC (rev 206) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.h 2006-12-27 17:07:29 UTC (rev 207) @@ -92,6 +92,9 @@ */ typedef ip3db_variant_t ip3db_music_record_t[IP3DBF_MUSIC_LAST]; +/** + * Fields in a object record. + */ enum { IP3DBF_OBJECTS_NONE = -1, IP3DBF_OBJECTS_BEGIN = 0, @@ -109,11 +112,17 @@ IP3DBF_OBJECTS_LAST, }; +/** + * Fields chunks in db.dat. + */ enum { IP3DBIDX_MUSIC = 0, IP3DBIDX_OBJECTS, }; +/** + * Indices for the music chunk. + */ enum { IP3DBIDX_MUSIC_NONE = -1, IP3DBIDX_MUSIC_BEGIN = 0, @@ -132,6 +141,9 @@ IP3DBIDX_MUSIC_LAST, }; +/** + * Indices for the object chunk. + */ enum { IP3DBIDX_OBJECT_NONE = -1, IP3DBIDX_OBJECT_BEGIN = 0, @@ -149,8 +161,6 @@ struct tag_idx_t; typedef struct tag_idx_t idx_t; typedef struct { - uint8_t* dat_buffer; - long dat_size; uint8_t* dic_buffer; long dic_size; @@ -172,9 +182,9 @@ void ip3db_finish(ip3db_t* db); 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); result_t ip3db_dump(ip3db_t* db, FILE *fpo); void ip3db_record_init(ip3db_t* db, ip3db_music_record_t* record); -result_t ip3db_set(ip3db_t* db, const ip3db_music_record_t* records, int num_records); #endif /*_IP3DB_IP3DB_H__*/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2006-12-27 16:38:55
|
Revision: 206 http://svn.sourceforge.net/pmplib/?rev=206&view=rev Author: nyaochi Date: 2006-12-27 08:38:53 -0800 (Wed, 27 Dec 2006) Log Message: ----------- - Trivial comments. - Reduce some warnings with MSVC2005. Modified Paths: -------------- trunk/pmplib/frontend/easypmp/cui/main.c trunk/pmplib/frontend/easypmp/cui/option.c trunk/pmplib/include/os.h trunk/pmplib/lib/gmi/gmi_vorbis.c trunk/pmplib/lib/pmp_iriverplus3/dat.c trunk/pmplib/lib/pmp_iriverplus3/ip3db.c trunk/pmplib/lib/pmp_iriverplus3/ip3db.h Modified: trunk/pmplib/frontend/easypmp/cui/main.c =================================================================== --- trunk/pmplib/frontend/easypmp/cui/main.c 2006-12-27 14:50:16 UTC (rev 205) +++ trunk/pmplib/frontend/easypmp/cui/main.c 2006-12-27 16:38:53 UTC (rev 206) @@ -25,14 +25,14 @@ #ifdef HAVE_CONFIG_H #include <config.h> #endif/*HAVE_CONFIG_H*/ -#ifdef HAVE_STRING_H -#include <string.h> -#endif/*HAVE_STRING_H*/ #include <os.h> #include <stdio.h> #include <stdlib.h> #include <locale.h> +#ifdef HAVE_STRING_H +#include <string.h> +#endif/*HAVE_STRING_H*/ #ifdef _MSC_VER #include <direct.h> /* getcwd() */ #endif/*_MSC_VER*/ Modified: trunk/pmplib/frontend/easypmp/cui/option.c =================================================================== --- trunk/pmplib/frontend/easypmp/cui/option.c 2006-12-27 14:50:16 UTC (rev 205) +++ trunk/pmplib/frontend/easypmp/cui/option.c 2006-12-27 16:38:53 UTC (rev 206) @@ -25,13 +25,13 @@ #ifdef HAVE_CONFIG_H #include <config.h> #endif/*HAVE_CONFIG_H*/ -#ifdef HAVE_STRING_H -#include <string.h> -#endif/*HAVE_STRING_H*/ #include <os.h> #include <stdio.h> #include <stdlib.h> +#ifdef HAVE_STRING_H +#include <string.h> +#endif/*HAVE_STRING_H*/ #ifdef _MSC_VER #include <direct.h> /* getcwd() */ #endif/*_MSC_VER*/ Modified: trunk/pmplib/include/os.h =================================================================== --- trunk/pmplib/include/os.h 2006-12-27 14:50:16 UTC (rev 205) +++ trunk/pmplib/include/os.h 2006-12-27 16:38:53 UTC (rev 206) @@ -24,6 +24,14 @@ #ifndef __OS_H__ #define __OS_H__ +#ifdef _MSC_VER +#define HAVE_STRING_H 1 +#endif/*_MSC_VER*/ + +#if _MSC_VER >= 1400 +#define _CRT_SECURE_NO_DEPRECATE 1 /* Use 'unsafe' CRT routines. */ +#endif/*_MSC_VER*/ + #include <stdio.h> #if defined(WIN32) || defined(OS2) @@ -45,8 +53,11 @@ #endif #if defined(WIN32) +#define fileno _fileno +#define strnicmp _strnicmp #define snprintf _snprintf #define snwprintf _snwprintf +#define strdup _strdup #define getcwd _getcwd #define alloca _alloca #define strnicmp _strnicmp Modified: trunk/pmplib/lib/gmi/gmi_vorbis.c =================================================================== --- trunk/pmplib/lib/gmi/gmi_vorbis.c 2006-12-27 14:50:16 UTC (rev 205) +++ trunk/pmplib/lib/gmi/gmi_vorbis.c 2006-12-27 16:38:53 UTC (rev 206) @@ -43,7 +43,7 @@ */ #ifdef WIN32 -#define strncasecmp strnicmp +#define strncasecmp _strnicmp #endif int gmi_vorbis(media_info_t* info, const ucs2char_t *filename) Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-27 14:50:16 UTC (rev 205) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-27 16:38:53 UTC (rev 206) @@ -274,6 +274,11 @@ fprintf(fp, "}\n"); } +typedef struct { + const ip3db_music_record_t* base; + int index; +} ip3db_sort_index_t; + static int comp_pathname(const void *__x, const void *__y) { const ip3db_sort_index_t* _x = (const ip3db_sort_index_t*)__x; Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-27 14:50:16 UTC (rev 205) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-27 16:38:53 UTC (rev 206) @@ -42,6 +42,9 @@ var->type = type; if (var->type == IP3DBVT_STRING) { var->value.str = mbsdupucs2(""); + if (!var->value.str) { + var->type = IP3DBVT_NONE; + } } } Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.h 2006-12-27 14:50:16 UTC (rev 205) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.h 2006-12-27 16:38:53 UTC (rev 206) @@ -25,18 +25,18 @@ #define __IP3DB_IP3DB_H__ enum { - IP3DBIDX_MAX_KEYLEVEL = 3, + IP3DBIDX_MAX_KEYLEVEL = 3, /**< The maximum number of multiple AVL trees. */ }; /** * Field type IDs used in db.dic (Do not change the associated values) */ enum { - IP3DBVT_NONE = 0, - IP3DBVT_STRING = 1, - IP3DBVT_BYTE = 2, - IP3DBVT_WORD = 3, - IP3DBVT_DWORD = 4, + IP3DBVT_NONE = 0, /**< Attached to no specific type. */ + IP3DBVT_STRING = 1, /**< UCS-2 string. */ + IP3DBVT_BYTE = 2, /**< uint8_t */ + IP3DBVT_WORD = 3, /**< uint16_t */ + IP3DBVT_DWORD = 4, /**< uint32_t */ }; /** @@ -52,6 +52,9 @@ } value; } ip3db_variant_t; +/** + * Fields in a music record. + */ enum { IP3DBF_MUSIC_NONE = -1, IP3DBF_MUSIC_BEGIN = 0, @@ -84,14 +87,11 @@ IP3DBF_MUSIC_LAST, }; +/** + * A music record. + */ typedef ip3db_variant_t ip3db_music_record_t[IP3DBF_MUSIC_LAST]; -typedef struct { - const ip3db_music_record_t* base; - int index; -} ip3db_sort_index_t; - - enum { IP3DBF_OBJECTS_NONE = -1, IP3DBF_OBJECTS_BEGIN = 0, This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2006-12-27 14:50:16
|
Revision: 205 http://svn.sourceforge.net/pmplib/?rev=205&view=rev Author: nyaochi Date: 2006-12-27 06:50:16 -0800 (Wed, 27 Dec 2006) Log Message: ----------- Convert back-slash characters to slash characters in path names in the database. Hooray! I did it. The player worked fine with the database now. Modified Paths: -------------- trunk/pmplib/lib/pmp_iriverplus3/dat.c trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-27 14:23:47 UTC (rev 204) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-27 14:50:16 UTC (rev 205) @@ -39,7 +39,6 @@ #include <stdlib.h> #include <memory.h> #include <ucs2char.h> -#include <filepath.h> #include "serialize.h" #include "util.h" @@ -346,7 +345,13 @@ return &dc->elems[i]; } +static const ucs2char_t* skip_one_directory(const ucs2char_t* path) +{ + ucs2char_t* p = ucs2chr(path, '/'); + return p ? p+1 : NULL; +} + void dat_construct(dat_t* dat, dic_t* dic, const ip3db_music_record_t* records, int num_records) { int i, j; @@ -354,7 +359,7 @@ uint32_t uid = 0; static const uint32_t uid_root = 0xFFFFFFFF; static const ucs2char_t ucs2cs_object_root[] = {'/','a','/',0}; - static const ucs2char_t ucs2cs_root[] = {PATHCHAR, 0}; + static const ucs2char_t ucs2cs_root[] = {'/', 0}; dat_list_t* dato = &dat->objects; dat_list_t* datm = &dat->musics; dircache_t dc; @@ -394,7 +399,7 @@ while (p && *p) { ucs2char_t tmp[MAX_PATH]; - const ucs2char_t* q = filepath_skip_one_directory(p); + const ucs2char_t* q = skip_one_directory(p); uid = dato->num_entries; ucs2ncpy(tmp, p, q-p); Modified: trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c 2006-12-27 14:23:47 UTC (rev 204) +++ trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c 2006-12-27 14:50:16 UTC (rev 205) @@ -515,6 +515,17 @@ 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; @@ -535,7 +546,7 @@ ip3db_variant_set_str(&dst[IP3DBF_MUSIC_FILEPATH], src->filename + ucs2len(path_to_root)); filepath_remove_filespec(dst[IP3DBF_MUSIC_FILEPATH].value.str); filepath_addslash(dst[IP3DBF_MUSIC_FILEPATH].value.str); - filepath_encode(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); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2006-12-27 14:23:48
|
Revision: 204 http://svn.sourceforge.net/pmplib/?rev=204&view=rev Author: nyaochi Date: 2006-12-27 06:23:47 -0800 (Wed, 27 Dec 2006) Log Message: ----------- A number of bug-fixes. The iriver E10 player can successfully navigate tracks in the database generated by EasyPMP now. The player cannot display the song information for some reason, and I'm finding out the reason. Modified Paths: -------------- trunk/pmplib/lib/pmp_iriverplus3/dat.c trunk/pmplib/lib/pmp_iriverplus3/idx.c trunk/pmplib/lib/pmp_iriverplus3/ip3db.c trunk/pmplib/lib/pmp_iriverplus3/ip3db.h trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-27 11:40:38 UTC (rev 203) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-27 14:23:47 UTC (rev 204) @@ -70,13 +70,20 @@ memset(entry, 0, sizeof(*entry)); } -static size_t dat_entry_serialize(dat_entry_t* entry, uint8_t* block, uint8_t* q, int is_storing) +static size_t dat_entry_serialize(dat_entry_t* entry, uint8_t* block, uint8_t* q, uint32_t start, int is_storing) { int i; uint8_t *p = block; + uint32_t offset; /* Serialize offset address of this entry. */ - q -= serialize_uint32be(q, &entry->offset, is_storing); + if (is_storing) { + offset = entry->offset - start; + q -= serialize_uint32be(q, &offset, is_storing); + } else { + q -= serialize_uint32be(q, &offset, is_storing); + entry->offset = offset + start; + } /* Serialize all fields in this entry. */ for (i = 0;i < entry->num_fields;++i) { @@ -161,17 +168,21 @@ dat_list_init(list); } -static size_t dat_list_serialize(dat_list_t* list, const dic_table_t* dic_list, uint8_t* buffer, int is_storing) +static size_t dat_list_serialize(dat_list_t* list, const dic_table_t* dic_list, uint8_t* buffer, uint32_t start, int is_storing) { uint32_t i; - uint8_t *p = buffer; - uint8_t *q = buffer + 0x00020000 - sizeof(uint32_t); + uint8_t *p = buffer + start; + uint8_t *q = buffer + start + 0x00020000 - sizeof(uint32_t); /* Serialize the header (with a dummy size for writing). */ - p += serialize_uint32be(p, &list->size, is_storing); - p += serialize_uint32be(p, &list->num_entries, is_storing); - p += serialize_uint32be(p, &list->unknown1, is_storing); - p += serialize_uint32be(p, &list->unknown2, is_storing); + if (!is_storing) { + p += serialize_uint32be(p, &list->size, is_storing); + p += serialize_uint32be(p, &list->num_entries, is_storing); + p += serialize_uint32be(p, &list->unknown1, is_storing); + p += serialize_uint32be(p, &list->unknown2, is_storing); + } else { + p += sizeof(uint32_t) * 4; + } /* Initialize fields when reading. */ if (!is_storing) { @@ -186,17 +197,19 @@ for (i = 0;i < list->num_entries;++i) { dat_entry_t* entry = &list->entries[i]; entry->offset = (uint32_t)(p - buffer); /* compute the current offset address */ - p += dat_entry_serialize(entry, p, q, is_storing); + p += dat_entry_serialize(entry, p, q, start, is_storing); q -= sizeof(uint32_t); } - /* Write the final size when writing. */ if (is_storing) { - uint32_t size = (uint32_t)(p - buffer); - serialize_uint32be(buffer, &size, is_storing); + list->size = (uint32_t)(p - (buffer + start)); + p = buffer + start; + p += serialize_uint32be(p, &list->size, is_storing); + p += serialize_uint32be(p, &list->num_entries, is_storing); + p += serialize_uint32be(p, &list->unknown1, is_storing); + p += serialize_uint32be(p, &list->unknown2, is_storing); } - - return (size_t)(p - buffer); + return (size_t)(list->size); } static void dat_list_dump(dat_list_t* list, const dic_table_t* dic_list, FILE *fp) @@ -237,8 +250,17 @@ size_t dat_serialize(dat_t* dat, const dic_t* dic, uint8_t* buffer, int is_storing) { - dat_list_serialize(&dat->objects, &dic->objects, buffer, is_storing); - dat_list_serialize(&dat->musics, &dic->music, buffer + 0x00020000, is_storing); + if (is_storing) { + int i; + ucs2char_t empty[] = {0}; + for (i = 0;i < dat->musics.num_entries;++i) { + dat_entry_t* entry = &dat->musics.entries[i]; + ip3db_variant_set_str(&entry->fields[IP3DBF_MUSIC_FILEPATH], empty); + ip3db_variant_set_str(&entry->fields[IP3DBF_MUSIC_FILENAME], empty); + } + } + dat_list_serialize(&dat->objects, &dic->objects, buffer, 0, is_storing); + dat_list_serialize(&dat->musics, &dic->music, buffer, 0x00020000, is_storing); return 0; } Modified: trunk/pmplib/lib/pmp_iriverplus3/idx.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-27 11:40:38 UTC (rev 203) +++ trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-27 14:23:47 UTC (rev 204) @@ -284,10 +284,10 @@ return COMP(*x, *y); } -static int avl_insert_key(avl_t* avl, const void* key, int type, uint32_t* offset, uint32_t* root) +static int avl_insert_key(avl_t* avl, const ip3db_variant_t* key, int type, uint32_t* offset, uint32_t* root) { int ret = 0; - static avl_comp_t comp[] = {NULL, avl_comp_byte, avl_comp_word, avl_comp_dword, avl_comp_ucs2string}; + static avl_comp_t comp[] = {NULL, avl_comp_ucs2string, avl_comp_byte, avl_comp_word, avl_comp_dword}; uint32_t offset_prev = avl_current(avl); uint32_t offset_this = avlnode_new(avl); size_t size = 0; @@ -295,20 +295,23 @@ switch (type) { case IP3DBVT_BYTE: - size = sizeof(uint8_t); + offset_key = avl_allocate(avl, sizeof(uint8_t)); + *((uint8_t*)avlnode(avl, offset_key)) = key->value.byte; break; case IP3DBVT_WORD: - size = sizeof(uint16_t); + offset_key = avl_allocate(avl, sizeof(uint16_t)); + *((uint16_t*)avlnode(avl, offset_key)) = key->value.word; break; case IP3DBVT_DWORD: - size = sizeof(uint32_t); + offset_key = avl_allocate(avl, sizeof(uint32_t)); + *((uint32_t*)avlnode(avl, offset_key)) = key->value.dword; break; case IP3DBVT_STRING: - size = (ucs2len((const ucs2char_t*)key) + 1) * sizeof(ucs2char_t); + offset_key = avl_allocate(avl, sizeof(ucs2char_t) * (ucs2len(key->value.str) + 1)); + ucs2cpy((ucs2char_t*)avlnode(avl, offset_key), key->value.str); break; } - offset_key = avl_allocate(avl, (uint32_t)size); memcpy(avlnode(avl, offset_key), key, size); ret = avl_insert(avl, root, &offset_this, comp[type]); if (ret != -1) { @@ -441,47 +444,55 @@ } } -static void to_be_avltree(avl_t* avl, uint32_t offset, dic_table_t* dic_table, int index, int level) +static uint32_t to_be_avltree(avl_t* avl, uint32_t offset, dic_table_t* dic_table, int index, int level) { - avlnode_t* nbe = avlnode(avl, offset); - avlnode_t node = *nbe; + avlnode_t* node = avlnode(avl, offset); int field = dic_table->indices[index].fields[level]; int type = dic_table->fields[field].type; + uint32_t height = 1; - /* Convert the current node. */ - to_uint32be(&nbe->left); - to_uint32be(&nbe->right); - to_uint32be(&nbe->balance); - to_uint32be(&nbe->tail); - /* Descend to the left node. */ - if (node.left) { - to_be_avltree(avl, node.left, dic_table, index, level); + if (node->left) { + uint32_t new_height = to_be_avltree(avl, node->left, dic_table, index, level) + 1; + if (height < new_height) { + height = new_height; + } } + /* Descend to the right node. */ + if (node->right) { + uint32_t new_height = to_be_avltree(avl, node->right, dic_table, index, level) + 1; + if (height < new_height) { + height = new_height; + } + } + + /* Overwrite the balance field with the height of the current node. */ + node->balance = height; + /* Convert the key value. */ switch (type) { case IP3DBVT_BYTE: break; case IP3DBVT_WORD: - to_uint16be((uint16_t*)(nbe+1)); + to_uint16be((uint16_t*)(node+1)); break; case IP3DBVT_DWORD: - to_uint32be((uint32_t*)(nbe+1)); + to_uint32be((uint32_t*)(node+1)); break; case IP3DBVT_STRING: - to_ucs2be_string((ucs2char_t*)(nbe+1)); + to_ucs2be_string((ucs2char_t*)(node+1)); break; } /* Convert the sub AVL trees or tail. */ - if (node.tail) { + if (node->tail) { if (level+1 < IP3DBIDX_MAX_KEYLEVEL && dic_table->indices[index].fields[level+1] != -1) { /* Convert the AVL tree in the next level. */ - to_be_avltree(avl, node.tail, dic_table, index, level+1); + to_be_avltree(avl, node->tail, dic_table, index, level+1); } else { /* Convert the tail. */ - avltail_t* tbe = (avltail_t*)avlnode(avl, node.tail); + avltail_t* tbe = (avltail_t*)avlnode(avl, node->tail); avltail_t tail = *tbe; for (;;) { from_uint32be(&tbe->next); @@ -495,10 +506,12 @@ } } - /* Descend to the right node. */ - if (node.right) { - to_be_avltree(avl, node.right, dic_table, index, level); - } + /* Convert the current node. */ + to_uint32be(&node->left); + to_uint32be(&node->right); + to_uint32be(&node->balance); + to_uint32be(&node->tail); + return height; } static void fprinti(FILE *fp, int n) @@ -526,6 +539,8 @@ fprinti(fpo, indent); fprintf(fpo, " right: 0x%08X\n", node->right); fprinti(fpo, indent); + fprintf(fpo, " height: 0x%08X\n", node->balance); + fprinti(fpo, indent); fprintf(fpo, " tail: 0x%08X\n", node->tail); fprinti(fpo, indent); fprintf(fpo, " key: "); @@ -658,6 +673,8 @@ int i; idx_header_t* header = (idx_header_t*)idx->buffer; + header->size = idx->avl->offset; + /* Convert the byte order of the header from big endian to the native one. */ to_uint32be(&header->size); to_uint32be(&header->unknown1); @@ -718,7 +735,7 @@ uint32_t offset = 0; int field = dictbl->indices[index].fields[level]; int type = dictbl->fields[field].type; - int ret = avl_insert_key(idx->avl, &entry->fields[field].value, type, &offset, root); + int ret = avl_insert_key(idx->avl, &entry->fields[field], type, &offset, root); if (level+1 < IP3DBIDX_MAX_KEYLEVEL && dictbl->indices[index].fields[level+1] != -1) { avlnode_t* node = avlnode(idx->avl, offset); idx_insert_dat(idx, dictbl, &node->tail, entry, index, level+1); @@ -752,13 +769,13 @@ idx->avl->size = idx->max_size; for (index = 0;index < dic->music.num_indices;++index) { - uint32_t root = dic_get_idxroot(dic, IP3DBIDX_MUSIC, index); + uint32_t root = 0; idx_construct_index(idx, &dic->music, &dat->musics, &root, index); dic_set_idxroot(dic, IP3DBIDX_MUSIC, index, root); } for (index = 0;index < dic->objects.num_indices;++index) { - uint32_t root = dic_get_idxroot(dic, IP3DBIDX_OBJECTS, index); + uint32_t root = 0; idx_construct_index(idx, &dic->objects, &dat->objects, &root, index); dic_set_idxroot(dic, IP3DBIDX_OBJECTS, index, root); } Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-27 11:40:38 UTC (rev 203) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-27 14:23:47 UTC (rev 204) @@ -40,6 +40,9 @@ { memset(var, 0, sizeof(*var)); var->type = type; + if (var->type == IP3DBVT_STRING) { + var->value.str = mbsdupucs2(""); + } } void ip3db_variant_finish(ip3db_variant_t* var) @@ -204,6 +207,11 @@ ip3db_finish(db); return 1; } + + fp = ucs2fopen(dicfn, "wb"); + if (!fp) { + return 1; + } fwrite(db->dic_buffer, 1, db->dic_size, fp); fclose(fp); Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.h 2006-12-27 11:40:38 UTC (rev 203) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.h 2006-12-27 14:23:47 UTC (rev 204) @@ -171,6 +171,7 @@ void ip3db_init(ip3db_t* db); void ip3db_finish(ip3db_t* db); 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_dump(ip3db_t* db, FILE *fpo); void ip3db_record_init(ip3db_t* db, ip3db_music_record_t* record); Modified: trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c 2006-12-27 11:40:38 UTC (rev 203) +++ trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c 2006-12-27 14:23:47 UTC (rev 204) @@ -505,6 +505,16 @@ ); } +static ucs2char_t* _filepath_removeslash(ucs2char_t* path) +{ + size_t length = ucs2len(path)-1; + while (length >= 0 && path[length] == PATHCHAR) { + path[length] = 0; + length--; + } + return (path + length); +} + static result_t pmpdb_set(pmpdb_t* pmpdb, const pmp_record_t* records, uint32_t num_records) { int i; @@ -515,7 +525,7 @@ 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); + _filepath_removeslash(path_to_root); for (i = 0;i < num_records;++i) { const pmp_record_t* src = &records[i]; @@ -527,6 +537,16 @@ filepath_addslash(dst[IP3DBF_MUSIC_FILEPATH].value.str); filepath_encode(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); + ip3db_variant_set_word(&dst[IP3DBF_MUSIC_FILEFORMAT], 3); + 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_UID], (uint32_t)i+1); } ip3db_set(&pmpdbi->ip3db, array, num_records); free(array); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2006-12-27 11:40:39
|
Revision: 203 http://svn.sourceforge.net/pmplib/?rev=203&view=rev Author: nyaochi Date: 2006-12-27 03:40:38 -0800 (Wed, 27 Dec 2006) Log Message: ----------- Incremental commit: implemented the generation routine for db.idx, which will be tested and debugged later. Modified Paths: -------------- trunk/pmplib/lib/pmp_iriverplus3/dic.c trunk/pmplib/lib/pmp_iriverplus3/dic.h trunk/pmplib/lib/pmp_iriverplus3/idx.c trunk/pmplib/lib/pmp_iriverplus3/idx.h trunk/pmplib/lib/pmp_iriverplus3/ip3db.c Modified: trunk/pmplib/lib/pmp_iriverplus3/dic.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dic.c 2006-12-27 08:08:26 UTC (rev 202) +++ trunk/pmplib/lib/pmp_iriverplus3/dic.c 2006-12-27 11:40:38 UTC (rev 203) @@ -212,6 +212,22 @@ } } +void dic_set_idxroot(dic_t* dic, int table, int index, uint32_t root) +{ + dic_index_t* indices = NULL; + switch (table) { + case IP3DBIDX_MUSIC: + indices = dic->music.indices; + break; + case IP3DBIDX_OBJECTS: + indices = dic->objects.indices; + break; + } + if (indices) { + indices[index].idx_root = root; + } +} + void dic_repr_index(dic_t* dic, int table, int index, FILE *fp) { int i; Modified: trunk/pmplib/lib/pmp_iriverplus3/dic.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dic.h 2006-12-27 08:08:26 UTC (rev 202) +++ trunk/pmplib/lib/pmp_iriverplus3/dic.h 2006-12-27 11:40:38 UTC (rev 203) @@ -55,6 +55,7 @@ int dic_serialize(dic_t* dic, uint8_t* buffer, int is_storing); void dic_dump(dic_t* dic, FILE *fp); uint32_t dic_get_idxroot(dic_t* dic, int table, int index); +void dic_set_idxroot(dic_t* dic, int table, int index, uint32_t root); void dic_repr_index(dic_t* dic, int table, int index, FILE *fp); uint8_t *dic_get_template(long* size); Modified: trunk/pmplib/lib/pmp_iriverplus3/idx.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-27 08:08:26 UTC (rev 202) +++ trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-27 11:40:38 UTC (rev 203) @@ -284,16 +284,32 @@ return COMP(*x, *y); } -static int avl_insert_key(avl_t* avl, const void* key, size_t size, int type, uint32_t* offset, uint32_t* root) +static int avl_insert_key(avl_t* avl, const void* key, int type, uint32_t* offset, uint32_t* root) { int ret = 0; + static avl_comp_t comp[] = {NULL, avl_comp_byte, avl_comp_word, avl_comp_dword, avl_comp_ucs2string}; uint32_t offset_prev = avl_current(avl); uint32_t offset_this = avlnode_new(avl); - uint32_t offset_key = avl_allocate(avl, (uint32_t)size); - void *pkey = avlnode(avl, offset_key); - static avl_comp_t comp[] = {NULL, avl_comp_byte, avl_comp_word, avl_comp_dword, avl_comp_ucs2string}; + size_t size = 0; + uint32_t offset_key = 0; - memcpy(pkey, key, size); + switch (type) { + case IP3DBVT_BYTE: + size = sizeof(uint8_t); + break; + case IP3DBVT_WORD: + size = sizeof(uint16_t); + break; + case IP3DBVT_DWORD: + size = sizeof(uint32_t); + break; + case IP3DBVT_STRING: + size = (ucs2len((const ucs2char_t*)key) + 1) * sizeof(ucs2char_t); + break; + } + + offset_key = avl_allocate(avl, (uint32_t)size); + memcpy(avlnode(avl, offset_key), key, size); ret = avl_insert(avl, root, &offset_this, comp[type]); if (ret != -1) { /* A new key. */ @@ -307,10 +323,10 @@ } } -static int avl_insert_keydata(avl_t* avl, const void* key, size_t size, int type, uint32_t data, uint32_t* root) +static int avl_insert_keydata(avl_t* avl, const void* key, int type, uint32_t data, uint32_t* root) { uint32_t offset = 0; - int ret = avl_insert_key(avl, key, size, type, &offset, root); + int ret = avl_insert_key(avl, key, type, &offset, root); avlnode_t* node = avlnode(avl, offset); uint32_t offset_tail = avltail_new(avl); avltail_t* tail = (avltail_t*)avlnode(avl, offset_tail); @@ -327,6 +343,14 @@ *value = tmp; } +static void to_uint16be(uint16_t* value) +{ + uint16_t tmp = *value; + uint8_t* dst = (uint8_t*)value; + dst[0] = (uint8_t)(tmp >> 8); + dst[1] = (uint8_t)(tmp & 0xFF); +} + static void from_uint32be(uint32_t* value) { uint8_t* src = (uint8_t*)value; @@ -334,6 +358,16 @@ *value = tmp; } +static void to_uint32be(uint32_t* value) +{ + uint32_t tmp = *value; + uint8_t* dst = (uint8_t*)value; + dst[0] = (uint8_t)(tmp >> 24); + dst[1] = (uint8_t)(tmp >> 16); + dst[2] = (uint8_t)(tmp >> 8); + dst[3] = (uint8_t)(tmp & 0xFF); +} + static void from_ucs2be_string(ucs2char_t* value) { while (*value) { @@ -342,12 +376,12 @@ } } -static void from_be_avlnode(avlnode_t* node) +static void to_ucs2be_string(ucs2char_t* value) { - from_uint32be(&node->left); - from_uint32be(&node->right); - from_uint32be(&node->balance); - from_uint32be(&node->tail); + while (*value) { + to_uint16be((uint16_t*)value); + value++; + } } static void from_be_avltree(avl_t* avl, uint32_t offset, dic_table_t* dic_table, int index, int level) @@ -357,7 +391,10 @@ int type = dic_table->fields[field].type; /* Convert the current node. */ - from_be_avlnode(node); + from_uint32be(&node->left); + from_uint32be(&node->right); + from_uint32be(&node->balance); + from_uint32be(&node->tail); /* Descend to the left node. */ if (node->left) { @@ -404,6 +441,66 @@ } } +static void to_be_avltree(avl_t* avl, uint32_t offset, dic_table_t* dic_table, int index, int level) +{ + avlnode_t* nbe = avlnode(avl, offset); + avlnode_t node = *nbe; + int field = dic_table->indices[index].fields[level]; + int type = dic_table->fields[field].type; + + /* Convert the current node. */ + to_uint32be(&nbe->left); + to_uint32be(&nbe->right); + to_uint32be(&nbe->balance); + to_uint32be(&nbe->tail); + + /* Descend to the left node. */ + if (node.left) { + to_be_avltree(avl, node.left, dic_table, index, level); + } + + /* Convert the key value. */ + switch (type) { + case IP3DBVT_BYTE: + break; + case IP3DBVT_WORD: + to_uint16be((uint16_t*)(nbe+1)); + break; + case IP3DBVT_DWORD: + to_uint32be((uint32_t*)(nbe+1)); + break; + case IP3DBVT_STRING: + to_ucs2be_string((ucs2char_t*)(nbe+1)); + break; + } + + /* Convert the sub AVL trees or tail. */ + if (node.tail) { + if (level+1 < IP3DBIDX_MAX_KEYLEVEL && dic_table->indices[index].fields[level+1] != -1) { + /* Convert the AVL tree in the next level. */ + to_be_avltree(avl, node.tail, dic_table, index, level+1); + } else { + /* Convert the tail. */ + avltail_t* tbe = (avltail_t*)avlnode(avl, node.tail); + avltail_t tail = *tbe; + for (;;) { + from_uint32be(&tbe->next); + from_uint32be(&tbe->data); + if (!tail.next) { + break; + } + tbe = (avltail_t*)avlnode(avl, tail.next); + tail = *tbe; + } + } + } + + /* Descend to the right node. */ + if (node.right) { + to_be_avltree(avl, node.right, dic_table, index, level); + } +} + static void fprinti(FILE *fp, int n) { while (n--) fputc(' ', fp); @@ -556,6 +653,34 @@ return 0; } +result_t idx_write(idx_t* idx, dic_t* dic, FILE *fpo) +{ + int i; + idx_header_t* header = (idx_header_t*)idx->buffer; + + /* Convert the byte order of the header from big endian to the native one. */ + to_uint32be(&header->size); + to_uint32be(&header->unknown1); + to_uint32be(&header->unknown2); + + /* Convert the byte order of AVL trees. */ + for (i = 0;i < dic->music.num_indices;++i) { + uint32_t idx_root = dic_get_idxroot(dic, IP3DBIDX_MUSIC, i); + to_be_avltree(idx->avl, idx_root, &dic->music, i, 0); + } + for (i = 0;i < dic->objects.num_indices;++i) { + uint32_t idx_root = dic_get_idxroot(dic, IP3DBIDX_OBJECTS, i); + to_be_avltree(idx->avl, idx_root, &dic->objects, i, 0); + } + + /* Read the whole data at a time. */ + if (fwrite(idx->buffer, 1, idx->max_size, fpo) != idx->max_size) { + return 1; + } + + return 0; +} + result_t idx_dump(idx_t* idx, dic_t* dic, FILE *fpo) { int i; @@ -587,3 +712,56 @@ fprintf(fpo, "\n"); return 0; } + +static void idx_insert_dat(idx_t* idx, dic_table_t* dictbl, uint32_t* root, dat_entry_t* entry, int index, int level) +{ + uint32_t offset = 0; + int field = dictbl->indices[index].fields[level]; + int type = dictbl->fields[field].type; + int ret = avl_insert_key(idx->avl, &entry->fields[field].value, type, &offset, root); + if (level+1 < IP3DBIDX_MAX_KEYLEVEL && dictbl->indices[index].fields[level+1] != -1) { + avlnode_t* node = avlnode(idx->avl, offset); + idx_insert_dat(idx, dictbl, &node->tail, entry, index, level+1); + } else { + avlnode_t* node = avlnode(idx->avl, offset); + uint32_t offset_tail = avltail_new(idx->avl); + avltail_t* tail = (avltail_t*)avlnode(idx->avl, offset_tail); + tail->data = entry->offset; + tail->next = node->tail; + node->tail = offset_tail; + } +} + +static void idx_construct_index(idx_t* idx, dic_table_t* dictbl, dat_list_t* list, uint32_t* root, int index) +{ + uint32_t i; + + for (i = 0;i < list->num_entries;++i) { + dat_entry_t* entry = &list->entries[i]; + idx_insert_dat(idx, dictbl, root, entry, index, 0); + } +} + +result_t idx_construct(idx_t* idx, dic_t* dic, dat_t* dat) +{ + int index; + + memset(idx->buffer, 0, idx->max_size); + idx->avl->buffer = idx->buffer; + idx->avl->offset = sizeof(idx_header_t); + idx->avl->size = idx->max_size; + + for (index = 0;index < dic->music.num_indices;++index) { + uint32_t root = dic_get_idxroot(dic, IP3DBIDX_MUSIC, index); + idx_construct_index(idx, &dic->music, &dat->musics, &root, index); + dic_set_idxroot(dic, IP3DBIDX_MUSIC, index, root); + } + + for (index = 0;index < dic->objects.num_indices;++index) { + uint32_t root = dic_get_idxroot(dic, IP3DBIDX_OBJECTS, index); + idx_construct_index(idx, &dic->objects, &dat->objects, &root, index); + dic_set_idxroot(dic, IP3DBIDX_OBJECTS, index, root); + } + + return 0; +} Modified: trunk/pmplib/lib/pmp_iriverplus3/idx.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/idx.h 2006-12-27 08:08:26 UTC (rev 202) +++ trunk/pmplib/lib/pmp_iriverplus3/idx.h 2006-12-27 11:40:38 UTC (rev 203) @@ -37,6 +37,9 @@ idx_t *idx_new(); void idx_finish(idx_t* idx); result_t idx_read(idx_t* idx, dic_t* dic, FILE *fpi); +result_t idx_write(idx_t* idx, dic_t* dic, FILE *fpo); result_t idx_dump(idx_t* idx, dic_t* dic, FILE *fpo); +result_t idx_construct(idx_t* idx, dic_t* dic, dat_t* dat); + #endif/*__IP3DB_IDX_H__*/ Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-27 08:08:26 UTC (rev 202) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-27 11:40:38 UTC (rev 203) @@ -127,6 +127,7 @@ { FILE *fp = 0; + /* Read db.dic */ fp = ucs2fopen(dicfn, "rb"); if (!fp) { ip3db_finish(db); @@ -135,11 +136,13 @@ fread_all(fp, &db->dic_buffer, &db->dic_size); fclose(fp); + /* Parse db.dic */ if (dic_serialize(db->dic, db->dic_buffer, 0) != 0) { ip3db_finish(db); return 1; } + /* Read db.dat */ fp = ucs2fopen(datfn, "rb"); if (!fp) { ip3db_finish(db); @@ -148,11 +151,13 @@ fread_all(fp, &db->dat_buffer, &db->dat_size); fclose(fp); + /* Parse db.dat */ if (dat_serialize(db->dat, db->dic, db->dat_buffer, 0) != 0) { ip3db_finish(db); return 1; } + /* Read and parse db.idx */ fp = ucs2fopen(idxfn, "rb"); if (!fp) { ip3db_finish(db); @@ -171,19 +176,13 @@ free(db->dat_buffer); db->dat_size = 0x00040000; - //db->dat_buffer = (uint8_t*)calloc(db->dat_size, sizeof(uint8_t)); - db->dat_buffer = (uint8_t*)malloc(db->dat_size); + db->dat_buffer = (uint8_t*)calloc(db->dat_size, sizeof(uint8_t)); if (dat_serialize(db->dat, db->dic, db->dat_buffer, 1) != 0) { ip3db_finish(db); return 1; } - if (dic_serialize(db->dic, db->dic_buffer, 1) != 0) { - ip3db_finish(db); - return 1; - } - fp = ucs2fopen(datfn, "wb"); if (!fp) { return 1; @@ -191,23 +190,22 @@ fwrite(db->dat_buffer, 1, db->dat_size, fp); fclose(fp); - /* - fp = ucs2fopen(dicfn, "rb"); + /* Construct db.idx and update db.dic. */ + idx_construct(db->idx, db->dic, db->dat); + + fp = ucs2fopen(idxfn, "wb"); if (!fp) { - ip3db_finish(db); return 1; } - fread_all(fp, &db->dic_buffer, &db->dic_size); + idx_write(db->idx, db->dic, fp); fclose(fp); - fp = ucs2fopen(idxfn, "rb"); - if (!fp) { + if (dic_serialize(db->dic, db->dic_buffer, 1) != 0) { ip3db_finish(db); return 1; } - fread_all(fp, &db->idx_buffer, &db->idx_size); + fwrite(db->dic_buffer, 1, db->dic_size, fp); fclose(fp); -*/ return 0; } @@ -229,11 +227,6 @@ { /* Construct Objects table in db.dat */ dat_construct(db->dat, db->dic, records, num_records); - - /* Construct db.idx */ - - /* Update db.dic */ - return 0; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2006-12-27 08:08:29
|
Revision: 202 http://svn.sourceforge.net/pmplib/?rev=202&view=rev Author: nyaochi Date: 2006-12-27 00:08:26 -0800 (Wed, 27 Dec 2006) Log Message: ----------- Implemented AVL tree for db.idx. Sophisticated dump routine for db.idx by using the AVL tree library. We are now close to generate db.idx Modified Paths: -------------- trunk/pmplib/include/os.h trunk/pmplib/lib/pmp_iriverplus3/idx.c trunk/pmplib/lib/pmp_iriverplus3/idx.h trunk/pmplib/lib/pmp_iriverplus3/ip3db.c trunk/pmplib/lib/pmp_iriverplus3/ip3db.h Modified: trunk/pmplib/include/os.h =================================================================== --- trunk/pmplib/include/os.h 2006-12-25 15:15:36 UTC (rev 201) +++ trunk/pmplib/include/os.h 2006-12-27 08:08:26 UTC (rev 202) @@ -29,6 +29,7 @@ #if defined(WIN32) || defined(OS2) typedef unsigned char uint8_t; typedef unsigned int uint32_t; +typedef int int32_t; typedef unsigned short uint16_t; #elif defined(bsdi) || defined(FREEBSD) || defined(OPENBSD) Modified: trunk/pmplib/lib/pmp_iriverplus3/idx.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-25 15:15:36 UTC (rev 201) +++ trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-27 08:08:26 UTC (rev 202) @@ -1,5 +1,5 @@ /* - * Low-level library for db.idx. + * AVL tree implementation for db.idx. * * Copyright (c) 2006 Nyaochi * @@ -42,138 +42,366 @@ #include "util.h" #include "ip3db.h" #include "dic.h" +#include "dat.h" +#include "idx.h" +#define COMP(a, b) ((a)>(b))-((a)<(b)) + typedef struct { uint32_t size; uint32_t unknown1; uint32_t unknown2; -} header_t; +} idx_header_t; -typedef struct { - uint32_t left; - uint32_t right; - uint32_t height; - uint32_t leaf; -} node_t; +struct tag_avlnode_t { + uint32_t left; + uint32_t right; + int32_t balance; + uint32_t tail; +}; +typedef struct tag_avlnode_t avlnode_t; -typedef struct { - uint32_t dat_offset; - uint32_t next; -} tail_t; +struct tag_avltail_t { + uint32_t data; + uint32_t next; +}; +typedef struct tag_avltail_t avltail_t; -static size_t idx_serialize_header(uint8_t *block, header_t *header, int is_storing) +struct tag_avl_t { + uint8_t* buffer; + uint32_t size; + uint32_t offset; +}; +typedef struct tag_avl_t avl_t; + +typedef int (*avl_comp_t)(avl_t* avl, uint32_t x, uint32_t y); + +static uint32_t avl_current(avl_t* avl) { - uint8_t *p = block; - p += serialize_uint32be(p, &header->size, is_storing); - p += serialize_uint32be(p, &header->unknown1, is_storing); - p += serialize_uint32be(p, &header->unknown2, is_storing); - return sizeof(header_t); + return avl->offset; } -static size_t idx_serialize_node(uint8_t *block, node_t *node, int is_storing) +static uint32_t avl_allocate(avl_t* avl, uint32_t size) { - uint8_t *p = block; - p += serialize_uint32be(p, &node->left, 0); - p += serialize_uint32be(p, &node->right, 0); - p += serialize_uint32be(p, &node->height, 0); - p += serialize_uint32be(p, &node->leaf, 0); - return sizeof(node_t); + uint32_t offset = avl->offset; + avl->offset += size; + return offset; } -static size_t idx_serialize_tail(uint8_t *block, tail_t* tail, int is_storing) +static avlnode_t *avlnode(avl_t* avl, uint32_t offset) { - uint8_t *p = block; - p += serialize_uint32be(p, &tail->dat_offset, is_storing); - p += serialize_uint32be(p, &tail->next, is_storing); - return sizeof(tail_t); + return (avlnode_t*)(avl->buffer + offset); } -/** - * Prototype definition of a callback function for idx_walk. - * @param buffer The pointer to the index buffer. - * @param offset The offset address of the current node. - * @param node The information of the node. - * @param key The key value of the node. - * @param types The key types. - * @param level The current key level. - * @param flag - * @param instance The instance value. - */ -typedef int (*idx_walk_callback_t)( - uint8_t* buffer, - uint32_t offset, - node_t* node, - ip3db_variant_t* key, - dic_table_t* dic_table, - int index, - int level, - int flag, - void *instance - ); +static void avl_rewind(avl_t* avl, uint32_t offset) +{ + memset(avlnode(avl, offset), 0, avl->offset - offset); + avl->offset = offset; +} -void idx_walk( - uint8_t *buffer, - uint32_t offset, - dic_table_t* dic_table, - int index, - int level, - idx_walk_callback_t callback, - void *instance - ) +static uint32_t avlnode_new(avl_t* avl) { - node_t node; - ip3db_variant_t key; + uint32_t offset = avl_allocate(avl, sizeof(avlnode_t)); + avlnode_t* a = avlnode(avl, offset); + a->left = 0; + a->right = 0; + a->balance = 0; + a->tail = 0; + return offset; +} + +static uint32_t avltail_new(avl_t* avl) +{ + uint32_t offset = avl_allocate(avl, sizeof(avltail_t)); + avltail_t* a = (avltail_t*)avlnode(avl, offset); + a->data = 0; + a->next = 0; + return offset; +} + +static void avl_swl(avl_t* avl, uint32_t *offr) +{ + uint32_t offa = *offr; + avlnode_t* a = avlnode(avl, offa); + uint32_t offb = a->right; + avlnode_t* b = avlnode(avl, offb); + *offr = offb; + a->right = b->left; + b->left = offa; +} + +static void avl_swr(avl_t* avl, uint32_t *offr) +{ + uint32_t offa = *offr; + avlnode_t* a = avlnode(avl, offa); + uint32_t offb = a->left; + avlnode_t* b = avlnode(avl, offb); + *offr = offb; + a->left = b->right; + b->right = offa; +} + +static void avl_nasty(avl_t* avl, uint32_t offr) +{ + avlnode_t* root = avlnode(avl, offr); + avlnode_t* left = avlnode(avl, root->left); + avlnode_t* right = avlnode(avl, root->right); + switch (root->balance) { + case -1: + left->balance = 0; + right->balance = 1; + break; + case 0: + left->balance = 0; + right->balance = 0; + break; + case 1: + left->balance = -1; + right->balance = 0; + break; + } + root->balance = 0; +} + +static int avl_insert(avl_t* avl, uint32_t* offr, uint32_t* offa, avl_comp_t comp) +{ + avlnode_t* root = NULL; + avlnode_t* left = NULL; + avlnode_t* right = NULL; + + if (!*offr) { + /* An empty tree: set the current node as the root node. */ + *offr = *offa; + return 1; + } else { + uint32_t x = *offr + sizeof(avlnode_t); + uint32_t y = *offa + sizeof(avlnode_t); + int cmp = comp(avl, x, y); + if (cmp > 0) { + /* Insert the node to the left sub-tree. */ + root = avlnode(avl, *offr); + if (root->left) { + uint32_t off_left = root->left; + int ret = avl_insert(avl, &off_left, offa, comp); + if (ret > 0) { + switch (root->balance--) { + case 1: return 0; + case 0: return 1; + } + left = avlnode(avl, root->left); + if (left->balance < 0) { + avl_swr(avl, offr); + root = avlnode(avl, *offr); + right = avlnode(avl, root->right); + root->balance = 0; + right->balance = 0; + } else { + avl_swl(avl, &root->left); + avl_swr(avl, offr); + avl_nasty(avl, *offr); + } + } else if (ret == 0) { + root->left = off_left; + } else { + return -1; + } + return 0; + } else { + root->left = *offa; + if (root->balance--) return 0; + return 1; + } + } else if (cmp < 0) { + /* Insert the node to the right sub-tree. */ + root = avlnode(avl, *offr); + if (root->right) { + uint32_t off_right = root->right; + int ret = avl_insert(avl, &off_right, offa, comp); + if (ret > 0) { + switch (root->balance++) { + case -1: return 0; + case 0: return 1; + } + right = avlnode(avl, root->right); + if (right->balance > 0) { + avl_swl(avl, offr); + root = avlnode(avl, *offr); + left = avlnode(avl, root->left); + root->balance = 0; + left->balance = 0; + } else { + avl_swr(avl, &root->right); + avl_swl(avl, offr); + avl_nasty(avl, *offr); + } + } else if (ret == 0) { + root->right = off_right; + } else { + return -1; + } + return 0; + } else { + root->right = *offa; + if (root->balance++) return 0; + return 1; + } + } else { + *offa = *offr; + return -1; + } + } +} + +static int avl_comp_byte(avl_t* avl, uint32_t _x, uint32_t _y) +{ + uint8_t* x = avl->buffer + _x; + uint8_t* y = avl->buffer + _y; + return COMP(*x, *y); +} + +static int avl_comp_word(avl_t* avl, uint32_t _x, uint32_t _y) +{ + uint16_t* x = (uint16_t*)(avl->buffer + _x); + uint16_t* y = (uint16_t*)(avl->buffer + _y); + return COMP(*x, *y); +} + +static int avl_comp_dword(avl_t* avl, uint32_t _x, uint32_t _y) +{ + uint32_t* x = (uint32_t*)(avl->buffer + _x); + uint32_t* y = (uint32_t*)(avl->buffer + _y); + return COMP(*x, *y); +} + +static int avl_comp_ucs2string(avl_t* avl, uint32_t _x, uint32_t _y) +{ + ucs2char_t* x = (ucs2char_t*)(avl->buffer + _x); + ucs2char_t* y = (ucs2char_t*)(avl->buffer + _y); + while (*x && *y && *x == *y) { + x++; + y++; + } + return COMP(*x, *y); +} + +static int avl_insert_key(avl_t* avl, const void* key, size_t size, int type, uint32_t* offset, uint32_t* root) +{ + int ret = 0; + uint32_t offset_prev = avl_current(avl); + uint32_t offset_this = avlnode_new(avl); + uint32_t offset_key = avl_allocate(avl, (uint32_t)size); + void *pkey = avlnode(avl, offset_key); + static avl_comp_t comp[] = {NULL, avl_comp_byte, avl_comp_word, avl_comp_dword, avl_comp_ucs2string}; + + memcpy(pkey, key, size); + ret = avl_insert(avl, root, &offset_this, comp[type]); + if (ret != -1) { + /* A new key. */ + *offset = offset_this; + return 0; + } else { + /* The key exists in the AVL tree. */ + avl_rewind(avl, offset_prev); + *offset = offset_this; + return 1; + } +} + +static int avl_insert_keydata(avl_t* avl, const void* key, size_t size, int type, uint32_t data, uint32_t* root) +{ + uint32_t offset = 0; + int ret = avl_insert_key(avl, key, size, type, &offset, root); + avlnode_t* node = avlnode(avl, offset); + uint32_t offset_tail = avltail_new(avl); + avltail_t* tail = (avltail_t*)avlnode(avl, offset_tail); + tail->data = data; + tail->next = node->tail; + node->tail = offset_tail; + return ret; +} + +static void from_uint16be(uint16_t* value) +{ + uint8_t* src = (uint8_t*)value; + uint16_t tmp = (uint16_t)src[0] << 8 | (uint16_t)src[1]; + *value = tmp; +} + +static void from_uint32be(uint32_t* value) +{ + uint8_t* src = (uint8_t*)value; + uint32_t tmp = (uint32_t)src[0] << 24 | (uint32_t)src[1] << 16 | (uint32_t)src[2] << 8 | (uint32_t)src[3]; + *value = tmp; +} + +static void from_ucs2be_string(ucs2char_t* value) +{ + while (*value) { + from_uint16be((uint16_t*)value); + value++; + } +} + +static void from_be_avlnode(avlnode_t* node) +{ + from_uint32be(&node->left); + from_uint32be(&node->right); + from_uint32be(&node->balance); + from_uint32be(&node->tail); +} + +static void from_be_avltree(avl_t* avl, uint32_t offset, dic_table_t* dic_table, int index, int level) +{ + avlnode_t* node = avlnode(avl, offset); int field = dic_table->indices[index].fields[level]; int type = dic_table->fields[field].type; - uint8_t* p = buffer + offset; - /* Read the node information. */ - p += idx_serialize_node(p, &node, 0); + /* Convert the current node. */ + from_be_avlnode(node); - /* Descend to left children. */ - if (node.left) { - idx_walk(buffer, node.left, dic_table, index, level, callback, instance); + /* Descend to the left node. */ + if (node->left) { + from_be_avltree(avl, node->left, dic_table, index, level); } - /* Read the key value. */ - ip3db_variant_init(&key, type); + /* Convert the key value. */ switch (type) { case IP3DBVT_BYTE: - p += serialize_uint8(p, &key.value.byte, 0); break; case IP3DBVT_WORD: - p += serialize_uint16be(p, &key.value.word, 0); + from_uint16be((uint16_t*)(node+1)); break; case IP3DBVT_DWORD: - p += serialize_uint32be(p, &key.value.dword, 0); + from_uint32be((uint32_t*)(node+1)); break; case IP3DBVT_STRING: - p += serialize_ucs2be_string_var_alloc(p, &key.value.str) * sizeof(ucs2char_t); + from_ucs2be_string((ucs2char_t*)(node+1)); break; } - /* Invoke the callback function. */ - if (callback && type) { - callback(buffer, offset, &node, &key, dic_table, index, level, 1, instance); - } - - /* Descend to the next key level if necessary. */ - if (level+1 < IP3DBIDX_MAX_KEYLEVEL) { - int next_field = dic_table->indices[index].fields[level+1]; - if (next_field != -1) { - idx_walk(buffer, node.leaf, dic_table, index, level+1, callback, instance); + /* Convert the sub AVL trees or tail. */ + if (node->tail) { + if (level+1 < IP3DBIDX_MAX_KEYLEVEL && dic_table->indices[index].fields[level+1] != -1) { + /* Convert the AVL tree in the next level. */ + from_be_avltree(avl, node->tail, dic_table, index, level+1); + } else { + /* Convert the tail. */ + avltail_t* tail = (avltail_t*)avlnode(avl, node->tail); + for (;;) { + from_uint32be(&tail->next); + from_uint32be(&tail->data); + if (!tail->next) { + break; + } + tail = (avltail_t*)avlnode(avl, tail->next); + } } } - /* Invoke the callback function. */ - if (callback && type) { - callback(buffer, offset, &node, &key, dic_table, index, level, 0, instance); + /* Descend to the right node. */ + if (node->right) { + from_be_avltree(avl, node->right, dic_table, index, level); } - - /* Descend to right children. */ - if (node.right) { - idx_walk(buffer, node.right, dic_table, index, level, callback, instance); - } } static void fprinti(FILE *fp, int n) @@ -181,89 +409,164 @@ while (n--) fputc(' ', fp); } -int idx_walkcb_dump( - uint8_t* buffer, - uint32_t offset, - node_t* node, - ip3db_variant_t* key, - dic_table_t* dic_table, - int index, - int level, - int flag, - void *instance - ) +static void avl_dump(avl_t* avl, uint32_t offset, dic_table_t* dic_table, int index, int level, FILE *fpo) { - FILE *fp = (FILE*)instance; + avlnode_t* node = avlnode(avl, offset); int field = dic_table->indices[index].fields[level]; int type = dic_table->fields[field].type; - int is_tail = (IP3DBIDX_MAX_KEYLEVEL <= level+1 || dic_table->indices[index].fields[level+1] == -1); int indent = 2 * (level + 1); - if (flag) { - fprinti(fp, indent); - fprintf(fp, "NODE (0x%08X) = {\n", offset); - fprinti(fp, indent); - fprintf(fp, " left: 0x%08X\n", node->left); - fprinti(fp, indent); - fprintf(fp, " right: 0x%08X\n", node->right); - fprinti(fp, indent); - fprintf(fp, " data: 0x%08X\n", node->leaf); + /* Descend to the left node. */ + if (node->left) { + avl_dump(avl, node->left, dic_table, index, level, fpo); + } - fprinti(fp, indent); - fprintf(fp, " key: "); - switch (key->type) { - case IP3DBVT_BYTE: - fprintf(fp, "0x%02X", key->value.byte); + /* Dump the current node. */ + fprinti(fpo, indent); + fprintf(fpo, "NODE (0x%08X)\n", offset); + fprinti(fpo, indent); + fprintf(fpo, " left: 0x%08X\n", node->left); + fprinti(fpo, indent); + fprintf(fpo, " right: 0x%08X\n", node->right); + fprinti(fpo, indent); + fprintf(fpo, " tail: 0x%08X\n", node->tail); + fprinti(fpo, indent); + fprintf(fpo, " key: "); + switch (type) { + case IP3DBVT_BYTE: + fprintf(fpo, "0x%02X", *(uint8_t*)(node+1)); + break; + case IP3DBVT_WORD: + fprintf(fpo, "0x%04X", *(uint16_t*)(node+1)); + break; + case IP3DBVT_DWORD: + fprintf(fpo, "0x%08X", *(uint32_t*)(node+1)); + break; + case IP3DBVT_STRING: + fprints(fpo, "%s", (ucs2char_t*)(node+1)); + break; + } + fprintf(fpo, "\n"); + + /* Convert the sub AVL trees or tail. */ + if (node->tail) { + if (level+1 < IP3DBIDX_MAX_KEYLEVEL && dic_table->indices[index].fields[level+1] != -1) { + /* Convert the AVL tree in the next level. */ + avl_dump(avl, node->tail, dic_table, index, level+1, fpo); + } else { + /* Convert the tail. */ + avltail_t* tail = (avltail_t*)avlnode(avl, node->tail); + + fprinti(fpo, indent); + fprintf(fpo, " TAIL: [\n"); + for (;;) { + fprinti(fpo, indent); + fprintf(fpo, " 0x%08X\n", tail->data); + if (!tail->next) { + break; + } + tail = (avltail_t*)avlnode(avl, tail->next); + } + fprinti(fpo, indent); + fprintf(fpo, " ]\n", node->left); + } + } + + /* Descend to the right node. */ + if (node->right) { + avl_dump(avl, node->right, dic_table, index, level, fpo); + } +} + +void avl_walk2(avl_t* avl, uint32_t offr, avl_comp_t comp) +{ + wchar_t* key = 0; + avlnode_t* root = avlnode(avl, offr); + avltail_t* tail = (avltail_t*)avlnode(avl, root->tail); + if (root->left) avl_walk2(avl, root->left, comp); + key = (wchar_t*)avlnode(avl, offr + sizeof(avlnode_t)); + printf("%S: ", key); + for (;;) { + printf("%d ", tail->data); + if (!tail->next) { break; - case IP3DBVT_WORD: - fprintf(fp, "0x%04X", key->value.word); - break; - case IP3DBVT_DWORD: - fprintf(fp, "0x%08X", key->value.dword); - break; - case IP3DBVT_STRING: - fprints(fp, "%s", key->value.str); - break; } - fprintf(fp, "\n"); + tail = (avltail_t*)avlnode(avl, tail->next); + } + printf("\n"); - if (is_tail) { - tail_t tail; + if (root->right) avl_walk2(avl, root->right, comp); +} - memset(&tail, 0, sizeof(tail)); - tail.next = node->leaf; +void avl_walk(avl_t* avl, uint32_t offr, avl_comp_t comp) +{ + wchar_t* key = 0; + avlnode_t* root = avlnode(avl, offr); + if (root->left) avl_walk(avl, root->left, comp); + key = (wchar_t*)avlnode(avl, offr + sizeof(avlnode_t)); + printf("%S: ", key); + avl_walk2(avl, root->tail, comp); + if (root->right) avl_walk(avl, root->right, comp); +} - fprinti(fp, indent); - fprintf(fp, " TAIL: [\n", node->left); - while (tail.next) { - uint8_t *p = buffer + tail.next; - idx_serialize_tail(p, &tail, 0); - fprinti(fp, indent); - fprintf(fp, " 0x%08X\n", tail.dat_offset); - } - fprinti(fp, indent); - fprintf(fp, " ]\n", node->left); - } - } else { - fprinti(fp, indent); - fprintf(fp, "}\n"); +idx_t *idx_new() +{ + idx_t* idx = (idx_t*)malloc(sizeof(idx_t)); + idx->max_size = 0x00020000; + idx->buffer = (uint8_t*)malloc(idx->max_size); + idx->size = 0; + idx->avl = (avl_t*)malloc(sizeof(avl_t)); + idx->avl->buffer = idx->buffer; + idx->avl->offset = sizeof(idx_header_t); + idx->avl->size = idx->max_size; + return idx; +} + +void idx_finish(idx_t* idx) +{ + free(idx->avl); + free(idx->buffer); + free(idx); +} + +int idx_read(idx_t* idx, dic_t* dic, FILE *fpi) +{ + int i; + idx_header_t* header = (idx_header_t*)idx->buffer; + + /* Read the whole data at a time. */ + if (fread(idx->buffer, 1, idx->max_size, fpi) != idx->max_size) { + return 1; } + /* Convert the byte order of the header from big endian to the native one. */ + from_uint32be(&header->size); + from_uint32be(&header->unknown1); + from_uint32be(&header->unknown2); + + /* Convert the byte order of AVL trees. */ + for (i = 0;i < dic->music.num_indices;++i) { + uint32_t idx_root = dic_get_idxroot(dic, IP3DBIDX_MUSIC, i); + from_be_avltree(idx->avl, idx_root, &dic->music, i, 0); + } + for (i = 0;i < dic->objects.num_indices;++i) { + uint32_t idx_root = dic_get_idxroot(dic, IP3DBIDX_OBJECTS, i); + from_be_avltree(idx->avl, idx_root, &dic->objects, i, 0); + } return 0; } -int idx_dump(uint8_t* buffer, dic_t* dic, FILE *fpo) +result_t idx_dump(idx_t* idx, dic_t* dic, FILE *fpo) { int i; - header_t header; + idx_header_t* header = (idx_header_t*)idx->buffer; fprintf(fpo, "===== db.idx =====\n"); /* Dump the header. */ - idx_serialize_header(buffer, &header, 0); - fprintf(fpo, "size: 0x%08X\n", header.size); - fprintf(fpo, "unknown1: 0x%08X\n", header.unknown1); - fprintf(fpo, "unknown2: 0x%08X\n", header.unknown2); + fprintf(fpo, "size: 0x%08X\n", header->size); + fprintf(fpo, "unknown1: 0x%08X\n", header->unknown1); + fprintf(fpo, "unknown2: 0x%08X\n", header->unknown2); /* Dump the binary search trees. */ for (i = 0;i < dic->music.num_indices;++i) { @@ -271,17 +574,16 @@ fprintf(fpo, "["); dic_repr_index(dic, IP3DBIDX_MUSIC, i, fpo); fprintf(fpo, "]\n"); - idx_walk(buffer, idx_root, &dic->music, i, 0, idx_walkcb_dump, (void*)stdout); + avl_dump(idx->avl, idx_root, &dic->music, i, 0, fpo); } for (i = 0;i < dic->objects.num_indices;++i) { uint32_t idx_root = dic_get_idxroot(dic, IP3DBIDX_OBJECTS, i); fprintf(fpo, "["); dic_repr_index(dic, IP3DBIDX_OBJECTS, i, fpo); fprintf(fpo, "]\n"); - idx_walk(buffer, idx_root, &dic->objects, i, 0, idx_walkcb_dump, (void*)stdout); + avl_dump(idx->avl, idx_root, &dic->objects, i, 0, fpo); } fprintf(fpo, "\n"); return 0; } - Modified: trunk/pmplib/lib/pmp_iriverplus3/idx.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/idx.h 2006-12-25 15:15:36 UTC (rev 201) +++ trunk/pmplib/lib/pmp_iriverplus3/idx.h 2006-12-27 08:08:26 UTC (rev 202) @@ -24,6 +24,19 @@ #ifndef __IP3DB_IDX_H__ #define __IP3DB_IDX_H__ -int idx_dump(uint8_t* buffer, dic_t* dic, FILE *fpo); +struct tag_avl_t; typedef struct tag_avl_t avl_t; +struct tag_idx_t { + uint8_t* buffer; + uint32_t size; + uint32_t max_size; + avl_t* avl; +}; +typedef struct tag_idx_t idx_t; + +idx_t *idx_new(); +void idx_finish(idx_t* idx); +result_t idx_read(idx_t* idx, dic_t* dic, FILE *fpi); +result_t idx_dump(idx_t* idx, dic_t* dic, FILE *fpo); + #endif/*__IP3DB_IDX_H__*/ Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-25 15:15:36 UTC (rev 201) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-27 08:08:26 UTC (rev 202) @@ -105,6 +105,7 @@ memset(db, 0, sizeof(*db)); db->dat = dat_new(); db->dic = dic_new(); + db->idx = idx_new(); dic_template = dic_get_template(&db->dic_size); db->dic_buffer = (uint8_t*)malloc(db->dic_size); @@ -116,9 +117,9 @@ { dic_finish(db->dic); dat_finish(db->dat); + idx_finish(db->idx); free(db->dat_buffer); free(db->dic_buffer); - free(db->idx_buffer); ip3db_init(db); } @@ -126,39 +127,39 @@ { FILE *fp = 0; - fp = ucs2fopen(datfn, "rb"); + fp = ucs2fopen(dicfn, "rb"); if (!fp) { ip3db_finish(db); return 1; } - fread_all(fp, &db->dat_buffer, &db->dat_size); + fread_all(fp, &db->dic_buffer, &db->dic_size); fclose(fp); - fp = ucs2fopen(dicfn, "rb"); - if (!fp) { + if (dic_serialize(db->dic, db->dic_buffer, 0) != 0) { ip3db_finish(db); return 1; } - fread_all(fp, &db->dic_buffer, &db->dic_size); - fclose(fp); - fp = ucs2fopen(idxfn, "rb"); + fp = ucs2fopen(datfn, "rb"); if (!fp) { ip3db_finish(db); return 1; } - fread_all(fp, &db->idx_buffer, &db->idx_size); + fread_all(fp, &db->dat_buffer, &db->dat_size); fclose(fp); - if (dic_serialize(db->dic, db->dic_buffer, 0) != 0) { + if (dat_serialize(db->dat, db->dic, db->dat_buffer, 0) != 0) { ip3db_finish(db); return 1; } - if (dat_serialize(db->dat, db->dic, db->dat_buffer, 0) != 0) { + fp = ucs2fopen(idxfn, "rb"); + if (!fp) { ip3db_finish(db); return 1; } + idx_read(db->idx, db->dic, fp); + fclose(fp); return 0; } @@ -168,7 +169,6 @@ FILE *fp = 0; free(db->dat_buffer); - free(db->idx_buffer); db->dat_size = 0x00040000; //db->dat_buffer = (uint8_t*)calloc(db->dat_size, sizeof(uint8_t)); @@ -221,7 +221,7 @@ dat_dump(db->dat, db->dic, fpo); /* Dump db.idx */ - idx_dump(db->idx_buffer, db->dic, fpo); + idx_dump(db->idx, db->dic, fpo); return 0; } @@ -230,8 +230,6 @@ /* Construct Objects table in db.dat */ dat_construct(db->dat, db->dic, records, num_records); - /* Construct Music table in db.dat */ - /* Construct db.idx */ /* Update db.dic */ Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.h 2006-12-25 15:15:36 UTC (rev 201) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.h 2006-12-27 08:08:26 UTC (rev 202) @@ -146,17 +146,17 @@ struct tag_dat_t; typedef struct tag_dat_t dat_t; struct tag_dic_t; typedef struct tag_dic_t dic_t; +struct tag_idx_t; typedef struct tag_idx_t idx_t; typedef struct { uint8_t* dat_buffer; long dat_size; uint8_t* dic_buffer; long dic_size; - uint8_t* idx_buffer; - long idx_size; dat_t* dat; dic_t* dic; + idx_t* idx; } ip3db_t; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2006-12-25 15:15:35
|
Revision: 201 http://svn.sourceforge.net/pmplib/?rev=201&view=rev Author: nyaochi Date: 2006-12-25 07:15:36 -0800 (Mon, 25 Dec 2006) Log Message: ----------- Implemented pmpdb_write() interface for pmp_iriverplus3. Modified Paths: -------------- trunk/pmplib/lib/pmp_iriverplus3/dat.c trunk/pmplib/lib/pmp_iriverplus3/ip3db.c trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-25 14:33:57 UTC (rev 200) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-25 15:15:36 UTC (rev 201) @@ -84,7 +84,12 @@ switch (var->type) { case IP3DBVT_STRING: if (is_storing) { - p += (serialize_ucs2be_string_var(p, var->value.str, is_storing) + 1) * sizeof(ucs2char_t); + if (var->value.str) { + p += (serialize_ucs2be_string_var(p, var->value.str, is_storing) + 1) * sizeof(ucs2char_t); + } else { + ucs2char_t v = 0; + p += serialize_ucs2be(p, &v, is_storing); + } } else { p += (serialize_ucs2be_string_var_alloc(p, &var->value.str) + 1) * sizeof(ucs2char_t); } @@ -162,11 +167,13 @@ uint8_t *p = buffer; uint8_t *q = buffer + 0x00020000 - sizeof(uint32_t); + /* Serialize the header (with a dummy size for writing). */ p += serialize_uint32be(p, &list->size, is_storing); p += serialize_uint32be(p, &list->num_entries, is_storing); p += serialize_uint32be(p, &list->unknown1, is_storing); p += serialize_uint32be(p, &list->unknown2, is_storing); + /* Initialize fields when reading. */ if (!is_storing) { free(list->entries); list->entries = (dat_entry_t*)calloc(list->num_entries, sizeof(dat_entry_t)); @@ -175,12 +182,20 @@ } } + /* Serialize entries in this table. */ for (i = 0;i < list->num_entries;++i) { dat_entry_t* entry = &list->entries[i]; + entry->offset = (uint32_t)(p - buffer); /* compute the current offset address */ p += dat_entry_serialize(entry, p, q, is_storing); q -= sizeof(uint32_t); } + /* Write the final size when writing. */ + if (is_storing) { + uint32_t size = (uint32_t)(p - buffer); + serialize_uint32be(buffer, &size, is_storing); + } + return (size_t)(p - buffer); } Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-25 14:33:57 UTC (rev 200) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-25 15:15:36 UTC (rev 201) @@ -163,6 +163,55 @@ return 0; } +result_t ip3db_write(ip3db_t* db, const ucs2char_t* datfn, const ucs2char_t* dicfn, const ucs2char_t* idxfn) +{ + FILE *fp = 0; + + free(db->dat_buffer); + free(db->idx_buffer); + + db->dat_size = 0x00040000; + //db->dat_buffer = (uint8_t*)calloc(db->dat_size, sizeof(uint8_t)); + db->dat_buffer = (uint8_t*)malloc(db->dat_size); + + if (dat_serialize(db->dat, db->dic, db->dat_buffer, 1) != 0) { + ip3db_finish(db); + return 1; + } + + if (dic_serialize(db->dic, db->dic_buffer, 1) != 0) { + ip3db_finish(db); + return 1; + } + + fp = ucs2fopen(datfn, "wb"); + if (!fp) { + return 1; + } + fwrite(db->dat_buffer, 1, db->dat_size, fp); + fclose(fp); + + /* + fp = ucs2fopen(dicfn, "rb"); + if (!fp) { + ip3db_finish(db); + return 1; + } + fread_all(fp, &db->dic_buffer, &db->dic_size); + fclose(fp); + + fp = ucs2fopen(idxfn, "rb"); + if (!fp) { + ip3db_finish(db); + return 1; + } + fread_all(fp, &db->idx_buffer, &db->idx_size); + fclose(fp); +*/ + + return 0; +} + result_t ip3db_dump(ip3db_t* db, FILE *fpo) { /* Dump db.dic */ Modified: trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c 2006-12-25 14:33:57 UTC (rev 200) +++ trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c 2006-12-25 15:15:36 UTC (rev 201) @@ -497,8 +497,12 @@ { pmpdb_internal_t* pmpdbi = (pmpdb_internal_t*)pmpdb->instance; pmp_internal_t* pmpi = (pmp_internal_t*)pmpdb->pmp->instance; - return PMP_NOTIMPLIMENTED; - //return ip2db_write(&pmpdbi->ip2db, pmpi->env.dat_filename, pmpi->env.idx_filename); + return ip3db_write( + &pmpdbi->ip3db, + pmpi->env.dat_filename, + pmpi->env.dic_filename, + pmpi->env.idx_filename + ); } static result_t pmpdb_set(pmpdb_t* pmpdb, const pmp_record_t* records, uint32_t num_records) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |