diff options
-rw-r--r-- | c/data.cpp | 6 | ||||
-rw-r--r-- | c/data.h | 42 | ||||
-rw-r--r-- | c/episodelistview.cpp | 4 | ||||
-rw-r--r-- | c/episodelistview.h | 2 | ||||
-rw-r--r-- | c/test.cpp | 81 |
5 files changed, 92 insertions, 43 deletions
@@ -52,14 +52,14 @@ FileView::~FileView() CloseHandle(hf); } -void Write(unsigned char* buf, const ElvData& e) +void Write(unsigned char* buf, const ElvDataA& e) { memcpy(buf, reinterpret_cast<const unsigned char*>(&e), sizeof(e)); } -ElvData* Read(unsigned char* const buf) +ElvDataA* Read(unsigned char* const buf) { if (buf[0] != 'a') return nullptr; - return reinterpret_cast<ElvData*>(buf); + return reinterpret_cast<ElvDataA*>(buf); } @@ -5,27 +5,29 @@ #include "util.h" #include "wcharptr.h" -/* ElvData and DlvData are written as-is to disk; note the careful - * alignment. */ +/* ElvDataA and DlvDataA are written as-is to disk; note the careful + * alignment. As such, they should be regarded as immutable. If the + * format needs to be changed in the future, then new structs called + * ElvDataB and DlvDataB should be added. */ -struct ElvData +struct ElvDataA { - unsigned char version = 'a'; /* 0-1 */ - unsigned char rating = 0; /* 1-2 */ - unsigned char bWatched = 0; /* 2-3 */ - unsigned char bTVOriginal = 0; /* 3-4 */ - wchar_t sRating[4] = {0}; /* 4-12 */ - wchar_t siEp[6] = {0}; /* 12-24 */ - wchar_t title[128] = {0}; /* 24-280 */ + unsigned char version = 'a'; + unsigned char rating = 0; + unsigned char bWatched = 0; + unsigned char bTVOriginal = 0; + wchar_t sRating[4] = {0}; + wchar_t siEp[6] = {0}; + wchar_t title[128] = {0}; }; -struct DlvData +struct DlvDataA { - wchar_t date[64] = {0}; - wchar_t source[64] = {0}; - wchar_t screenwriter[64] = {0}; + wchar_t date[32] = {0}; + wchar_t source[48] = {0}; + wchar_t screenwriter[48] = {0}; wchar_t hint[128] = {0}; - wchar_t wiki[128] = {0}; + wchar_t wiki[192] = {0}; }; struct FileView @@ -39,10 +41,10 @@ struct FileView /* TODO: Handle exceptions on read and write... */ }; -void Write(unsigned char* buf, const ElvData& e); -ElvData* Read(unsigned char* buf); +void Write(unsigned char* buf, const ElvDataA& e); +ElvDataA* Read(unsigned char* buf); -inline int FromWeb(const int iEp, ElvData& e, DlvData& d) noexcept +inline int FromWeb(const int iEp, ElvDataA& e, DlvDataA& d) noexcept { WcharPtr title, wiki, date, source, hint; const int r = Pl("episode_data","fetch_episode_data",iEp,&title,&wiki,&date,&source,&hint); @@ -54,7 +56,7 @@ inline int FromWeb(const int iEp, ElvData& e, DlvData& d) noexcept return r; } -inline bool FromProlog(const int iEp, ElvData& e) noexcept +inline bool FromProlog(const int iEp, ElvDataA& e) noexcept { if (WcharPtr title; Pl("episode_data","episode_title",iEp,&title)) Wcscpy(e.title, title); @@ -75,7 +77,7 @@ inline bool FromProlog(const int iEp, ElvData& e) noexcept return true; } -inline void FromProlog(const int iEp, DlvData& d) noexcept +inline void FromProlog(const int iEp, DlvDataA& d) noexcept { if (WcharPtr wiki; Pl("episode_data","episode_wiki",iEp,&wiki)) Wcscpy(d.wiki, wiki); diff --git a/c/episodelistview.cpp b/c/episodelistview.cpp index e591952..3f2104f 100644 --- a/c/episodelistview.cpp +++ b/c/episodelistview.cpp @@ -53,7 +53,7 @@ LRESULT EpisodeListView::HandleNotify(const LPARAM lParam) case LVN_GETDISPINFO: /* Display item. */ { NMLVDISPINFO* const nm = reinterpret_cast<NMLVDISPINFO*>(lParam); - ElvData& e = m_vData.at(nm->item.lParam-1); + ElvDataA& e = m_vData.at(nm->item.lParam-1); wchar_t* vs[] = {e.siEp, e.title, e.sRating}; /* ELVSIEPISODE, ELVSITITLE, ELVSIRATING */ nm->item.pszText = vs[nm->item.iSubItem]; return 0; @@ -336,7 +336,7 @@ void EpisodeListView::Update() m_vData.clear(); ListView_DeleteAllItems(hWnd); for (int iEp = 1; iEp <= cEp; iEp++) { - ElvData e; + ElvDataA e; if (!FromProlog(iEp, e)) goto push; diff --git a/c/episodelistview.h b/c/episodelistview.h index 7e0c539..0fcf444 100644 --- a/c/episodelistview.h +++ b/c/episodelistview.h @@ -32,7 +32,7 @@ struct EpisodeListView : public ListView private: int m_iSortCol; static int CALLBACK SortProc(LPARAM lParam1, LPARAM lParam2, LPARAM extra); - std::vector<ElvData> m_vData; + std::vector<ElvDataA> m_vData; }; #endif @@ -1,5 +1,6 @@ #include "data.h" #include "test.h" +#include "pl.h" #include "util.h" #include "win.h" @@ -26,8 +27,8 @@ TESTS TEST(EpisodeDataFromWeb) { - ElvData e; - DlvData d; + ElvDataA e; + DlvDataA d; FromWeb(10, e, d); if (wcscmp(e.title, L"Pro Soccer Player Blackmail Case") != 0) FAIL("title is not correct"); @@ -37,8 +38,8 @@ TESTS TEST(EpisodeDataFromProlog) { - ElvData e; - DlvData d; + ElvDataA e; + DlvDataA d; FromProlog(10, e); FromProlog(10, d); if (wcscmp(e.title, L"Pro Soccer Player Blackmail Case") != 0) @@ -49,28 +50,73 @@ TESTS TEST(IO) { - ElvData e1; - FromProlog(6, e1); + ElvDataA e1_0, e2_0; + FromProlog(6, e1_0); + FromProlog(10, e2_0); { - FileView fv{L"tmp.dat", sizeof(e1)}; - Write(fv, e1); + FileView fv{L"tmp.dat", sizeof(ElvDataA)*2}; + Write(fv, e1_0); + Write(fv+sizeof(ElvDataA), e2_0); } { - FileView fv{L"tmp.dat", sizeof(e1)}; - ElvData* e2 = Read(fv); - if (e1.rating != e2->rating) - FAIL("rating is different (%d/%d)", e1.rating, e2->rating); - if (e1.bWatched != e2->bWatched) + FileView fv{L"tmp.dat", sizeof(ElvDataA)}; + ElvDataA* e1 = Read(fv); + if (e1_0.rating != e1->rating) + FAIL("rating is different (%d/%d)", e1_0.rating, e1->rating); + if (e1_0.bWatched != e1->bWatched) FAIL("bWatched is different"); - if (e1.bTVOriginal != e2->bTVOriginal) + if (e1_0.bTVOriginal != e1->bTVOriginal) FAIL("bTVOriginal is different"); - if (wcscmp(e1.sRating, e2->sRating) != 0) + if (wcscmp(e1_0.sRating, e1->sRating) != 0) FAIL("sRating is different"); - if (wcscmp(e1.siEp, e2->siEp) != 0) + if (wcscmp(e1_0.siEp, e1->siEp) != 0) FAIL("siEp is different"); - if (wcscmp(e1.title, e2->title) != 0) + if (wcscmp(e1_0.title, e1->title) != 0) FAIL("title is different"); } + { + FileView fv{L"tmp.dat", sizeof(ElvDataA)*2}; + ElvDataA* e2 = Read(fv+sizeof(ElvDataA)); + if (e2_0.rating != e2->rating) + FAIL("rating is different (%d/%d)", e2_0.rating, e2->rating); + if (e2_0.bWatched != e2->bWatched) + FAIL("bWatched is different"); + if (e2_0.bTVOriginal != e2->bTVOriginal) + FAIL("bTVOriginal is different"); + if (wcscmp(e2_0.sRating, e2->sRating) != 0) + FAIL("sRating is different"); + if (wcscmp(e2_0.siEp, e2->siEp) != 0) + FAIL("siEp is different"); + if (wcscmp(e2_0.title, e2->title) != 0) + FAIL("title is different"); + } + //DeleteFile(L"tmp.dat"); + } + + TEST(MigrateElvDataFromPrologToDisk) + { + int cEp; + if (!Pl("episode_data","episode_count",&cEp)) + return; + + { + FileView fv{L"tmp.dat", sizeof(ElvDataA)*cEp}; + unsigned char* p = fv; + + for (int iEp = 1; iEp <= cEp; iEp++) { + ElvDataA e; + FromProlog(iEp, e); + Write(p, e); + p += sizeof(e); + } + } + { + FileView fv{L"tmp.dat", sizeof(ElvDataA)*cEp}; + ElvDataA* ve = reinterpret_cast<ElvDataA*>(fv.view); + ElvDataA e = ve[9]; + if (wcscmp(e.title, L"Pro Soccer Player Blackmail Case") != 0) + FAIL("title is not correct"); + } //DeleteFile(L"tmp.dat"); } }; @@ -82,6 +128,7 @@ int RunTests() //EpisodeDataFromWeb{}, EpisodeDataFromProlog{}, IO{}, + MigrateElvDataFromPrologToDisk{}, }; printf("Results (%llu tests):\n", sizeof(tests)/sizeof(*tests)); |