├── .gitattributes ├── .gitignore ├── GeekDb ├── GeekDb.sln └── GeekDb │ ├── GeekDb.h │ ├── GeekDb.vcxproj │ ├── GeekDb.vcxproj.filters │ ├── GeekDbManager.cpp │ ├── GeekDbManager.h │ ├── GeekDbStorage.cpp │ ├── GeekDbStorage.h │ ├── GeekDefs.h │ ├── GeekErrorCode.h │ ├── GeekSequenceDb.cpp │ ├── GeekSequenceDb.h │ ├── GeekUtils.h │ ├── Program.cpp │ ├── ReadMe.txt │ ├── stdafx.cpp │ ├── stdafx.h │ └── targetver.h ├── README.md ├── 极客班C++ 样本项目 .pdf ├── 极客班第一期C++专业期末综合测试题.pdf └── 极客班第一期C++专业考核细则.pdf /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear on external disk 35 | .Spotlight-V100 36 | .Trashes 37 | 38 | # Directories potentially created on remote AFP share 39 | .AppleDB 40 | .AppleDesktop 41 | Network Trash Folder 42 | Temporary Items 43 | .apdisk 44 | -------------------------------------------------------------------------------- /GeekDb/GeekDb.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.23107.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GeekDb", "GeekDb\GeekDb.vcxproj", "{64C4F436-7163-4868-8D0D-2486D9D2DAC3}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {64C4F436-7163-4868-8D0D-2486D9D2DAC3}.Debug|x64.ActiveCfg = Debug|x64 17 | {64C4F436-7163-4868-8D0D-2486D9D2DAC3}.Debug|x64.Build.0 = Debug|x64 18 | {64C4F436-7163-4868-8D0D-2486D9D2DAC3}.Debug|x86.ActiveCfg = Debug|Win32 19 | {64C4F436-7163-4868-8D0D-2486D9D2DAC3}.Debug|x86.Build.0 = Debug|Win32 20 | {64C4F436-7163-4868-8D0D-2486D9D2DAC3}.Release|x64.ActiveCfg = Release|x64 21 | {64C4F436-7163-4868-8D0D-2486D9D2DAC3}.Release|x64.Build.0 = Release|x64 22 | {64C4F436-7163-4868-8D0D-2486D9D2DAC3}.Release|x86.ActiveCfg = Release|Win32 23 | {64C4F436-7163-4868-8D0D-2486D9D2DAC3}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /GeekDb/GeekDb/GeekDb.h: -------------------------------------------------------------------------------- 1 | //************************************************* 2 | // Module: GeekDB.h 3 | // Notices: Copyright (c) 2015 Zhang Wenjie 4 | //************************************************* 5 | #pragma once 6 | 7 | #include "GeekDefs.h" 8 | #include "GeekErrorCode.h" 9 | #include 10 | 11 | namespace geek 12 | { 13 | // 14 | // Abstract class for Geek database. 15 | // 16 | class GeekDb 17 | { 18 | public: 19 | GeekDb(const GeekDbMetadata& metadata) 20 | : m_Metadata(metadata) 21 | { 22 | } 23 | 24 | public: 25 | virtual GeekResult InsertKeyValue(INPARAM const GeekKeyValue& entry) = 0; 26 | virtual GeekResult UpdateKeyValue(INPARAM const GeekKeyValue& entry) = 0; 27 | virtual GeekResult DeleteKeyValue(INPARAM const std::wstring& wszKey) = 0; 28 | 29 | virtual GeekResult QueryKeyValue( 30 | INPARAM const std::wstring& wszKey, 31 | OUTPARAM std::vector& entries 32 | ) = 0; 33 | 34 | virtual GeekResult DumpKeyValues(INPARAM const std::wstring& wszFileName) = 0; 35 | 36 | virtual GeekResult LoadKeyValues( 37 | INPARAM const std::wstring& wszFileName, 38 | OUTPARAM std::wstring& wszName 39 | ) = 0; 40 | 41 | virtual void TraverseKeyVaues(void) = 0; 42 | 43 | virtual const std::size_t GetSize(void) const = 0; 44 | 45 | protected: 46 | GeekDbMetadata m_Metadata; 47 | 48 | private: 49 | GeekDb(void); 50 | GeekDb(const GeekDb&); 51 | GeekDb(const GeekDb*); 52 | }; 53 | 54 | // 55 | // Traits for Geek database. 56 | // Traits is used for Creating concrete database implementation. 57 | // 58 | template 59 | struct GeekDbTraits 60 | { 61 | }; 62 | } -------------------------------------------------------------------------------- /GeekDb/GeekDb/GeekDb.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {64C4F436-7163-4868-8D0D-2486D9D2DAC3} 23 | Win32Proj 24 | GeekDb 25 | 8.1 26 | 27 | 28 | 29 | Application 30 | true 31 | v140 32 | Unicode 33 | false 34 | 35 | 36 | Application 37 | false 38 | v140 39 | true 40 | Unicode 41 | 42 | 43 | Application 44 | true 45 | v140 46 | Unicode 47 | 48 | 49 | Application 50 | false 51 | v140 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | 76 | 77 | true 78 | 79 | 80 | false 81 | 82 | 83 | false 84 | 85 | 86 | 87 | Use 88 | Level3 89 | Disabled 90 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 91 | MultiThreadedDebug 92 | 93 | 94 | Console 95 | true 96 | 97 | 98 | 99 | 100 | Use 101 | Level3 102 | Disabled 103 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 104 | 105 | 106 | Console 107 | true 108 | 109 | 110 | 111 | 112 | Level3 113 | Use 114 | MaxSpeed 115 | true 116 | true 117 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 118 | MultiThreaded 119 | 120 | 121 | Console 122 | true 123 | true 124 | true 125 | 126 | 127 | 128 | 129 | Level3 130 | Use 131 | MaxSpeed 132 | true 133 | true 134 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 135 | 136 | 137 | Console 138 | true 139 | true 140 | true 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | Create 164 | Create 165 | Create 166 | Create 167 | 168 | 169 | 170 | 171 | 172 | -------------------------------------------------------------------------------- /GeekDb/GeekDb/GeekDb.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | Header Files 32 | 33 | 34 | Header Files 35 | 36 | 37 | Header Files 38 | 39 | 40 | Header Files 41 | 42 | 43 | Header Files 44 | 45 | 46 | Header Files 47 | 48 | 49 | 50 | 51 | Source Files 52 | 53 | 54 | Source Files 55 | 56 | 57 | Source Files 58 | 59 | 60 | Source Files 61 | 62 | 63 | Source Files 64 | 65 | 66 | -------------------------------------------------------------------------------- /GeekDb/GeekDb/GeekDbManager.cpp: -------------------------------------------------------------------------------- 1 | //************************************************* 2 | // Module: GeekDbManager.cpp 3 | // Notices: Copyright (c) 2015 Zhang Wenjie 4 | //************************************************* 5 | 6 | #include "stdafx.h" 7 | #include "GeekDbManager.h" 8 | #include "GeekUtils.h" 9 | 10 | namespace geek 11 | { 12 | const size_t GeekDbManager::GetDatabaseSize(INPARAM const std::wstring & wszName) 13 | { 14 | if (geek::IsNullOrEmpty(wszName)) 15 | return GEEK_ERROR_INVALIDPARAM; 16 | 17 | GeekDb* db = this->GetDatabaseByName(wszName); 18 | if (db == NULL) 19 | return GEEK_ERROR_NULLPOINTER; 20 | 21 | return (db->GetSize()); 22 | } 23 | 24 | GeekResult GeekDbManager::InsertDatabase( 25 | INPARAM const std::wstring& wszName, 26 | INPARAM const GeekKeyValue& entry) 27 | { 28 | if (geek::IsNullOrEmpty(wszName)) 29 | return GEEK_ERROR_INVALIDPARAM; 30 | 31 | GeekDb* db = this->GetDatabaseByName(wszName); 32 | if (db == NULL) 33 | return GEEK_ERROR_NULLPOINTER; 34 | 35 | GeekResult result = db->InsertKeyValue(entry); 36 | return result; 37 | } 38 | 39 | GeekResult GeekDbManager::InsertDatabase( 40 | INPARAM const std::wstring& wszName, 41 | INPARAM const std::vector& entries) 42 | { 43 | if (geek::IsNullOrEmpty(wszName)) 44 | return GEEK_ERROR_INVALIDPARAM; 45 | 46 | if (entries.empty()) 47 | return GEEK_ERROR_EMPTY; 48 | 49 | GeekDb* db = this->GetDatabaseByName(wszName); 50 | if (db == NULL) 51 | return GEEK_ERROR_NULLPOINTER; 52 | 53 | GeekResult result = GEEK_SUCCESS; 54 | for (std::vector::const_iterator it = entries.begin(); 55 | it != entries.end(); it++) 56 | { 57 | GeekResult result = db->InsertKeyValue((*it)); 58 | } 59 | 60 | return result; 61 | } 62 | 63 | GeekResult GeekDbManager::UpdateDatabase( 64 | INPARAM const std::wstring& wszName, 65 | INPARAM const GeekKeyValue& entry) 66 | { 67 | if (geek::IsNullOrEmpty(wszName)) 68 | return GEEK_ERROR_INVALIDPARAM; 69 | 70 | GeekDb* db = this->GetDatabaseByName(wszName); 71 | if (db == NULL) 72 | return GEEK_ERROR_NULLPOINTER; 73 | 74 | GeekResult result = db->UpdateKeyValue(entry); 75 | return result; 76 | } 77 | 78 | GeekResult GeekDbManager::DeleteDatabase( 79 | INPARAM const std::wstring& wszName, 80 | INPARAM const std::wstring& wszKey) 81 | { 82 | if (geek::IsNullOrEmpty(wszName) || geek::IsNullOrEmpty(wszKey)) 83 | return GEEK_ERROR_INVALIDPARAM; 84 | 85 | GeekDb* db = this->GetDatabaseByName(wszName); 86 | if (db == NULL) 87 | return GEEK_ERROR_NULLPOINTER; 88 | 89 | GeekResult result = db->DeleteKeyValue(wszKey); 90 | return result; 91 | } 92 | 93 | GeekResult GeekDbManager::DisposeDatabase( 94 | INPARAM const std::wstring& wszName) 95 | { 96 | if (geek::IsNullOrEmpty(wszName)) 97 | return GEEK_ERROR_INVALIDPARAM; 98 | 99 | GeekDb* db = this->GetDatabaseByName(wszName); 100 | if (db == NULL) 101 | return GEEK_ERROR_NULLPOINTER; 102 | 103 | delete db; 104 | m_DbCollection.erase(wszName); 105 | 106 | return GEEK_SUCCESS; 107 | } 108 | 109 | GeekResult GeekDbManager::DumpDatabase( 110 | INPARAM const std::wstring& wszName, 111 | INPARAM const std::wstring& wszFileName) 112 | { 113 | if (geek::IsNullOrEmpty(wszName) || geek::IsNullOrEmpty(wszFileName)) 114 | return GEEK_ERROR_INVALIDPARAM; 115 | 116 | GeekDb* db = this->GetDatabaseByName(wszName); 117 | if (db == NULL) 118 | return GEEK_ERROR_NULLPOINTER; 119 | 120 | GeekResult result = db->DumpKeyValues(wszFileName); 121 | return result; 122 | } 123 | 124 | GeekResult GeekDbManager::TraverseDatabase(INPARAM const std::wstring & wszName) 125 | { 126 | if (geek::IsNullOrEmpty(wszName)) 127 | return GEEK_ERROR_INVALIDPARAM; 128 | 129 | GeekDb* db = this->GetDatabaseByName(wszName); 130 | if (db == NULL) 131 | return GEEK_ERROR_NULLPOINTER; 132 | 133 | db->TraverseKeyVaues(); 134 | return GEEK_SUCCESS; 135 | } 136 | } -------------------------------------------------------------------------------- /GeekDb/GeekDb/GeekDbManager.h: -------------------------------------------------------------------------------- 1 | //************************************************* 2 | // Module: GeekDbManager.h 3 | // Notices: Copyright (c) 2015 Zhang Wenjie 4 | //************************************************* 5 | #pragma once 6 | 7 | #include "GeekDb.h" 8 | #include "GeekSequenceDb.h" 9 | #include "GeekUtils.h" 10 | #include "GeekErrorCode.h" 11 | #include 12 | #include 13 | #include 14 | 15 | namespace geek 16 | { 17 | // 18 | // Manages all geek database created in memory. 19 | // 20 | class GeekDbManager 21 | { 22 | public: 23 | GeekDbManager(void) { } 24 | ~GeekDbManager(void) { } 25 | 26 | public: 27 | template 28 | GeekResult CreateDatabase( 29 | INPARAM const std::wstring& wszName 30 | ); 31 | 32 | // 33 | // Load database into memory from file system. 34 | // 35 | template 36 | GeekResult LoadDatabase( 37 | INPARAM const std::wstring& wszFileName, 38 | OUTPARAM std::wstring& wszName 39 | ); 40 | 41 | // 42 | // Get the size the database by the given name. 43 | // 44 | const size_t GetDatabaseSize( 45 | INPARAM const std::wstring& wszName 46 | ); 47 | 48 | GeekResult InsertDatabase( 49 | INPARAM const std::wstring& wszName, 50 | INPARAM const GeekKeyValue& entry 51 | ); 52 | 53 | // 54 | // Batch insert 55 | // 56 | GeekResult InsertDatabase( 57 | INPARAM const std::wstring& wszName, 58 | INPARAM const std::vector& entries 59 | ); 60 | 61 | GeekResult UpdateDatabase( 62 | INPARAM const std::wstring& wszName, 63 | INPARAM const GeekKeyValue& entry 64 | ); 65 | 66 | GeekResult DeleteDatabase( 67 | INPARAM const std::wstring& wszName, 68 | INPARAM const std::wstring& wszKey 69 | ); 70 | 71 | GeekResult DisposeDatabase(INPARAM const std::wstring& wszName); 72 | 73 | GeekResult DumpDatabase( 74 | INPARAM const std::wstring& wszName, 75 | INPARAM const std::wstring& wszFileName 76 | ); 77 | 78 | GeekResult TraverseDatabase(INPARAM const std::wstring& wszName); 79 | 80 | private: 81 | inline GeekDb* GetDatabaseByName(const std::wstring& wszName) 82 | { 83 | CollectionIterator it = m_DbCollection.find(wszName); 84 | if (it == m_DbCollection.end()) 85 | return NULL; 86 | 87 | return (*it).second; 88 | } 89 | 90 | private: 91 | typedef std::map::iterator CollectionIterator; 92 | std::map m_DbCollection; 93 | }; 94 | 95 | template 96 | GeekResult GeekDbManager::CreateDatabase( 97 | INPARAM const std::wstring& wszName) 98 | { 99 | typedef typename GeekDbTraits::Database Database; 100 | GeekDbMetadata metadata; 101 | metadata.wszName = wszName; 102 | 103 | Database* pdb = new Database(metadata); 104 | if (pdb == NULL) 105 | return GEEK_ERROR_OUTOFMEMORY; 106 | 107 | m_DbCollection.insert(std::make_pair(wszName, pdb)); 108 | return GEEK_SUCCESS; 109 | } 110 | 111 | template 112 | GeekResult GeekDbManager::LoadDatabase( 113 | INPARAM const std::wstring & wszFileName, 114 | OUTPARAM std::wstring& wszName) 115 | { 116 | if (geek::IsNullOrEmpty(wszFileName)) 117 | return GEEK_ERROR_INVALIDPARAM; 118 | 119 | if (!geek::IsFileExists(wszFileName)) 120 | return GEEK_ERROR_FILENOTFOUND; 121 | 122 | typedef typename GeekDbTraits::Database Database; 123 | Database* pdb = new Database(GeekDbMetadata()); 124 | if (pdb == NULL) 125 | return GEEK_ERROR_OUTOFMEMORY; 126 | 127 | GeekResult result = pdb->LoadKeyValues(wszFileName, wszName); 128 | 129 | // does the database name already exists ? 130 | CollectionIterator it = m_DbCollection.find(wszName); 131 | if (it != m_DbCollection.end()) 132 | { 133 | // already exists, replace with the loaded db. 134 | m_DbCollection[wszName] = pdb; 135 | } 136 | else 137 | { 138 | // add the loaded db. 139 | m_DbCollection.insert(std::make_pair(wszName, pdb)); 140 | } 141 | 142 | return result; 143 | } 144 | } -------------------------------------------------------------------------------- /GeekDb/GeekDb/GeekDbStorage.cpp: -------------------------------------------------------------------------------- 1 | //************************************************* 2 | // Module: GeekDbStorage.cpp 3 | // Notices: Copyright (c) 2015 Zhang Wenjie 4 | //************************************************* 5 | 6 | #include "stdafx.h" 7 | #include "GeekDbStorage.h" 8 | 9 | namespace geek 10 | { 11 | GeekResult GeekDbStorage::CreateStorage() 12 | { 13 | GeekResult result = GEEK_SUCCESS; 14 | HRESULT hr = S_OK; 15 | IStorage* pstgGeekPackage = NULL; 16 | IStorage* pstgGeekMetadata = NULL; 17 | IStream* pstm = NULL; 18 | 19 | // Create the root storage 20 | hr = ::StgCreateStorageEx( 21 | this->m_wszFileName.c_str(), 22 | STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 23 | STGFMT_STORAGE, 24 | 0, 25 | NULL, 26 | NULL, 27 | IID_IStorage, 28 | reinterpret_cast(&this->m_pstg)); 29 | ON_FAILED_RETURN(hr, result, GEEK_ERROR_CREATESTGFAILED); 30 | 31 | // Create the "GeekMetadata" storage. 32 | this->m_pstg->CreateStorage( 33 | s_wszStorageNameGeekMetadata, 34 | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 35 | 0, 0, &pstgGeekMetadata); 36 | ON_FAILED_RETURN(hr, result, GEEK_ERROR_CREATESTGFAILED); 37 | 38 | // Create the "GeekDatabasePackage" storage. 39 | this->m_pstg->CreateStorage( 40 | s_wszStorageNameGeekPackage, 41 | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 42 | 0, 0, &pstgGeekPackage); 43 | ON_FAILED_RETURN(hr, result, GEEK_ERROR_CREATESTGFAILED); 44 | 45 | // Add metadata to the "GeekMetadata" storage. 46 | hr = pstgGeekMetadata->CreateStream( 47 | s_wszStreamNameDatabaseName, 48 | STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 49 | 0, 50 | 0, 51 | &pstm); 52 | ON_FAILED_RETURN(hr, result, GEEK_ERROR_CREATESTMFAILED); 53 | 54 | // Write metadata to the stream. 55 | result = this->WriteStringEntry(pstm, m_Metadata.wszName); 56 | ON_GEEKFAILED_RETURN(result); 57 | 58 | // Commit all changes. 59 | hr = m_pstg->Commit(STGC_DEFAULT); 60 | ON_FAILED_RETURN(hr, result, GEEK_ERROR_COMMITSTGFAILED); 61 | 62 | e_Exit: 63 | RELEASE_OLE_OBJECT(pstgGeekPackage); 64 | RELEASE_OLE_OBJECT(pstgGeekMetadata); 65 | RELEASE_OLE_OBJECT(pstm); 66 | return result; 67 | } 68 | 69 | GeekResult GeekDbStorage::OpenStorage() 70 | { 71 | GeekResult result = GEEK_SUCCESS; 72 | 73 | // Opens an existing storage file. 74 | HRESULT hr = StgOpenStorageEx( 75 | this->m_wszFileName.c_str(), 76 | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 77 | STGFMT_STORAGE, 78 | 0, 79 | NULL, 80 | NULL, 81 | IID_IStorage, 82 | reinterpret_cast(&this->m_pstg)); 83 | if (FAILED(hr)) 84 | result = GEEK_ERROR_OPENSTGFAILED; 85 | 86 | return result; 87 | } 88 | 89 | GeekResult GeekDbStorage::WriteStringEntry( 90 | INPARAM IStream* pstm, 91 | INPARAM const std::wstring& wsz) 92 | { 93 | GeekResult result = GEEK_SUCCESS; 94 | if (pstm == NULL || IsNullOrEmpty(wsz)) 95 | return GEEK_ERROR_INVALIDPARAM; 96 | 97 | const wchar_t* wszString = wsz.c_str(); 98 | 99 | // write the length of the wszString. 100 | DWORD cbString = (DWORD)::wcslen(wszString) * sizeof(wchar_t); 101 | result = this->WriteExact(pstm, &cbString, sizeof(DWORD), NULL); 102 | 103 | // write the content of the wszString. 104 | result = this->WriteExact(pstm, wszString, cbString, NULL); 105 | 106 | return result; 107 | } 108 | 109 | // 110 | // Attention: ppwz is allocated memory 111 | // and must be released out of this function. 112 | // 113 | GeekResult GeekDbStorage::ReadStringEntry( 114 | INPARAM IStream* pstm, 115 | OUTPARAM WCHAR** ppwz, 116 | OUTPARAM DWORD* pcch) 117 | { 118 | HRESULT hr = S_OK; 119 | DWORD dwLen = 0; 120 | DWORD cch = 0; 121 | WCHAR* wsz = NULL; 122 | GeekResult result = GEEK_SUCCESS; 123 | 124 | if (pstm == NULL || ppwz == NULL) 125 | return GEEK_ERROR_NULLPOINTER; 126 | 127 | *ppwz = NULL; 128 | 129 | // Read the length of the string. 130 | result = this->ReadExact(pstm, &dwLen, sizeof(DWORD), NULL); 131 | 132 | cch = dwLen / sizeof(WCHAR); 133 | wsz = new WCHAR[cch + 1]; 134 | if (wsz == NULL) 135 | return GEEK_ERROR_OUTOFMEMORY; 136 | 137 | // Read the contents of the string. 138 | wsz[cch] = L'\0'; 139 | hr = ReadExact(pstm, wsz, dwLen, NULL); 140 | 141 | // Assign the output parameters. 142 | *ppwz = wsz; 143 | *pcch = cch; 144 | 145 | wsz = NULL; 146 | return GEEK_SUCCESS; 147 | } 148 | 149 | GeekResult GeekDbStorage::Add(INPARAM const GeekKeyValue& entry) 150 | { 151 | if (m_pstg == NULL) 152 | return GEEK_ERROR_NULLPOINTER; 153 | 154 | HRESULT hr = S_OK; 155 | GeekResult result = GEEK_SUCCESS; 156 | IStorage* pstgGeekPackage = NULL; 157 | IStream* pstm = NULL; 158 | 159 | // Locate the "GeekDatabasePackage" storage. 160 | hr = this->m_pstg->OpenStorage( 161 | s_wszStorageNameGeekPackage, 162 | NULL, 163 | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 164 | NULL, 0, &pstgGeekPackage); 165 | ON_FAILED_RETURN(hr, result, GEEK_ERROR_CREATESTGFAILED); 166 | 167 | // Create a stream for storing the key/value entry. 168 | const OLECHAR* wszName = entry.first.c_str(); 169 | hr = pstgGeekPackage->CreateStream( 170 | wszName, 171 | STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 172 | 0, 173 | 0, 174 | &pstm); 175 | ON_FAILED_RETURN(hr, result, GEEK_ERROR_CREATESTMFAILED); 176 | 177 | result = this->WriteStringEntry(pstm, entry.second); 178 | ON_GEEKFAILED_RETURN(result); 179 | 180 | e_Exit: 181 | RELEASE_OLE_OBJECT(pstgGeekPackage); 182 | RELEASE_OLE_OBJECT(pstm); 183 | return result; 184 | } 185 | 186 | GeekResult GeekDbStorage::AddRange(INPARAM const std::vector& entries) 187 | { 188 | if (m_pstg == NULL) 189 | return GEEK_ERROR_NULLPOINTER; 190 | 191 | HRESULT hr = S_OK; 192 | GeekResult result = GEEK_SUCCESS; 193 | IStorage* pstgGeekPackage = NULL; 194 | IStream* pstm = NULL; 195 | std::vector::const_iterator it = entries.begin(); 196 | 197 | // Locate the "GeekDatabasePackage" storage. 198 | hr = this->m_pstg->OpenStorage( 199 | s_wszStorageNameGeekPackage, 200 | NULL, 201 | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 202 | NULL, 0, &pstgGeekPackage); 203 | ON_FAILED_RETURN(hr, result, GEEK_ERROR_CREATESTGFAILED); 204 | 205 | while (it != entries.end()) 206 | { 207 | const OLECHAR* wszName = (*it).first.c_str(); 208 | hr = pstgGeekPackage->CreateStream( 209 | wszName, 210 | STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 211 | 0, 212 | 0, 213 | &pstm); 214 | ON_FAILED_RETURN(hr, result, GEEK_ERROR_CREATESTMFAILED); 215 | 216 | result = this->WriteStringEntry(pstm, (*it).second); 217 | ON_GEEKFAILED_RETURN(result); 218 | 219 | it++; 220 | } 221 | 222 | // Commit all changes. 223 | hr = pstgGeekPackage->Commit(STGC_DEFAULT); 224 | ON_FAILED_RETURN(hr, result, GEEK_ERROR_COMMITSTGFAILED); 225 | 226 | e_Exit: 227 | RELEASE_OLE_OBJECT(pstgGeekPackage); 228 | RELEASE_OLE_OBJECT(pstm); 229 | return result; 230 | } 231 | 232 | GeekResult GeekDbStorage::LoadAll( 233 | OUTPARAM GeekDbMetadata& metadata, 234 | OUTPARAM std::vector& entries) 235 | { 236 | if (m_pstg == NULL) 237 | return GEEK_ERROR_NULLPOINTER; 238 | 239 | HRESULT hr = S_OK; 240 | GeekResult result = GEEK_SUCCESS; 241 | ULONG ulFetched = 0; 242 | const ULONG ulCelt = 1UL; 243 | IEnumSTATSTG* pEnumStat = NULL; 244 | IStorage* pstgGeekMetadata = NULL; 245 | IStorage* pstgGeekPackage = NULL; 246 | IStream* pstm = NULL; 247 | PWSTR pwszValue = NULL; 248 | PWSTR pwszName = NULL; 249 | DWORD dwRead = 0; 250 | STATSTG stg; 251 | 252 | // Locate the "GeekMetadata" storage. 253 | hr = this->m_pstg->OpenStorage( 254 | s_wszStorageNameGeekMetadata, 255 | NULL, 256 | STGM_READ | STGM_SHARE_EXCLUSIVE, 257 | NULL, 258 | 0, 259 | &pstgGeekMetadata); 260 | ON_FAILED_RETURN(hr, result, GEEK_ERROR_OPENSTGFAILED); 261 | 262 | // Get the metadata info. 263 | hr = pstgGeekMetadata->OpenStream( 264 | s_wszStreamNameDatabaseName, 265 | NULL, 266 | STGM_READ | STGM_SHARE_EXCLUSIVE, 267 | 0, 268 | &pstm); 269 | ON_FAILED_RETURN(hr, result, GEEK_ERROR_OPENSTMFAILED); 270 | 271 | result = this->ReadStringEntry(pstm, &pwszName, &dwRead); 272 | ON_GEEKFAILED_RETURN(result); 273 | metadata.wszName = std::wstring(pwszName); 274 | 275 | // Locate the "GeekDatabasePackage" storage. 276 | hr = this->m_pstg->OpenStorage( 277 | s_wszStorageNameGeekPackage, 278 | NULL, 279 | STGM_READ | STGM_SHARE_EXCLUSIVE, 280 | NULL, 281 | 0, 282 | &pstgGeekPackage); 283 | ON_FAILED_RETURN(hr, result, GEEK_ERROR_OPENSTGFAILED); 284 | 285 | hr = pstgGeekPackage->EnumElements(0, NULL, 0, &pEnumStat); 286 | ON_FAILED_RETURN(hr, result, GEEK_ERROR_ENUMSTGELEMENTSFAILED); 287 | 288 | hr = pEnumStat->Next(ulCelt, &stg, &ulFetched); 289 | ON_FAILED_RETURN(hr, result, GEEK_ERROR_ENUMSTGNEXTFAILED); 290 | 291 | while (hr == S_OK) 292 | { 293 | // Get stream name. 294 | std::wstring wszKey = stg.pwcsName; 295 | 296 | // Read stream contents. 297 | hr = pstgGeekPackage->OpenStream( 298 | stg.pwcsName, 299 | NULL, 300 | STGM_READ | STGM_SHARE_EXCLUSIVE, 301 | 0, 302 | &pstm); 303 | ON_FAILED_RETURN(hr, result, GEEK_ERROR_OPENSTMFAILED); 304 | 305 | DWORD dwRead; 306 | result = this->ReadStringEntry(pstm, &pwszValue, &dwRead); 307 | if (GEEKSUCCEEDED(result)) 308 | { 309 | std::wstring wszValue(pwszValue); 310 | entries.push_back(GeekKeyValue(wszKey, wszValue)); 311 | 312 | // Attention: array must be released here. 313 | DISPOSE_ARRAY(pwszValue); 314 | } 315 | 316 | hr = pEnumStat->Next(ulCelt, &stg, &ulFetched); 317 | ON_FAILED_RETURN(hr, result, GEEK_ERROR_ENUMSTGNEXTFAILED); 318 | } 319 | 320 | e_Exit: 321 | RELEASE_OLE_OBJECT(pstgGeekPackage); 322 | RELEASE_OLE_OBJECT(pstgGeekMetadata); 323 | RELEASE_OLE_OBJECT(pEnumStat); 324 | RELEASE_OLE_OBJECT(pstm); 325 | DISPOSE_ARRAY(pwszName); 326 | DISPOSE_ARRAY(pwszValue); 327 | return result; 328 | } 329 | } -------------------------------------------------------------------------------- /GeekDb/GeekDb/GeekDbStorage.h: -------------------------------------------------------------------------------- 1 | //************************************************* 2 | // Module: GeekDbStorage.h 3 | // Notices: Copyright (c) 2015 Zhang Wenjie 4 | //************************************************* 5 | #pragma once 6 | 7 | #include "GeekUtils.h" 8 | #include "GeekErrorCode.h" 9 | #include "GeekDefs.h" 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #pragma warning(disable : 4244) 17 | #pragma warning(disable : 4267) 18 | #pragma warning(disable : 4996) 19 | #pragma warning(disable : 4995) 20 | #pragma comment(lib, "Ole32.lib") 21 | 22 | namespace geek 23 | { 24 | // 25 | // Storage implementation for the geek database. 26 | // By taking the advantages of the IStorage COM interface, 27 | // key/values could be stored in a compound file structure. 28 | // 29 | class GeekDbStorage 30 | { 31 | public: 32 | GeekDbStorage( 33 | INPARAM const std::wstring& wszFileName, 34 | INPARAM const GeekDbMetadata& metadata, 35 | INPARAM const bool createNew) 36 | : m_wszFileName(wszFileName), 37 | m_Metadata(metadata) 38 | { 39 | if (createNew) 40 | { 41 | this->CreateStorage(); 42 | } 43 | else 44 | { 45 | if (IsFileExists(wszFileName)) 46 | this->OpenStorage(); 47 | else 48 | this->CreateStorage(); 49 | } 50 | } 51 | 52 | ~GeekDbStorage() 53 | { 54 | RELEASE_OLE_OBJECT(m_pstg); 55 | } 56 | 57 | public: 58 | GeekResult Add(INPARAM const GeekKeyValue& entry); 59 | 60 | GeekResult AddRange(INPARAM const std::vector& entries); 61 | 62 | // 63 | // Load all key/value entries from the storage. 64 | // 65 | GeekResult LoadAll( 66 | OUTPARAM GeekDbMetadata& metadata, 67 | OUTPARAM std::vector& entries 68 | ); 69 | 70 | private: 71 | // 72 | // For more information about IStorage and compound files, 73 | // refer to: https://msdn.microsoft.com/en-us/library/windows/desktop/aa378938(v=vs.85).aspx 74 | // and: https://msdn.microsoft.com/en-us/library/windows/desktop/aa380015(v=vs.85).aspx 75 | // 76 | GeekResult CreateStorage(void); 77 | GeekResult OpenStorage(void); 78 | 79 | GeekResult WriteStringEntry( 80 | INPARAM IStream* pstm, 81 | INPARAM const std::wstring& wsz 82 | ); 83 | 84 | GeekResult ReadStringEntry( 85 | INPARAM IStream* pstm, 86 | OUTPARAM WCHAR** ppwz, 87 | OUTPARAM DWORD* pcch 88 | ); 89 | 90 | inline GeekResult ReadExact( 91 | INPARAM IStream* pstm, 92 | INPARAM void* pv, 93 | INPARAM ULONG cb, 94 | OUTPARAM ULONG* pcb) 95 | { 96 | HRESULT hr = S_OK; 97 | ULONG cbRead = 0; 98 | 99 | if (pstm == NULL || pv == NULL) 100 | return GEEK_ERROR_NULLPOINTER; 101 | 102 | if (pcb == NULL) 103 | pcb = &cbRead; 104 | 105 | hr = pstm->Read(pv, cb, pcb); 106 | if (SUCCEEDED(hr) && *pcb != cb) 107 | return GEEK_ERROR_READSTMFAILED; 108 | 109 | return GEEK_SUCCESS; 110 | } 111 | 112 | inline GeekResult WriteExact( 113 | INPARAM IStream* pstm, 114 | INPARAM void const* pv, 115 | INPARAM ULONG cb, 116 | OUTPARAM ULONG* pcb) 117 | { 118 | if (pstm == NULL || pv == NULL) 119 | return GEEK_ERROR_INVALIDPARAM; 120 | 121 | HRESULT hr = S_OK; 122 | ULONG cbWritten = 0; 123 | if (pcb == NULL) 124 | pcb = &cbWritten; 125 | 126 | hr = pstm->Write(pv, cb, pcb); 127 | if (SUCCEEDED(hr) && *pcb != cb) 128 | return GEEK_ERROR_WRITESTMFAILED; 129 | 130 | return GEEK_SUCCESS; 131 | } 132 | 133 | // 134 | // Constants for storage and stream names. 135 | // 136 | const wchar_t* const s_wszStorageNameGeekMetadata = L"GeekMetadata"; 137 | const wchar_t* const s_wszStorageNameGeekPackage = L"GeekDatabasePackage"; 138 | const wchar_t* const s_wszStreamNameDatabaseName = L"\006DatabaseName"; 139 | 140 | private: 141 | IStorage* m_pstg = NULL; 142 | std::wstring m_wszFileName; 143 | GeekDbMetadata m_Metadata; 144 | }; 145 | } -------------------------------------------------------------------------------- /GeekDb/GeekDb/GeekDefs.h: -------------------------------------------------------------------------------- 1 | //************************************************* 2 | // Module: GeekDefs.h 3 | // Notices: Copyright (c) 2015 Zhang Wenjie 4 | //************************************************* 5 | 6 | #pragma once 7 | 8 | #include 9 | #include 10 | 11 | namespace geek 12 | { 13 | // 14 | // Defines the input parameter label. 15 | // This label indicates that a parameter is input to a function. 16 | // 17 | #ifndef INPARAM 18 | #define INPARAM 19 | #endif 20 | 21 | // 22 | // Defines the output parameter label. 23 | // This label indicates that a parameter is ouput from a function. 24 | // 25 | #ifndef OUTPARAM 26 | #define OUTPARAM 27 | #endif 28 | 29 | // 30 | // Defines the key/value pair used for the database entry. 31 | // Key: wstring 32 | // Value : wstring 33 | // 34 | typedef std::pair GeekKeyValue; 35 | 36 | // 37 | // Defines the metadata stucture for the geek database. 38 | // Currently only the database name is added. 39 | // 40 | struct GeekDbMetadata 41 | { 42 | public: 43 | std::wstring wszName; 44 | } ; 45 | } -------------------------------------------------------------------------------- /GeekDb/GeekDb/GeekErrorCode.h: -------------------------------------------------------------------------------- 1 | //************************************************* 2 | // Module: GeekErrorCode.h 3 | // Notices: Copyright (c) 2015 Zhang Wenjie 4 | //************************************************* 5 | 6 | #pragma once 7 | 8 | namespace geek 9 | { 10 | typedef long GeekResult; 11 | 12 | #define GEEK_SUCCESS ((GeekResult)0x22000000L) 13 | #define GEEK_ERROR ((GeekResult)0xE2000000L) 14 | 15 | #define GEEKFAILED(gr) ((gr) != GEEK_SUCCESS) 16 | #define GEEKSUCCEEDED(gr) ((gr) == GEEK_SUCCESS) 17 | 18 | #define GEEK_ERROR_OUTOFMEMORY ((GeekResult)(GEEK_ERROR + 1L)) 19 | #define GEEK_ERROR_INVALIDPARAM ((GeekResult)(GEEK_ERROR + 2L)) 20 | #define GEEK_ERROR_NULLPOINTER ((GeekResult)(GEEK_ERROR + 3L)) 21 | #define GEEK_ERROR_EMPTY ((GeekResult)(GEEK_ERROR + 4L)) 22 | #define GEEK_ERROR_NAMEALREADYEXIST ((GeekResult)(GEEK_ERROR + 8L)) 23 | #define GEEK_ERROR_FILENOTFOUND ((GeekResult)(GEEK_ERROR + 9L)) 24 | #define GEEK_ERROR_ENTRYNOTFOUND ((GeekResult)(GEEK_ERROR + 10L)) 25 | 26 | 27 | #define GEEK_ERROR_CREATESTGFAILED ((GeekResult)(GEEK_ERROR + 51L)) 28 | #define GEEK_ERROR_CREATESTMFAILED ((GeekResult)(GEEK_ERROR + 52L)) 29 | #define GEEK_ERROR_OPENSTGFAILED ((GeekResult)(GEEK_ERROR + 53L)) 30 | #define GEEK_ERROR_OPENSTMFAILED ((GeekResult)(GEEK_ERROR + 54L)) 31 | #define GEEK_ERROR_READSTMFAILED ((GeekResult)(GEEK_ERROR + 55L)) 32 | #define GEEK_ERROR_WRITESTMFAILED ((GeekResult)(GEEK_ERROR + 56L)) 33 | #define GEEK_ERROR_ENUMSTGELEMENTSFAILED ((GeekResult)(GEEK_ERROR + 57L)) 34 | #define GEEK_ERROR_ENUMSTGNEXTFAILED ((GeekResult)(GEEK_ERROR + 58L)) 35 | #define GEEK_ERROR_COMMITSTGFAILED ((GeekResult)(GEEK_ERROR + 59L)) 36 | } -------------------------------------------------------------------------------- /GeekDb/GeekDb/GeekSequenceDb.cpp: -------------------------------------------------------------------------------- 1 | //************************************************* 2 | // Module: GeekSequenceDb.cpp 3 | // Notices: Copyright (c) 2015 Zhang Wenjie 4 | //************************************************* 5 | 6 | #include "stdafx.h" 7 | #include "GeekSequenceDb.h" 8 | #include "GeekUtils.h" 9 | #include 10 | #include 11 | 12 | namespace geek 13 | { 14 | GeekResult GeekSequenceDb::InsertKeyValue(INPARAM const GeekKeyValue& entry) 15 | { 16 | m_kvContainer.push_back(entry); 17 | return GEEK_SUCCESS; 18 | } 19 | 20 | GeekResult GeekSequenceDb::UpdateKeyValue(INPARAM const GeekKeyValue& entry) 21 | { 22 | KeyValueIterator it = std::find(m_kvContainer.begin(), m_kvContainer.end(), entry); 23 | if (it == m_kvContainer.end()) 24 | return GEEK_ERROR_ENTRYNOTFOUND; 25 | 26 | (*it).first = entry.first; 27 | (*it).second = entry.second; 28 | return GEEK_SUCCESS; 29 | } 30 | 31 | GeekResult GeekSequenceDb::DeleteKeyValue(INPARAM const std::wstring& wszKey) 32 | { 33 | if (IsNullOrEmpty(wszKey)) 34 | return GEEK_ERROR_INVALIDPARAM; 35 | 36 | GeekKeyValue entry; 37 | for(KeyValueIterator it = m_kvContainer.begin(); it != m_kvContainer.end(); it++) 38 | { 39 | if ((*it).first == wszKey) 40 | { 41 | entry = (*it); 42 | break; 43 | } 44 | } 45 | 46 | m_kvContainer.erase(std::remove(m_kvContainer.begin(), m_kvContainer.end(), entry)); 47 | return GEEK_SUCCESS; 48 | } 49 | 50 | GeekResult GeekSequenceDb::QueryKeyValue( 51 | INPARAM const std::wstring& wszKey, 52 | OUTPARAM std::vector& entries) 53 | { 54 | if (IsNullOrEmpty(wszKey)) 55 | return GEEK_ERROR_INVALIDPARAM; 56 | 57 | for (KeyValueIterator it = m_kvContainer.begin(); it != m_kvContainer.end(); it++) 58 | { 59 | if ((*it).first == wszKey) 60 | { 61 | entries.push_back((*it)); 62 | } 63 | } 64 | 65 | return GEEK_SUCCESS; 66 | } 67 | 68 | GeekResult GeekSequenceDb::DumpKeyValues(INPARAM const std::wstring & wszFileName) 69 | { 70 | if (IsNullOrEmpty(wszFileName)) 71 | return GEEK_ERROR_INVALIDPARAM; 72 | 73 | GeekDbStorage* pstg = new GeekDbStorage(wszFileName, this->m_Metadata, true); 74 | if (pstg == NULL) 75 | return GEEK_ERROR_OUTOFMEMORY; 76 | 77 | GeekResult result = pstg->AddRange(m_kvContainer); 78 | DISPOSE_OBJECT(pstg); 79 | return result; 80 | } 81 | 82 | GeekResult GeekSequenceDb::LoadKeyValues( 83 | INPARAM const std::wstring & wszFileName, 84 | OUTPARAM std::wstring& wszName) 85 | { 86 | if (IsNullOrEmpty(wszFileName)) 87 | return GEEK_ERROR_INVALIDPARAM; 88 | 89 | GeekDbStorage* pstg = new GeekDbStorage(wszFileName, m_Metadata, false); 90 | if (pstg == NULL) 91 | return GEEK_ERROR_OUTOFMEMORY; 92 | 93 | // Ensure the container's size and capacity is 0 by shrinking it! 94 | KeyValueContainer().swap(m_kvContainer); 95 | wszName.clear(); 96 | 97 | GeekResult result = pstg->LoadAll(m_Metadata, m_kvContainer); 98 | wszName.assign(m_Metadata.wszName); 99 | DISPOSE_OBJECT(pstg); 100 | return result; 101 | } 102 | 103 | void GeekSequenceDb::TraverseKeyVaues(void) 104 | { 105 | std::for_each(m_kvContainer.begin(), m_kvContainer.end(), 106 | geek::PrintKeyValue()); 107 | } 108 | 109 | const std::size_t GeekSequenceDb::GetSize(void) const 110 | { 111 | return m_kvContainer.size(); 112 | } 113 | } -------------------------------------------------------------------------------- /GeekDb/GeekDb/GeekSequenceDb.h: -------------------------------------------------------------------------------- 1 | //************************************************* 2 | // Module: GeekSequenceDb.h 3 | // Notices: Copyright (c) 2015 Zhang Wenjie 4 | //************************************************* 5 | 6 | #pragma once 7 | 8 | #include "GeekDb.h" 9 | #include "GeekDbStorage.h" 10 | #include 11 | 12 | namespace geek 13 | { 14 | // 15 | // Geek database implementation using std::vector 16 | // 17 | class GeekSequenceDb : public GeekDb 18 | { 19 | public: 20 | GeekSequenceDb(const GeekDbMetadata& metadata) 21 | : GeekDb(metadata) 22 | { 23 | } 24 | 25 | ~GeekSequenceDb(void) 26 | { 27 | } 28 | 29 | public: 30 | GeekResult InsertKeyValue(INPARAM const GeekKeyValue& entry); 31 | 32 | GeekResult UpdateKeyValue(INPARAM const GeekKeyValue& entry); 33 | 34 | GeekResult DeleteKeyValue(INPARAM const std::wstring& wszKey); 35 | 36 | GeekResult QueryKeyValue( 37 | INPARAM const std::wstring& wszKey, 38 | OUTPARAM std::vector& entries 39 | ); 40 | 41 | GeekResult DumpKeyValues(INPARAM const std::wstring& wszFileName); 42 | 43 | GeekResult LoadKeyValues( 44 | INPARAM const std::wstring& wszFileName, 45 | OUTPARAM std::wstring& wszName 46 | ); 47 | 48 | void TraverseKeyVaues(void); 49 | 50 | const std::size_t GetSize(void) const; 51 | 52 | private: 53 | typedef std::vector KeyValueContainer; 54 | typedef KeyValueContainer::iterator KeyValueIterator; 55 | KeyValueContainer m_kvContainer; 56 | }; 57 | 58 | // 59 | // Traits returns the concrete database type. 60 | // 61 | template<> 62 | struct GeekDbTraits 63 | { 64 | public: 65 | typedef GeekSequenceDb Database; 66 | }; 67 | } -------------------------------------------------------------------------------- /GeekDb/GeekDb/GeekUtils.h: -------------------------------------------------------------------------------- 1 | //************************************************* 2 | // Module: GeekUtils.h 3 | // Notices: Copyright (c) 2015 Zhang Wenjie 4 | //************************************************* 5 | 6 | #pragma once 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include // for PathFileExists invocation 13 | #include "GeekDefs.h" 14 | 15 | // 16 | // Must link the Shlwapi.lib module for the Windows function: 17 | // PathFileExists. 18 | // 19 | #pragma comment(lib, "Shlwapi.lib") 20 | 21 | namespace geek 22 | { 23 | // 24 | // Indicates whether a string is empty. 25 | // 26 | inline const bool IsNullOrEmpty(const std::wstring& wsz) 27 | { 28 | return (wsz.empty() ? true : false); 29 | } 30 | 31 | inline const bool IsFileExists(const std::wstring& wszFileName) 32 | { 33 | return (::PathFileExists(wszFileName.c_str()) == TRUE) ? true : false; 34 | } 35 | 36 | // 37 | // Functor to print all the key/value entries in a database. 38 | // Must overload operator(). 39 | // 40 | struct PrintKeyValue : std::unary_function 41 | { 42 | public: 43 | void operator()(const GeekKeyValue& entry) 44 | { 45 | std::wcout << L"[Key]: -> " << entry.first << std::endl 46 | << L"[Value]:-> " << entry.second << std::endl 47 | << std::endl; 48 | } 49 | }; 50 | 51 | // 52 | // The Macro to exit a function once a "Geek Error" occurs. 53 | // 54 | #if !defined(ON_GEEKFAILED_RETURN) 55 | #define ON_GEEKFAILED_RETURN(gr) { \ 56 | if (GEEKFAILED(gr)) { \ 57 | goto e_Exit; \ 58 | } \ 59 | } 60 | #endif 61 | 62 | // 63 | // The Macro to exit a function once a "Windows Error" occurs. 64 | // 65 | #if !defined(ON_FAILED_RETURN) 66 | #define ON_FAILED_RETURN(hr, gr, err) { \ 67 | if (FAILED(hr)) { \ 68 | gr = err; \ 69 | goto e_Exit; \ 70 | } \ 71 | } 72 | #endif 73 | 74 | // 75 | // The Macro to release an Ole object. 76 | // 77 | #if !defined(RELEASE_OLE_OBJECT) 78 | #define RELEASE_OLE_OBJECT(obj) { \ 79 | if (obj != NULL) { \ 80 | obj->Release(); \ 81 | obj = NULL; \ 82 | } \ 83 | } 84 | #endif 85 | 86 | // 87 | // The Macro to release an object created by the [new] operator. 88 | // 89 | #if !defined(DISPOSE_OBJECT) 90 | #define DISPOSE_OBJECT(obj) { \ 91 | if (obj != NULL) { \ 92 | delete obj; \ 93 | obj = NULL; \ 94 | } \ 95 | } 96 | #endif 97 | 98 | // 99 | // The Macro to release an array. 100 | // 101 | #if !defined(DISPOSE_ARRAY) 102 | #define DISPOSE_ARRAY(obj) { \ 103 | if (obj != NULL) { \ 104 | delete[] obj; \ 105 | obj = NULL; \ 106 | } \ 107 | } 108 | #endif 109 | } -------------------------------------------------------------------------------- /GeekDb/GeekDb/Program.cpp: -------------------------------------------------------------------------------- 1 | //****************************************************************** 2 | // Module: GeekSequenceDb.cpp 3 | // Defines the entry point for the console application. 4 | // 5 | // Notices: Copyright (c) 2015 Zhang Wenjie 6 | //****************************************************************** 7 | 8 | #include "stdafx.h" 9 | #include "GeekDbManager.h" 10 | #include 11 | using namespace geek; 12 | 13 | // The global database manager. 14 | geek::GeekDbManager g_DbManager; 15 | 16 | void CreateSequenceDatabase(const std::wstring& wszDumpFileName) 17 | { 18 | std::wstring wszFileName = wszDumpFileName; 19 | if (geek::IsNullOrEmpty(wszFileName)) 20 | wszFileName = L"sequence01.geekdb"; 21 | 22 | geek::GeekKeyValue gkv[] = { 23 | geek::GeekKeyValue(L"name", L"zhangwenjie"), 24 | geek::GeekKeyValue(L"age", L"30"), 25 | geek::GeekKeyValue(L"class", L"AABBCCC"), 26 | geek::GeekKeyValue(L"grade", L"900"), 27 | geek::GeekKeyValue(L"language", L"us-en"), 28 | geek::GeekKeyValue(L"sex", L"male"), 29 | }; 30 | 31 | g_DbManager.CreateDatabase(L"Testdb01"); 32 | g_DbManager.InsertDatabase(L"Testdb01", 33 | std::vector(gkv, gkv + 6)); 34 | 35 | geek::GeekResult r = g_DbManager.DumpDatabase(L"Testdb01", 36 | wszFileName); 37 | } 38 | 39 | int main() 40 | { 41 | CreateSequenceDatabase(L"D:\\Boolan\\dump02.geekdb"); 42 | 43 | std::wstring wszName; 44 | geek::GeekResult r = g_DbManager.LoadDatabase( 45 | L"D:\\Boolan\\dump02.geekdb", wszName); 46 | g_DbManager.TraverseDatabase(wszName); 47 | 48 | return 0; 49 | } 50 | 51 | -------------------------------------------------------------------------------- /GeekDb/GeekDb/ReadMe.txt: -------------------------------------------------------------------------------- 1 | ======================================================================== 2 | CONSOLE APPLICATION : GeekDb Project Overview 3 | ======================================================================== 4 | 5 | AppWizard has created this GeekDb application for you. 6 | 7 | This file contains a summary of what you will find in each of the files that 8 | make up your GeekDb application. 9 | 10 | 11 | GeekDb.vcxproj 12 | This is the main project file for VC++ projects generated using an Application Wizard. 13 | It contains information about the version of Visual C++ that generated the file, and 14 | information about the platforms, configurations, and project features selected with the 15 | Application Wizard. 16 | 17 | GeekDb.vcxproj.filters 18 | This is the filters file for VC++ projects generated using an Application Wizard. 19 | It contains information about the association between the files in your project 20 | and the filters. This association is used in the IDE to show grouping of files with 21 | similar extensions under a specific node (for e.g. ".cpp" files are associated with the 22 | "Source Files" filter). 23 | 24 | GeekDb.cpp 25 | This is the main application source file. 26 | 27 | ///////////////////////////////////////////////////////////////////////////// 28 | Other standard files: 29 | 30 | StdAfx.h, StdAfx.cpp 31 | These files are used to build a precompiled header (PCH) file 32 | named GeekDb.pch and a precompiled types file named StdAfx.obj. 33 | 34 | ///////////////////////////////////////////////////////////////////////////// 35 | Other notes: 36 | 37 | AppWizard uses "TODO:" comments to indicate parts of the source code you 38 | should add to or customize. 39 | 40 | ///////////////////////////////////////////////////////////////////////////// 41 | -------------------------------------------------------------------------------- /GeekDb/GeekDb/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // GeekDb.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /GeekDb/GeekDb/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit 15 | 16 | #include 17 | #include 18 | 19 | // TODO: reference additional headers your program requires here 20 | -------------------------------------------------------------------------------- /GeekDb/GeekDb/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 极客班C++样本项目资源统一在这里发布 2 | -------------------------------------------------------------------------------- /极客班C++ 样本项目 .pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekBand/GeekBand-CPP-1501-SampleProject/609d7b8c4071718b71f8cecb46f1b4f16b231659/极客班C++ 样本项目 .pdf -------------------------------------------------------------------------------- /极客班第一期C++专业期末综合测试题.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekBand/GeekBand-CPP-1501-SampleProject/609d7b8c4071718b71f8cecb46f1b4f16b231659/极客班第一期C++专业期末综合测试题.pdf -------------------------------------------------------------------------------- /极客班第一期C++专业考核细则.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekBand/GeekBand-CPP-1501-SampleProject/609d7b8c4071718b71f8cecb46f1b4f16b231659/极客班第一期C++专业考核细则.pdf --------------------------------------------------------------------------------