├── .gitattributes
├── .gitignore
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── TODO.txt
├── logo.png
├── screenshot.png
└── src
├── BigJsonTreeViewMfc.cpp
├── BigJsonTreeViewMfc.h
├── BigJsonTreeViewMfc.rc
├── BigJsonTreeViewMfc.sln
├── BigJsonTreeViewMfc.vcxproj
├── BigJsonTreeViewMfc.vcxproj.filters
├── BigJsonTreeViewMfcDoc.cpp
├── BigJsonTreeViewMfcDoc.h
├── BigJsonTreeViewMfcView.cpp
├── BigJsonTreeViewMfcView.h
├── Bread
├── FileLoader.cpp
├── FileLoader.h
├── FileLoading.cpp
├── FileLoading.h
├── FileState.cpp
├── FileState.h
├── OpenFileManager.cpp
├── OpenFileManager.h
├── RapidJsonDomFileState.cpp
├── RapidJsonDomFileState.h
├── Search.cpp
├── Search.h
├── SearchResult.h
├── Timer.h
└── Utils.h
├── Butter
├── JsonTreeViewController.cpp
├── JsonTreeViewController.h
├── JsonTreeViewControllerImpl.cpp
├── JsonTreeViewControllerImpl.h
├── Log.cpp
├── Log.h
├── LoggerImpl.cpp
├── LoggerImpl.h
├── SearchPrompt.cpp
├── SearchPrompt.h
├── SearchResults.cpp
└── SearchResults.h
├── ChildFrm.cpp
├── ChildFrm.h
├── ClassView.cpp
├── ClassView.h
├── FileView.cpp
├── FileView.h
├── FindDialog.cpp
├── FindDialog.h
├── MainFrm.cpp
├── MainFrm.h
├── OutputWnd.cpp
├── OutputWnd.h
├── PropertiesWnd.cpp
├── PropertiesWnd.h
├── Resource.h
├── ViewTree.cpp
├── ViewTree.h
├── calendarbar.cpp
├── calendarbar.h
├── external
└── include
│ └── rapidjson
│ ├── allocators.h
│ ├── cursorstreamwrapper.h
│ ├── document.h
│ ├── encodedstream.h
│ ├── encodings.h
│ ├── error
│ ├── en.h
│ └── error.h
│ ├── filereadstream.h
│ ├── filewritestream.h
│ ├── fwd.h
│ ├── internal
│ ├── biginteger.h
│ ├── clzll.h
│ ├── diyfp.h
│ ├── dtoa.h
│ ├── ieee754.h
│ ├── itoa.h
│ ├── meta.h
│ ├── pow10.h
│ ├── regex.h
│ ├── stack.h
│ ├── strfunc.h
│ ├── strtod.h
│ └── swap.h
│ ├── istreamwrapper.h
│ ├── memorybuffer.h
│ ├── memorystream.h
│ ├── msinttypes
│ ├── inttypes.h
│ └── stdint.h
│ ├── ostreamwrapper.h
│ ├── pointer.h
│ ├── prettywriter.h
│ ├── rapidjson.h
│ ├── reader.h
│ ├── schema.h
│ ├── stream.h
│ ├── stringbuffer.h
│ ├── uri.h
│ └── writer.h
├── framework.h
├── pch.cpp
├── pch.h
├── res
├── BigJsonTreeViewMfc.ico
├── BigJsonTreeViewMfc.rc2
├── BigJsonTreeViewMfcDoc.ico
├── Toolbar.bmp
├── Toolbar256.bmp
├── class_view.ico
├── class_view_hc.ico
├── classview.bmp
├── classview_hc.bmp
├── explorer.bmp
├── explorer_hc.bmp
├── file_view.ico
├── file_view_hc.ico
├── fileview.bmp
├── fileview_hc.bmp
├── info.bmp
├── menuimages.bmp
├── menuimages_hc.bmp
├── nav_large.bmp
├── nav_large_hc.bmp
├── output_wnd.ico
├── output_wnd_hc.ico
├── pages.bmp
├── pages_hc.bmp
├── pages_small.bmp
├── pages_small_hc.bmp
├── properties.bmp
├── properties_hc.bmp
├── properties_wnd.ico
├── properties_wnd_hc.ico
├── sort.bmp
├── sort_hc.bmp
└── userimages.bmp
└── targetver.h
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.rc diff text eol=lf
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | src/x64/
2 | *.vs
3 | *.user
4 | *.aps
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to Big JSON Tree Viewer
2 |
3 | Feel free to submit bug reports or suggestions/feature requests to the issue tracker, but please
4 | first check existing issues and [TODO.txt](./TODO.txt).
5 |
6 | Given the very early state of this tool, multiple contributors are likely to bump heads. If
7 | you'd like to contribute, please first comment on an issue and state that you wish to help.
8 |
9 | The code is organized like this:
10 | * To get started, open the .sln in the src directory with Visual Studio 2022
11 | * Root directory contains generated MFC template files with minimal modifications.
12 | ** Many of these files are not used currently but have not been cleaned up yet.
13 | * Bread and Butter directories contain most of the actual logic. Butter is UI related.
14 | * The external dir contains third party libraries
15 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Ruslan Balagansky
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Big JSON Tree Viewer (for Windows)
2 |
3 | A simple Windows desktop application for viewing large (100MB+) JSON files in a tree view.
4 |
5 |
6 |
7 |
8 |
9 |
10 | This tool is in very early development, but being made available as is now to fill an apparent
11 | gap in such tooling. At time of writing, the author is not aware of any other similar tool that
12 | is free, open source, runs as a Windows desktop application, and can comfortably handle large
13 | files while providing an intuitive, functional interface.
14 |
15 | ## Features
16 |
17 | * Fast loading (<1 second for 250MB)
18 | * Intuitive tree view
19 | * Dynamic folding of large arrays
20 | * Multiple Document Interface with dockable tree view panels - view multiple files side by side!
21 | * Basic string search
22 | * [More to come...](./TODO.txt)
23 |
24 | ## Downloading Releases
25 |
26 | Simply download the latest release from the [GitHub Releases page](https://github.com/balagansky/BigJsonTreeViewer/releases/).
27 |
28 | In order to run the Windows executable, you must have the [VC 2022 Redistributable](https://aka.ms/vs/17/release/vc_redist.x64.exe) installed.
29 |
30 | ## Building
31 |
32 | To build the application for Windows, you need Visual Studio 2022. The .sln file is in the root
33 | directory.
34 |
35 | ## Can I help?
36 |
37 | Feel free to submit bug reports or suggestions/feature requests to the issue tracker, but please
38 | first check existing issues and [TODO.txt](./TODO.txt).
39 |
40 | Given the very early state of this tool, multiple contributors are likely to bump heads. If
41 | you'd like to contribute, please read [CONTRIBUTING.md](./CONTRIBUTING.md).
42 |
--------------------------------------------------------------------------------
/TODO.txt:
--------------------------------------------------------------------------------
1 | Now:
2 | * basic search function
3 | + auto-select first result
4 | * fix new window views into same file (handle vector of tree ctrls)
5 | * reload from disk
6 |
7 | Performance/Robustness:
8 | * Handle objects with huge property list same way as arrays (dynamic folding)
9 | * Optimize file reading
10 | + parse while reading! (bottleneck will be the slower of the two)
11 | + memory mapped IO ?
12 | + overlapped IO?
13 | * Replace rapidjson with simdjson (4x faster?) - might not be the bottleneck though
14 | * test handling of files with single value content
15 | * handle bad buffer alloc(s)
16 | * async updates
17 |
18 | Code Cleanup:
19 | * single version var
20 | * clean up MFC code
21 | * clean up PCH, windows includes (search for #undef)
22 | * separate MFC code into a separate lib from the implementations (use interfaces for MFC hooks)
23 |
24 | UX Glitches:
25 | * context menus
26 | * special display / auto-expansion of empty arrays/objects
27 |
28 | UX Enhancements:
29 | * Enable copying values from tree views
30 | + context menu choices for key and/or value
31 | + copy entire object/array to clipboard? (any limit?)
32 | * Reload from disk
33 | + auto-prompt
34 | * Tab tooltip shows full file path
35 | * colors + icons in tree view
36 | * support various ways of opening files:
37 | + drag and drop
38 | + context menu hook
39 | + file association
40 | * Show array sizes
41 | + also object field count?
42 | * installer
43 | * Find enhancements:
44 | + separate key + value fields
45 | + ignore empty/null option
46 |
47 | Feature Wishlist:
48 | * Show pretty printed content of selected json values in doc panel (with syntax highlighting)
49 | * Seach bar
50 | * Save as formatted (with settings!)
51 | * Memory limit settings - dedupe strings to try to keep under limit
52 | + Use trie with efficient allocator for optimal memory usage
53 | + simple map might be good enough
--------------------------------------------------------------------------------
/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/balagansky/BigJsonTreeViewer/bd3b1b0a2e6d57487d43d5bc9385fe5938e175fb/logo.png
--------------------------------------------------------------------------------
/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/balagansky/BigJsonTreeViewer/bd3b1b0a2e6d57487d43d5bc9385fe5938e175fb/screenshot.png
--------------------------------------------------------------------------------
/src/BigJsonTreeViewMfc.cpp:
--------------------------------------------------------------------------------
1 |
2 | // BigJsonTreeViewMfc.cpp : Defines the class behaviors for the application.
3 | //
4 |
5 | #include "pch.h"
6 | #include "framework.h"
7 | #include "afxwinappex.h"
8 | #include "afxdialogex.h"
9 | #include "BigJsonTreeViewMfc.h"
10 | #include "MainFrm.h"
11 |
12 | #include "ChildFrm.h"
13 | #include "BigJsonTreeViewMfcDoc.h"
14 | #include "BigJsonTreeViewMfcView.h"
15 |
16 | #ifdef _DEBUG
17 | #define new DEBUG_NEW
18 | #endif
19 |
20 |
21 | // CBigJsonTreeViewMfcApp
22 |
23 | BEGIN_MESSAGE_MAP(CBigJsonTreeViewMfcApp, CWinAppEx)
24 | ON_COMMAND(ID_APP_ABOUT, &CBigJsonTreeViewMfcApp::OnAppAbout)
25 | // Standard file based document commands
26 | //ON_COMMAND(ID_FILE_NEW, &CWinAppEx::OnFileNew)
27 | ON_COMMAND(ID_FILE_OPEN, &CWinAppEx::OnFileOpen)
28 | // disable saving
29 | ON_UPDATE_COMMAND_UI(ID_FILE_SAVE, &CBigJsonTreeViewMfcApp::DisableUi)
30 | ON_UPDATE_COMMAND_UI(ID_FILE_SAVE_AS, &CBigJsonTreeViewMfcApp::DisableUi)
31 | // Standard print setup command
32 | //ON_COMMAND(ID_FILE_PRINT_SETUP, &CWinAppEx::OnFilePrintSetup)
33 | END_MESSAGE_MAP()
34 |
35 |
36 | // CBigJsonTreeViewMfcApp construction
37 |
38 | CBigJsonTreeViewMfcApp::CBigJsonTreeViewMfcApp() noexcept
39 | {
40 | m_bHiColorIcons = TRUE;
41 |
42 |
43 | m_nAppLook = 0;
44 | // support Restart Manager
45 | m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_ALL_ASPECTS;
46 | #ifdef _MANAGED
47 | // If the application is built using Common Language Runtime support (/clr):
48 | // 1) This additional setting is needed for Restart Manager support to work properly.
49 | // 2) In your project, you must add a reference to System.Windows.Forms in order to build.
50 | System::Windows::Forms::Application::SetUnhandledExceptionMode(System::Windows::Forms::UnhandledExceptionMode::ThrowException);
51 | #endif
52 |
53 | // TODO: replace application ID string below with unique ID string; recommended
54 | // format for string is CompanyName.ProductName.SubProduct.VersionInformation
55 | SetAppID(_T("BigJsonTreeViewer.0.3.1"));
56 |
57 | // TODO: add construction code here,
58 | // Place all significant initialization in InitInstance
59 | }
60 |
61 | // The one and only CBigJsonTreeViewMfcApp object
62 |
63 | CBigJsonTreeViewMfcApp theApp;
64 |
65 |
66 | // CBigJsonTreeViewMfcApp initialization
67 |
68 | BOOL CBigJsonTreeViewMfcApp::InitInstance()
69 | {
70 | // InitCommonControlsEx() is required on Windows XP if an application
71 | // manifest specifies use of ComCtl32.dll version 6 or later to enable
72 | // visual styles. Otherwise, any window creation will fail.
73 | INITCOMMONCONTROLSEX InitCtrls;
74 | InitCtrls.dwSize = sizeof(InitCtrls);
75 | // Set this to include all the common control classes you want to use
76 | // in your application.
77 | InitCtrls.dwICC = ICC_WIN95_CLASSES;
78 | InitCommonControlsEx(&InitCtrls);
79 |
80 | CWinAppEx::InitInstance();
81 |
82 |
83 | // Initialize OLE libraries
84 | if (!AfxOleInit())
85 | {
86 | AfxMessageBox(IDP_OLE_INIT_FAILED);
87 | return FALSE;
88 | }
89 |
90 | AfxEnableControlContainer();
91 |
92 | EnableTaskbarInteraction();
93 |
94 | // AfxInitRichEdit2() is required to use RichEdit control
95 | // AfxInitRichEdit2();
96 |
97 | // Standard initialization
98 | // If you are not using these features and wish to reduce the size
99 | // of your final executable, you should remove from the following
100 | // the specific initialization routines you do not need
101 | // Change the registry key under which our settings are stored
102 | // TODO: You should modify this string to be something appropriate
103 | // such as the name of your company or organization
104 | SetRegistryKey(_T("BigJsonTreeViewMfc"));
105 | LoadStdProfileSettings(4); // Load standard INI file options (including MRU)
106 |
107 |
108 | InitContextMenuManager();
109 | InitShellManager();
110 |
111 | InitKeyboardManager();
112 |
113 | InitTooltipManager();
114 | CMFCToolTipInfo ttParams;
115 | ttParams.m_bVislManagerTheme = TRUE;
116 | theApp.GetTooltipManager()->SetTooltipParams(AFX_TOOLTIP_TYPE_ALL,
117 | RUNTIME_CLASS(CMFCToolTipCtrl), &ttParams);
118 |
119 | // Register the application's document templates. Document templates
120 | // serve as the connection between documents, frame windows and views
121 | CMultiDocTemplate* pDocTemplate;
122 | pDocTemplate = new CMultiDocTemplate(IDR_BigJsonTreeViewMfcTYPE,
123 | RUNTIME_CLASS(CBigJsonTreeViewMfcDoc),
124 | RUNTIME_CLASS(CChildFrame), // custom MDI child frame
125 | RUNTIME_CLASS(CBigJsonTreeViewMfcView));
126 | if (!pDocTemplate)
127 | return FALSE;
128 | AddDocTemplate(pDocTemplate);
129 |
130 | // create main MDI Frame window
131 | CMainFrame* pMainFrame = new CMainFrame;
132 | if (!pMainFrame || !pMainFrame->LoadFrame(IDR_MAINFRAME))
133 | {
134 | delete pMainFrame;
135 | return FALSE;
136 | }
137 | m_pMainWnd = pMainFrame;
138 |
139 | // Parse command line for standard shell commands, DDE, file open
140 | CCommandLineInfo cmdInfo;
141 | ParseCommandLine(cmdInfo);
142 |
143 | // don't open new doc on launch
144 | cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing;
145 |
146 | // Dispatch commands specified on the command line. Will return FALSE if
147 | // app was launched with /RegServer, /Register, /Unregserver or /Unregister.
148 | if (!ProcessShellCommand(cmdInfo))
149 | return FALSE;
150 | // The main window has been initialized, so show and update it
151 | pMainFrame->ShowWindow(m_nCmdShow);
152 | pMainFrame->UpdateWindow();
153 |
154 | return TRUE;
155 | }
156 |
157 | int CBigJsonTreeViewMfcApp::ExitInstance()
158 | {
159 | //TODO: handle additional resources you may have added
160 | AfxOleTerm(FALSE);
161 |
162 | return CWinAppEx::ExitInstance();
163 | }
164 |
165 | // CBigJsonTreeViewMfcApp message handlers
166 |
167 |
168 | // CAboutDlg dialog used for App About
169 |
170 | class CAboutDlg : public CDialogEx
171 | {
172 | public:
173 | CAboutDlg() noexcept;
174 |
175 | // Dialog Data
176 | #ifdef AFX_DESIGN_TIME
177 | enum { IDD = IDD_ABOUTBOX };
178 | #endif
179 |
180 | protected:
181 | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
182 |
183 | // Implementation
184 | protected:
185 | DECLARE_MESSAGE_MAP()
186 | };
187 |
188 | CAboutDlg::CAboutDlg() noexcept : CDialogEx(IDD_ABOUTBOX)
189 | {
190 | }
191 |
192 | void CAboutDlg::DoDataExchange(CDataExchange* pDX)
193 | {
194 | CDialogEx::DoDataExchange(pDX);
195 | }
196 |
197 | BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
198 | END_MESSAGE_MAP()
199 |
200 | // App command to run the dialog
201 | void CBigJsonTreeViewMfcApp::OnAppAbout()
202 | {
203 | CAboutDlg aboutDlg;
204 | aboutDlg.DoModal();
205 | }
206 |
207 | // CBigJsonTreeViewMfcApp customization load/save methods
208 |
209 | void CBigJsonTreeViewMfcApp::PreLoadState()
210 | {
211 | BOOL bNameValid;
212 | CString strName;
213 | bNameValid = strName.LoadString(IDS_EDIT_MENU);
214 | ASSERT(bNameValid);
215 | GetContextMenuManager()->AddMenu(strName, IDR_POPUP_EDIT);
216 | bNameValid = strName.LoadString(IDS_EXPLORER);
217 | ASSERT(bNameValid);
218 | GetContextMenuManager()->AddMenu(strName, IDR_POPUP_EXPLORER);
219 | }
220 |
221 | BOOL CBigJsonTreeViewMfcApp::LoadState(LPCTSTR lpszSectionName, CFrameImpl* pFrameImpl)
222 | {
223 | // do nothing while UI is still in flux
224 | // TODO: re-enable when UI is more stable
225 | //CWinAppEx::LoadState(lpszSectionName, pFrameImpl);
226 |
227 | return TRUE;
228 | }
229 |
230 | void CBigJsonTreeViewMfcApp::LoadCustomState()
231 | {
232 | }
233 |
234 | void CBigJsonTreeViewMfcApp::SaveCustomState()
235 | {
236 | }
237 |
238 | // CBigJsonTreeViewMfcApp message handlers
239 |
240 |
241 |
242 |
--------------------------------------------------------------------------------
/src/BigJsonTreeViewMfc.h:
--------------------------------------------------------------------------------
1 |
2 | // BigJsonTreeViewMfc.h : main header file for the BigJsonTreeViewMfc application
3 | //
4 | #pragma once
5 |
6 | #ifndef __AFXWIN_H__
7 | #error "include 'pch.h' before including this file for PCH"
8 | #endif
9 |
10 | #include "resource.h" // main symbols
11 |
12 |
13 | // CBigJsonTreeViewMfcApp:
14 | // See BigJsonTreeViewMfc.cpp for the implementation of this class
15 | //
16 |
17 | class CBigJsonTreeViewMfcApp : public CWinAppEx
18 | {
19 | public:
20 | CBigJsonTreeViewMfcApp() noexcept;
21 |
22 |
23 | // Overrides
24 | public:
25 | virtual BOOL InitInstance();
26 | virtual int ExitInstance();
27 |
28 | // Implementation
29 | UINT m_nAppLook;
30 | BOOL m_bHiColorIcons;
31 |
32 | virtual void PreLoadState();
33 | virtual void LoadCustomState();
34 | virtual void SaveCustomState();
35 |
36 | BOOL LoadState(LPCTSTR lpszSectionName = NULL, CFrameImpl* pFrameImpl = NULL) override;
37 |
38 | afx_msg void OnAppAbout();
39 |
40 | void DisableUi(CCmdUI *pCmdUI) { pCmdUI->Enable( FALSE ); }
41 |
42 | DECLARE_MESSAGE_MAP()
43 | };
44 |
45 | extern CBigJsonTreeViewMfcApp theApp;
46 |
--------------------------------------------------------------------------------
/src/BigJsonTreeViewMfc.rc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/balagansky/BigJsonTreeViewer/bd3b1b0a2e6d57487d43d5bc9385fe5938e175fb/src/BigJsonTreeViewMfc.rc
--------------------------------------------------------------------------------
/src/BigJsonTreeViewMfc.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.4.33110.190
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BigJsonTreeViewMfc", "BigJsonTreeViewMfc.vcxproj", "{BEB205C0-0994-41FE-874E-A6A7AFAF3865}"
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 | {BEB205C0-0994-41FE-874E-A6A7AFAF3865}.Debug|x64.ActiveCfg = Debug|x64
17 | {BEB205C0-0994-41FE-874E-A6A7AFAF3865}.Debug|x64.Build.0 = Debug|x64
18 | {BEB205C0-0994-41FE-874E-A6A7AFAF3865}.Debug|x86.ActiveCfg = Debug|Win32
19 | {BEB205C0-0994-41FE-874E-A6A7AFAF3865}.Debug|x86.Build.0 = Debug|Win32
20 | {BEB205C0-0994-41FE-874E-A6A7AFAF3865}.Release|x64.ActiveCfg = Release|x64
21 | {BEB205C0-0994-41FE-874E-A6A7AFAF3865}.Release|x64.Build.0 = Release|x64
22 | {BEB205C0-0994-41FE-874E-A6A7AFAF3865}.Release|x86.ActiveCfg = Release|Win32
23 | {BEB205C0-0994-41FE-874E-A6A7AFAF3865}.Release|x86.Build.0 = Release|Win32
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(ExtensibilityGlobals) = postSolution
29 | SolutionGuid = {5C1364C0-B321-4690-B0AB-062F627195C7}
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/src/BigJsonTreeViewMfcDoc.cpp:
--------------------------------------------------------------------------------
1 |
2 | // BigJsonTreeViewMfcDoc.cpp : implementation of the CBigJsonTreeViewMfcDoc class
3 | //
4 |
5 | #include "pch.h"
6 | #include "framework.h"
7 | // SHARED_HANDLERS can be defined in an ATL project implementing preview, thumbnail
8 | // and search filter handlers and allows sharing of document code with that project.
9 | #ifndef SHARED_HANDLERS
10 | #include "BigJsonTreeViewMfc.h"
11 | #endif
12 |
13 | #include "BigJsonTreeViewMfcDoc.h"
14 |
15 | #include
16 |
17 | #ifdef _DEBUG
18 | #define new DEBUG_NEW
19 | #endif
20 |
21 | // CBigJsonTreeViewMfcDoc
22 |
23 | IMPLEMENT_DYNCREATE(CBigJsonTreeViewMfcDoc, CDocument)
24 |
25 | BEGIN_MESSAGE_MAP(CBigJsonTreeViewMfcDoc, CDocument)
26 | END_MESSAGE_MAP()
27 |
28 |
29 | // CBigJsonTreeViewMfcDoc construction/destruction
30 |
31 | CBigJsonTreeViewMfcDoc::CBigJsonTreeViewMfcDoc() noexcept
32 | {
33 | // TODO: add one-time construction code here
34 |
35 | }
36 |
37 | CBigJsonTreeViewMfcDoc::~CBigJsonTreeViewMfcDoc()
38 | {
39 | }
40 |
41 | BOOL CBigJsonTreeViewMfcDoc::OnNewDocument()
42 | {
43 | if (!CDocument::OnNewDocument())
44 | return FALSE;
45 |
46 | // TODO: add reinitialization code here
47 | // (SDI documents will reuse this document)
48 |
49 | return TRUE;
50 | }
51 |
52 |
53 | #include "Bread/OpenFileManager.h"
54 |
55 | BOOL CBigJsonTreeViewMfcDoc::OnOpenDocument(LPCTSTR lpszPathName)
56 | {
57 | return gOpenFileManager.OpenFile(lpszPathName);
58 | }
59 |
60 | void CBigJsonTreeViewMfcDoc::OnCloseDocument()
61 | {
62 | gOpenFileManager.CloseFile(std::string(GetPathName()));
63 |
64 | CDocument::OnCloseDocument();
65 | }
66 |
67 | // CBigJsonTreeViewMfcDoc serialization
68 |
69 | void CBigJsonTreeViewMfcDoc::Serialize(CArchive& ar)
70 | {
71 | if (ar.IsStoring())
72 | {
73 | // TODO: add storing code here
74 | }
75 | else
76 | {
77 | // TODO: add loading code here
78 | }
79 | }
80 |
81 | #ifdef SHARED_HANDLERS
82 |
83 | // Support for thumbnails
84 | void CBigJsonTreeViewMfcDoc::OnDrawThumbnail(CDC& dc, LPRECT lprcBounds)
85 | {
86 | // Modify this code to draw the document's data
87 | dc.FillSolidRect(lprcBounds, RGB(255, 255, 255));
88 |
89 | CString strText = _T("TODO: implement thumbnail drawing here");
90 | LOGFONT lf;
91 |
92 | CFont* pDefaultGUIFont = CFont::FromHandle((HFONT) GetStockObject(DEFAULT_GUI_FONT));
93 | pDefaultGUIFont->GetLogFont(&lf);
94 | lf.lfHeight = 36;
95 |
96 | CFont fontDraw;
97 | fontDraw.CreateFontIndirect(&lf);
98 |
99 | CFont* pOldFont = dc.SelectObject(&fontDraw);
100 | dc.DrawText(strText, lprcBounds, DT_CENTER | DT_WORDBREAK);
101 | dc.SelectObject(pOldFont);
102 | }
103 |
104 | // Support for Search Handlers
105 | void CBigJsonTreeViewMfcDoc::InitializeSearchContent()
106 | {
107 | CString strSearchContent;
108 | // Set search contents from document's data.
109 | // The content parts should be separated by ";"
110 |
111 | // For example: strSearchContent = _T("point;rectangle;circle;ole object;");
112 | SetSearchContent(strSearchContent);
113 | }
114 |
115 | void CBigJsonTreeViewMfcDoc::SetSearchContent(const CString& value)
116 | {
117 | if (value.IsEmpty())
118 | {
119 | RemoveChunk(PKEY_Search_Contents.fmtid, PKEY_Search_Contents.pid);
120 | }
121 | else
122 | {
123 | CMFCFilterChunkValueImpl *pChunk = nullptr;
124 | ATLTRY(pChunk = new CMFCFilterChunkValueImpl);
125 | if (pChunk != nullptr)
126 | {
127 | pChunk->SetTextValue(PKEY_Search_Contents, value, CHUNK_TEXT);
128 | SetChunkValue(pChunk);
129 | }
130 | }
131 | }
132 |
133 | #endif // SHARED_HANDLERS
134 |
135 | // CBigJsonTreeViewMfcDoc diagnostics
136 |
137 | #ifdef _DEBUG
138 | void CBigJsonTreeViewMfcDoc::AssertValid() const
139 | {
140 | CDocument::AssertValid();
141 | }
142 |
143 | void CBigJsonTreeViewMfcDoc::Dump(CDumpContext& dc) const
144 | {
145 | CDocument::Dump(dc);
146 | }
147 | #endif //_DEBUG
148 |
149 |
150 | // CBigJsonTreeViewMfcDoc commands
151 |
--------------------------------------------------------------------------------
/src/BigJsonTreeViewMfcDoc.h:
--------------------------------------------------------------------------------
1 |
2 | // BigJsonTreeViewMfcDoc.h : interface of the CBigJsonTreeViewMfcDoc class
3 | //
4 |
5 |
6 | #pragma once
7 |
8 |
9 | class CBigJsonTreeViewMfcDoc : public CDocument
10 | {
11 | protected: // create from serialization only
12 | CBigJsonTreeViewMfcDoc() noexcept;
13 | DECLARE_DYNCREATE(CBigJsonTreeViewMfcDoc)
14 |
15 | // Attributes
16 | public:
17 |
18 | // Operations
19 | public:
20 |
21 | // Overrides
22 | public:
23 | virtual BOOL OnNewDocument();
24 | virtual void Serialize(CArchive& ar);
25 | BOOL OnOpenDocument(LPCTSTR lpszPathName) override;
26 | void OnCloseDocument() override;
27 | #ifdef SHARED_HANDLERS
28 | virtual void InitializeSearchContent();
29 | virtual void OnDrawThumbnail(CDC& dc, LPRECT lprcBounds);
30 | #endif // SHARED_HANDLERS
31 |
32 | // Implementation
33 | public:
34 | virtual ~CBigJsonTreeViewMfcDoc();
35 | #ifdef _DEBUG
36 | virtual void AssertValid() const;
37 | virtual void Dump(CDumpContext& dc) const;
38 | #endif
39 |
40 | protected:
41 |
42 | // Generated message map functions
43 | protected:
44 | DECLARE_MESSAGE_MAP()
45 |
46 | #ifdef SHARED_HANDLERS
47 | // Helper function that sets search content for a Search Handler
48 | void SetSearchContent(const CString& value);
49 | #endif // SHARED_HANDLERS
50 | };
51 |
--------------------------------------------------------------------------------
/src/BigJsonTreeViewMfcView.cpp:
--------------------------------------------------------------------------------
1 |
2 | // BigJsonTreeViewMfcView.cpp : implementation of the CBigJsonTreeViewMfcView class
3 | //
4 |
5 | #include "pch.h"
6 | #include "framework.h"
7 | // SHARED_HANDLERS can be defined in an ATL project implementing preview, thumbnail
8 | // and search filter handlers and allows sharing of document code with that project.
9 | #ifndef SHARED_HANDLERS
10 | #include "BigJsonTreeViewMfc.h"
11 | #endif
12 |
13 | #include "BigJsonTreeViewMfcDoc.h"
14 | #include "BigJsonTreeViewMfcView.h"
15 |
16 | #include "Bread/OpenFileManager.h"
17 | #include "Butter/JsonTreeViewController.h"
18 |
19 | #ifdef _DEBUG
20 | #define new DEBUG_NEW
21 | #endif
22 |
23 |
24 | // CBigJsonTreeViewMfcView
25 |
26 | IMPLEMENT_DYNCREATE(CBigJsonTreeViewMfcView, CView)
27 |
28 | BEGIN_MESSAGE_MAP(CBigJsonTreeViewMfcView, CView)
29 | ON_WM_CREATE()
30 | ON_WM_PAINT()
31 | ON_WM_SIZE()
32 | // Standard printing commands
33 | //ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)
34 | //ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
35 | //ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CBigJsonTreeViewMfcView::OnFilePrintPreview)
36 | ON_WM_CONTEXTMENU()
37 | ON_WM_RBUTTONUP()
38 | END_MESSAGE_MAP()
39 |
40 | // CBigJsonTreeViewMfcView construction/destruction
41 |
42 | CBigJsonTreeViewMfcView::CBigJsonTreeViewMfcView() noexcept
43 | {
44 | // TODO: add construction code here
45 |
46 | }
47 |
48 | CBigJsonTreeViewMfcView::~CBigJsonTreeViewMfcView()
49 | {
50 | gJsonTreeViewController.RemoveTreeCtrl(m_wndTreeView);
51 | }
52 |
53 | BOOL CBigJsonTreeViewMfcView::PreCreateWindow(CREATESTRUCT& cs)
54 | {
55 | // TODO: Modify the Window class or styles here by modifying
56 | // the CREATESTRUCT cs
57 |
58 | return CView::PreCreateWindow(cs);
59 | }
60 |
61 | // CBigJsonTreeViewMfcView drawing
62 |
63 | void CBigJsonTreeViewMfcView::OnDraw(CDC* pDC)
64 | {
65 | CView::OnDraw(pDC);
66 |
67 | CBigJsonTreeViewMfcDoc* pDoc = GetDocument();
68 | ASSERT_VALID(pDoc);
69 | if (!pDoc)
70 | return;
71 |
72 | // TODO: add draw code for native data here
73 | CPaintDC dc(this); // device context for painting
74 |
75 | CRect rectTree;
76 | m_wndTreeView.GetWindowRect(rectTree);
77 | ScreenToClient(rectTree);
78 |
79 | rectTree.InflateRect(1, 1);
80 | dc.Draw3dRect(rectTree, ::GetSysColor(COLOR_3DSHADOW), ::GetSysColor(COLOR_3DSHADOW));
81 | }
82 |
83 | void CBigJsonTreeViewMfcView::OnSize(UINT nType, int cx, int cy)
84 | {
85 | CView::OnSize(nType, cx, cy);
86 |
87 | CRect rectClient;
88 | GetClientRect(rectClient);
89 |
90 | m_wndTreeView.SetWindowPos(nullptr, rectClient.left + 1, rectClient.top + 1, rectClient.Width() - 2, rectClient.Height() - 2, SWP_NOACTIVATE | SWP_NOZORDER);
91 | }
92 |
93 | // CBigJsonTreeViewMfcView printing
94 |
95 |
96 | void CBigJsonTreeViewMfcView::OnFilePrintPreview()
97 | {
98 | #ifndef SHARED_HANDLERS
99 | AFXPrintPreview(this);
100 | #endif
101 | }
102 |
103 | int CBigJsonTreeViewMfcView::OnCreate(LPCREATESTRUCT lpCreateStruct)
104 | {
105 | if (CView::OnCreate(lpCreateStruct) == -1)
106 | return -1;
107 |
108 | CRect rectDummy;
109 | rectDummy.SetRectEmpty();
110 |
111 | // Create tree view:
112 | const DWORD dwViewStyle = WS_CHILD | WS_VISIBLE | TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS;
113 |
114 | if (!m_wndTreeView.Create(dwViewStyle, rectDummy, this, 12))
115 | {
116 | TRACE0("Failed to create file view\n");
117 | return -1; // fail to create
118 | }
119 |
120 | AdjustLayout();
121 |
122 | return 0;
123 | }
124 |
125 | void CBigJsonTreeViewMfcView::AdjustLayout()
126 | {
127 | if (GetSafeHwnd() == nullptr)
128 | {
129 | return;
130 | }
131 |
132 | CRect rectClient;
133 | GetClientRect(rectClient);
134 |
135 | //int cyTlb = m_wndToolBar.CalcFixedLayout(FALSE, TRUE).cy;
136 |
137 | //m_wndToolBar.SetWindowPos(nullptr, rectClient.left, rectClient.top, rectClient.Width(), cyTlb, SWP_NOACTIVATE | SWP_NOZORDER);
138 | m_wndTreeView.SetWindowPos(nullptr, rectClient.left + 1, rectClient.top + /*cyTlb +*/ 1, rectClient.Width() - 2, rectClient.Height() /*- cyTlb*/ - 2, SWP_NOACTIVATE | SWP_NOZORDER);
139 | }
140 |
141 | void CBigJsonTreeViewMfcView::OnPaint()
142 | {
143 | CPaintDC dc(this); // device context for painting
144 |
145 | CRect rectTree;
146 | m_wndTreeView.GetWindowRect(rectTree);
147 | ScreenToClient(rectTree);
148 |
149 | rectTree.InflateRect(1, 1);
150 | dc.Draw3dRect(rectTree, ::GetSysColor(COLOR_3DSHADOW), ::GetSysColor(COLOR_3DSHADOW));
151 | }
152 |
153 | void CBigJsonTreeViewMfcView::OnActivateView(BOOL bActivate, CView* pActivateView,
154 | CView* pDeactiveView)
155 | {
156 | gJsonTreeViewController.SetTreeCtrlForFile(
157 | std::string(GetDocument()->GetPathName()), m_wndTreeView);
158 | gOpenFileManager.SetActiveFile(std::string(GetDocument()->GetPathName()));
159 | }
160 |
161 | void CBigJsonTreeViewMfcView::OnRButtonUp(UINT /* nFlags */, CPoint point)
162 | {
163 | ClientToScreen(&point);
164 | OnContextMenu(this, point);
165 | }
166 |
167 | void CBigJsonTreeViewMfcView::OnContextMenu(CWnd* /* pWnd */, CPoint point)
168 | {
169 | #ifndef SHARED_HANDLERS
170 | theApp.GetContextMenuManager()->ShowPopupMenu(IDR_POPUP_EDIT, point.x, point.y, this, TRUE);
171 | #endif
172 | }
173 |
174 |
175 | // CBigJsonTreeViewMfcView diagnostics
176 |
177 | #ifdef _DEBUG
178 | void CBigJsonTreeViewMfcView::AssertValid() const
179 | {
180 | CView::AssertValid();
181 | }
182 |
183 | void CBigJsonTreeViewMfcView::Dump(CDumpContext& dc) const
184 | {
185 | CView::Dump(dc);
186 | }
187 |
188 | CBigJsonTreeViewMfcDoc* CBigJsonTreeViewMfcView::GetDocument() const // non-debug version is inline
189 | {
190 | ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CBigJsonTreeViewMfcDoc)));
191 | return (CBigJsonTreeViewMfcDoc*)m_pDocument;
192 | }
193 | #endif //_DEBUG
194 |
195 |
196 | // CBigJsonTreeViewMfcView message handlers
197 |
--------------------------------------------------------------------------------
/src/BigJsonTreeViewMfcView.h:
--------------------------------------------------------------------------------
1 |
2 | // BigJsonTreeViewMfcView.h : interface of the CBigJsonTreeViewMfcView class
3 | //
4 |
5 | #pragma once
6 |
7 | #include "ViewTree.h"
8 |
9 | class CBigJsonTreeViewMfcView : public CView
10 | {
11 | protected: // create from serialization only
12 | CBigJsonTreeViewMfcView() noexcept;
13 | DECLARE_DYNCREATE(CBigJsonTreeViewMfcView)
14 |
15 | // Attributes
16 | public:
17 | CBigJsonTreeViewMfcDoc* GetDocument() const;
18 |
19 | // Operations
20 | public:
21 |
22 | // Overrides
23 | public:
24 | virtual void OnDraw(CDC* pDC); // overridden to draw this view
25 | virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
26 | protected:
27 | afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
28 | afx_msg void OnPaint();
29 | afx_msg void OnSize(UINT nType, int cx, int cy);
30 | void OnActivateView(BOOL bActivate, CView* pActivateView,
31 | CView* pDeactiveView) override;
32 |
33 | void AdjustLayout();
34 |
35 | // Implementation
36 | public:
37 | virtual ~CBigJsonTreeViewMfcView();
38 | #ifdef _DEBUG
39 | virtual void AssertValid() const;
40 | virtual void Dump(CDumpContext& dc) const;
41 | #endif
42 |
43 | protected:
44 | CViewTree m_wndTreeView;
45 |
46 | // Generated message map functions
47 | protected:
48 | afx_msg void OnFilePrintPreview();
49 | afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
50 | afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
51 | DECLARE_MESSAGE_MAP()
52 | };
53 |
54 | #ifndef _DEBUG // debug version in BigJsonTreeViewMfcView.cpp
55 | inline CBigJsonTreeViewMfcDoc* CBigJsonTreeViewMfcView::GetDocument() const
56 | { return reinterpret_cast(m_pDocument); }
57 | #endif
58 |
59 |
--------------------------------------------------------------------------------
/src/Bread/FileLoader.cpp:
--------------------------------------------------------------------------------
1 | #include "FileLoader.h"
2 | #include "Butter/Log.h"
3 | #include "RapidJsonDomFileState.h"
4 | #include "Timer.h"
5 |
6 | #include
7 | #include
8 |
9 | #include
10 | #include
11 |
12 | // returns (unaligned 1-byte) null terminated buffer containing file contents on success
13 | // (there could also be nulls in the middle of the buffer)
14 | // returns empty buffer on failure
15 | std::vector ReadFileIntoBuffer(const std::filesystem::path& path)
16 | {
17 | // open the file
18 | HANDLE hFile = CreateFile(path.string().c_str(),
19 | GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
20 | if (hFile == INVALID_HANDLE_VALUE) {
21 | return {};
22 | }
23 |
24 | // preallocate the buffer
25 | DWORD dwFileSize = GetFileSize(hFile, NULL);
26 | std::vector buffer;
27 | buffer.resize(dwFileSize + 1);
28 |
29 | // read file into buffer
30 | DWORD dwBytesRead;
31 | if (!ReadFile(hFile, buffer.data(), dwFileSize, &dwBytesRead, NULL)) {
32 | buffer.clear();
33 | }
34 | else
35 | {
36 | if (dwBytesRead != dwFileSize)
37 | buffer.resize(dwBytesRead+1);
38 | buffer.back() = 0;
39 | }
40 |
41 | // close file
42 | CloseHandle(hFile);
43 | return buffer;
44 | }
45 |
46 | std::shared_ptr FileLoader::Load()
47 | {
48 | Log::Info(std::string() + "Loading " + m_Path.string().c_str());
49 |
50 | Timer timer;
51 |
52 | std::shared_ptr outFile = std::make_shared();
53 |
54 | outFile->m_Buffer = ReadFileIntoBuffer(m_Path);
55 |
56 | if (outFile->m_Buffer.empty())
57 | return Log::Error(std::string() + "Failed to open " + m_Path.string().c_str());
58 |
59 | Log::Info(std::format("Loaded in {:.2f}ms", timer.Ms()));
60 |
61 | rapidjson::ParseResult result;
62 |
63 | // insitu dom
64 | rapidjson::Document doc;
65 | result = outFile->m_Doc.ParseInsitu(
66 | outFile->m_Buffer.data());
67 |
68 |
69 | if (!result)
70 | return Log::Error(std::format("Parse failure at {}: {}", result.Offset(),
71 | GetParseError_En(result.Code())));
72 |
73 | Log::Info(std::format("Parsed in {:.2f}ms", timer.Ms()));
74 |
75 | return outFile;
76 | }
77 |
--------------------------------------------------------------------------------
/src/Bread/FileLoader.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 |
6 | struct JsonFile;
7 |
8 | class FileLoader
9 | {
10 | public:
11 | static std::shared_ptr Load(const std::filesystem::path& path) {
12 | return FileLoader(path).Load();
13 | }
14 |
15 | private:
16 | FileLoader(const std::filesystem::path& path) : m_Path(path) {}
17 |
18 | std::shared_ptr Load();
19 |
20 | private:
21 | // input
22 | const std::filesystem::path& m_Path;
23 | };
--------------------------------------------------------------------------------
/src/Bread/FileLoading.cpp:
--------------------------------------------------------------------------------
1 | #include "FileLoading.h"
2 | #include "FileLoader.h"
3 |
4 | static std::shared_ptr FileLoading::Load(const std::filesystem::path& path)
5 | {
6 | return FileLoader::Load(path);
7 | }
8 |
--------------------------------------------------------------------------------
/src/Bread/FileLoading.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | struct JsonFile;
6 |
7 | namespace FileLoading
8 | {
9 | static std::shared_ptr Load(const std::filesystem::path &path);
10 | }
--------------------------------------------------------------------------------
/src/Bread/FileState.cpp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/balagansky/BigJsonTreeViewer/bd3b1b0a2e6d57487d43d5bc9385fe5938e175fb/src/Bread/FileState.cpp
--------------------------------------------------------------------------------
/src/Bread/FileState.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | class JsonNode
10 | {
11 | public:
12 | virtual ~JsonNode() = default;
13 |
14 |
15 | };
16 |
17 | struct JsonFile
18 | {
19 | public:
20 | virtual ~JsonFile() = default;
21 |
22 | //virtual const JsonNode *GetRoot() const = 0;
23 | };
24 |
--------------------------------------------------------------------------------
/src/Bread/OpenFileManager.cpp:
--------------------------------------------------------------------------------
1 | #include "OpenFileManager.h"
2 | #include "FileLoader.h"
3 | #include "Butter/JsonTreeViewController.h"
4 |
5 | #include
6 | #include
7 |
8 | OpenFileManager gOpenFileManager;
9 |
10 | bool OpenFileManager::OpenFile(const std::filesystem::path& path)
11 | {
12 | if (auto loadedFile = FileLoader::Load(path))
13 | {
14 | OpenJsonFile openFile = {
15 | .filename = path.filename().string(),
16 | .path = path,
17 | .file{loadedFile}
18 | };
19 | m_OpenFiles.push_back(std::move(openFile));
20 | m_ActiveFile = &m_OpenFiles.back();
21 |
22 | gJsonTreeViewController.SetFile(*m_ActiveFile);
23 |
24 | return true;
25 | }
26 |
27 | return false;
28 | }
29 |
30 | void OpenFileManager::CloseFile(const std::filesystem::path& path)
31 | {
32 | auto foundOpenFile = std::ranges::find_if(m_OpenFiles,
33 | [&](const OpenJsonFile &file) { return path == file.path; });
34 |
35 | if (foundOpenFile == m_OpenFiles.end())
36 | return;
37 |
38 | gJsonTreeViewController.RemoveFile(*foundOpenFile);
39 |
40 | m_OpenFiles.erase(foundOpenFile);
41 |
42 | m_ActiveFile = nullptr;
43 | }
44 |
45 | void OpenFileManager::SetActiveFile(const std::filesystem::path& path)
46 | {
47 | if (m_ActiveFile && m_ActiveFile->path == path)
48 | return;
49 |
50 | for (const OpenJsonFile &file : m_OpenFiles) {
51 | if (file.path == path)
52 | m_ActiveFile = &file;
53 | }
54 |
55 | // no action for now
56 | /*if (m_ActiveFile)
57 | gJsonTreeViewController.Update(*m_ActiveFile);*/
58 | }
--------------------------------------------------------------------------------
/src/Bread/OpenFileManager.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | struct JsonFile;
9 |
10 | struct OpenJsonFile {
11 | std::string filename;
12 | std::filesystem::path path;
13 | std::shared_ptr file;
14 | };
15 |
16 | struct OpenFileManager
17 | {
18 | bool OpenFile(const std::filesystem::path &path);
19 | void CloseFile(const std::filesystem::path &path);
20 |
21 | void SetActiveFile(const std::filesystem::path &path);
22 |
23 | const OpenJsonFile *m_ActiveFile = nullptr;
24 | std::list m_OpenFiles;
25 | };
26 |
27 | extern OpenFileManager gOpenFileManager;
28 |
--------------------------------------------------------------------------------
/src/Bread/RapidJsonDomFileState.cpp:
--------------------------------------------------------------------------------
1 | #include "RapidJsonDomFileState.h"
--------------------------------------------------------------------------------
/src/Bread/RapidJsonDomFileState.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "FileState.h"
4 |
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 |
11 | #include
12 |
13 | struct RapidJsonDomNode
14 | {
15 | };
16 |
17 | class RapidJsonDomFile : public JsonFile
18 | {
19 | public:
20 |
21 | public:
22 | rapidjson::Document m_Doc;
23 | std::vector m_Buffer;
24 | };
25 |
--------------------------------------------------------------------------------
/src/Bread/Search.cpp:
--------------------------------------------------------------------------------
1 | #include "Search.h"
2 | #include "OpenFileManager.h"
3 | #include "Butter/Log.h"
4 | #include "RapidJsonDomFileState.h"
5 | #include "SearchResult.h"
6 | #include "Butter/SearchResults.h"
7 |
8 | #include
9 | #include
10 |
11 | class SearchHandler {
12 | using JsonSize = rapidjson::SizeType;
13 | public:
14 | SearchHandler(const std::string& searchString, bool exact,
15 | const std::filesystem::path& filePath)
16 | : m_SearchString(searchString), m_Exact(exact)
17 | {
18 | m_Current.filePath = filePath;
19 | }
20 |
21 | bool StartObject() {
22 | m_Current.path.emplace_back(); return true;
23 | }
24 | bool EndObject(JsonSize) {
25 | m_Current.path.pop_back(); Increment(); return true;
26 | }
27 | bool Key(const char* key, JsonSize len, bool) {
28 | m_Current.path.back().SetKey(key); return CheckMatch({ key, len }, false);
29 | }
30 | bool StartArray() {
31 | InitPath(); m_Current.path.back().indices.emplace_back(); return true;
32 | }
33 | bool EndArray(JsonSize) {
34 | m_Current.path.back().indices.pop_back();
35 | Increment(); return true;
36 | }
37 | bool String(const char* str, JsonSize len, bool) {
38 | InitPath();
39 | bool shouldContinue = CheckMatch({ str,len }, true);
40 | Increment();
41 | return shouldContinue;
42 | }
43 |
44 | #define JTV_IGNORE(func, type) bool func(type) { InitPath(); Increment(); return true; }
45 | JTV_IGNORE(Null, );
46 | JTV_IGNORE(Bool, bool);
47 | JTV_IGNORE(Double, double);
48 | JTV_IGNORE(Int, int);
49 | JTV_IGNORE(Uint, unsigned);
50 | JTV_IGNORE(Int64, int64_t);
51 | JTV_IGNORE(Uint64, uint64_t);
52 |
53 | private:
54 | void InitPath() {
55 | // TODO: avoid the need for this by handling single-value file cases up front
56 | if (m_Current.path.empty())
57 | m_Current.path.emplace_back();
58 | }
59 | void Increment() {
60 | if (m_Current.path.empty())
61 | return;
62 | auto& indices = m_Current.path.back().indices;
63 | if (!indices.empty())
64 | ++indices.back();
65 | }
66 | bool CheckMatch(std::string_view fileStr, bool isValue)
67 | {
68 | bool matches = m_Exact
69 | ? fileStr == m_SearchString
70 | : fileStr.find(m_SearchString) != std::string_view::npos;
71 | if (!matches)
72 | return true;
73 |
74 | if (isValue)
75 | m_Current.value = fileStr;
76 |
77 | std::ranges::for_each(m_Current.path, &SearchResult::Frame::Bake);
78 | return SearchResults::AddResult(m_Current);
79 | }
80 |
81 | private:
82 | SearchResult m_Current;
83 | const std::string& m_SearchString;
84 | bool m_Exact;
85 | };
86 |
87 | void Search(const std::string& searchString, bool exact)
88 | {
89 | const OpenJsonFile* activeFile = gOpenFileManager.m_ActiveFile;
90 |
91 | if (!activeFile)
92 | {
93 | assert(false);
94 | Log::Error("Can't search - no active file.");
95 | return;
96 | }
97 |
98 | const RapidJsonDomFile& domFile = static_cast(*activeFile->file);
99 |
100 | SearchHandler searchHandler(searchString, exact, activeFile->path);
101 |
102 | SearchResults::SearchStarted(searchString.c_str());
103 | domFile.m_Doc.Accept(searchHandler);
104 | SearchResults::SearchFinished();
105 | }
106 |
--------------------------------------------------------------------------------
/src/Bread/Search.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | void Search(const std::string &searchString, bool exact);
6 |
--------------------------------------------------------------------------------
/src/Bread/SearchResult.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | // represents a location in a JSON file
9 | struct SearchResult {
10 | using JsonSize = unsigned int; // same as rapidjson::SizeType
11 | struct Frame {
12 | void SetKey(const char *key) { this->key = key; }
13 | void Bake() { keyStr = key; }
14 |
15 | const char* Key() const { return keyStr.empty() ? key : keyStr.c_str(); }
16 | std::vector indices; // size > 1 in case of nested arrays
17 | private:
18 | const char* key = "";
19 | std::string keyStr;
20 | };
21 | std::vector path;
22 | std::string value;
23 |
24 | std::filesystem::path filePath;
25 | };
26 |
--------------------------------------------------------------------------------
/src/Bread/Timer.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | struct Timer {
6 | Timer() {
7 | m_Start = std::chrono::high_resolution_clock::now();
8 | }
9 |
10 | void Reset() { m_Start = std::chrono::high_resolution_clock::now(); }
11 |
12 | double Ms(bool reset = true)
13 | {
14 | auto now = std::chrono::high_resolution_clock::now();
15 | double ms = std::chrono::duration(
16 | std::chrono::high_resolution_clock::now() - m_Start).count() * 1000;
17 | if (reset)
18 | m_Start = now;
19 | return ms;
20 | }
21 |
22 | decltype(std::chrono::high_resolution_clock::now()) m_Start;
23 | };
--------------------------------------------------------------------------------
/src/Bread/Utils.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | namespace Utils
6 | {
7 | // tries to find key in associative container
8 | // returns std::optional
9 | auto Lookup(const auto& container, auto&& key) {
10 | auto findResult = container.find(std::forward(key));
11 | if (findResult == container.end())
12 | return decltype(std::optional{findResult->second})(std::nullopt);
13 |
14 | return std::optional{ findResult->second };
15 | }
16 |
17 | // tries to find an item in a sequence by predicate
18 | // returns std::optional
19 | auto FindIf(const auto &seq, auto &&pred) {
20 | auto findResult = std::ranges::find_if(seq, pred);
21 | if (findResult == seq.end())
22 | return decltype(std::optional{*findResult})(std::nullopt);
23 |
24 | return std::optional{ *findResult };
25 | }
26 |
27 | bool InRange(auto val, auto min, auto max) {
28 | return val >= min && val <= max;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/Butter/JsonTreeViewController.cpp:
--------------------------------------------------------------------------------
1 | #include "JsonTreeViewController.h"
2 | #include "JsonTreeViewControllerImpl.h"
3 |
4 | JsonTreeViewController gJsonTreeViewController;
5 |
6 | JsonTreeViewController::JsonTreeViewController()
7 | {
8 | m_Impl = std::make_shared();
9 | }
10 |
11 | void JsonTreeViewController::SetTreeCtrlForFile(
12 | const std::filesystem::path &path, CViewTree &treeCtrl)
13 | {
14 | m_Impl->SetTreeCtrlForFile(path, treeCtrl);
15 | }
16 |
17 | void JsonTreeViewController::SetFile(const OpenJsonFile &file)
18 | {
19 | m_Impl->SetFile(file);
20 | }
21 |
22 | void JsonTreeViewController::RemoveFile(const OpenJsonFile &file)
23 | {
24 | m_Impl->RemoveFile(file);
25 | }
26 |
27 | void JsonTreeViewController::RemoveTreeCtrl(CViewTree &treeCtrl)
28 | {
29 | m_Impl->RemoveTreeCtrl(treeCtrl);
30 | }
31 |
32 | void JsonTreeViewController::ExpandItem(CViewTree &treeCtrl, HTREEITEM item)
33 | {
34 | m_Impl->ExpandItem(treeCtrl, item);
35 | }
36 |
37 | void JsonTreeViewController::SelectSearchResult(const SearchResult &searchResult)
38 | {
39 | m_Impl->SelectSearchResult(searchResult);
40 | }
41 |
--------------------------------------------------------------------------------
/src/Butter/JsonTreeViewController.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 |
7 | struct OpenJsonFile;
8 | class CViewTree;
9 | class JsonTreeViewControllerImpl;
10 | struct SearchResult;
11 |
12 | class JsonTreeViewController
13 | {
14 | public:
15 | JsonTreeViewController();
16 |
17 | void SetTreeCtrlForFile(const std::filesystem::path &path, CViewTree &treeCtrl);
18 | void SetFile(const OpenJsonFile &file);
19 |
20 | void RemoveFile(const OpenJsonFile &file);
21 | void RemoveTreeCtrl(CViewTree &treeCtrl);
22 |
23 | void ExpandItem(CViewTree &treeCtrl, HTREEITEM item);
24 |
25 | void SelectSearchResult(const SearchResult &searchResult);
26 |
27 | private:
28 | std::shared_ptr m_Impl;
29 | };
30 |
31 | extern JsonTreeViewController gJsonTreeViewController;
32 |
--------------------------------------------------------------------------------
/src/Butter/JsonTreeViewControllerImpl.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "rapidjson/document.h"
4 |
5 | #include
6 | #include
7 | #include
8 |
9 | struct OpenJsonFile;
10 | class CViewTree;
11 | struct SearchResult;
12 |
13 | class JsonTreeViewControllerImpl
14 | {
15 | friend class JsonTreeViewController;
16 |
17 | void SetTreeCtrlForFile(const std::filesystem::path& path, CViewTree& treeCtrl);
18 | void SetFile(const OpenJsonFile& file);
19 |
20 | void RemoveFile(const OpenJsonFile& file);
21 | void RemoveTreeCtrl(CViewTree& treeCtrl);
22 |
23 | void ExpandItem(CViewTree& treeCtrl, HTREEITEM item,
24 | std::optional index = {});
25 |
26 | void SelectSearchResult(const SearchResult& searchResult);
27 |
28 | private:
29 | struct File;
30 | void InitTree(File& file);
31 |
32 | private:
33 |
34 | private:
35 | struct ExpandableItem {
36 | struct Value {
37 | struct Range {
38 | rapidjson::SizeType start;
39 | rapidjson::SizeType end; // exclusive
40 | };
41 | const rapidjson::Value* value;
42 | std::optional arrayRange;
43 | };
44 |
45 | Value value;
46 | HTREEITEM placeholder;
47 | };
48 |
49 | struct File {
50 | void AddValue(const rapidjson::Value& value, HTREEITEM parent);
51 | HTREEITEM AddRange(HTREEITEM parent, rapidjson::SizeType start, rapidjson::SizeType end,
52 | const rapidjson::Value& value, HTREEITEM where = TVI_LAST);
53 | void AddArrayValues(rapidjson::Value::ConstArray array, rapidjson::SizeType start,
54 | rapidjson::SizeType end, HTREEITEM parent, HTREEITEM where = TVI_LAST);
55 | void MakeExpandable(HTREEITEM item, ExpandableItem::Value expansionValue);
56 |
57 | bool m_Initialized = false;
58 | CViewTree* m_TreeCtrl = nullptr;
59 | const OpenJsonFile* m_File = nullptr;
60 | std::unordered_map m_ExpandableItems;
61 | std::unordered_map m_ArrayMemberItems;
62 | std::unordered_map > m_JsonValueToTreeItems;
63 | };
64 | std::unordered_map m_Files;
65 | };
66 |
67 |
--------------------------------------------------------------------------------
/src/Butter/Log.cpp:
--------------------------------------------------------------------------------
1 | #include "Log.h"
2 | #include "LoggerImpl.h"
3 |
4 | Log::DefaultAny Log::Info(const std::string& msg)
5 | {
6 | if (LoggerHooks::gWriteLineFn)
7 | LoggerHooks::gWriteLineFn(msg.c_str());
8 | return {};
9 | }
10 |
11 | Log::DefaultAny Log::Error(const std::string& msg)
12 | {
13 | return Info(std::string("ERROR: ") + msg);
14 | }
15 |
16 | bool Log::Invariant(bool check, const char* msg)
17 | {
18 | if (!check && LoggerHooks::gWriteLineFn)
19 | Info((std::string("ASSERTION ERROR: ") + msg
20 | + " This is a bug - please report it (provide a repro if you can)!"));
21 |
22 | return check;
23 | }
24 |
--------------------------------------------------------------------------------
/src/Butter/Log.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | namespace Log
6 | {
7 | // for convenience, these always return false
8 | struct DefaultAny {
9 | template
10 | operator T() { return {}; }
11 | };
12 |
13 | DefaultAny Info(const std::string &msg);
14 | DefaultAny Error(const std::string &msg);
15 |
16 | // asserts check and prints msg followed by direction to report the issue
17 | // returns check
18 | bool Invariant(bool check, const char *msg);
19 | }
20 |
--------------------------------------------------------------------------------
/src/Butter/LoggerImpl.cpp:
--------------------------------------------------------------------------------
1 | #include "LoggerImpl.h"
2 |
3 | namespace LoggerHooks {
4 | std::function gWriteLineFn;
5 | }
6 |
--------------------------------------------------------------------------------
/src/Butter/LoggerImpl.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | namespace LoggerHooks {
6 | // must be set externally
7 | extern std::function gWriteLineFn;
8 | }
9 |
--------------------------------------------------------------------------------
/src/Butter/SearchPrompt.cpp:
--------------------------------------------------------------------------------
1 | #include "SearchPrompt.h"
2 |
3 | #include "FindDialog.h"
4 | #include "Bread/Search.h"
5 | #include "Bread/OpenFileManager.h"
6 |
7 | void PromptSearch()
8 | {
9 | if (!gOpenFileManager.m_ActiveFile)
10 | return; // TODO: prevent this from being called in the first place in this case
11 |
12 | FindDialog findDlg;
13 | findDlg.DoModal();
14 |
15 | if (findDlg.m_Confirmed)
16 | Search(findDlg.m_SearchString.GetString(),
17 | findDlg.m_Exact == BST_CHECKED);
18 | }
19 |
--------------------------------------------------------------------------------
/src/Butter/SearchPrompt.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | void PromptSearch();
6 |
--------------------------------------------------------------------------------
/src/Butter/SearchResults.cpp:
--------------------------------------------------------------------------------
1 | #include "SearchResults.h"
2 | #include "JsonTreeViewController.h"
3 | #include "Bread/SearchResult.h"
4 |
5 | #include
6 |
7 | namespace {
8 | unsigned int gCurrentResultCount = 0;
9 | constexpr unsigned int cMaxResults = 100;
10 |
11 | SearchResults::SearchResultCallbacks gCallbacks;
12 |
13 | std::unordered_map gSearchResults;
14 | }
15 |
16 | void SearchResults::SetCallbacks(SearchResultCallbacks callbacks)
17 | {
18 | gCallbacks = std::move(callbacks);
19 | }
20 |
21 | void SearchResults::SearchStarted(const char* searchString)
22 | {
23 | gCurrentResultCount = 0;
24 | gSearchResults.clear();
25 | gCallbacks.clear();
26 | gCallbacks.focus();
27 | gCallbacks.addLine(std::format("Searching for \"{}\"...", searchString).c_str());
28 | }
29 |
30 | void SearchResults::SearchFinished() {
31 | if (gCurrentResultCount < cMaxResults)
32 | gCallbacks.addLine("Search finished.");
33 | }
34 |
35 | bool SearchResults::AddResult(const SearchResult& searchResult)
36 | {
37 | if (++gCurrentResultCount > cMaxResults)
38 | {
39 | gCallbacks.addLine("Max result display exceeded. Stopping search.");
40 | return false;
41 | }
42 |
43 | std::string str;
44 | for (const SearchResult::Frame& frame : searchResult.path)
45 | {
46 | if (!str.empty())
47 | str += " : ";
48 |
49 | if (*frame.Key())
50 | str += std::string() + '\"' + frame.Key() + '\"';
51 |
52 | for (auto index : frame.indices)
53 | str += std::format("[{}]", index);
54 | }
55 |
56 | if (!searchResult.value.empty())
57 | str += std::format(" : {}", searchResult.value);
58 |
59 | gSearchResults[gCallbacks.addLine(str.c_str())] = searchResult;
60 |
61 | return true;
62 | }
63 |
64 | void SearchResults::SelectResultLine(int line)
65 | {
66 | if (gSearchResults.contains(line))
67 | gJsonTreeViewController.SelectSearchResult(gSearchResults.at(line));
68 | }
69 |
--------------------------------------------------------------------------------
/src/Butter/SearchResults.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | struct SearchResult;
6 |
7 | namespace SearchResults {
8 |
9 | struct SearchResultCallbacks {
10 | std::function clear;
11 | std::function focus;
12 | std::function addLine;
13 | };
14 | void SetCallbacks(SearchResultCallbacks callbacks);
15 |
16 | void SearchStarted(const char* searchString);
17 | // returns false if no more results can be accepted
18 | bool AddResult(const SearchResult& searchResult);
19 | void SearchFinished();
20 |
21 | void SelectResultLine(int line);
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/src/ChildFrm.cpp:
--------------------------------------------------------------------------------
1 |
2 | // ChildFrm.cpp : implementation of the CChildFrame class
3 | //
4 |
5 | #include "pch.h"
6 | #include "framework.h"
7 | #include "BigJsonTreeViewMfc.h"
8 |
9 | #include "ChildFrm.h"
10 |
11 | #ifdef _DEBUG
12 | #define new DEBUG_NEW
13 | #endif
14 |
15 | // CChildFrame
16 |
17 | IMPLEMENT_DYNCREATE(CChildFrame, CMDIChildWndEx)
18 |
19 | BEGIN_MESSAGE_MAP(CChildFrame, CMDIChildWndEx)
20 | END_MESSAGE_MAP()
21 |
22 | // CChildFrame construction/destruction
23 |
24 | CChildFrame::CChildFrame() noexcept
25 | {
26 | // TODO: add member initialization code here
27 | }
28 |
29 | CChildFrame::~CChildFrame()
30 | {
31 | }
32 |
33 |
34 | BOOL CChildFrame::PreCreateWindow(CREATESTRUCT& cs)
35 | {
36 | // TODO: Modify the Window class or styles here by modifying the CREATESTRUCT cs
37 | if( !CMDIChildWndEx::PreCreateWindow(cs) )
38 | return FALSE;
39 |
40 | return TRUE;
41 | }
42 |
43 | // CChildFrame diagnostics
44 |
45 | #ifdef _DEBUG
46 | void CChildFrame::AssertValid() const
47 | {
48 | CMDIChildWndEx::AssertValid();
49 | }
50 |
51 | void CChildFrame::Dump(CDumpContext& dc) const
52 | {
53 | CMDIChildWndEx::Dump(dc);
54 | }
55 | #endif //_DEBUG
56 |
57 | // CChildFrame message handlers
58 |
--------------------------------------------------------------------------------
/src/ChildFrm.h:
--------------------------------------------------------------------------------
1 |
2 | // ChildFrm.h : interface of the CChildFrame class
3 | //
4 |
5 | #pragma once
6 |
7 | class CChildFrame : public CMDIChildWndEx
8 | {
9 | DECLARE_DYNCREATE(CChildFrame)
10 | public:
11 | CChildFrame() noexcept;
12 |
13 | // Attributes
14 | protected:
15 | CSplitterWndEx m_wndSplitter;
16 | public:
17 |
18 | // Operations
19 | public:
20 |
21 | // Overrides
22 | virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
23 |
24 | // Implementation
25 | public:
26 | virtual ~CChildFrame();
27 | #ifdef _DEBUG
28 | virtual void AssertValid() const;
29 | virtual void Dump(CDumpContext& dc) const;
30 | #endif
31 |
32 | // Generated message map functions
33 | protected:
34 | DECLARE_MESSAGE_MAP()
35 | };
36 |
--------------------------------------------------------------------------------
/src/ClassView.h:
--------------------------------------------------------------------------------
1 |
2 | #pragma once
3 |
4 | #include "ViewTree.h"
5 |
6 | class CClassToolBar : public CMFCToolBar
7 | {
8 | virtual void OnUpdateCmdUI(CFrameWnd* /*pTarget*/, BOOL bDisableIfNoHndler)
9 | {
10 | CMFCToolBar::OnUpdateCmdUI((CFrameWnd*) GetOwner(), bDisableIfNoHndler);
11 | }
12 |
13 | virtual BOOL AllowShowOnList() const { return FALSE; }
14 | };
15 |
16 | class CClassView : public CDockablePane
17 | {
18 | public:
19 | CClassView() noexcept;
20 | virtual ~CClassView();
21 |
22 | void AdjustLayout();
23 | void OnChangeVisualStyle();
24 |
25 | protected:
26 | CClassToolBar m_wndToolBar;
27 | CViewTree m_wndClassView;
28 | CImageList m_ClassViewImages;
29 | UINT m_nCurrSort;
30 |
31 | void FillClassView();
32 |
33 | // Overrides
34 | public:
35 | virtual BOOL PreTranslateMessage(MSG* pMsg);
36 |
37 | protected:
38 | afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
39 | afx_msg void OnSize(UINT nType, int cx, int cy);
40 | afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
41 | afx_msg void OnClassAddMemberFunction();
42 | afx_msg void OnClassAddMemberVariable();
43 | afx_msg void OnClassDefinition();
44 | afx_msg void OnClassProperties();
45 | afx_msg void OnNewFolder();
46 | afx_msg void OnPaint();
47 | afx_msg void OnSetFocus(CWnd* pOldWnd);
48 | afx_msg LRESULT OnChangeActiveTab(WPARAM, LPARAM);
49 | afx_msg void OnSort(UINT id);
50 | afx_msg void OnUpdateSort(CCmdUI* pCmdUI);
51 |
52 | DECLARE_MESSAGE_MAP()
53 | };
54 |
55 |
--------------------------------------------------------------------------------
/src/FileView.cpp:
--------------------------------------------------------------------------------
1 |
2 | #include "pch.h"
3 | #include "framework.h"
4 | #include "mainfrm.h"
5 | #include "FileView.h"
6 | #include "Resource.h"
7 | #include "BigJsonTreeViewMfc.h"
8 |
9 | #include "Butter/JsonTreeViewController.h"
10 |
11 | #ifdef _DEBUG
12 | #undef THIS_FILE
13 | static char THIS_FILE[]=__FILE__;
14 | #define new DEBUG_NEW
15 | #endif
16 |
17 | /////////////////////////////////////////////////////////////////////////////
18 | // CFileView
19 |
20 | CFileView::CFileView() noexcept
21 | {
22 | }
23 |
24 | CFileView::~CFileView()
25 | {
26 | //gJsonTreeViewController.SetTreeCtrl(m_wndFileView);
27 | }
28 |
29 | BEGIN_MESSAGE_MAP(CFileView, CDockablePane)
30 | ON_WM_CREATE()
31 | ON_WM_SIZE()
32 | //ON_WM_CONTEXTMENU()
33 | ON_COMMAND(ID_PROPERTIES, OnProperties)
34 | ON_COMMAND(ID_OPEN, OnFileOpen)
35 | ON_COMMAND(ID_OPEN_WITH, OnFileOpenWith)
36 | ON_COMMAND(ID_DUMMY_COMPILE, OnDummyCompile)
37 | ON_COMMAND(ID_EDIT_CUT, OnEditCut)
38 | ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
39 | ON_COMMAND(ID_EDIT_CLEAR, OnEditClear)
40 | ON_WM_PAINT()
41 | ON_WM_SETFOCUS()
42 | END_MESSAGE_MAP()
43 |
44 | /////////////////////////////////////////////////////////////////////////////
45 | // CWorkspaceBar message handlers
46 |
47 | int CFileView::OnCreate(LPCREATESTRUCT lpCreateStruct)
48 | {
49 | if (CDockablePane::OnCreate(lpCreateStruct) == -1)
50 | return -1;
51 |
52 | CRect rectDummy;
53 | rectDummy.SetRectEmpty();
54 |
55 | // Create view:
56 | const DWORD dwViewStyle = WS_CHILD | WS_VISIBLE | TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS;
57 |
58 | if (!m_wndFileView.Create(dwViewStyle, rectDummy, this, 4))
59 | {
60 | TRACE0("Failed to create file view\n");
61 | return -1; // fail to create
62 | }
63 |
64 | // Load view images:
65 | m_FileViewImages.Create(IDB_FILE_VIEW, 16, 0, RGB(255, 0, 255));
66 | m_wndFileView.SetImageList(&m_FileViewImages, TVSIL_NORMAL);
67 |
68 | m_wndToolBar.Create(this, AFX_DEFAULT_TOOLBAR_STYLE, IDR_EXPLORER);
69 | m_wndToolBar.LoadToolBar(IDR_EXPLORER, 0, 0, TRUE /* Is locked */);
70 |
71 | OnChangeVisualStyle();
72 |
73 | m_wndToolBar.SetPaneStyle(m_wndToolBar.GetPaneStyle() | CBRS_TOOLTIPS | CBRS_FLYBY);
74 |
75 | m_wndToolBar.SetPaneStyle(m_wndToolBar.GetPaneStyle() & ~(CBRS_GRIPPER | CBRS_SIZE_DYNAMIC | CBRS_BORDER_TOP | CBRS_BORDER_BOTTOM | CBRS_BORDER_LEFT | CBRS_BORDER_RIGHT));
76 |
77 | m_wndToolBar.SetOwner(this);
78 |
79 | // All commands will be routed via this control , not via the parent frame:
80 | m_wndToolBar.SetRouteCommandsViaFrame(FALSE);
81 |
82 | // Fill in some static tree view data (dummy code, nothing magic here)
83 | FillFileView();
84 | AdjustLayout();
85 |
86 | //gJsonTreeViewController.SetTreeCtrl(m_wndFileView);
87 |
88 | return 0;
89 | }
90 |
91 | void CFileView::OnSize(UINT nType, int cx, int cy)
92 | {
93 | CDockablePane::OnSize(nType, cx, cy);
94 | AdjustLayout();
95 | }
96 |
97 | void CFileView::FillFileView()
98 | {
99 | HTREEITEM hRoot = m_wndFileView.InsertItem(_T("Open a JSON file to begin..."), 0, 0);
100 | HTREEITEM hChild = m_wndFileView.InsertItem("data will appear", 0, 0, hRoot);
101 | m_wndFileView.InsertItem("here", 1, 1, hChild);
102 |
103 | m_wndFileView.Expand(hRoot, TVE_EXPAND);
104 | m_wndFileView.Expand(hChild, TVE_EXPAND);
105 |
106 |
107 | /*HTREEITEM hRoot = m_wndFileView.InsertItem(_T("FakeApp files"), 0, 0);
108 | m_wndFileView.SetItemState(hRoot, TVIS_BOLD, TVIS_BOLD);
109 |
110 | HTREEITEM hSrc = m_wndFileView.InsertItem(_T("FakeApp Source Files"), 0, 0, hRoot);
111 |
112 | m_wndFileView.InsertItem(_T("FakeApp.cpp"), 1, 1, hSrc);
113 | m_wndFileView.InsertItem(_T("FakeApp.rc"), 1, 1, hSrc);
114 | m_wndFileView.InsertItem(_T("FakeAppDoc.cpp"), 1, 1, hSrc);
115 | m_wndFileView.InsertItem(_T("FakeAppView.cpp"), 1, 1, hSrc);
116 | m_wndFileView.InsertItem(_T("MainFrm.cpp"), 1, 1, hSrc);
117 | m_wndFileView.InsertItem(_T("pch.cpp"), 1, 1, hSrc);
118 |
119 | HTREEITEM hInc = m_wndFileView.InsertItem(_T("FakeApp Header Files"), 0, 0, hRoot);
120 |
121 | m_wndFileView.InsertItem(_T("FakeApp.h"), 2, 2, hInc);
122 | m_wndFileView.InsertItem(_T("FakeAppDoc.h"), 2, 2, hInc);
123 | m_wndFileView.InsertItem(_T("FakeAppView.h"), 2, 2, hInc);
124 | m_wndFileView.InsertItem(_T("Resource.h"), 2, 2, hInc);
125 | m_wndFileView.InsertItem(_T("MainFrm.h"), 2, 2, hInc);
126 | m_wndFileView.InsertItem(_T("pch.h"), 2, 2, hInc);
127 |
128 | HTREEITEM hRes = m_wndFileView.InsertItem(_T("FakeApp Resource Files"), 0, 0, hRoot);
129 |
130 | m_wndFileView.InsertItem(_T("FakeApp.ico"), 2, 2, hRes);
131 | m_wndFileView.InsertItem(_T("FakeApp.rc2"), 2, 2, hRes);
132 | m_wndFileView.InsertItem(_T("FakeAppDoc.ico"), 2, 2, hRes);
133 | m_wndFileView.InsertItem(_T("FakeToolbar.bmp"), 2, 2, hRes);
134 |
135 | m_wndFileView.Expand(hRoot, TVE_EXPAND);
136 | m_wndFileView.Expand(hSrc, TVE_EXPAND);
137 | m_wndFileView.Expand(hInc, TVE_EXPAND);*/
138 | }
139 |
140 | void CFileView::OnContextMenu(CWnd* pWnd, CPoint point)
141 | {
142 | CTreeCtrl* pWndTree = (CTreeCtrl*) &m_wndFileView;
143 | ASSERT_VALID(pWndTree);
144 |
145 | if (pWnd != pWndTree)
146 | {
147 | CDockablePane::OnContextMenu(pWnd, point);
148 | return;
149 | }
150 |
151 | if (point != CPoint(-1, -1))
152 | {
153 | // Select clicked item:
154 | CPoint ptTree = point;
155 | pWndTree->ScreenToClient(&ptTree);
156 |
157 | UINT flags = 0;
158 | HTREEITEM hTreeItem = pWndTree->HitTest(ptTree, &flags);
159 | if (hTreeItem != nullptr)
160 | {
161 | pWndTree->SelectItem(hTreeItem);
162 | }
163 | }
164 |
165 | pWndTree->SetFocus();
166 | theApp.GetContextMenuManager()->ShowPopupMenu(IDR_POPUP_EXPLORER, point.x, point.y, this, TRUE);
167 | }
168 |
169 | void CFileView::AdjustLayout()
170 | {
171 | if (GetSafeHwnd() == nullptr)
172 | {
173 | return;
174 | }
175 |
176 | CRect rectClient;
177 | GetClientRect(rectClient);
178 |
179 | //int cyTlb = m_wndToolBar.CalcFixedLayout(FALSE, TRUE).cy;
180 |
181 | //m_wndToolBar.SetWindowPos(nullptr, rectClient.left, rectClient.top, rectClient.Width(), cyTlb, SWP_NOACTIVATE | SWP_NOZORDER);
182 | m_wndFileView.SetWindowPos(nullptr, rectClient.left + 1, rectClient.top + /*cyTlb +*/ 1, rectClient.Width() - 2, rectClient.Height() /*- cyTlb*/ - 2, SWP_NOACTIVATE | SWP_NOZORDER);
183 | }
184 |
185 | void CFileView::OnProperties()
186 | {
187 | AfxMessageBox(_T("Properties...."));
188 |
189 | }
190 |
191 | void CFileView::OnFileOpen()
192 | {
193 | // TODO: Add your command handler code here
194 | }
195 |
196 | void CFileView::OnFileOpenWith()
197 | {
198 | // TODO: Add your command handler code here
199 | }
200 |
201 | void CFileView::OnDummyCompile()
202 | {
203 | // TODO: Add your command handler code here
204 | }
205 |
206 | void CFileView::OnEditCut()
207 | {
208 | // TODO: Add your command handler code here
209 | }
210 |
211 | void CFileView::OnEditCopy()
212 | {
213 | // TODO: Add your command handler code here
214 | }
215 |
216 | void CFileView::OnEditClear()
217 | {
218 | // TODO: Add your command handler code here
219 | }
220 |
221 | void CFileView::OnPaint()
222 | {
223 | CPaintDC dc(this); // device context for painting
224 |
225 | CRect rectTree;
226 | m_wndFileView.GetWindowRect(rectTree);
227 | ScreenToClient(rectTree);
228 |
229 | rectTree.InflateRect(1, 1);
230 | dc.Draw3dRect(rectTree, ::GetSysColor(COLOR_3DSHADOW), ::GetSysColor(COLOR_3DSHADOW));
231 | }
232 |
233 | void CFileView::OnSetFocus(CWnd* pOldWnd)
234 | {
235 | CDockablePane::OnSetFocus(pOldWnd);
236 |
237 | m_wndFileView.SetFocus();
238 | }
239 |
240 | void CFileView::OnChangeVisualStyle()
241 | {
242 | m_wndToolBar.CleanUpLockedImages();
243 | m_wndToolBar.LoadBitmap(theApp.m_bHiColorIcons ? IDB_EXPLORER_24 : IDR_EXPLORER, 0, 0, TRUE /* Locked */);
244 |
245 | m_FileViewImages.DeleteImageList();
246 |
247 | UINT uiBmpId = theApp.m_bHiColorIcons ? IDB_FILE_VIEW_24 : IDB_FILE_VIEW;
248 |
249 | CBitmap bmp;
250 | if (!bmp.LoadBitmap(uiBmpId))
251 | {
252 | TRACE(_T("Can't load bitmap: %x\n"), uiBmpId);
253 | ASSERT(FALSE);
254 | return;
255 | }
256 |
257 | BITMAP bmpObj;
258 | bmp.GetBitmap(&bmpObj);
259 |
260 | UINT nFlags = ILC_MASK;
261 |
262 | nFlags |= (theApp.m_bHiColorIcons) ? ILC_COLOR24 : ILC_COLOR4;
263 |
264 | m_FileViewImages.Create(16, bmpObj.bmHeight, nFlags, 0, 0);
265 | m_FileViewImages.Add(&bmp, RGB(255, 0, 255));
266 |
267 | m_wndFileView.SetImageList(&m_FileViewImages, TVSIL_NORMAL);
268 | }
269 |
270 |
271 |
--------------------------------------------------------------------------------
/src/FileView.h:
--------------------------------------------------------------------------------
1 |
2 | #pragma once
3 |
4 | #include "ViewTree.h"
5 |
6 | class CFileViewToolBar : public CMFCToolBar
7 | {
8 | virtual void OnUpdateCmdUI(CFrameWnd* /*pTarget*/, BOOL bDisableIfNoHndler)
9 | {
10 | CMFCToolBar::OnUpdateCmdUI((CFrameWnd*) GetOwner(), bDisableIfNoHndler);
11 | }
12 |
13 | virtual BOOL AllowShowOnList() const { return FALSE; }
14 | };
15 |
16 | class CFileView : public CDockablePane
17 | {
18 | // Construction
19 | public:
20 | CFileView() noexcept;
21 |
22 | void AdjustLayout();
23 | void OnChangeVisualStyle();
24 |
25 | // Attributes
26 | protected:
27 |
28 | CViewTree m_wndFileView;
29 | CImageList m_FileViewImages;
30 | CFileViewToolBar m_wndToolBar;
31 |
32 | protected:
33 | void FillFileView();
34 |
35 | // Implementation
36 | public:
37 | virtual ~CFileView();
38 |
39 | protected:
40 | afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
41 | afx_msg void OnSize(UINT nType, int cx, int cy);
42 | afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
43 | afx_msg void OnProperties();
44 | afx_msg void OnFileOpen();
45 | afx_msg void OnFileOpenWith();
46 | afx_msg void OnDummyCompile();
47 | afx_msg void OnEditCut();
48 | afx_msg void OnEditCopy();
49 | afx_msg void OnEditClear();
50 | afx_msg void OnPaint();
51 | afx_msg void OnSetFocus(CWnd* pOldWnd);
52 |
53 | DECLARE_MESSAGE_MAP()
54 | };
55 |
56 |
--------------------------------------------------------------------------------
/src/FindDialog.cpp:
--------------------------------------------------------------------------------
1 | // FindDialog.cpp : implementation file
2 | //
3 |
4 | #include "pch.h"
5 | #include "BigJsonTreeViewMfc.h"
6 | #include "afxdialogex.h"
7 | #include "FindDialog.h"
8 |
9 |
10 | // FindDialog dialog
11 |
12 | IMPLEMENT_DYNAMIC(FindDialog, CDialogEx)
13 |
14 | FindDialog::FindDialog(CWnd* pParent /*=nullptr*/)
15 | : CDialogEx(IDD_FIND_DIALOG, pParent)
16 | , m_SearchString(_T(""))
17 | {
18 |
19 | }
20 |
21 | FindDialog::~FindDialog()
22 | {
23 | }
24 |
25 | void FindDialog::DoDataExchange(CDataExchange* pDX)
26 | {
27 | CDialogEx::DoDataExchange(pDX);
28 | DDX_Text(pDX, IDC_SEARCH_STRING, m_SearchString);
29 | DDX_Check(pDX, IDC_SEARCH_EXACT, m_Exact);
30 | }
31 |
32 |
33 | BEGIN_MESSAGE_MAP(FindDialog, CDialogEx)
34 | ON_EN_CHANGE(IDC_SEARCH_STRING, &FindDialog::OnEnChangeSearchString)
35 | ON_BN_CLICKED(IDOK, &FindDialog::OnBnClickedOk)
36 | END_MESSAGE_MAP()
37 |
38 |
39 | // FindDialog message handlers
40 |
41 |
42 | BOOL FindDialog::OnInitDialog()
43 | {
44 | CDialogEx::OnInitDialog();
45 |
46 | GetDlgItem(IDC_SEARCH_STRING)->SetFocus();
47 |
48 | GetDlgItem(IDOK)->EnableWindow(FALSE);
49 |
50 | return FALSE; // return TRUE unless you set the focus to a control
51 | }
52 |
53 | void FindDialog::OnEnChangeSearchString()
54 | {
55 | GetDlgItem(IDOK)->EnableWindow((BOOL)
56 | GetDlgItem(ID_SEARCH_STRING)->GetWindowTextLengthA());
57 | }
58 |
59 |
60 | void FindDialog::OnBnClickedOk()
61 | {
62 | m_Confirmed = true;
63 |
64 | CDialogEx::OnOK();
65 | }
66 |
--------------------------------------------------------------------------------
/src/FindDialog.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "afxdialogex.h"
3 |
4 |
5 | // FindDialog dialog
6 |
7 | class FindDialog : public CDialogEx
8 | {
9 | DECLARE_DYNAMIC(FindDialog)
10 |
11 | public:
12 | FindDialog(CWnd* pParent = nullptr); // standard constructor
13 | virtual ~FindDialog();
14 |
15 | // Dialog Data
16 | #ifdef AFX_DESIGN_TIME
17 | enum { IDD = IDD_FIND_DIALOG };
18 | #endif
19 |
20 | protected:
21 | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
22 |
23 | DECLARE_MESSAGE_MAP()
24 | public:
25 | CString m_SearchString;
26 | int m_Exact = false;
27 | bool m_Confirmed = false;
28 |
29 | virtual BOOL OnInitDialog();
30 | afx_msg void OnEnChangeSearchString();
31 | afx_msg void OnBnClickedOk();
32 | };
33 |
--------------------------------------------------------------------------------
/src/MainFrm.h:
--------------------------------------------------------------------------------
1 |
2 | // MainFrm.h : interface of the CMainFrame class
3 | //
4 |
5 | #pragma once
6 | #include "FileView.h"
7 | #include "ClassView.h"
8 | #include "OutputWnd.h"
9 | #include "PropertiesWnd.h"
10 | #include "CalendarBar.h"
11 | #include "Resource.h"
12 |
13 | class COutlookBar : public CMFCOutlookBar
14 | {
15 | virtual BOOL AllowShowOnPaneMenu() const { return TRUE; }
16 | virtual void GetPaneName(CString& strName) const { BOOL bNameValid = strName.LoadString(IDS_OUTLOOKBAR); ASSERT(bNameValid); if (!bNameValid) strName.Empty(); }
17 | };
18 |
19 | class CMainFrame : public CMDIFrameWndEx
20 | {
21 | DECLARE_DYNAMIC(CMainFrame)
22 | public:
23 | CMainFrame() noexcept;
24 |
25 | // Attributes
26 | public:
27 |
28 | // Operations
29 | public:
30 |
31 | // Overrides
32 | public:
33 | virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
34 | virtual BOOL LoadFrame(UINT nIDResource, DWORD dwDefaultStyle = WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, CWnd* pParentWnd = nullptr, CCreateContext* pContext = nullptr);
35 |
36 | // Implementation
37 | public:
38 | virtual ~CMainFrame();
39 | #ifdef _DEBUG
40 | virtual void AssertValid() const;
41 | virtual void Dump(CDumpContext& dc) const;
42 | #endif
43 |
44 | protected: // control bar embedded members
45 | CMFCMenuBar m_wndMenuBar;
46 | CMFCToolBar m_wndToolBar;
47 | CMFCStatusBar m_wndStatusBar;
48 | CMFCToolBarImages m_UserImages;
49 | CFileView m_wndFileView;
50 | CClassView m_wndClassView;
51 | COutputWnd m_wndOutput;
52 | CPropertiesWnd m_wndProperties;
53 | COutlookBar m_wndNavigationBar;
54 | CMFCShellTreeCtrl m_wndTree;
55 | CCalendarBar m_wndCalendar;
56 | CMFCCaptionBar m_wndCaptionBar;
57 |
58 | // Generated message map functions
59 | protected:
60 | afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
61 | afx_msg void OnWindowManager();
62 | afx_msg void OnViewCustomize();
63 | afx_msg LRESULT OnToolbarCreateNew(WPARAM wp, LPARAM lp);
64 | afx_msg void OnApplicationLook(UINT id);
65 | afx_msg void OnUpdateApplicationLook(CCmdUI* pCmdUI);
66 | afx_msg void OnViewCaptionBar();
67 | afx_msg void OnUpdateViewCaptionBar(CCmdUI* pCmdUI);
68 | afx_msg void OnOptions();
69 | afx_msg void OnSettingChange(UINT uFlags, LPCTSTR lpszSection);
70 | afx_msg void OnEditFind();
71 | DECLARE_MESSAGE_MAP()
72 |
73 | BOOL CreateDockingWindows();
74 | void SetDockingWindowIcons(BOOL bHiColorIcons);
75 | BOOL CreateOutlookBar(CMFCOutlookBar& bar, UINT uiID, CMFCShellTreeCtrl& tree, CCalendarBar& calendar, int nInitialWidth);
76 | BOOL CreateCaptionBar();
77 |
78 | int FindFocusedOutlookWnd(CMFCOutlookBarTabCtrl** ppOutlookWnd);
79 |
80 | CMFCOutlookBarTabCtrl* FindOutlookParent(CWnd* pWnd);
81 | CMFCOutlookBarTabCtrl* m_pCurrOutlookWnd;
82 | CMFCOutlookBarPane* m_pCurrOutlookPage;
83 | };
84 |
85 |
86 |
--------------------------------------------------------------------------------
/src/OutputWnd.cpp:
--------------------------------------------------------------------------------
1 |
2 | #include "pch.h"
3 | #include "framework.h"
4 |
5 | #include "OutputWnd.h"
6 | #include "Resource.h"
7 | #include "MainFrm.h"
8 |
9 | #include "Butter/LoggerImpl.h"
10 | #include "Butter/SearchResults.h"
11 |
12 | #ifdef _DEBUG
13 | #define new DEBUG_NEW
14 | #undef THIS_FILE
15 | static char THIS_FILE[] = __FILE__;
16 | #endif
17 |
18 | /////////////////////////////////////////////////////////////////////////////
19 | // COutputBar
20 |
21 | COutputWnd::COutputWnd() noexcept
22 | {
23 | }
24 |
25 | COutputWnd::~COutputWnd()
26 | {
27 | }
28 |
29 | BEGIN_MESSAGE_MAP(COutputWnd, CDockablePane)
30 | ON_WM_CREATE()
31 | ON_WM_SIZE()
32 | END_MESSAGE_MAP()
33 |
34 | int COutputWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
35 | {
36 | if (CDockablePane::OnCreate(lpCreateStruct) == -1)
37 | return -1;
38 |
39 | CRect rectDummy;
40 | rectDummy.SetRectEmpty();
41 |
42 | // Create tabs window:
43 | if (!m_wndTabs.Create(CMFCTabCtrl::STYLE_FLAT, rectDummy, this, 1))
44 | {
45 | TRACE0("Failed to create output tab window\n");
46 | return -1; // fail to create
47 | }
48 |
49 | // Create output panes:
50 | const DWORD dwStyle = LBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL;
51 |
52 | auto fCreateTab = [&](CListBox &listBox, int strId, DWORD extraStyle = 0) {
53 | static int tabId = 2;
54 | if (!listBox.Create(dwStyle | extraStyle, rectDummy, &m_wndTabs, tabId++))
55 | return false;
56 | listBox.SetFont(&afxGlobalData.fontRegular);
57 |
58 | CString strTabName;
59 | BOOL bNameValid;
60 |
61 | // Attach list windows to tab:
62 | bNameValid = strTabName.LoadString(strId);
63 | ASSERT(bNameValid);
64 | m_wndTabs.AddTab(&listBox, strTabName);
65 |
66 | return true;
67 | };
68 |
69 | if (!fCreateTab(m_wndOutputInfo, IDS_BUILD_TAB) ||
70 | !fCreateTab(m_wndOutputFind, IDS_FIND_TAB, LBS_NOTIFY))
71 | {
72 | TRACE0("Failed to create output windows\n");
73 | return -1; // fail to create
74 | }
75 |
76 | LoggerHooks::gWriteLineFn = [this](const char* msg) {
77 | m_wndOutputInfo.AddString(msg);
78 | m_wndOutputInfo.SetTopIndex(m_wndOutputInfo.GetCount() - 1);
79 | OutputDebugString(msg);
80 | OutputDebugString("\n");
81 | };
82 |
83 | SearchResults::SetCallbacks({
84 | .clear = [&] {m_wndOutputFind.ResetContent();},
85 | .focus = [&] {
86 | m_wndTabs.SetActiveTab(m_wndTabs.GetTabFromHwnd(m_wndOutputFind));
87 | },
88 | .addLine = [&](const char* str) {
89 | auto index = m_wndOutputFind.AddString(str);
90 | m_wndOutputFind.SetTopIndex(m_wndOutputInfo.GetCount() - 1);
91 | return index;
92 | }
93 | });
94 |
95 | m_wndOutputInfo.AddString(_T("Welcome to Big JSON Tree Viewer!"));
96 |
97 | return 0;
98 | }
99 |
100 | void COutputWnd::OnSize(UINT nType, int cx, int cy)
101 | {
102 | CDockablePane::OnSize(nType, cx, cy);
103 |
104 | // Tab control should cover the whole client area:
105 | m_wndTabs.SetWindowPos(nullptr, -1, -1, cx, cy, SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
106 | }
107 |
108 | void COutputWnd::AdjustHorzScroll(CListBox& wndListBox)
109 | {
110 | CClientDC dc(this);
111 | CFont* pOldFont = dc.SelectObject(&afxGlobalData.fontRegular);
112 |
113 | int cxExtentMax = 0;
114 |
115 | for (int i = 0; i < wndListBox.GetCount(); i++)
116 | {
117 | CString strItem;
118 | wndListBox.GetText(i, strItem);
119 |
120 | cxExtentMax = std::max(cxExtentMax, (int)dc.GetTextExtent(strItem).cx);
121 | }
122 |
123 | wndListBox.SetHorizontalExtent(cxExtentMax);
124 | dc.SelectObject(pOldFont);
125 | }
126 |
127 | void COutputWnd::UpdateFonts()
128 | {
129 | m_wndOutputInfo.SetFont(&afxGlobalData.fontRegular);
130 | /*m_wndOutputDebug.SetFont(&afxGlobalData.fontRegular);*/
131 | m_wndOutputFind.SetFont(&afxGlobalData.fontRegular);
132 | }
133 |
134 | /////////////////////////////////////////////////////////////////////////////
135 | // COutputList1
136 |
137 | COutputList::COutputList() noexcept
138 | {
139 | }
140 |
141 | COutputList::~COutputList()
142 | {
143 | }
144 |
145 | BEGIN_MESSAGE_MAP(COutputList, CListBox)
146 | ON_WM_CONTEXTMENU()
147 | ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
148 | ON_COMMAND(ID_EDIT_CLEAR, OnEditClear)
149 | ON_COMMAND(ID_VIEW_OUTPUTWND, OnViewOutput)
150 | //ON_COMMAND(LBN_DBLCLK, OnFindResultClick)
151 | ON_WM_WINDOWPOSCHANGING()
152 | ON_CONTROL_REFLECT(LBN_SELCHANGE, &COutputList::OnLbnSelchange)
153 | END_MESSAGE_MAP()
154 | /////////////////////////////////////////////////////////////////////////////
155 | // COutputList message handlers
156 |
157 | void COutputList::OnContextMenu(CWnd* /*pWnd*/, CPoint point)
158 | {
159 | CMenu menu;
160 | menu.LoadMenu(IDR_OUTPUT_POPUP);
161 |
162 | CMenu* pSumMenu = menu.GetSubMenu(0);
163 |
164 | if (AfxGetMainWnd()->IsKindOf(RUNTIME_CLASS(CMDIFrameWndEx)))
165 | {
166 | CMFCPopupMenu* pPopupMenu = new CMFCPopupMenu;
167 |
168 | if (!pPopupMenu->Create(this, point.x, point.y, (HMENU)pSumMenu->m_hMenu, FALSE, TRUE))
169 | return;
170 |
171 | ((CMDIFrameWndEx*)AfxGetMainWnd())->OnShowPopupMenu(pPopupMenu);
172 | UpdateDialogControls(this, FALSE);
173 | }
174 |
175 | SetFocus();
176 | }
177 |
178 | void COutputList::OnEditCopy()
179 | {
180 | MessageBox(_T("Copy output"));
181 | }
182 |
183 | void COutputList::OnEditClear()
184 | {
185 | MessageBox(_T("Clear output"));
186 | }
187 |
188 | void COutputList::OnViewOutput()
189 | {
190 | CDockablePane* pParentBar = DYNAMIC_DOWNCAST(CDockablePane, GetOwner());
191 | CMDIFrameWndEx* pMainFrame = DYNAMIC_DOWNCAST(CMDIFrameWndEx, GetTopLevelFrame());
192 |
193 | if (pMainFrame != nullptr && pParentBar != nullptr)
194 | {
195 | pMainFrame->SetFocus();
196 | pMainFrame->ShowPane(pParentBar, FALSE, FALSE, FALSE);
197 | pMainFrame->RecalcLayout();
198 |
199 | }
200 | }
201 |
202 | #include "Butter/Log.h"
203 | void COutputList::OnLbnSelchange()
204 | {
205 | SearchResults::SelectResultLine(GetCurSel());
206 | }
207 |
--------------------------------------------------------------------------------
/src/OutputWnd.h:
--------------------------------------------------------------------------------
1 |
2 | #pragma once
3 |
4 | /////////////////////////////////////////////////////////////////////////////
5 | // COutputList window
6 |
7 | class COutputList : public CListBox
8 | {
9 | // Construction
10 | public:
11 | COutputList() noexcept;
12 |
13 | // Implementation
14 | public:
15 | virtual ~COutputList();
16 |
17 | protected:
18 | afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
19 | afx_msg void OnEditCopy();
20 | afx_msg void OnEditClear();
21 | afx_msg void OnViewOutput();
22 | afx_msg void OnLbnSelchange();
23 |
24 | DECLARE_MESSAGE_MAP()
25 | public:
26 | };
27 |
28 | class COutputWnd : public CDockablePane
29 | {
30 | // Construction
31 | public:
32 | COutputWnd() noexcept;
33 |
34 | void UpdateFonts();
35 |
36 | // Attributes
37 | protected:
38 | CMFCTabCtrl m_wndTabs;
39 |
40 | COutputList m_wndOutputInfo;
41 | COutputList m_wndOutputDebug;
42 | COutputList m_wndOutputFind;
43 |
44 | protected:
45 | void AdjustHorzScroll(CListBox& wndListBox);
46 |
47 | // Implementation
48 | public:
49 | virtual ~COutputWnd();
50 |
51 | protected:
52 | afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
53 | afx_msg void OnSize(UINT nType, int cx, int cy);
54 |
55 | DECLARE_MESSAGE_MAP()
56 | };
57 |
58 |
--------------------------------------------------------------------------------
/src/PropertiesWnd.cpp:
--------------------------------------------------------------------------------
1 |
2 | #include "pch.h"
3 | #include "framework.h"
4 |
5 | #include "PropertiesWnd.h"
6 | #include "Resource.h"
7 | #include "MainFrm.h"
8 | #include "BigJsonTreeViewMfc.h"
9 |
10 | #ifdef _DEBUG
11 | #undef THIS_FILE
12 | static char THIS_FILE[]=__FILE__;
13 | #define new DEBUG_NEW
14 | #endif
15 |
16 | /////////////////////////////////////////////////////////////////////////////
17 | // CResourceViewBar
18 |
19 | CPropertiesWnd::CPropertiesWnd() noexcept
20 | {
21 | m_nComboHeight = 0;
22 | }
23 |
24 | CPropertiesWnd::~CPropertiesWnd()
25 | {
26 | }
27 |
28 | BEGIN_MESSAGE_MAP(CPropertiesWnd, CDockablePane)
29 | ON_WM_CREATE()
30 | ON_WM_SIZE()
31 | ON_COMMAND(ID_EXPAND_ALL, OnExpandAllProperties)
32 | ON_UPDATE_COMMAND_UI(ID_EXPAND_ALL, OnUpdateExpandAllProperties)
33 | ON_COMMAND(ID_SORTPROPERTIES, OnSortProperties)
34 | ON_UPDATE_COMMAND_UI(ID_SORTPROPERTIES, OnUpdateSortProperties)
35 | ON_COMMAND(ID_PROPERTIES1, OnProperties1)
36 | ON_UPDATE_COMMAND_UI(ID_PROPERTIES1, OnUpdateProperties1)
37 | ON_COMMAND(ID_PROPERTIES2, OnProperties2)
38 | ON_UPDATE_COMMAND_UI(ID_PROPERTIES2, OnUpdateProperties2)
39 | ON_WM_SETFOCUS()
40 | ON_WM_SETTINGCHANGE()
41 | END_MESSAGE_MAP()
42 |
43 | /////////////////////////////////////////////////////////////////////////////
44 | // CResourceViewBar message handlers
45 |
46 | void CPropertiesWnd::AdjustLayout()
47 | {
48 | if (GetSafeHwnd () == nullptr || (AfxGetMainWnd() != nullptr && AfxGetMainWnd()->IsIconic()))
49 | {
50 | return;
51 | }
52 |
53 | CRect rectClient;
54 | GetClientRect(rectClient);
55 |
56 | //int cyTlb = m_wndToolBar.CalcFixedLayout(FALSE, TRUE).cy;
57 |
58 | //m_wndObjectCombo.SetWindowPos(nullptr, rectClient.left, rectClient.top, rectClient.Width(), m_nComboHeight, SWP_NOACTIVATE | SWP_NOZORDER);
59 | //m_wndToolBar.SetWindowPos(nullptr, rectClient.left, rectClient.top + m_nComboHeight, rectClient.Width(), cyTlb, SWP_NOACTIVATE | SWP_NOZORDER);
60 | m_wndPropList.SetWindowPos(nullptr, rectClient.left, rectClient.top /*+ m_nComboHeight + cyTlb*/, rectClient.Width(), rectClient.Height() /*-(m_nComboHeight+cyTlb)*/, SWP_NOACTIVATE | SWP_NOZORDER);
61 | }
62 |
63 | int CPropertiesWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
64 | {
65 | if (CDockablePane::OnCreate(lpCreateStruct) == -1)
66 | return -1;
67 |
68 | CRect rectDummy;
69 | rectDummy.SetRectEmpty();
70 |
71 | // Create combo:
72 | //const DWORD dwViewStyle = WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | WS_BORDER | CBS_SORT | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
73 |
74 | //if (!m_wndObjectCombo.Create(dwViewStyle, rectDummy, this, 1))
75 | //{
76 | // TRACE0("Failed to create Properties Combo \n");
77 | // return -1; // fail to create
78 | //}
79 |
80 | //m_wndObjectCombo.AddString(_T("Application"));
81 | //m_wndObjectCombo.AddString(_T("Properties Window"));
82 | //m_wndObjectCombo.SetCurSel(0);
83 |
84 | //CRect rectCombo;
85 | //m_wndObjectCombo.GetClientRect (&rectCombo);
86 |
87 | //m_nComboHeight = rectCombo.Height();
88 |
89 | if (!m_wndPropList.Create(WS_VISIBLE | WS_CHILD, rectDummy, this, 2))
90 | {
91 | TRACE0("Failed to create Properties Grid \n");
92 | return -1; // fail to create
93 | }
94 |
95 | InitPropList();
96 |
97 | //m_wndToolBar.Create(this, AFX_DEFAULT_TOOLBAR_STYLE, IDR_PROPERTIES);
98 | //m_wndToolBar.LoadToolBar(IDR_PROPERTIES, 0, 0, TRUE /* Is locked */);
99 | //m_wndToolBar.CleanUpLockedImages();
100 | //m_wndToolBar.LoadBitmap(theApp.m_bHiColorIcons ? IDB_PROPERTIES_HC : IDR_PROPERTIES, 0, 0, TRUE /* Locked */);
101 |
102 | //m_wndToolBar.SetPaneStyle(m_wndToolBar.GetPaneStyle() | CBRS_TOOLTIPS | CBRS_FLYBY);
103 | //m_wndToolBar.SetPaneStyle(m_wndToolBar.GetPaneStyle() & ~(CBRS_GRIPPER | CBRS_SIZE_DYNAMIC | CBRS_BORDER_TOP | CBRS_BORDER_BOTTOM | CBRS_BORDER_LEFT | CBRS_BORDER_RIGHT));
104 | //m_wndToolBar.SetOwner(this);
105 |
106 | //// All commands will be routed via this control , not via the parent frame:
107 | //m_wndToolBar.SetRouteCommandsViaFrame(FALSE);
108 |
109 | AdjustLayout();
110 | return 0;
111 | }
112 |
113 | void CPropertiesWnd::OnSize(UINT nType, int cx, int cy)
114 | {
115 | CDockablePane::OnSize(nType, cx, cy);
116 | AdjustLayout();
117 | }
118 |
119 | void CPropertiesWnd::OnExpandAllProperties()
120 | {
121 | m_wndPropList.ExpandAll();
122 | }
123 |
124 | void CPropertiesWnd::OnUpdateExpandAllProperties(CCmdUI* /* pCmdUI */)
125 | {
126 | }
127 |
128 | void CPropertiesWnd::OnSortProperties()
129 | {
130 | m_wndPropList.SetAlphabeticMode(!m_wndPropList.IsAlphabeticMode());
131 | }
132 |
133 | void CPropertiesWnd::OnUpdateSortProperties(CCmdUI* pCmdUI)
134 | {
135 | pCmdUI->SetCheck(m_wndPropList.IsAlphabeticMode());
136 | }
137 |
138 | void CPropertiesWnd::OnProperties1()
139 | {
140 | // TODO: Add your command handler code here
141 | }
142 |
143 | void CPropertiesWnd::OnUpdateProperties1(CCmdUI* /*pCmdUI*/)
144 | {
145 | // TODO: Add your command update UI handler code here
146 | }
147 |
148 | void CPropertiesWnd::OnProperties2()
149 | {
150 | // TODO: Add your command handler code here
151 | }
152 |
153 | void CPropertiesWnd::OnUpdateProperties2(CCmdUI* /*pCmdUI*/)
154 | {
155 | // TODO: Add your command update UI handler code here
156 | }
157 |
158 | void CPropertiesWnd::InitPropList()
159 | {
160 | SetPropListFont();
161 |
162 | m_wndPropList.EnableHeaderCtrl(FALSE);
163 | m_wndPropList.EnableDescriptionArea();
164 | m_wndPropList.SetVSDotNetLook();
165 | m_wndPropList.MarkModifiedProperties();
166 |
167 | CMFCPropertyGridProperty* pGroup1 = new CMFCPropertyGridProperty(_T("Appearance"));
168 |
169 | pGroup1->AddSubItem(new CMFCPropertyGridProperty(_T("These"), (_variant_t) false, _T("Specifies the window's font will be non-bold and controls will have a 3D border")));
170 |
171 | CMFCPropertyGridProperty* pProp = new CMFCPropertyGridProperty(_T("Do"), _T("Dialog Frame"), _T("One of: None, Thin, Resizable, or Dialog Frame"));
172 | pProp->AddOption(_T("None"));
173 | pProp->AddOption(_T("Thin"));
174 | pProp->AddOption(_T("Resizable"));
175 | pProp->AddOption(_T("Dialog Frame"));
176 | pProp->AllowEdit(FALSE);
177 |
178 | pGroup1->AddSubItem(pProp);
179 | pGroup1->AddSubItem(new CMFCPropertyGridProperty(_T("Nothing"), (_variant_t) _T("About"), _T("Specifies the text that will be displayed in the window's title bar")));
180 |
181 | m_wndPropList.AddProperty(pGroup1);
182 |
183 | CMFCPropertyGridProperty* pSize = new CMFCPropertyGridProperty(_T("Yet..."), 0, TRUE);
184 |
185 | pProp = new CMFCPropertyGridProperty(_T("Height"), (_variant_t) 250l, _T("Specifies the window's height"));
186 | pProp->EnableSpinControl(TRUE, 50, 300);
187 | pSize->AddSubItem(pProp);
188 |
189 | pProp = new CMFCPropertyGridProperty( _T("Width"), (_variant_t) 150l, _T("Specifies the window's width"));
190 | pProp->EnableSpinControl(TRUE, 50, 200);
191 | pSize->AddSubItem(pProp);
192 |
193 | m_wndPropList.AddProperty(pSize);
194 |
195 | /*CMFCPropertyGridProperty* pGroup2 = new CMFCPropertyGridProperty(_T("Font"));
196 |
197 | LOGFONT lf;
198 | CFont* font = CFont::FromHandle((HFONT) GetStockObject(DEFAULT_GUI_FONT));
199 | font->GetLogFont(&lf);
200 |
201 | _tcscpy_s(lf.lfFaceName, _T("Arial"));
202 |
203 | pGroup2->AddSubItem(new CMFCPropertyGridFontProperty(_T("Font"), lf, CF_EFFECTS | CF_SCREENFONTS, _T("Specifies the default font for the window")));
204 | pGroup2->AddSubItem(new CMFCPropertyGridProperty(_T("Use System Font"), (_variant_t) true, _T("Specifies that the window uses MS Shell Dlg font")));
205 |
206 | m_wndPropList.AddProperty(pGroup2);
207 |
208 | CMFCPropertyGridProperty* pGroup3 = new CMFCPropertyGridProperty(_T("Misc"));
209 | pProp = new CMFCPropertyGridProperty(_T("(Name)"), _T("Application"));
210 | pProp->Enable(FALSE);
211 | pGroup3->AddSubItem(pProp);
212 |
213 | CMFCPropertyGridColorProperty* pColorProp = new CMFCPropertyGridColorProperty(_T("Window Color"), RGB(210, 192, 254), nullptr, _T("Specifies the default window color"));
214 | pColorProp->EnableOtherButton(_T("Other..."));
215 | pColorProp->EnableAutomaticButton(_T("Default"), ::GetSysColor(COLOR_3DFACE));
216 | pGroup3->AddSubItem(pColorProp);
217 |
218 | static const TCHAR szFilter[] = _T("Icon Files(*.ico)|*.ico|All Files(*.*)|*.*||");
219 | pGroup3->AddSubItem(new CMFCPropertyGridFileProperty(_T("Icon"), TRUE, _T(""), _T("ico"), 0, szFilter, _T("Specifies the window icon")));
220 |
221 | pGroup3->AddSubItem(new CMFCPropertyGridFileProperty(_T("Folder"), _T("c:\\")));
222 |
223 | m_wndPropList.AddProperty(pGroup3);
224 |
225 | CMFCPropertyGridProperty* pGroup4 = new CMFCPropertyGridProperty(_T("Hierarchy"));
226 |
227 | CMFCPropertyGridProperty* pGroup41 = new CMFCPropertyGridProperty(_T("First sub-level"));
228 | pGroup4->AddSubItem(pGroup41);
229 |
230 | CMFCPropertyGridProperty* pGroup411 = new CMFCPropertyGridProperty(_T("Second sub-level"));
231 | pGroup41->AddSubItem(pGroup411);
232 |
233 | pGroup411->AddSubItem(new CMFCPropertyGridProperty(_T("Item 1"), (_variant_t) _T("Value 1"), _T("This is a description")));
234 | pGroup411->AddSubItem(new CMFCPropertyGridProperty(_T("Item 2"), (_variant_t) _T("Value 2"), _T("This is a description")));
235 | pGroup411->AddSubItem(new CMFCPropertyGridProperty(_T("Item 3"), (_variant_t) _T("Value 3"), _T("This is a description")));
236 |
237 | pGroup4->Expand(FALSE);
238 | m_wndPropList.AddProperty(pGroup4);*/
239 | }
240 |
241 | void CPropertiesWnd::OnSetFocus(CWnd* pOldWnd)
242 | {
243 | CDockablePane::OnSetFocus(pOldWnd);
244 | m_wndPropList.SetFocus();
245 | }
246 |
247 | void CPropertiesWnd::OnSettingChange(UINT uFlags, LPCTSTR lpszSection)
248 | {
249 | CDockablePane::OnSettingChange(uFlags, lpszSection);
250 | SetPropListFont();
251 | }
252 |
253 | void CPropertiesWnd::SetPropListFont()
254 | {
255 | ::DeleteObject(m_fntPropList.Detach());
256 |
257 | LOGFONT lf;
258 | afxGlobalData.fontRegular.GetLogFont(&lf);
259 |
260 | NONCLIENTMETRICS info;
261 | info.cbSize = sizeof(info);
262 |
263 | afxGlobalData.GetNonClientMetrics(info);
264 |
265 | lf.lfHeight = info.lfMenuFont.lfHeight;
266 | lf.lfWeight = info.lfMenuFont.lfWeight;
267 | lf.lfItalic = info.lfMenuFont.lfItalic;
268 |
269 | m_fntPropList.CreateFontIndirect(&lf);
270 |
271 | m_wndPropList.SetFont(&m_fntPropList);
272 | //m_wndObjectCombo.SetFont(&m_fntPropList);
273 | }
274 |
--------------------------------------------------------------------------------
/src/PropertiesWnd.h:
--------------------------------------------------------------------------------
1 |
2 | #pragma once
3 |
4 | class CPropertiesToolBar : public CMFCToolBar
5 | {
6 | public:
7 | virtual void OnUpdateCmdUI(CFrameWnd* /*pTarget*/, BOOL bDisableIfNoHndler)
8 | {
9 | CMFCToolBar::OnUpdateCmdUI((CFrameWnd*) GetOwner(), bDisableIfNoHndler);
10 | }
11 |
12 | virtual BOOL AllowShowOnList() const { return FALSE; }
13 | };
14 |
15 | class CPropertiesWnd : public CDockablePane
16 | {
17 | // Construction
18 | public:
19 | CPropertiesWnd() noexcept;
20 |
21 | void AdjustLayout();
22 |
23 | // Attributes
24 | public:
25 | void SetVSDotNetLook(BOOL bSet)
26 | {
27 | m_wndPropList.SetVSDotNetLook(bSet);
28 | m_wndPropList.SetGroupNameFullWidth(bSet);
29 | }
30 |
31 | protected:
32 | CFont m_fntPropList;
33 | CComboBox m_wndObjectCombo;
34 | CPropertiesToolBar m_wndToolBar;
35 | CMFCPropertyGridCtrl m_wndPropList;
36 |
37 | // Implementation
38 | public:
39 | virtual ~CPropertiesWnd();
40 |
41 | protected:
42 | afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
43 | afx_msg void OnSize(UINT nType, int cx, int cy);
44 | afx_msg void OnExpandAllProperties();
45 | afx_msg void OnUpdateExpandAllProperties(CCmdUI* pCmdUI);
46 | afx_msg void OnSortProperties();
47 | afx_msg void OnUpdateSortProperties(CCmdUI* pCmdUI);
48 | afx_msg void OnProperties1();
49 | afx_msg void OnUpdateProperties1(CCmdUI* pCmdUI);
50 | afx_msg void OnProperties2();
51 | afx_msg void OnUpdateProperties2(CCmdUI* pCmdUI);
52 | afx_msg void OnSetFocus(CWnd* pOldWnd);
53 | afx_msg void OnSettingChange(UINT uFlags, LPCTSTR lpszSection);
54 |
55 | DECLARE_MESSAGE_MAP()
56 |
57 | void InitPropList();
58 | void SetPropListFont();
59 |
60 | int m_nComboHeight;
61 | };
62 |
63 |
--------------------------------------------------------------------------------
/src/Resource.h:
--------------------------------------------------------------------------------
1 | //{{NO_DEPENDENCIES}}
2 | // Microsoft Visual C++ generated include file.
3 | // Used by BigJsonTreeViewMfc.rc
4 | //
5 | #define IDD_ABOUTBOX 100
6 | #define IDP_OLE_INIT_FAILED 100
7 | #define IDR_POPUP_EDIT 119
8 | #define ID_STATUSBAR_PANE1 120
9 | #define ID_STATUSBAR_PANE2 121
10 | #define IDS_STATUS_PANE1 122
11 | #define IDS_STATUS_PANE2 123
12 | #define IDS_TOOLBAR_STANDARD 124
13 | #define IDS_TOOLBAR_CUSTOMIZE 125
14 | #define ID_VIEW_CUSTOMIZE 126
15 | #define IDR_MAINFRAME 128
16 | #define IDR_MAINFRAME_256 129
17 | #define IDR_BigJsonTreeViewMfcTYPE 130
18 | #define ID_WINDOW_MANAGER 131
19 | #define ID_VIEW_FILEVIEW 133
20 | #define ID_VIEW_CLASSVIEW 134
21 | #define ID_PROPERTIES 135
22 | #define ID_OPEN 136
23 | #define ID_OPEN_WITH 137
24 | #define ID_DUMMY_COMPILE 138
25 | #define ID_CLASS_ADD_MEMBER_FUNCTION 139
26 | #define ID_CLASS_ADD_MEMBER_VARIABLE 140
27 | #define ID_CLASS_DEFINITION 141
28 | #define ID_CLASS_PROPERTIES 142
29 | #define ID_NEW_FOLDER 143
30 | #define ID_SORT_MENU 144
31 | #define ID_SORTING_GROUPBYTYPE 145
32 | #define ID_SORTING_SORTALPHABETIC 146
33 | #define ID_SORTING_SORTBYTYPE 147
34 | #define ID_SORTING_SORTBYACCESS 148
35 | #define ID_VIEW_OUTPUTWND 149
36 | #define ID_VIEW_PROPERTIESWND 150
37 | #define ID_SORTPROPERTIES 151
38 | #define ID_PROPERTIES1 152
39 | #define ID_PROPERTIES2 153
40 | #define ID_EXPAND_ALL 154
41 | #define IDS_FILE_VIEW 155
42 | #define IDS_CLASS_VIEW 156
43 | #define IDS_OUTPUT_WND 157
44 | #define IDS_PROPERTIES_WND 158
45 | #define IDI_FILE_VIEW 161
46 | #define IDI_FILE_VIEW_HC 162
47 | #define IDI_CLASS_VIEW 163
48 | #define IDI_CLASS_VIEW_HC 164
49 | #define IDI_OUTPUT_WND 165
50 | #define IDI_OUTPUT_WND_HC 166
51 | #define IDI_PROPERTIES_WND 167
52 | #define IDI_PROPERTIES_WND_HC 168
53 | #define IDR_EXPLORER 169
54 | #define IDB_EXPLORER_24 170
55 | #define IDR_SORT 171
56 | #define IDB_SORT_24 172
57 | #define IDR_POPUP_SORT 173
58 | #define IDR_POPUP_EXPLORER 174
59 | #define IDB_FILE_VIEW 175
60 | #define IDB_FILE_VIEW_24 176
61 | #define IDB_CLASS_VIEW 177
62 | #define IDB_CLASS_VIEW_24 178
63 | #define IDR_MENU_IMAGES 179
64 | #define IDB_MENU_IMAGES_24 180
65 | #define ID_TOOLS_MACRO 181
66 | #define IDR_OUTPUT_POPUP 182
67 | #define IDR_PROPERTIES 183
68 | #define IDB_PROPERTIES_HC 184
69 | #define ID_VIEW_NAVIGATION 185
70 | #define IDB_NAVIGATION_LARGE 186
71 | #define IDB_NAVIGATION_LARGE_HC 187
72 | #define IDB_PAGES 188
73 | #define IDB_PAGES_HC 189
74 | #define IDB_PAGES_SMALL 190
75 | #define IDB_PAGES_SMALL_HC 191
76 | #define IDR_THEME_MENU 200
77 | #define ID_SET_STYLE 201
78 | #define ID_VIEW_APPLOOK_WIN_2000 205
79 | #define ID_VIEW_APPLOOK_OFF_XP 206
80 | #define ID_VIEW_APPLOOK_WIN_XP 207
81 | #define ID_VIEW_APPLOOK_OFF_2003 208
82 | #define ID_VIEW_APPLOOK_VS_2005 209
83 | #define ID_VIEW_APPLOOK_VS_2008 210
84 | #define ID_VIEW_APPLOOK_OFF_2007_BLUE 215
85 | #define ID_VIEW_APPLOOK_OFF_2007_BLACK 216
86 | #define ID_VIEW_APPLOOK_OFF_2007_SILVER 217
87 | #define ID_VIEW_APPLOOK_OFF_2007_AQUA 218
88 | #define ID_VIEW_APPLOOK_WINDOWS_7 219
89 | #define ID_TOOLS_OPTIONS 220
90 | #define ID_VIEW_CAPTION_BAR 221
91 | #define IDB_INFO 230
92 | #define IDS_CAPTION_BUTTON 231
93 | #define IDS_CAPTION_BUTTON_TIP 232
94 | #define IDS_CAPTION_TEXT 233
95 | #define IDS_CAPTION_IMAGE_TIP 234
96 | #define IDS_CAPTION_IMAGE_TEXT 235
97 | #define IDS_MYCALENDARS 250
98 | #define IDS_CALENDAR 251
99 | #define IDS_SHORTCUTS 252
100 | #define IDS_FOLDERS 253
101 | #define IDS_OUTLOOKBAR 258
102 | #define IDS_BUILD_TAB 300
103 | #define IDS_DEBUG_TAB 301
104 | #define IDS_FIND_TAB 302
105 | #define IDS_EXPLORER 305
106 | #define IDS_EDIT_MENU 306
107 | #define IDD_FIND_DIALOG 310
108 | #define IDC_SEARCH_STRING 1000
109 | #define ID_SEARCH_STRING 1000
110 | #define IDC_LBL_SEARCH_STRING 1002
111 | #define IDC_LBL_SEARCH_STRING2 1003
112 | #define IDC_FIND_EXACT 1003
113 | #define IDC_SEARCH_EXACT 1003
114 | #define ID_EDIT_FIND32771 32771
115 |
116 | // Next default values for new objects
117 | //
118 | #ifdef APSTUDIO_INVOKED
119 | #ifndef APSTUDIO_READONLY_SYMBOLS
120 | #define _APS_NEXT_RESOURCE_VALUE 312
121 | #define _APS_NEXT_COMMAND_VALUE 32772
122 | #define _APS_NEXT_CONTROL_VALUE 1004
123 | #define _APS_NEXT_SYMED_VALUE 310
124 | #endif
125 | #endif
126 |
--------------------------------------------------------------------------------
/src/ViewTree.cpp:
--------------------------------------------------------------------------------
1 |
2 | #include "pch.h"
3 | #include "framework.h"
4 | #include "ViewTree.h"
5 |
6 | #include "Butter/Log.h"
7 |
8 | #ifdef _DEBUG
9 | #define new DEBUG_NEW
10 | #undef THIS_FILE
11 | static char THIS_FILE[] = __FILE__;
12 | #endif
13 |
14 | /////////////////////////////////////////////////////////////////////////////
15 | // CViewTree
16 |
17 | CViewTree::CViewTree() noexcept
18 | {
19 | }
20 |
21 | CViewTree::~CViewTree()
22 | {
23 | }
24 |
25 | BEGIN_MESSAGE_MAP(CViewTree, CTreeCtrl)
26 | ON_NOTIFY_REFLECT(TVN_ITEMEXPANDING, OnItemExpanding)
27 | END_MESSAGE_MAP()
28 |
29 | /////////////////////////////////////////////////////////////////////////////
30 | // CViewTree message handlers
31 |
32 | BOOL CViewTree::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
33 | {
34 | BOOL bRes = CTreeCtrl::OnNotify(wParam, lParam, pResult);
35 |
36 | NMHDR* pNMHDR = (NMHDR*)lParam;
37 | ASSERT(pNMHDR != nullptr);
38 |
39 | #pragma warning(suppress : 26454)
40 | if (pNMHDR && pNMHDR->code == TTN_SHOW && GetToolTips() != nullptr)
41 | {
42 | GetToolTips()->SetWindowPos(&wndTop, -1, -1, -1, -1, SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOSIZE);
43 | }
44 |
45 | return bRes;
46 | }
47 |
48 | #include "Butter/JsonTreeViewController.h"
49 |
50 | afx_msg void CViewTree::OnItemExpanding(NMHDR* pNMHDR, LRESULT* pResult)
51 | {
52 | NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
53 |
54 | gJsonTreeViewController.ExpandItem(*this, pNMTreeView->itemNew.hItem);
55 |
56 | *pResult = FALSE;
57 | }
--------------------------------------------------------------------------------
/src/ViewTree.h:
--------------------------------------------------------------------------------
1 |
2 | #pragma once
3 |
4 | /////////////////////////////////////////////////////////////////////////////
5 | // CViewTree window
6 |
7 | class CViewTree : public CTreeCtrl
8 | {
9 | // Construction
10 | public:
11 | CViewTree() noexcept;
12 |
13 | // Overrides
14 | protected:
15 | virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
16 |
17 | // Implementation
18 | public:
19 | virtual ~CViewTree();
20 |
21 | protected:
22 | afx_msg void OnItemExpanding(NMHDR* pNMHDR, LRESULT* pResult);
23 |
24 | DECLARE_MESSAGE_MAP()
25 | };
26 |
--------------------------------------------------------------------------------
/src/calendarbar.cpp:
--------------------------------------------------------------------------------
1 |
2 | #include "pch.h"
3 | #include "framework.h"
4 | #include "CalendarBar.h"
5 | #include "BigJsonTreeViewMfc.h"
6 |
7 | #ifdef _DEBUG
8 | #define new DEBUG_NEW
9 | #undef THIS_FILE
10 | static char THIS_FILE[] = __FILE__;
11 | #endif
12 |
13 | const int nBorderSize = 10;
14 |
15 | /////////////////////////////////////////////////////////////////////////////
16 | // CCalendarBar
17 |
18 | CCalendarBar::CCalendarBar()
19 | {
20 | m_nMyCalendarsY = 0;
21 | }
22 |
23 | CCalendarBar::~CCalendarBar()
24 | {
25 | }
26 |
27 | BEGIN_MESSAGE_MAP(CCalendarBar, CWnd)
28 | ON_WM_CREATE()
29 | ON_WM_ERASEBKGND()
30 | ON_WM_SIZE()
31 | ON_WM_PAINT()
32 | ON_WM_SETFOCUS()
33 | ON_WM_SETTINGCHANGE()
34 | END_MESSAGE_MAP()
35 |
36 | /////////////////////////////////////////////////////////////////////////////
37 | // CCalendarBar message handlers
38 |
39 | int CCalendarBar::OnCreate(LPCREATESTRUCT lpCreateStruct)
40 | {
41 | if (CWnd::OnCreate(lpCreateStruct) == -1)
42 | return -1;
43 |
44 | CRect rectDummy(0, 0, 0, 0);
45 | m_wndCalendar.Create(WS_CHILD | WS_VISIBLE, rectDummy, this, 1);
46 |
47 | CBitmap bmp;
48 | bmp.LoadBitmap(IDB_PAGES_SMALL_HC);
49 |
50 | m_Images.Create(16, 16, ILC_COLOR24 | ILC_MASK, 0, 0);
51 | m_Images.Add(&bmp, RGB(255, 0, 255));
52 |
53 | return 0;
54 | }
55 |
56 | BOOL CCalendarBar::PreTranslateMessage(MSG *pMsg)
57 | {
58 | if (pMsg->message == WM_LBUTTONDOWN)
59 | {
60 | // Ensure that keyboard focus is set to the calendar
61 | m_wndCalendar.SetFocus();
62 | }
63 |
64 | return CWnd::PreTranslateMessage(pMsg);
65 | }
66 |
67 | BOOL CCalendarBar::OnEraseBkgnd(CDC* /*pDC*/)
68 | {
69 | return TRUE;
70 | }
71 |
72 | void CCalendarBar::OnSetFocus(CWnd *pOldWnd)
73 | {
74 | CWnd::OnSetFocus(pOldWnd);
75 | m_wndCalendar.SetFocus();
76 | }
77 |
78 | void CCalendarBar::OnSize(UINT nType, int cx, int cy)
79 | {
80 | CWnd::OnSize(nType, cx, cy);
81 |
82 | int nMyCalendarsHeight = 70;
83 |
84 | if (m_wndCalendar.GetSafeHwnd() != nullptr)
85 | {
86 | m_wndCalendar.SetWindowPos(nullptr, nBorderSize, nBorderSize, cx - 2 * nBorderSize, cy - 2 * nBorderSize - nMyCalendarsHeight - 10, SWP_NOZORDER | SWP_NOACTIVATE);
87 | }
88 |
89 | m_nMyCalendarsY = cy - nMyCalendarsHeight;
90 | }
91 |
92 | BOOL CCalendarBar::Create(const RECT& rect, CWnd* pParentWnd, UINT nID)
93 | {
94 | return CWnd::Create(nullptr, _T(""), WS_CHILD | WS_VISIBLE, rect, pParentWnd, nID);
95 | }
96 |
97 | void CCalendarBar::OnPaint()
98 | {
99 | CPaintDC dc(this); // device context for painting
100 |
101 | CRect rectClient;
102 | GetClientRect(rectClient);
103 |
104 | dc.FillRect(rectClient, &afxGlobalData.brWindow);
105 |
106 | if (rectClient.bottom - m_nMyCalendarsY > 0)
107 | {
108 | CRect rectMyCalendarsCaption = rectClient;
109 | rectMyCalendarsCaption.top = m_nMyCalendarsY;
110 | rectMyCalendarsCaption.bottom = rectMyCalendarsCaption.top + afxGlobalData.GetTextHeight(TRUE) * 3 / 2;
111 |
112 | COLORREF clrText = CMFCVisualManager::GetInstance()->OnDrawPaneCaption(&dc, nullptr, FALSE, rectMyCalendarsCaption, CRect(0, 0, 0, 0));
113 |
114 | CPen* pOldPen = dc.SelectObject(&afxGlobalData.penBarShadow);
115 |
116 | dc.MoveTo(rectMyCalendarsCaption.left - 1, rectMyCalendarsCaption.top);
117 | dc.LineTo(rectMyCalendarsCaption.right, rectMyCalendarsCaption.top);
118 |
119 | dc.SelectStockObject(BLACK_PEN);
120 |
121 | dc.MoveTo(rectMyCalendarsCaption.left - 1, rectMyCalendarsCaption.bottom);
122 | dc.LineTo(rectMyCalendarsCaption.right, rectMyCalendarsCaption.bottom);
123 |
124 | dc.SelectObject(pOldPen);
125 |
126 | CRect rectText = rectMyCalendarsCaption;
127 | rectText.DeflateRect(10, 0);
128 |
129 | dc.SetBkMode(TRANSPARENT);
130 | dc.SetTextColor(clrText);
131 |
132 | CFont* pOldFont = dc.SelectObject(&afxGlobalData.fontRegular);
133 |
134 | BOOL bNameValid;
135 | CString str;
136 |
137 | bNameValid = str.LoadString(IDS_MYCALENDARS);
138 | ASSERT(bNameValid);
139 | dc.DrawText(str, rectText, DT_VCENTER | DT_LEFT | DT_SINGLELINE);
140 |
141 | CRect rectCalendar = rectClient;
142 | rectCalendar.top = rectMyCalendarsCaption.bottom + 5;
143 | rectCalendar.bottom = rectCalendar.top + afxGlobalData.GetTextHeight(TRUE) * 3 / 2 - 5;
144 |
145 | dc.FillSolidRect(rectCalendar, RGB(255, 255, 213));
146 |
147 | rectCalendar.DeflateRect(20, 0);
148 | m_Images.Draw(&dc, 3, rectCalendar.TopLeft(), 0);
149 |
150 | rectCalendar.left += 20;
151 |
152 | bNameValid = str.LoadString(IDS_CALENDAR);
153 | ASSERT(bNameValid);
154 |
155 | dc.SetTextColor(afxGlobalData.clrHotLinkNormalText);
156 | dc.DrawText(str, rectCalendar, DT_VCENTER | DT_LEFT | DT_SINGLELINE);
157 |
158 | dc.SelectObject(pOldFont);
159 | }
160 | }
161 |
162 |
163 |
--------------------------------------------------------------------------------
/src/calendarbar.h:
--------------------------------------------------------------------------------
1 |
2 | #pragma once
3 |
4 | /////////////////////////////////////////////////////////////////////////////
5 | // CCalendarBar window
6 |
7 | class CCalendarBar : public CWnd
8 | {
9 | // Construction
10 | public:
11 | CCalendarBar();
12 |
13 | // Attributes
14 | protected:
15 | CMonthCalCtrl m_wndCalendar;
16 | int m_nMyCalendarsY;
17 | CImageList m_Images;
18 |
19 | // Overrides
20 | public:
21 | virtual BOOL Create(const RECT& rect, CWnd* pParentWnd, UINT nID = (UINT)-1);
22 | virtual BOOL PreTranslateMessage(MSG *pMsg);
23 |
24 | // Implementation
25 | public:
26 | virtual ~CCalendarBar();
27 |
28 | protected:
29 | afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
30 | afx_msg BOOL OnEraseBkgnd(CDC* pDC);
31 | afx_msg void OnSize(UINT nType, int cx, int cy);
32 | afx_msg void OnPaint();
33 | afx_msg void OnSetFocus(CWnd *pOldWnd);
34 |
35 | DECLARE_MESSAGE_MAP()
36 | };
37 |
--------------------------------------------------------------------------------
/src/external/include/rapidjson/cursorstreamwrapper.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making RapidJSON available.
2 | //
3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
4 | //
5 | // Licensed under the MIT License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // http://opensource.org/licenses/MIT
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef RAPIDJSON_CURSORSTREAMWRAPPER_H_
16 | #define RAPIDJSON_CURSORSTREAMWRAPPER_H_
17 |
18 | #include "stream.h"
19 |
20 | #if defined(__GNUC__)
21 | RAPIDJSON_DIAG_PUSH
22 | RAPIDJSON_DIAG_OFF(effc++)
23 | #endif
24 |
25 | #if defined(_MSC_VER) && _MSC_VER <= 1800
26 | RAPIDJSON_DIAG_PUSH
27 | RAPIDJSON_DIAG_OFF(4702) // unreachable code
28 | RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
29 | #endif
30 |
31 | RAPIDJSON_NAMESPACE_BEGIN
32 |
33 |
34 | //! Cursor stream wrapper for counting line and column number if error exists.
35 | /*!
36 | \tparam InputStream Any stream that implements Stream Concept
37 | */
38 | template >
39 | class CursorStreamWrapper : public GenericStreamWrapper {
40 | public:
41 | typedef typename Encoding::Ch Ch;
42 |
43 | CursorStreamWrapper(InputStream& is):
44 | GenericStreamWrapper(is), line_(1), col_(0) {}
45 |
46 | // counting line and column number
47 | Ch Take() {
48 | Ch ch = this->is_.Take();
49 | if(ch == '\n') {
50 | line_ ++;
51 | col_ = 0;
52 | } else {
53 | col_ ++;
54 | }
55 | return ch;
56 | }
57 |
58 | //! Get the error line number, if error exists.
59 | size_t GetLine() const { return line_; }
60 | //! Get the error column number, if error exists.
61 | size_t GetColumn() const { return col_; }
62 |
63 | private:
64 | size_t line_; //!< Current Line
65 | size_t col_; //!< Current Column
66 | };
67 |
68 | #if defined(_MSC_VER) && _MSC_VER <= 1800
69 | RAPIDJSON_DIAG_POP
70 | #endif
71 |
72 | #if defined(__GNUC__)
73 | RAPIDJSON_DIAG_POP
74 | #endif
75 |
76 | RAPIDJSON_NAMESPACE_END
77 |
78 | #endif // RAPIDJSON_CURSORSTREAMWRAPPER_H_
79 |
--------------------------------------------------------------------------------
/src/external/include/rapidjson/filereadstream.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making RapidJSON available.
2 | //
3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
4 | //
5 | // Licensed under the MIT License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // http://opensource.org/licenses/MIT
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef RAPIDJSON_FILEREADSTREAM_H_
16 | #define RAPIDJSON_FILEREADSTREAM_H_
17 |
18 | #include "stream.h"
19 | #include
20 |
21 | #ifdef __clang__
22 | RAPIDJSON_DIAG_PUSH
23 | RAPIDJSON_DIAG_OFF(padded)
24 | RAPIDJSON_DIAG_OFF(unreachable-code)
25 | RAPIDJSON_DIAG_OFF(missing-noreturn)
26 | #endif
27 |
28 | RAPIDJSON_NAMESPACE_BEGIN
29 |
30 | //! File byte stream for input using fread().
31 | /*!
32 | \note implements Stream concept
33 | */
34 | class FileReadStream {
35 | public:
36 | typedef char Ch; //!< Character type (byte).
37 |
38 | //! Constructor.
39 | /*!
40 | \param fp File pointer opened for read.
41 | \param buffer user-supplied buffer.
42 | \param bufferSize size of buffer in bytes. Must >=4 bytes.
43 | */
44 | FileReadStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferSize_(bufferSize), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) {
45 | RAPIDJSON_ASSERT(fp_ != 0);
46 | RAPIDJSON_ASSERT(bufferSize >= 4);
47 | Read();
48 | }
49 |
50 | Ch Peek() const { return *current_; }
51 | Ch Take() { Ch c = *current_; Read(); return c; }
52 | size_t Tell() const { return count_ + static_cast(current_ - buffer_); }
53 |
54 | // Not implemented
55 | void Put(Ch) { RAPIDJSON_ASSERT(false); }
56 | void Flush() { RAPIDJSON_ASSERT(false); }
57 | Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
58 | size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
59 |
60 | // For encoding detection only.
61 | const Ch* Peek4() const {
62 | return (current_ + 4 - !eof_ <= bufferLast_) ? current_ : 0;
63 | }
64 |
65 | private:
66 | void Read() {
67 | if (current_ < bufferLast_)
68 | ++current_;
69 | else if (!eof_) {
70 | count_ += readCount_;
71 | readCount_ = std::fread(buffer_, 1, bufferSize_, fp_);
72 | bufferLast_ = buffer_ + readCount_ - 1;
73 | current_ = buffer_;
74 |
75 | if (readCount_ < bufferSize_) {
76 | buffer_[readCount_] = '\0';
77 | ++bufferLast_;
78 | eof_ = true;
79 | }
80 | }
81 | }
82 |
83 | std::FILE* fp_;
84 | Ch *buffer_;
85 | size_t bufferSize_;
86 | Ch *bufferLast_;
87 | Ch *current_;
88 | size_t readCount_;
89 | size_t count_; //!< Number of characters read
90 | bool eof_;
91 | };
92 |
93 | RAPIDJSON_NAMESPACE_END
94 |
95 | #ifdef __clang__
96 | RAPIDJSON_DIAG_POP
97 | #endif
98 |
99 | #endif // RAPIDJSON_FILESTREAM_H_
100 |
--------------------------------------------------------------------------------
/src/external/include/rapidjson/filewritestream.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making RapidJSON available.
2 | //
3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
4 | //
5 | // Licensed under the MIT License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // http://opensource.org/licenses/MIT
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef RAPIDJSON_FILEWRITESTREAM_H_
16 | #define RAPIDJSON_FILEWRITESTREAM_H_
17 |
18 | #include "stream.h"
19 | #include
20 |
21 | #ifdef __clang__
22 | RAPIDJSON_DIAG_PUSH
23 | RAPIDJSON_DIAG_OFF(unreachable-code)
24 | #endif
25 |
26 | RAPIDJSON_NAMESPACE_BEGIN
27 |
28 | //! Wrapper of C file stream for output using fwrite().
29 | /*!
30 | \note implements Stream concept
31 | */
32 | class FileWriteStream {
33 | public:
34 | typedef char Ch; //!< Character type. Only support char.
35 |
36 | FileWriteStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferEnd_(buffer + bufferSize), current_(buffer_) {
37 | RAPIDJSON_ASSERT(fp_ != 0);
38 | }
39 |
40 | void Put(char c) {
41 | if (current_ >= bufferEnd_)
42 | Flush();
43 |
44 | *current_++ = c;
45 | }
46 |
47 | void PutN(char c, size_t n) {
48 | size_t avail = static_cast(bufferEnd_ - current_);
49 | while (n > avail) {
50 | std::memset(current_, c, avail);
51 | current_ += avail;
52 | Flush();
53 | n -= avail;
54 | avail = static_cast(bufferEnd_ - current_);
55 | }
56 |
57 | if (n > 0) {
58 | std::memset(current_, c, n);
59 | current_ += n;
60 | }
61 | }
62 |
63 | void Flush() {
64 | if (current_ != buffer_) {
65 | size_t result = std::fwrite(buffer_, 1, static_cast(current_ - buffer_), fp_);
66 | if (result < static_cast(current_ - buffer_)) {
67 | // failure deliberately ignored at this time
68 | // added to avoid warn_unused_result build errors
69 | }
70 | current_ = buffer_;
71 | }
72 | }
73 |
74 | // Not implemented
75 | char Peek() const { RAPIDJSON_ASSERT(false); return 0; }
76 | char Take() { RAPIDJSON_ASSERT(false); return 0; }
77 | size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }
78 | char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
79 | size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; }
80 |
81 | private:
82 | // Prohibit copy constructor & assignment operator.
83 | FileWriteStream(const FileWriteStream&);
84 | FileWriteStream& operator=(const FileWriteStream&);
85 |
86 | std::FILE* fp_;
87 | char *buffer_;
88 | char *bufferEnd_;
89 | char *current_;
90 | };
91 |
92 | //! Implement specialized version of PutN() with memset() for better performance.
93 | template<>
94 | inline void PutN(FileWriteStream& stream, char c, size_t n) {
95 | stream.PutN(c, n);
96 | }
97 |
98 | RAPIDJSON_NAMESPACE_END
99 |
100 | #ifdef __clang__
101 | RAPIDJSON_DIAG_POP
102 | #endif
103 |
104 | #endif // RAPIDJSON_FILESTREAM_H_
105 |
--------------------------------------------------------------------------------
/src/external/include/rapidjson/fwd.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making RapidJSON available.
2 | //
3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
4 | //
5 | // Licensed under the MIT License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // http://opensource.org/licenses/MIT
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef RAPIDJSON_FWD_H_
16 | #define RAPIDJSON_FWD_H_
17 |
18 | #include "rapidjson.h"
19 |
20 | RAPIDJSON_NAMESPACE_BEGIN
21 |
22 | // encodings.h
23 |
24 | template struct UTF8;
25 | template struct UTF16;
26 | template struct UTF16BE;
27 | template struct UTF16LE;
28 | template struct UTF32;
29 | template struct UTF32BE;
30 | template struct UTF32LE;
31 | template struct ASCII;
32 | template struct AutoUTF;
33 |
34 | template
35 | struct Transcoder;
36 |
37 | // allocators.h
38 |
39 | class CrtAllocator;
40 |
41 | template
42 | class MemoryPoolAllocator;
43 |
44 | // stream.h
45 |
46 | template
47 | struct GenericStringStream;
48 |
49 | typedef GenericStringStream > StringStream;
50 |
51 | template
52 | struct GenericInsituStringStream;
53 |
54 | typedef GenericInsituStringStream > InsituStringStream;
55 |
56 | // stringbuffer.h
57 |
58 | template
59 | class GenericStringBuffer;
60 |
61 | typedef GenericStringBuffer, CrtAllocator> StringBuffer;
62 |
63 | // filereadstream.h
64 |
65 | class FileReadStream;
66 |
67 | // filewritestream.h
68 |
69 | class FileWriteStream;
70 |
71 | // memorybuffer.h
72 |
73 | template
74 | struct GenericMemoryBuffer;
75 |
76 | typedef GenericMemoryBuffer MemoryBuffer;
77 |
78 | // memorystream.h
79 |
80 | struct MemoryStream;
81 |
82 | // reader.h
83 |
84 | template
85 | struct BaseReaderHandler;
86 |
87 | template
88 | class GenericReader;
89 |
90 | typedef GenericReader, UTF8, CrtAllocator> Reader;
91 |
92 | // writer.h
93 |
94 | template
95 | class Writer;
96 |
97 | // prettywriter.h
98 |
99 | template
100 | class PrettyWriter;
101 |
102 | // document.h
103 |
104 | template
105 | class GenericMember;
106 |
107 | template
108 | class GenericMemberIterator;
109 |
110 | template
111 | struct GenericStringRef;
112 |
113 | template
114 | class GenericValue;
115 |
116 | typedef GenericValue, MemoryPoolAllocator > Value;
117 |
118 | template
119 | class GenericDocument;
120 |
121 | typedef GenericDocument, MemoryPoolAllocator, CrtAllocator> Document;
122 |
123 | // pointer.h
124 |
125 | template
126 | class GenericPointer;
127 |
128 | typedef GenericPointer Pointer;
129 |
130 | // schema.h
131 |
132 | template
133 | class IGenericRemoteSchemaDocumentProvider;
134 |
135 | template
136 | class GenericSchemaDocument;
137 |
138 | typedef GenericSchemaDocument SchemaDocument;
139 | typedef IGenericRemoteSchemaDocumentProvider IRemoteSchemaDocumentProvider;
140 |
141 | template <
142 | typename SchemaDocumentType,
143 | typename OutputHandler,
144 | typename StateAllocator>
145 | class GenericSchemaValidator;
146 |
147 | typedef GenericSchemaValidator, void>, CrtAllocator> SchemaValidator;
148 |
149 | RAPIDJSON_NAMESPACE_END
150 |
151 | #endif // RAPIDJSON_RAPIDJSONFWD_H_
152 |
--------------------------------------------------------------------------------
/src/external/include/rapidjson/internal/clzll.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making RapidJSON available.
2 | //
3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
4 | //
5 | // Licensed under the MIT License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // http://opensource.org/licenses/MIT
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef RAPIDJSON_CLZLL_H_
16 | #define RAPIDJSON_CLZLL_H_
17 |
18 | #include "../rapidjson.h"
19 |
20 | #if defined(_MSC_VER) && !defined(UNDER_CE)
21 | #include
22 | #if defined(_WIN64)
23 | #pragma intrinsic(_BitScanReverse64)
24 | #else
25 | #pragma intrinsic(_BitScanReverse)
26 | #endif
27 | #endif
28 |
29 | RAPIDJSON_NAMESPACE_BEGIN
30 | namespace internal {
31 |
32 | inline uint32_t clzll(uint64_t x) {
33 | // Passing 0 to __builtin_clzll is UB in GCC and results in an
34 | // infinite loop in the software implementation.
35 | RAPIDJSON_ASSERT(x != 0);
36 |
37 | #if defined(_MSC_VER) && !defined(UNDER_CE)
38 | unsigned long r = 0;
39 | #if defined(_WIN64)
40 | _BitScanReverse64(&r, x);
41 | #else
42 | // Scan the high 32 bits.
43 | if (_BitScanReverse(&r, static_cast(x >> 32)))
44 | return 63 - (r + 32);
45 |
46 | // Scan the low 32 bits.
47 | _BitScanReverse(&r, static_cast(x & 0xFFFFFFFF));
48 | #endif // _WIN64
49 |
50 | return 63 - r;
51 | #elif (defined(__GNUC__) && __GNUC__ >= 4) || RAPIDJSON_HAS_BUILTIN(__builtin_clzll)
52 | // __builtin_clzll wrapper
53 | return static_cast(__builtin_clzll(x));
54 | #else
55 | // naive version
56 | uint32_t r = 0;
57 | while (!(x & (static_cast(1) << 63))) {
58 | x <<= 1;
59 | ++r;
60 | }
61 |
62 | return r;
63 | #endif // _MSC_VER
64 | }
65 |
66 | #define RAPIDJSON_CLZLL RAPIDJSON_NAMESPACE::internal::clzll
67 |
68 | } // namespace internal
69 | RAPIDJSON_NAMESPACE_END
70 |
71 | #endif // RAPIDJSON_CLZLL_H_
72 |
--------------------------------------------------------------------------------
/src/external/include/rapidjson/internal/dtoa.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making RapidJSON available.
2 | //
3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
4 | //
5 | // Licensed under the MIT License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // http://opensource.org/licenses/MIT
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | // This is a C++ header-only implementation of Grisu2 algorithm from the publication:
16 | // Loitsch, Florian. "Printing floating-point numbers quickly and accurately with
17 | // integers." ACM Sigplan Notices 45.6 (2010): 233-243.
18 |
19 | #ifndef RAPIDJSON_DTOA_
20 | #define RAPIDJSON_DTOA_
21 |
22 | #include "itoa.h" // GetDigitsLut()
23 | #include "diyfp.h"
24 | #include "ieee754.h"
25 |
26 | RAPIDJSON_NAMESPACE_BEGIN
27 | namespace internal {
28 |
29 | #ifdef __GNUC__
30 | RAPIDJSON_DIAG_PUSH
31 | RAPIDJSON_DIAG_OFF(effc++)
32 | RAPIDJSON_DIAG_OFF(array-bounds) // some gcc versions generate wrong warnings https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59124
33 | #endif
34 |
35 | inline void GrisuRound(char* buffer, int len, uint64_t delta, uint64_t rest, uint64_t ten_kappa, uint64_t wp_w) {
36 | while (rest < wp_w && delta - rest >= ten_kappa &&
37 | (rest + ten_kappa < wp_w || /// closer
38 | wp_w - rest > rest + ten_kappa - wp_w)) {
39 | buffer[len - 1]--;
40 | rest += ten_kappa;
41 | }
42 | }
43 |
44 | inline int CountDecimalDigit32(uint32_t n) {
45 | // Simple pure C++ implementation was faster than __builtin_clz version in this situation.
46 | if (n < 10) return 1;
47 | if (n < 100) return 2;
48 | if (n < 1000) return 3;
49 | if (n < 10000) return 4;
50 | if (n < 100000) return 5;
51 | if (n < 1000000) return 6;
52 | if (n < 10000000) return 7;
53 | if (n < 100000000) return 8;
54 | // Will not reach 10 digits in DigitGen()
55 | //if (n < 1000000000) return 9;
56 | //return 10;
57 | return 9;
58 | }
59 |
60 | inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buffer, int* len, int* K) {
61 | static const uint64_t kPow10[] = { 1ULL, 10ULL, 100ULL, 1000ULL, 10000ULL, 100000ULL, 1000000ULL, 10000000ULL, 100000000ULL,
62 | 1000000000ULL, 10000000000ULL, 100000000000ULL, 1000000000000ULL,
63 | 10000000000000ULL, 100000000000000ULL, 1000000000000000ULL,
64 | 10000000000000000ULL, 100000000000000000ULL, 1000000000000000000ULL,
65 | 10000000000000000000ULL };
66 | const DiyFp one(uint64_t(1) << -Mp.e, Mp.e);
67 | const DiyFp wp_w = Mp - W;
68 | uint32_t p1 = static_cast(Mp.f >> -one.e);
69 | uint64_t p2 = Mp.f & (one.f - 1);
70 | int kappa = CountDecimalDigit32(p1); // kappa in [0, 9]
71 | *len = 0;
72 |
73 | while (kappa > 0) {
74 | uint32_t d = 0;
75 | switch (kappa) {
76 | case 9: d = p1 / 100000000; p1 %= 100000000; break;
77 | case 8: d = p1 / 10000000; p1 %= 10000000; break;
78 | case 7: d = p1 / 1000000; p1 %= 1000000; break;
79 | case 6: d = p1 / 100000; p1 %= 100000; break;
80 | case 5: d = p1 / 10000; p1 %= 10000; break;
81 | case 4: d = p1 / 1000; p1 %= 1000; break;
82 | case 3: d = p1 / 100; p1 %= 100; break;
83 | case 2: d = p1 / 10; p1 %= 10; break;
84 | case 1: d = p1; p1 = 0; break;
85 | default:;
86 | }
87 | if (d || *len)
88 | buffer[(*len)++] = static_cast('0' + static_cast(d));
89 | kappa--;
90 | uint64_t tmp = (static_cast(p1) << -one.e) + p2;
91 | if (tmp <= delta) {
92 | *K += kappa;
93 | GrisuRound(buffer, *len, delta, tmp, kPow10[kappa] << -one.e, wp_w.f);
94 | return;
95 | }
96 | }
97 |
98 | // kappa = 0
99 | for (;;) {
100 | p2 *= 10;
101 | delta *= 10;
102 | char d = static_cast(p2 >> -one.e);
103 | if (d || *len)
104 | buffer[(*len)++] = static_cast('0' + d);
105 | p2 &= one.f - 1;
106 | kappa--;
107 | if (p2 < delta) {
108 | *K += kappa;
109 | int index = -kappa;
110 | GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * (index < 20 ? kPow10[index] : 0));
111 | return;
112 | }
113 | }
114 | }
115 |
116 | inline void Grisu2(double value, char* buffer, int* length, int* K) {
117 | const DiyFp v(value);
118 | DiyFp w_m, w_p;
119 | v.NormalizedBoundaries(&w_m, &w_p);
120 |
121 | const DiyFp c_mk = GetCachedPower(w_p.e, K);
122 | const DiyFp W = v.Normalize() * c_mk;
123 | DiyFp Wp = w_p * c_mk;
124 | DiyFp Wm = w_m * c_mk;
125 | Wm.f++;
126 | Wp.f--;
127 | DigitGen(W, Wp, Wp.f - Wm.f, buffer, length, K);
128 | }
129 |
130 | inline char* WriteExponent(int K, char* buffer) {
131 | if (K < 0) {
132 | *buffer++ = '-';
133 | K = -K;
134 | }
135 |
136 | if (K >= 100) {
137 | *buffer++ = static_cast('0' + static_cast(K / 100));
138 | K %= 100;
139 | const char* d = GetDigitsLut() + K * 2;
140 | *buffer++ = d[0];
141 | *buffer++ = d[1];
142 | }
143 | else if (K >= 10) {
144 | const char* d = GetDigitsLut() + K * 2;
145 | *buffer++ = d[0];
146 | *buffer++ = d[1];
147 | }
148 | else
149 | *buffer++ = static_cast('0' + static_cast(K));
150 |
151 | return buffer;
152 | }
153 |
154 | inline char* Prettify(char* buffer, int length, int k, int maxDecimalPlaces) {
155 | const int kk = length + k; // 10^(kk-1) <= v < 10^kk
156 |
157 | if (0 <= k && kk <= 21) {
158 | // 1234e7 -> 12340000000
159 | for (int i = length; i < kk; i++)
160 | buffer[i] = '0';
161 | buffer[kk] = '.';
162 | buffer[kk + 1] = '0';
163 | return &buffer[kk + 2];
164 | }
165 | else if (0 < kk && kk <= 21) {
166 | // 1234e-2 -> 12.34
167 | std::memmove(&buffer[kk + 1], &buffer[kk], static_cast(length - kk));
168 | buffer[kk] = '.';
169 | if (0 > k + maxDecimalPlaces) {
170 | // When maxDecimalPlaces = 2, 1.2345 -> 1.23, 1.102 -> 1.1
171 | // Remove extra trailing zeros (at least one) after truncation.
172 | for (int i = kk + maxDecimalPlaces; i > kk + 1; i--)
173 | if (buffer[i] != '0')
174 | return &buffer[i + 1];
175 | return &buffer[kk + 2]; // Reserve one zero
176 | }
177 | else
178 | return &buffer[length + 1];
179 | }
180 | else if (-6 < kk && kk <= 0) {
181 | // 1234e-6 -> 0.001234
182 | const int offset = 2 - kk;
183 | std::memmove(&buffer[offset], &buffer[0], static_cast(length));
184 | buffer[0] = '0';
185 | buffer[1] = '.';
186 | for (int i = 2; i < offset; i++)
187 | buffer[i] = '0';
188 | if (length - kk > maxDecimalPlaces) {
189 | // When maxDecimalPlaces = 2, 0.123 -> 0.12, 0.102 -> 0.1
190 | // Remove extra trailing zeros (at least one) after truncation.
191 | for (int i = maxDecimalPlaces + 1; i > 2; i--)
192 | if (buffer[i] != '0')
193 | return &buffer[i + 1];
194 | return &buffer[3]; // Reserve one zero
195 | }
196 | else
197 | return &buffer[length + offset];
198 | }
199 | else if (kk < -maxDecimalPlaces) {
200 | // Truncate to zero
201 | buffer[0] = '0';
202 | buffer[1] = '.';
203 | buffer[2] = '0';
204 | return &buffer[3];
205 | }
206 | else if (length == 1) {
207 | // 1e30
208 | buffer[1] = 'e';
209 | return WriteExponent(kk - 1, &buffer[2]);
210 | }
211 | else {
212 | // 1234e30 -> 1.234e33
213 | std::memmove(&buffer[2], &buffer[1], static_cast(length - 1));
214 | buffer[1] = '.';
215 | buffer[length + 1] = 'e';
216 | return WriteExponent(kk - 1, &buffer[0 + length + 2]);
217 | }
218 | }
219 |
220 | inline char* dtoa(double value, char* buffer, int maxDecimalPlaces = 324) {
221 | RAPIDJSON_ASSERT(maxDecimalPlaces >= 1);
222 | Double d(value);
223 | if (d.IsZero()) {
224 | if (d.Sign())
225 | *buffer++ = '-'; // -0.0, Issue #289
226 | buffer[0] = '0';
227 | buffer[1] = '.';
228 | buffer[2] = '0';
229 | return &buffer[3];
230 | }
231 | else {
232 | if (value < 0) {
233 | *buffer++ = '-';
234 | value = -value;
235 | }
236 | int length, K;
237 | Grisu2(value, buffer, &length, &K);
238 | return Prettify(buffer, length, K, maxDecimalPlaces);
239 | }
240 | }
241 |
242 | #ifdef __GNUC__
243 | RAPIDJSON_DIAG_POP
244 | #endif
245 |
246 | } // namespace internal
247 | RAPIDJSON_NAMESPACE_END
248 |
249 | #endif // RAPIDJSON_DTOA_
250 |
--------------------------------------------------------------------------------
/src/external/include/rapidjson/internal/ieee754.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making RapidJSON available.
2 | //
3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
4 | //
5 | // Licensed under the MIT License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // http://opensource.org/licenses/MIT
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef RAPIDJSON_IEEE754_
16 | #define RAPIDJSON_IEEE754_
17 |
18 | #include "../rapidjson.h"
19 |
20 | RAPIDJSON_NAMESPACE_BEGIN
21 | namespace internal {
22 |
23 | class Double {
24 | public:
25 | Double() {}
26 | Double(double d) : d_(d) {}
27 | Double(uint64_t u) : u_(u) {}
28 |
29 | double Value() const { return d_; }
30 | uint64_t Uint64Value() const { return u_; }
31 |
32 | double NextPositiveDouble() const {
33 | RAPIDJSON_ASSERT(!Sign());
34 | return Double(u_ + 1).Value();
35 | }
36 |
37 | bool Sign() const { return (u_ & kSignMask) != 0; }
38 | uint64_t Significand() const { return u_ & kSignificandMask; }
39 | int Exponent() const { return static_cast(((u_ & kExponentMask) >> kSignificandSize) - kExponentBias); }
40 |
41 | bool IsNan() const { return (u_ & kExponentMask) == kExponentMask && Significand() != 0; }
42 | bool IsInf() const { return (u_ & kExponentMask) == kExponentMask && Significand() == 0; }
43 | bool IsNanOrInf() const { return (u_ & kExponentMask) == kExponentMask; }
44 | bool IsNormal() const { return (u_ & kExponentMask) != 0 || Significand() == 0; }
45 | bool IsZero() const { return (u_ & (kExponentMask | kSignificandMask)) == 0; }
46 |
47 | uint64_t IntegerSignificand() const { return IsNormal() ? Significand() | kHiddenBit : Significand(); }
48 | int IntegerExponent() const { return (IsNormal() ? Exponent() : kDenormalExponent) - kSignificandSize; }
49 | uint64_t ToBias() const { return (u_ & kSignMask) ? ~u_ + 1 : u_ | kSignMask; }
50 |
51 | static int EffectiveSignificandSize(int order) {
52 | if (order >= -1021)
53 | return 53;
54 | else if (order <= -1074)
55 | return 0;
56 | else
57 | return order + 1074;
58 | }
59 |
60 | private:
61 | static const int kSignificandSize = 52;
62 | static const int kExponentBias = 0x3FF;
63 | static const int kDenormalExponent = 1 - kExponentBias;
64 | static const uint64_t kSignMask = RAPIDJSON_UINT64_C2(0x80000000, 0x00000000);
65 | static const uint64_t kExponentMask = RAPIDJSON_UINT64_C2(0x7FF00000, 0x00000000);
66 | static const uint64_t kSignificandMask = RAPIDJSON_UINT64_C2(0x000FFFFF, 0xFFFFFFFF);
67 | static const uint64_t kHiddenBit = RAPIDJSON_UINT64_C2(0x00100000, 0x00000000);
68 |
69 | union {
70 | double d_;
71 | uint64_t u_;
72 | };
73 | };
74 |
75 | } // namespace internal
76 | RAPIDJSON_NAMESPACE_END
77 |
78 | #endif // RAPIDJSON_IEEE754_
79 |
--------------------------------------------------------------------------------
/src/external/include/rapidjson/internal/meta.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making RapidJSON available.
2 | //
3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
4 | //
5 | // Licensed under the MIT License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // http://opensource.org/licenses/MIT
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef RAPIDJSON_INTERNAL_META_H_
16 | #define RAPIDJSON_INTERNAL_META_H_
17 |
18 | #include "../rapidjson.h"
19 |
20 | #ifdef __GNUC__
21 | RAPIDJSON_DIAG_PUSH
22 | RAPIDJSON_DIAG_OFF(effc++)
23 | #endif
24 |
25 | #if defined(_MSC_VER) && !defined(__clang__)
26 | RAPIDJSON_DIAG_PUSH
27 | RAPIDJSON_DIAG_OFF(6334)
28 | #endif
29 |
30 | #if RAPIDJSON_HAS_CXX11_TYPETRAITS
31 | #include
32 | #endif
33 |
34 | //@cond RAPIDJSON_INTERNAL
35 | RAPIDJSON_NAMESPACE_BEGIN
36 | namespace internal {
37 |
38 | // Helper to wrap/convert arbitrary types to void, useful for arbitrary type matching
39 | template struct Void { typedef void Type; };
40 |
41 | ///////////////////////////////////////////////////////////////////////////////
42 | // BoolType, TrueType, FalseType
43 | //
44 | template struct BoolType {
45 | static const bool Value = Cond;
46 | typedef BoolType Type;
47 | };
48 | typedef BoolType TrueType;
49 | typedef BoolType FalseType;
50 |
51 |
52 | ///////////////////////////////////////////////////////////////////////////////
53 | // SelectIf, BoolExpr, NotExpr, AndExpr, OrExpr
54 | //
55 |
56 | template struct SelectIfImpl { template struct Apply { typedef T1 Type; }; };
57 | template <> struct SelectIfImpl { template struct Apply { typedef T2 Type; }; };
58 | template struct SelectIfCond : SelectIfImpl::template Apply {};
59 | template struct SelectIf : SelectIfCond {};
60 |
61 | template struct AndExprCond : FalseType {};
62 | template <> struct AndExprCond : TrueType {};
63 | template struct OrExprCond : TrueType {};
64 | template <> struct OrExprCond : FalseType {};
65 |
66 | template struct BoolExpr : SelectIf::Type {};
67 | template struct NotExpr : SelectIf::Type {};
68 | template struct AndExpr : AndExprCond::Type {};
69 | template struct OrExpr : OrExprCond::Type {};
70 |
71 |
72 | ///////////////////////////////////////////////////////////////////////////////
73 | // AddConst, MaybeAddConst, RemoveConst
74 | template struct AddConst { typedef const T Type; };
75 | template struct MaybeAddConst : SelectIfCond {};
76 | template struct RemoveConst { typedef T Type; };
77 | template struct RemoveConst { typedef T Type; };
78 |
79 |
80 | ///////////////////////////////////////////////////////////////////////////////
81 | // IsSame, IsConst, IsMoreConst, IsPointer
82 | //
83 | template struct IsSame : FalseType {};
84 | template struct IsSame : TrueType {};
85 |
86 | template struct IsConst : FalseType {};
87 | template struct IsConst : TrueType {};
88 |
89 | template
90 | struct IsMoreConst
91 | : AndExpr::Type, typename RemoveConst::Type>,
92 | BoolType::Value >= IsConst::Value> >::Type {};
93 |
94 | template struct IsPointer : FalseType {};
95 | template struct IsPointer : TrueType {};
96 |
97 | ///////////////////////////////////////////////////////////////////////////////
98 | // IsBaseOf
99 | //
100 | #if RAPIDJSON_HAS_CXX11_TYPETRAITS
101 |
102 | template struct IsBaseOf
103 | : BoolType< ::std::is_base_of::value> {};
104 |
105 | #else // simplified version adopted from Boost
106 |
107 | template struct IsBaseOfImpl {
108 | RAPIDJSON_STATIC_ASSERT(sizeof(B) != 0);
109 | RAPIDJSON_STATIC_ASSERT(sizeof(D) != 0);
110 |
111 | typedef char (&Yes)[1];
112 | typedef char (&No) [2];
113 |
114 | template
115 | static Yes Check(const D*, T);
116 | static No Check(const B*, int);
117 |
118 | struct Host {
119 | operator const B*() const;
120 | operator const D*();
121 | };
122 |
123 | enum { Value = (sizeof(Check(Host(), 0)) == sizeof(Yes)) };
124 | };
125 |
126 | template struct IsBaseOf
127 | : OrExpr, BoolExpr > >::Type {};
128 |
129 | #endif // RAPIDJSON_HAS_CXX11_TYPETRAITS
130 |
131 |
132 | //////////////////////////////////////////////////////////////////////////
133 | // EnableIf / DisableIf
134 | //
135 | template struct EnableIfCond { typedef T Type; };
136 | template struct EnableIfCond { /* empty */ };
137 |
138 | template struct DisableIfCond { typedef T Type; };
139 | template struct DisableIfCond { /* empty */ };
140 |
141 | template
142 | struct EnableIf : EnableIfCond {};
143 |
144 | template
145 | struct DisableIf : DisableIfCond {};
146 |
147 | // SFINAE helpers
148 | struct SfinaeTag {};
149 | template struct RemoveSfinaeTag;
150 | template struct RemoveSfinaeTag { typedef T Type; };
151 |
152 | #define RAPIDJSON_REMOVEFPTR_(type) \
153 | typename ::RAPIDJSON_NAMESPACE::internal::RemoveSfinaeTag \
154 | < ::RAPIDJSON_NAMESPACE::internal::SfinaeTag&(*) type>::Type
155 |
156 | #define RAPIDJSON_ENABLEIF(cond) \
157 | typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \
158 | ::Type * = NULL
159 |
160 | #define RAPIDJSON_DISABLEIF(cond) \
161 | typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \
162 | ::Type * = NULL
163 |
164 | #define RAPIDJSON_ENABLEIF_RETURN(cond,returntype) \
165 | typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \
166 | ::Type
168 |
169 | #define RAPIDJSON_DISABLEIF_RETURN(cond,returntype) \
170 | typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \
171 | ::Type
173 |
174 | } // namespace internal
175 | RAPIDJSON_NAMESPACE_END
176 | //@endcond
177 |
178 | #if defined(_MSC_VER) && !defined(__clang__)
179 | RAPIDJSON_DIAG_POP
180 | #endif
181 |
182 | #ifdef __GNUC__
183 | RAPIDJSON_DIAG_POP
184 | #endif
185 |
186 | #endif // RAPIDJSON_INTERNAL_META_H_
187 |
--------------------------------------------------------------------------------
/src/external/include/rapidjson/internal/pow10.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making RapidJSON available.
2 | //
3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
4 | //
5 | // Licensed under the MIT License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // http://opensource.org/licenses/MIT
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef RAPIDJSON_POW10_
16 | #define RAPIDJSON_POW10_
17 |
18 | #include "../rapidjson.h"
19 |
20 | RAPIDJSON_NAMESPACE_BEGIN
21 | namespace internal {
22 |
23 | //! Computes integer powers of 10 in double (10.0^n).
24 | /*! This function uses lookup table for fast and accurate results.
25 | \param n non-negative exponent. Must <= 308.
26 | \return 10.0^n
27 | */
28 | inline double Pow10(int n) {
29 | static const double e[] = { // 1e-0...1e308: 309 * 8 bytes = 2472 bytes
30 | 1e+0,
31 | 1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, 1e+8, 1e+9, 1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16, 1e+17, 1e+18, 1e+19, 1e+20,
32 | 1e+21, 1e+22, 1e+23, 1e+24, 1e+25, 1e+26, 1e+27, 1e+28, 1e+29, 1e+30, 1e+31, 1e+32, 1e+33, 1e+34, 1e+35, 1e+36, 1e+37, 1e+38, 1e+39, 1e+40,
33 | 1e+41, 1e+42, 1e+43, 1e+44, 1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50, 1e+51, 1e+52, 1e+53, 1e+54, 1e+55, 1e+56, 1e+57, 1e+58, 1e+59, 1e+60,
34 | 1e+61, 1e+62, 1e+63, 1e+64, 1e+65, 1e+66, 1e+67, 1e+68, 1e+69, 1e+70, 1e+71, 1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80,
35 | 1e+81, 1e+82, 1e+83, 1e+84, 1e+85, 1e+86, 1e+87, 1e+88, 1e+89, 1e+90, 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98, 1e+99, 1e+100,
36 | 1e+101,1e+102,1e+103,1e+104,1e+105,1e+106,1e+107,1e+108,1e+109,1e+110,1e+111,1e+112,1e+113,1e+114,1e+115,1e+116,1e+117,1e+118,1e+119,1e+120,
37 | 1e+121,1e+122,1e+123,1e+124,1e+125,1e+126,1e+127,1e+128,1e+129,1e+130,1e+131,1e+132,1e+133,1e+134,1e+135,1e+136,1e+137,1e+138,1e+139,1e+140,
38 | 1e+141,1e+142,1e+143,1e+144,1e+145,1e+146,1e+147,1e+148,1e+149,1e+150,1e+151,1e+152,1e+153,1e+154,1e+155,1e+156,1e+157,1e+158,1e+159,1e+160,
39 | 1e+161,1e+162,1e+163,1e+164,1e+165,1e+166,1e+167,1e+168,1e+169,1e+170,1e+171,1e+172,1e+173,1e+174,1e+175,1e+176,1e+177,1e+178,1e+179,1e+180,
40 | 1e+181,1e+182,1e+183,1e+184,1e+185,1e+186,1e+187,1e+188,1e+189,1e+190,1e+191,1e+192,1e+193,1e+194,1e+195,1e+196,1e+197,1e+198,1e+199,1e+200,
41 | 1e+201,1e+202,1e+203,1e+204,1e+205,1e+206,1e+207,1e+208,1e+209,1e+210,1e+211,1e+212,1e+213,1e+214,1e+215,1e+216,1e+217,1e+218,1e+219,1e+220,
42 | 1e+221,1e+222,1e+223,1e+224,1e+225,1e+226,1e+227,1e+228,1e+229,1e+230,1e+231,1e+232,1e+233,1e+234,1e+235,1e+236,1e+237,1e+238,1e+239,1e+240,
43 | 1e+241,1e+242,1e+243,1e+244,1e+245,1e+246,1e+247,1e+248,1e+249,1e+250,1e+251,1e+252,1e+253,1e+254,1e+255,1e+256,1e+257,1e+258,1e+259,1e+260,
44 | 1e+261,1e+262,1e+263,1e+264,1e+265,1e+266,1e+267,1e+268,1e+269,1e+270,1e+271,1e+272,1e+273,1e+274,1e+275,1e+276,1e+277,1e+278,1e+279,1e+280,
45 | 1e+281,1e+282,1e+283,1e+284,1e+285,1e+286,1e+287,1e+288,1e+289,1e+290,1e+291,1e+292,1e+293,1e+294,1e+295,1e+296,1e+297,1e+298,1e+299,1e+300,
46 | 1e+301,1e+302,1e+303,1e+304,1e+305,1e+306,1e+307,1e+308
47 | };
48 | RAPIDJSON_ASSERT(n >= 0 && n <= 308);
49 | return e[n];
50 | }
51 |
52 | } // namespace internal
53 | RAPIDJSON_NAMESPACE_END
54 |
55 | #endif // RAPIDJSON_POW10_
56 |
--------------------------------------------------------------------------------
/src/external/include/rapidjson/internal/stack.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making RapidJSON available.
2 | //
3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
4 | //
5 | // Licensed under the MIT License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // http://opensource.org/licenses/MIT
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef RAPIDJSON_INTERNAL_STACK_H_
16 | #define RAPIDJSON_INTERNAL_STACK_H_
17 |
18 | #include "../allocators.h"
19 | #include "swap.h"
20 | #include
21 |
22 | #if defined(__clang__)
23 | RAPIDJSON_DIAG_PUSH
24 | RAPIDJSON_DIAG_OFF(c++98-compat)
25 | #endif
26 |
27 | RAPIDJSON_NAMESPACE_BEGIN
28 | namespace internal {
29 |
30 | ///////////////////////////////////////////////////////////////////////////////
31 | // Stack
32 |
33 | //! A type-unsafe stack for storing different types of data.
34 | /*! \tparam Allocator Allocator for allocating stack memory.
35 | */
36 | template
37 | class Stack {
38 | public:
39 | // Optimization note: Do not allocate memory for stack_ in constructor.
40 | // Do it lazily when first Push() -> Expand() -> Resize().
41 | Stack(Allocator* allocator, size_t stackCapacity) : allocator_(allocator), ownAllocator_(0), stack_(0), stackTop_(0), stackEnd_(0), initialCapacity_(stackCapacity) {
42 | }
43 |
44 | #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
45 | Stack(Stack&& rhs)
46 | : allocator_(rhs.allocator_),
47 | ownAllocator_(rhs.ownAllocator_),
48 | stack_(rhs.stack_),
49 | stackTop_(rhs.stackTop_),
50 | stackEnd_(rhs.stackEnd_),
51 | initialCapacity_(rhs.initialCapacity_)
52 | {
53 | rhs.allocator_ = 0;
54 | rhs.ownAllocator_ = 0;
55 | rhs.stack_ = 0;
56 | rhs.stackTop_ = 0;
57 | rhs.stackEnd_ = 0;
58 | rhs.initialCapacity_ = 0;
59 | }
60 | #endif
61 |
62 | ~Stack() {
63 | Destroy();
64 | }
65 |
66 | #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
67 | Stack& operator=(Stack&& rhs) {
68 | if (&rhs != this)
69 | {
70 | Destroy();
71 |
72 | allocator_ = rhs.allocator_;
73 | ownAllocator_ = rhs.ownAllocator_;
74 | stack_ = rhs.stack_;
75 | stackTop_ = rhs.stackTop_;
76 | stackEnd_ = rhs.stackEnd_;
77 | initialCapacity_ = rhs.initialCapacity_;
78 |
79 | rhs.allocator_ = 0;
80 | rhs.ownAllocator_ = 0;
81 | rhs.stack_ = 0;
82 | rhs.stackTop_ = 0;
83 | rhs.stackEnd_ = 0;
84 | rhs.initialCapacity_ = 0;
85 | }
86 | return *this;
87 | }
88 | #endif
89 |
90 | void Swap(Stack& rhs) RAPIDJSON_NOEXCEPT {
91 | internal::Swap(allocator_, rhs.allocator_);
92 | internal::Swap(ownAllocator_, rhs.ownAllocator_);
93 | internal::Swap(stack_, rhs.stack_);
94 | internal::Swap(stackTop_, rhs.stackTop_);
95 | internal::Swap(stackEnd_, rhs.stackEnd_);
96 | internal::Swap(initialCapacity_, rhs.initialCapacity_);
97 | }
98 |
99 | void Clear() { stackTop_ = stack_; }
100 |
101 | void ShrinkToFit() {
102 | if (Empty()) {
103 | // If the stack is empty, completely deallocate the memory.
104 | Allocator::Free(stack_); // NOLINT (+clang-analyzer-unix.Malloc)
105 | stack_ = 0;
106 | stackTop_ = 0;
107 | stackEnd_ = 0;
108 | }
109 | else
110 | Resize(GetSize());
111 | }
112 |
113 | // Optimization note: try to minimize the size of this function for force inline.
114 | // Expansion is run very infrequently, so it is moved to another (probably non-inline) function.
115 | template
116 | RAPIDJSON_FORCEINLINE void Reserve(size_t count = 1) {
117 | // Expand the stack if needed
118 | if (RAPIDJSON_UNLIKELY(static_cast(sizeof(T) * count) > (stackEnd_ - stackTop_)))
119 | Expand(count);
120 | }
121 |
122 | template
123 | RAPIDJSON_FORCEINLINE T* Push(size_t count = 1) {
124 | Reserve(count);
125 | return PushUnsafe(count);
126 | }
127 |
128 | template
129 | RAPIDJSON_FORCEINLINE T* PushUnsafe(size_t count = 1) {
130 | RAPIDJSON_ASSERT(stackTop_);
131 | RAPIDJSON_ASSERT(static_cast(sizeof(T) * count) <= (stackEnd_ - stackTop_));
132 | T* ret = reinterpret_cast(stackTop_);
133 | stackTop_ += sizeof(T) * count;
134 | return ret;
135 | }
136 |
137 | template
138 | T* Pop(size_t count) {
139 | RAPIDJSON_ASSERT(GetSize() >= count * sizeof(T));
140 | stackTop_ -= count * sizeof(T);
141 | return reinterpret_cast(stackTop_);
142 | }
143 |
144 | template
145 | T* Top() {
146 | RAPIDJSON_ASSERT(GetSize() >= sizeof(T));
147 | return reinterpret_cast(stackTop_ - sizeof(T));
148 | }
149 |
150 | template
151 | const T* Top() const {
152 | RAPIDJSON_ASSERT(GetSize() >= sizeof(T));
153 | return reinterpret_cast(stackTop_ - sizeof(T));
154 | }
155 |
156 | template
157 | T* End() { return reinterpret_cast(stackTop_); }
158 |
159 | template
160 | const T* End() const { return reinterpret_cast(stackTop_); }
161 |
162 | template
163 | T* Bottom() { return reinterpret_cast(stack_); }
164 |
165 | template
166 | const T* Bottom() const { return reinterpret_cast(stack_); }
167 |
168 | bool HasAllocator() const {
169 | return allocator_ != 0;
170 | }
171 |
172 | Allocator& GetAllocator() {
173 | RAPIDJSON_ASSERT(allocator_);
174 | return *allocator_;
175 | }
176 |
177 | bool Empty() const { return stackTop_ == stack_; }
178 | size_t GetSize() const { return static_cast(stackTop_ - stack_); }
179 | size_t GetCapacity() const { return static_cast(stackEnd_ - stack_); }
180 |
181 | private:
182 | template
183 | void Expand(size_t count) {
184 | // Only expand the capacity if the current stack exists. Otherwise just create a stack with initial capacity.
185 | size_t newCapacity;
186 | if (stack_ == 0) {
187 | if (!allocator_)
188 | ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
189 | newCapacity = initialCapacity_;
190 | } else {
191 | newCapacity = GetCapacity();
192 | newCapacity += (newCapacity + 1) / 2;
193 | }
194 | size_t newSize = GetSize() + sizeof(T) * count;
195 | if (newCapacity < newSize)
196 | newCapacity = newSize;
197 |
198 | Resize(newCapacity);
199 | }
200 |
201 | void Resize(size_t newCapacity) {
202 | const size_t size = GetSize(); // Backup the current size
203 | stack_ = static_cast(allocator_->Realloc(stack_, GetCapacity(), newCapacity));
204 | stackTop_ = stack_ + size;
205 | stackEnd_ = stack_ + newCapacity;
206 | }
207 |
208 | void Destroy() {
209 | Allocator::Free(stack_);
210 | RAPIDJSON_DELETE(ownAllocator_); // Only delete if it is owned by the stack
211 | }
212 |
213 | // Prohibit copy constructor & assignment operator.
214 | Stack(const Stack&);
215 | Stack& operator=(const Stack&);
216 |
217 | Allocator* allocator_;
218 | Allocator* ownAllocator_;
219 | char *stack_;
220 | char *stackTop_;
221 | char *stackEnd_;
222 | size_t initialCapacity_;
223 | };
224 |
225 | } // namespace internal
226 | RAPIDJSON_NAMESPACE_END
227 |
228 | #if defined(__clang__)
229 | RAPIDJSON_DIAG_POP
230 | #endif
231 |
232 | #endif // RAPIDJSON_STACK_H_
233 |
--------------------------------------------------------------------------------
/src/external/include/rapidjson/internal/strfunc.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making RapidJSON available.
2 | //
3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
4 | //
5 | // Licensed under the MIT License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // http://opensource.org/licenses/MIT
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef RAPIDJSON_INTERNAL_STRFUNC_H_
16 | #define RAPIDJSON_INTERNAL_STRFUNC_H_
17 |
18 | #include "../stream.h"
19 | #include
20 |
21 | RAPIDJSON_NAMESPACE_BEGIN
22 | namespace internal {
23 |
24 | //! Custom strlen() which works on different character types.
25 | /*! \tparam Ch Character type (e.g. char, wchar_t, short)
26 | \param s Null-terminated input string.
27 | \return Number of characters in the string.
28 | \note This has the same semantics as strlen(), the return value is not number of Unicode codepoints.
29 | */
30 | template
31 | inline SizeType StrLen(const Ch* s) {
32 | RAPIDJSON_ASSERT(s != 0);
33 | const Ch* p = s;
34 | while (*p) ++p;
35 | return SizeType(p - s);
36 | }
37 |
38 | template <>
39 | inline SizeType StrLen(const char* s) {
40 | return SizeType(std::strlen(s));
41 | }
42 |
43 | template <>
44 | inline SizeType StrLen(const wchar_t* s) {
45 | return SizeType(std::wcslen(s));
46 | }
47 |
48 | //! Custom strcmpn() which works on different character types.
49 | /*! \tparam Ch Character type (e.g. char, wchar_t, short)
50 | \param s1 Null-terminated input string.
51 | \param s2 Null-terminated input string.
52 | \return 0 if equal
53 | */
54 | template
55 | inline int StrCmp(const Ch* s1, const Ch* s2) {
56 | RAPIDJSON_ASSERT(s1 != 0);
57 | RAPIDJSON_ASSERT(s2 != 0);
58 | while(*s1 && (*s1 == *s2)) { s1++; s2++; }
59 | return static_cast(*s1) < static_cast(*s2) ? -1 : static_cast