├── .gitignore
├── .gitmodules
├── CMakeLists.txt
├── LICENSE
├── README.md
├── extern
└── sqlite
│ ├── shell.c
│ ├── sqlite3.c
│ ├── sqlite3.h
│ └── sqlite3ext.h
├── images
├── Console.gif
└── GUI.gif
├── include
├── API
│ ├── Card.h
│ ├── DB_API.h
│ ├── Date.h
│ └── File.h
├── Console
│ └── Console.h
└── GUI
│ └── GUI.h
└── src
├── API
├── Card.cpp
├── DB_API.cpp
├── DB_API_.h
└── Date.cpp
├── CC_Generator
├── ProjectInfo_.h
├── console_main.cpp
└── gui_main.cpp
├── Console
├── Console.cpp
└── Console_.h
└── GUI
├── GUI.cpp
├── GUI_.h
└── emscripten_funcs.h
/.gitignore:
--------------------------------------------------------------------------------
1 | .vscode
2 | build
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "extern/ImGuiFileDialog"]
2 | path = extern/ImGuiFileDialog
3 | url = https://github.com/aiekick/ImGuiFileDialog.git
4 | [submodule "extern/DearImGui"]
5 | path = extern/DearImGui
6 | url = https://github.com/ocornut/imgui.git
7 | [submodule "extern/glfw"]
8 | path = extern/glfw
9 | url = https://github.com/glfw/glfw.git
10 | [submodule "extern/PDCurses"]
11 | path = extern/PDCurses
12 | url = https://github.com/wmcbrine/PDCurses.git
13 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.16...3.27)
2 | project(CC_Generator VERSION 2.0.1 LANGUAGES C CXX)
3 |
4 | set(CMAKE_CXX_STANDARD 20)
5 | set(CMAKE_CXX_STANDARD_REQUIRED YES)
6 |
7 | add_library(api STATIC src/API/DB_API.cpp src/API/Card.cpp src/API/Date.cpp)
8 | target_include_directories(api PUBLIC include/API extern/sqlite)
9 | add_library(sqlite STATIC extern/sqlite/sqlite3.c)
10 |
11 | if(UNIX)
12 | target_link_libraries(sqlite PRIVATE sqlite3)
13 | endif()
14 |
15 | # Console
16 | if (WIN32)
17 | set(CURSES_SOURCES
18 | extern/PDCurses/pdcurses/addch.c
19 | extern/PDCurses/pdcurses/addchstr.c
20 | extern/PDCurses/pdcurses/addstr.c
21 | extern/PDCurses/pdcurses/attr.c
22 | extern/PDCurses/pdcurses/beep.c
23 | extern/PDCurses/pdcurses/bkgd.c
24 | extern/PDCurses/pdcurses/border.c
25 | extern/PDCurses/pdcurses/clear.c
26 | extern/PDCurses/pdcurses/color.c
27 | extern/PDCurses/pdcurses/debug.c
28 | extern/PDCurses/pdcurses/delch.c
29 | extern/PDCurses/pdcurses/deleteln.c
30 | extern/PDCurses/pdcurses/getch.c
31 | extern/PDCurses/pdcurses/getstr.c
32 | extern/PDCurses/pdcurses/getyx.c
33 | extern/PDCurses/pdcurses/inch.c
34 | extern/PDCurses/pdcurses/inchstr.c
35 | extern/PDCurses/pdcurses/initscr.c
36 | extern/PDCurses/pdcurses/inopts.c
37 | extern/PDCurses/pdcurses/insch.c
38 | extern/PDCurses/pdcurses/insstr.c
39 | extern/PDCurses/pdcurses/instr.c
40 | extern/PDCurses/pdcurses/kernel.c
41 | extern/PDCurses/pdcurses/keyname.c
42 | extern/PDCurses/pdcurses/mouse.c
43 | extern/PDCurses/pdcurses/move.c
44 | extern/PDCurses/pdcurses/outopts.c
45 | extern/PDCurses/pdcurses/overlay.c
46 | extern/PDCurses/pdcurses/pad.c
47 | extern/PDCurses/pdcurses/panel.c
48 | extern/PDCurses/pdcurses/printw.c
49 | extern/PDCurses/pdcurses/README.md
50 | extern/PDCurses/pdcurses/refresh.c
51 | extern/PDCurses/pdcurses/scanw.c
52 | extern/PDCurses/pdcurses/scroll.c
53 | extern/PDCurses/pdcurses/scr_dump.c
54 | extern/PDCurses/pdcurses/slk.c
55 | extern/PDCurses/pdcurses/termattr.c
56 | extern/PDCurses/pdcurses/touch.c
57 | extern/PDCurses/pdcurses/util.c
58 | extern/PDCurses/pdcurses/window.c
59 | extern/PDCurses/wincon/pdcclip.c
60 | extern/PDCurses/wincon/pdcdisp.c
61 | extern/PDCurses/wincon/pdcgetsc.c
62 | extern/PDCurses/wincon/pdckbd.c
63 | extern/PDCurses/wincon/pdcscrn.c
64 | extern/PDCurses/wincon/pdcsetsc.c
65 | extern/PDCurses/wincon/pdcutil.c
66 | )
67 |
68 | add_library(ncurses STATIC ${CURSES_SOURCES})
69 | target_include_directories(ncurses PUBLIC extern/PDCurses extern/PDCurses/wincon)
70 | endif()
71 |
72 | add_library(console STATIC src/Console/Console.cpp)
73 | target_include_directories(console PUBLIC include/Console)
74 | target_link_libraries(console PRIVATE api ncurses)
75 |
76 |
77 | add_executable(CC_Generator_Console src/CC_Generator/console_main.cpp)
78 | target_link_libraries(CC_Generator_Console PRIVATE api console sqlite ncurses)
79 | target_compile_features(CC_Generator_Console PUBLIC cxx_std_20)
80 |
81 | # GUI
82 |
83 | add_library(imgui STATIC
84 | extern/DearImGui/imgui.cpp
85 | extern/DearImGui/imgui_draw.cpp
86 | extern/DearImGui/imgui_widgets.cpp
87 | extern/DearImGui/imgui_tables.cpp
88 | extern/DearImGui/backends/imgui_impl_glfw.cpp
89 | extern/DearImGui/backends/imgui_impl_opengl3.cpp
90 | extern/DearImGui/misc/cpp/imgui_stdlib.cpp
91 | )
92 |
93 |
94 | target_include_directories(imgui PUBLIC extern/DearImGui)
95 | target_include_directories(imgui PUBLIC extern/DearImGui/misc/cpp)
96 |
97 | add_library(imguifiledialog STATIC extern/ImGuiFileDialog/ImGuiFileDialog.cpp)
98 | target_include_directories(imguifiledialog PUBLIC extern/ImGuiFileDialog extern/DearImGui)
99 | target_link_libraries(imgui PUBLIC imguifiledialog)
100 |
101 |
102 | if(WIN32)
103 | add_definitions(-D_GLFW_WIN32)
104 | add_library(glfw STATIC
105 | extern/glfw/src/context.c
106 | extern/glfw/src/init.c
107 | extern/glfw/src/input.c
108 | extern/glfw/src/monitor.c
109 | extern/glfw/src/vulkan.c
110 | extern/glfw/src/window.c
111 | extern/glfw/src/platform.c
112 | extern/glfw/src/null_init.c
113 | extern/glfw/src/null_monitor.c
114 | extern/glfw/src/null_window.c
115 | extern/glfw/src/win32_module.c
116 | extern/glfw/src/null_joystick.c
117 | extern/glfw/src/win32_init.c
118 | extern/glfw/src/win32_joystick.c
119 | extern/glfw/src/win32_monitor.c
120 | extern/glfw/src/win32_time.c
121 | extern/glfw/src/win32_thread.c
122 | extern/glfw/src/win32_window.c
123 | extern/glfw/src/wgl_context.c
124 | extern/glfw/src/egl_context.c
125 | extern/glfw/src/osmesa_context.c
126 | )
127 |
128 | target_link_libraries(glfw PRIVATE opengl32)
129 | elseif(UNIX)
130 | add_definitions(-D_GLFW_X11)
131 | add_library(glfw STATIC
132 | extern/glfw/src/context.c
133 | extern/glfw/src/init.c
134 | extern/glfw/src/input.c
135 | extern/glfw/src/monitor.c
136 | extern/glfw/src/vulkan.c
137 | extern/glfw/src/window.c
138 | extern/glfw/src/platform.c
139 | extern/glfw/src/null_init.c
140 | extern/glfw/src/null_monitor.c
141 | extern/glfw/src/null_window.c
142 | extern/glfw/src/x11_init.c
143 | extern/glfw/src/x11_monitor.c
144 | extern/glfw/src/x11_window.c
145 | extern/glfw/src/xkb_unicode.c
146 | extern/glfw/src/glx_context.c
147 | extern/glfw/src/egl_context.c
148 | extern/glfw/src/osmesa_context.c
149 | extern/glfw/src/linux_joystick.c
150 | extern/glfw/src/posix_time.c
151 | extern/glfw/src/posix_thread.c
152 | extern/glfw/src/posix_module.c
153 | extern/glfw/src/posix_poll.c
154 | extern/glfw/src/null_joystick.c
155 | )
156 | target_link_libraries(glfw PRIVATE dl GL X11)
157 |
158 |
159 | target_link_libraries(glfw PRIVATE dl GL X11)
160 | endif()
161 |
162 | target_include_directories(glfw PUBLIC extern/glfw/include)
163 | target_link_libraries(imgui PUBLIC glfw)
164 |
165 | add_library(gui STATIC src/GUI/GUI.cpp)
166 | target_include_directories(gui PUBLIC include/GUI extern/DearImGui/backends)
167 | target_link_libraries(gui PUBLIC api imgui)
168 | if (WIN32)
169 | add_executable(CC_Generator_GUI WIN32 src/CC_Generator/gui_main.cpp)
170 | elseif(UNIX)
171 | add_executable(CC_Generator_GUI src/CC_Generator/gui_main.cpp)
172 | endif()
173 |
174 | target_link_libraries(CC_Generator_GUI PRIVATE api gui sqlite)
175 | target_compile_features(CC_Generator_GUI PUBLIC cxx_std_20)
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU AFFERO GENERAL PUBLIC LICENSE
2 | Version 3, 19 November 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU Affero General Public License is a free, copyleft license for
11 | software and other kinds of works, specifically designed to ensure
12 | cooperation with the community in the case of network server software.
13 |
14 | The licenses for most software and other practical works are designed
15 | to take away your freedom to share and change the works. By contrast,
16 | our General Public Licenses are intended to guarantee your freedom to
17 | share and change all versions of a program--to make sure it remains free
18 | software for all its users.
19 |
20 | When we speak of free software, we are referring to freedom, not
21 | price. Our General Public Licenses are designed to make sure that you
22 | have the freedom to distribute copies of free software (and charge for
23 | them if you wish), that you receive source code or can get it if you
24 | want it, that you can change the software or use pieces of it in new
25 | free programs, and that you know you can do these things.
26 |
27 | Developers that use our General Public Licenses protect your rights
28 | with two steps: (1) assert copyright on the software, and (2) offer
29 | you this License which gives you legal permission to copy, distribute
30 | and/or modify the software.
31 |
32 | A secondary benefit of defending all users' freedom is that
33 | improvements made in alternate versions of the program, if they
34 | receive widespread use, become available for other developers to
35 | incorporate. Many developers of free software are heartened and
36 | encouraged by the resulting cooperation. However, in the case of
37 | software used on network servers, this result may fail to come about.
38 | The GNU General Public License permits making a modified version and
39 | letting the public access it on a server without ever releasing its
40 | source code to the public.
41 |
42 | The GNU Affero General Public License is designed specifically to
43 | ensure that, in such cases, the modified source code becomes available
44 | to the community. It requires the operator of a network server to
45 | provide the source code of the modified version running there to the
46 | users of that server. Therefore, public use of a modified version, on
47 | a publicly accessible server, gives the public access to the source
48 | code of the modified version.
49 |
50 | An older license, called the Affero General Public License and
51 | published by Affero, was designed to accomplish similar goals. This is
52 | a different license, not a version of the Affero GPL, but Affero has
53 | released a new version of the Affero GPL which permits relicensing under
54 | this license.
55 |
56 | The precise terms and conditions for copying, distribution and
57 | modification follow.
58 |
59 | TERMS AND CONDITIONS
60 |
61 | 0. Definitions.
62 |
63 | "This License" refers to version 3 of the GNU Affero General Public License.
64 |
65 | "Copyright" also means copyright-like laws that apply to other kinds of
66 | works, such as semiconductor masks.
67 |
68 | "The Program" refers to any copyrightable work licensed under this
69 | License. Each licensee is addressed as "you". "Licensees" and
70 | "recipients" may be individuals or organizations.
71 |
72 | To "modify" a work means to copy from or adapt all or part of the work
73 | in a fashion requiring copyright permission, other than the making of an
74 | exact copy. The resulting work is called a "modified version" of the
75 | earlier work or a work "based on" the earlier work.
76 |
77 | A "covered work" means either the unmodified Program or a work based
78 | on the Program.
79 |
80 | To "propagate" a work means to do anything with it that, without
81 | permission, would make you directly or secondarily liable for
82 | infringement under applicable copyright law, except executing it on a
83 | computer or modifying a private copy. Propagation includes copying,
84 | distribution (with or without modification), making available to the
85 | public, and in some countries other activities as well.
86 |
87 | To "convey" a work means any kind of propagation that enables other
88 | parties to make or receive copies. Mere interaction with a user through
89 | a computer network, with no transfer of a copy, is not conveying.
90 |
91 | An interactive user interface displays "Appropriate Legal Notices"
92 | to the extent that it includes a convenient and prominently visible
93 | feature that (1) displays an appropriate copyright notice, and (2)
94 | tells the user that there is no warranty for the work (except to the
95 | extent that warranties are provided), that licensees may convey the
96 | work under this License, and how to view a copy of this License. If
97 | the interface presents a list of user commands or options, such as a
98 | menu, a prominent item in the list meets this criterion.
99 |
100 | 1. Source Code.
101 |
102 | The "source code" for a work means the preferred form of the work
103 | for making modifications to it. "Object code" means any non-source
104 | form of a work.
105 |
106 | A "Standard Interface" means an interface that either is an official
107 | standard defined by a recognized standards body, or, in the case of
108 | interfaces specified for a particular programming language, one that
109 | is widely used among developers working in that language.
110 |
111 | The "System Libraries" of an executable work include anything, other
112 | than the work as a whole, that (a) is included in the normal form of
113 | packaging a Major Component, but which is not part of that Major
114 | Component, and (b) serves only to enable use of the work with that
115 | Major Component, or to implement a Standard Interface for which an
116 | implementation is available to the public in source code form. A
117 | "Major Component", in this context, means a major essential component
118 | (kernel, window system, and so on) of the specific operating system
119 | (if any) on which the executable work runs, or a compiler used to
120 | produce the work, or an object code interpreter used to run it.
121 |
122 | The "Corresponding Source" for a work in object code form means all
123 | the source code needed to generate, install, and (for an executable
124 | work) run the object code and to modify the work, including scripts to
125 | control those activities. However, it does not include the work's
126 | System Libraries, or general-purpose tools or generally available free
127 | programs which are used unmodified in performing those activities but
128 | which are not part of the work. For example, Corresponding Source
129 | includes interface definition files associated with source files for
130 | the work, and the source code for shared libraries and dynamically
131 | linked subprograms that the work is specifically designed to require,
132 | such as by intimate data communication or control flow between those
133 | subprograms and other parts of the work.
134 |
135 | The Corresponding Source need not include anything that users
136 | can regenerate automatically from other parts of the Corresponding
137 | Source.
138 |
139 | The Corresponding Source for a work in source code form is that
140 | same work.
141 |
142 | 2. Basic Permissions.
143 |
144 | All rights granted under this License are granted for the term of
145 | copyright on the Program, and are irrevocable provided the stated
146 | conditions are met. This License explicitly affirms your unlimited
147 | permission to run the unmodified Program. The output from running a
148 | covered work is covered by this License only if the output, given its
149 | content, constitutes a covered work. This License acknowledges your
150 | rights of fair use or other equivalent, as provided by copyright law.
151 |
152 | You may make, run and propagate covered works that you do not
153 | convey, without conditions so long as your license otherwise remains
154 | in force. You may convey covered works to others for the sole purpose
155 | of having them make modifications exclusively for you, or provide you
156 | with facilities for running those works, provided that you comply with
157 | the terms of this License in conveying all material for which you do
158 | not control copyright. Those thus making or running the covered works
159 | for you must do so exclusively on your behalf, under your direction
160 | and control, on terms that prohibit them from making any copies of
161 | your copyrighted material outside their relationship with you.
162 |
163 | Conveying under any other circumstances is permitted solely under
164 | the conditions stated below. Sublicensing is not allowed; section 10
165 | makes it unnecessary.
166 |
167 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
168 |
169 | No covered work shall be deemed part of an effective technological
170 | measure under any applicable law fulfilling obligations under article
171 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
172 | similar laws prohibiting or restricting circumvention of such
173 | measures.
174 |
175 | When you convey a covered work, you waive any legal power to forbid
176 | circumvention of technological measures to the extent such circumvention
177 | is effected by exercising rights under this License with respect to
178 | the covered work, and you disclaim any intention to limit operation or
179 | modification of the work as a means of enforcing, against the work's
180 | users, your or third parties' legal rights to forbid circumvention of
181 | technological measures.
182 |
183 | 4. Conveying Verbatim Copies.
184 |
185 | You may convey verbatim copies of the Program's source code as you
186 | receive it, in any medium, provided that you conspicuously and
187 | appropriately publish on each copy an appropriate copyright notice;
188 | keep intact all notices stating that this License and any
189 | non-permissive terms added in accord with section 7 apply to the code;
190 | keep intact all notices of the absence of any warranty; and give all
191 | recipients a copy of this License along with the Program.
192 |
193 | You may charge any price or no price for each copy that you convey,
194 | and you may offer support or warranty protection for a fee.
195 |
196 | 5. Conveying Modified Source Versions.
197 |
198 | You may convey a work based on the Program, or the modifications to
199 | produce it from the Program, in the form of source code under the
200 | terms of section 4, provided that you also meet all of these conditions:
201 |
202 | a) The work must carry prominent notices stating that you modified
203 | it, and giving a relevant date.
204 |
205 | b) The work must carry prominent notices stating that it is
206 | released under this License and any conditions added under section
207 | 7. This requirement modifies the requirement in section 4 to
208 | "keep intact all notices".
209 |
210 | c) You must license the entire work, as a whole, under this
211 | License to anyone who comes into possession of a copy. This
212 | License will therefore apply, along with any applicable section 7
213 | additional terms, to the whole of the work, and all its parts,
214 | regardless of how they are packaged. This License gives no
215 | permission to license the work in any other way, but it does not
216 | invalidate such permission if you have separately received it.
217 |
218 | d) If the work has interactive user interfaces, each must display
219 | Appropriate Legal Notices; however, if the Program has interactive
220 | interfaces that do not display Appropriate Legal Notices, your
221 | work need not make them do so.
222 |
223 | A compilation of a covered work with other separate and independent
224 | works, which are not by their nature extensions of the covered work,
225 | and which are not combined with it such as to form a larger program,
226 | in or on a volume of a storage or distribution medium, is called an
227 | "aggregate" if the compilation and its resulting copyright are not
228 | used to limit the access or legal rights of the compilation's users
229 | beyond what the individual works permit. Inclusion of a covered work
230 | in an aggregate does not cause this License to apply to the other
231 | parts of the aggregate.
232 |
233 | 6. Conveying Non-Source Forms.
234 |
235 | You may convey a covered work in object code form under the terms
236 | of sections 4 and 5, provided that you also convey the
237 | machine-readable Corresponding Source under the terms of this License,
238 | in one of these ways:
239 |
240 | a) Convey the object code in, or embodied in, a physical product
241 | (including a physical distribution medium), accompanied by the
242 | Corresponding Source fixed on a durable physical medium
243 | customarily used for software interchange.
244 |
245 | b) Convey the object code in, or embodied in, a physical product
246 | (including a physical distribution medium), accompanied by a
247 | written offer, valid for at least three years and valid for as
248 | long as you offer spare parts or customer support for that product
249 | model, to give anyone who possesses the object code either (1) a
250 | copy of the Corresponding Source for all the software in the
251 | product that is covered by this License, on a durable physical
252 | medium customarily used for software interchange, for a price no
253 | more than your reasonable cost of physically performing this
254 | conveying of source, or (2) access to copy the
255 | Corresponding Source from a network server at no charge.
256 |
257 | c) Convey individual copies of the object code with a copy of the
258 | written offer to provide the Corresponding Source. This
259 | alternative is allowed only occasionally and noncommercially, and
260 | only if you received the object code with such an offer, in accord
261 | with subsection 6b.
262 |
263 | d) Convey the object code by offering access from a designated
264 | place (gratis or for a charge), and offer equivalent access to the
265 | Corresponding Source in the same way through the same place at no
266 | further charge. You need not require recipients to copy the
267 | Corresponding Source along with the object code. If the place to
268 | copy the object code is a network server, the Corresponding Source
269 | may be on a different server (operated by you or a third party)
270 | that supports equivalent copying facilities, provided you maintain
271 | clear directions next to the object code saying where to find the
272 | Corresponding Source. Regardless of what server hosts the
273 | Corresponding Source, you remain obligated to ensure that it is
274 | available for as long as needed to satisfy these requirements.
275 |
276 | e) Convey the object code using peer-to-peer transmission, provided
277 | you inform other peers where the object code and Corresponding
278 | Source of the work are being offered to the general public at no
279 | charge under subsection 6d.
280 |
281 | A separable portion of the object code, whose source code is excluded
282 | from the Corresponding Source as a System Library, need not be
283 | included in conveying the object code work.
284 |
285 | A "User Product" is either (1) a "consumer product", which means any
286 | tangible personal property which is normally used for personal, family,
287 | or household purposes, or (2) anything designed or sold for incorporation
288 | into a dwelling. In determining whether a product is a consumer product,
289 | doubtful cases shall be resolved in favor of coverage. For a particular
290 | product received by a particular user, "normally used" refers to a
291 | typical or common use of that class of product, regardless of the status
292 | of the particular user or of the way in which the particular user
293 | actually uses, or expects or is expected to use, the product. A product
294 | is a consumer product regardless of whether the product has substantial
295 | commercial, industrial or non-consumer uses, unless such uses represent
296 | the only significant mode of use of the product.
297 |
298 | "Installation Information" for a User Product means any methods,
299 | procedures, authorization keys, or other information required to install
300 | and execute modified versions of a covered work in that User Product from
301 | a modified version of its Corresponding Source. The information must
302 | suffice to ensure that the continued functioning of the modified object
303 | code is in no case prevented or interfered with solely because
304 | modification has been made.
305 |
306 | If you convey an object code work under this section in, or with, or
307 | specifically for use in, a User Product, and the conveying occurs as
308 | part of a transaction in which the right of possession and use of the
309 | User Product is transferred to the recipient in perpetuity or for a
310 | fixed term (regardless of how the transaction is characterized), the
311 | Corresponding Source conveyed under this section must be accompanied
312 | by the Installation Information. But this requirement does not apply
313 | if neither you nor any third party retains the ability to install
314 | modified object code on the User Product (for example, the work has
315 | been installed in ROM).
316 |
317 | The requirement to provide Installation Information does not include a
318 | requirement to continue to provide support service, warranty, or updates
319 | for a work that has been modified or installed by the recipient, or for
320 | the User Product in which it has been modified or installed. Access to a
321 | network may be denied when the modification itself materially and
322 | adversely affects the operation of the network or violates the rules and
323 | protocols for communication across the network.
324 |
325 | Corresponding Source conveyed, and Installation Information provided,
326 | in accord with this section must be in a format that is publicly
327 | documented (and with an implementation available to the public in
328 | source code form), and must require no special password or key for
329 | unpacking, reading or copying.
330 |
331 | 7. Additional Terms.
332 |
333 | "Additional permissions" are terms that supplement the terms of this
334 | License by making exceptions from one or more of its conditions.
335 | Additional permissions that are applicable to the entire Program shall
336 | be treated as though they were included in this License, to the extent
337 | that they are valid under applicable law. If additional permissions
338 | apply only to part of the Program, that part may be used separately
339 | under those permissions, but the entire Program remains governed by
340 | this License without regard to the additional permissions.
341 |
342 | When you convey a copy of a covered work, you may at your option
343 | remove any additional permissions from that copy, or from any part of
344 | it. (Additional permissions may be written to require their own
345 | removal in certain cases when you modify the work.) You may place
346 | additional permissions on material, added by you to a covered work,
347 | for which you have or can give appropriate copyright permission.
348 |
349 | Notwithstanding any other provision of this License, for material you
350 | add to a covered work, you may (if authorized by the copyright holders of
351 | that material) supplement the terms of this License with terms:
352 |
353 | a) Disclaiming warranty or limiting liability differently from the
354 | terms of sections 15 and 16 of this License; or
355 |
356 | b) Requiring preservation of specified reasonable legal notices or
357 | author attributions in that material or in the Appropriate Legal
358 | Notices displayed by works containing it; or
359 |
360 | c) Prohibiting misrepresentation of the origin of that material, or
361 | requiring that modified versions of such material be marked in
362 | reasonable ways as different from the original version; or
363 |
364 | d) Limiting the use for publicity purposes of names of licensors or
365 | authors of the material; or
366 |
367 | e) Declining to grant rights under trademark law for use of some
368 | trade names, trademarks, or service marks; or
369 |
370 | f) Requiring indemnification of licensors and authors of that
371 | material by anyone who conveys the material (or modified versions of
372 | it) with contractual assumptions of liability to the recipient, for
373 | any liability that these contractual assumptions directly impose on
374 | those licensors and authors.
375 |
376 | All other non-permissive additional terms are considered "further
377 | restrictions" within the meaning of section 10. If the Program as you
378 | received it, or any part of it, contains a notice stating that it is
379 | governed by this License along with a term that is a further
380 | restriction, you may remove that term. If a license document contains
381 | a further restriction but permits relicensing or conveying under this
382 | License, you may add to a covered work material governed by the terms
383 | of that license document, provided that the further restriction does
384 | not survive such relicensing or conveying.
385 |
386 | If you add terms to a covered work in accord with this section, you
387 | must place, in the relevant source files, a statement of the
388 | additional terms that apply to those files, or a notice indicating
389 | where to find the applicable terms.
390 |
391 | Additional terms, permissive or non-permissive, may be stated in the
392 | form of a separately written license, or stated as exceptions;
393 | the above requirements apply either way.
394 |
395 | 8. Termination.
396 |
397 | You may not propagate or modify a covered work except as expressly
398 | provided under this License. Any attempt otherwise to propagate or
399 | modify it is void, and will automatically terminate your rights under
400 | this License (including any patent licenses granted under the third
401 | paragraph of section 11).
402 |
403 | However, if you cease all violation of this License, then your
404 | license from a particular copyright holder is reinstated (a)
405 | provisionally, unless and until the copyright holder explicitly and
406 | finally terminates your license, and (b) permanently, if the copyright
407 | holder fails to notify you of the violation by some reasonable means
408 | prior to 60 days after the cessation.
409 |
410 | Moreover, your license from a particular copyright holder is
411 | reinstated permanently if the copyright holder notifies you of the
412 | violation by some reasonable means, this is the first time you have
413 | received notice of violation of this License (for any work) from that
414 | copyright holder, and you cure the violation prior to 30 days after
415 | your receipt of the notice.
416 |
417 | Termination of your rights under this section does not terminate the
418 | licenses of parties who have received copies or rights from you under
419 | this License. If your rights have been terminated and not permanently
420 | reinstated, you do not qualify to receive new licenses for the same
421 | material under section 10.
422 |
423 | 9. Acceptance Not Required for Having Copies.
424 |
425 | You are not required to accept this License in order to receive or
426 | run a copy of the Program. Ancillary propagation of a covered work
427 | occurring solely as a consequence of using peer-to-peer transmission
428 | to receive a copy likewise does not require acceptance. However,
429 | nothing other than this License grants you permission to propagate or
430 | modify any covered work. These actions infringe copyright if you do
431 | not accept this License. Therefore, by modifying or propagating a
432 | covered work, you indicate your acceptance of this License to do so.
433 |
434 | 10. Automatic Licensing of Downstream Recipients.
435 |
436 | Each time you convey a covered work, the recipient automatically
437 | receives a license from the original licensors, to run, modify and
438 | propagate that work, subject to this License. You are not responsible
439 | for enforcing compliance by third parties with this License.
440 |
441 | An "entity transaction" is a transaction transferring control of an
442 | organization, or substantially all assets of one, or subdividing an
443 | organization, or merging organizations. If propagation of a covered
444 | work results from an entity transaction, each party to that
445 | transaction who receives a copy of the work also receives whatever
446 | licenses to the work the party's predecessor in interest had or could
447 | give under the previous paragraph, plus a right to possession of the
448 | Corresponding Source of the work from the predecessor in interest, if
449 | the predecessor has it or can get it with reasonable efforts.
450 |
451 | You may not impose any further restrictions on the exercise of the
452 | rights granted or affirmed under this License. For example, you may
453 | not impose a license fee, royalty, or other charge for exercise of
454 | rights granted under this License, and you may not initiate litigation
455 | (including a cross-claim or counterclaim in a lawsuit) alleging that
456 | any patent claim is infringed by making, using, selling, offering for
457 | sale, or importing the Program or any portion of it.
458 |
459 | 11. Patents.
460 |
461 | A "contributor" is a copyright holder who authorizes use under this
462 | License of the Program or a work on which the Program is based. The
463 | work thus licensed is called the contributor's "contributor version".
464 |
465 | A contributor's "essential patent claims" are all patent claims
466 | owned or controlled by the contributor, whether already acquired or
467 | hereafter acquired, that would be infringed by some manner, permitted
468 | by this License, of making, using, or selling its contributor version,
469 | but do not include claims that would be infringed only as a
470 | consequence of further modification of the contributor version. For
471 | purposes of this definition, "control" includes the right to grant
472 | patent sublicenses in a manner consistent with the requirements of
473 | this License.
474 |
475 | Each contributor grants you a non-exclusive, worldwide, royalty-free
476 | patent license under the contributor's essential patent claims, to
477 | make, use, sell, offer for sale, import and otherwise run, modify and
478 | propagate the contents of its contributor version.
479 |
480 | In the following three paragraphs, a "patent license" is any express
481 | agreement or commitment, however denominated, not to enforce a patent
482 | (such as an express permission to practice a patent or covenant not to
483 | sue for patent infringement). To "grant" such a patent license to a
484 | party means to make such an agreement or commitment not to enforce a
485 | patent against the party.
486 |
487 | If you convey a covered work, knowingly relying on a patent license,
488 | and the Corresponding Source of the work is not available for anyone
489 | to copy, free of charge and under the terms of this License, through a
490 | publicly available network server or other readily accessible means,
491 | then you must either (1) cause the Corresponding Source to be so
492 | available, or (2) arrange to deprive yourself of the benefit of the
493 | patent license for this particular work, or (3) arrange, in a manner
494 | consistent with the requirements of this License, to extend the patent
495 | license to downstream recipients. "Knowingly relying" means you have
496 | actual knowledge that, but for the patent license, your conveying the
497 | covered work in a country, or your recipient's use of the covered work
498 | in a country, would infringe one or more identifiable patents in that
499 | country that you have reason to believe are valid.
500 |
501 | If, pursuant to or in connection with a single transaction or
502 | arrangement, you convey, or propagate by procuring conveyance of, a
503 | covered work, and grant a patent license to some of the parties
504 | receiving the covered work authorizing them to use, propagate, modify
505 | or convey a specific copy of the covered work, then the patent license
506 | you grant is automatically extended to all recipients of the covered
507 | work and works based on it.
508 |
509 | A patent license is "discriminatory" if it does not include within
510 | the scope of its coverage, prohibits the exercise of, or is
511 | conditioned on the non-exercise of one or more of the rights that are
512 | specifically granted under this License. You may not convey a covered
513 | work if you are a party to an arrangement with a third party that is
514 | in the business of distributing software, under which you make payment
515 | to the third party based on the extent of your activity of conveying
516 | the work, and under which the third party grants, to any of the
517 | parties who would receive the covered work from you, a discriminatory
518 | patent license (a) in connection with copies of the covered work
519 | conveyed by you (or copies made from those copies), or (b) primarily
520 | for and in connection with specific products or compilations that
521 | contain the covered work, unless you entered into that arrangement,
522 | or that patent license was granted, prior to 28 March 2007.
523 |
524 | Nothing in this License shall be construed as excluding or limiting
525 | any implied license or other defenses to infringement that may
526 | otherwise be available to you under applicable patent law.
527 |
528 | 12. No Surrender of Others' Freedom.
529 |
530 | If conditions are imposed on you (whether by court order, agreement or
531 | otherwise) that contradict the conditions of this License, they do not
532 | excuse you from the conditions of this License. If you cannot convey a
533 | covered work so as to satisfy simultaneously your obligations under this
534 | License and any other pertinent obligations, then as a consequence you may
535 | not convey it at all. For example, if you agree to terms that obligate you
536 | to collect a royalty for further conveying from those to whom you convey
537 | the Program, the only way you could satisfy both those terms and this
538 | License would be to refrain entirely from conveying the Program.
539 |
540 | 13. Remote Network Interaction; Use with the GNU General Public License.
541 |
542 | Notwithstanding any other provision of this License, if you modify the
543 | Program, your modified version must prominently offer all users
544 | interacting with it remotely through a computer network (if your version
545 | supports such interaction) an opportunity to receive the Corresponding
546 | Source of your version by providing access to the Corresponding Source
547 | from a network server at no charge, through some standard or customary
548 | means of facilitating copying of software. This Corresponding Source
549 | shall include the Corresponding Source for any work covered by version 3
550 | of the GNU General Public License that is incorporated pursuant to the
551 | following paragraph.
552 |
553 | Notwithstanding any other provision of this License, you have
554 | permission to link or combine any covered work with a work licensed
555 | under version 3 of the GNU General Public License into a single
556 | combined work, and to convey the resulting work. The terms of this
557 | License will continue to apply to the part which is the covered work,
558 | but the work with which it is combined will remain governed by version
559 | 3 of the GNU General Public License.
560 |
561 | 14. Revised Versions of this License.
562 |
563 | The Free Software Foundation may publish revised and/or new versions of
564 | the GNU Affero General Public License from time to time. Such new versions
565 | will be similar in spirit to the present version, but may differ in detail to
566 | address new problems or concerns.
567 |
568 | Each version is given a distinguishing version number. If the
569 | Program specifies that a certain numbered version of the GNU Affero General
570 | Public License "or any later version" applies to it, you have the
571 | option of following the terms and conditions either of that numbered
572 | version or of any later version published by the Free Software
573 | Foundation. If the Program does not specify a version number of the
574 | GNU Affero General Public License, you may choose any version ever published
575 | by the Free Software Foundation.
576 |
577 | If the Program specifies that a proxy can decide which future
578 | versions of the GNU Affero General Public License can be used, that proxy's
579 | public statement of acceptance of a version permanently authorizes you
580 | to choose that version for the Program.
581 |
582 | Later license versions may give you additional or different
583 | permissions. However, no additional obligations are imposed on any
584 | author or copyright holder as a result of your choosing to follow a
585 | later version.
586 |
587 | 15. Disclaimer of Warranty.
588 |
589 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
590 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
591 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
592 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
593 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
594 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
595 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
596 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
597 |
598 | 16. Limitation of Liability.
599 |
600 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
601 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
602 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
603 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
604 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
605 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
606 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
607 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
608 | SUCH DAMAGES.
609 |
610 | 17. Interpretation of Sections 15 and 16.
611 |
612 | If the disclaimer of warranty and limitation of liability provided
613 | above cannot be given local legal effect according to their terms,
614 | reviewing courts shall apply local law that most closely approximates
615 | an absolute waiver of all civil liability in connection with the
616 | Program, unless a warranty or assumption of liability accompanies a
617 | copy of the Program in return for a fee.
618 |
619 | END OF TERMS AND CONDITIONS
620 |
621 | How to Apply These Terms to Your New Programs
622 |
623 | If you develop a new program, and you want it to be of the greatest
624 | possible use to the public, the best way to achieve this is to make it
625 | free software which everyone can redistribute and change under these terms.
626 |
627 | To do so, attach the following notices to the program. It is safest
628 | to attach them to the start of each source file to most effectively
629 | state the exclusion of warranty; and each file should have at least
630 | the "copyright" line and a pointer to where the full notice is found.
631 |
632 |
633 | Copyright (C)
634 |
635 | This program is free software: you can redistribute it and/or modify
636 | it under the terms of the GNU Affero General Public License as published
637 | by the Free Software Foundation, either version 3 of the License, or
638 | (at your option) any later version.
639 |
640 | This program is distributed in the hope that it will be useful,
641 | but WITHOUT ANY WARRANTY; without even the implied warranty of
642 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
643 | GNU Affero General Public License for more details.
644 |
645 | You should have received a copy of the GNU Affero General Public License
646 | along with this program. If not, see .
647 |
648 | Also add information on how to contact you by electronic and paper mail.
649 |
650 | If your software can interact with users remotely through a computer
651 | network, you should also make sure that it provides a way for users to
652 | get its source. For example, if your program is a web application, its
653 | interface could display a "Source" link that leads users to an archive
654 | of the code. There are many ways you could offer source, and different
655 | solutions will be better for different programs; see section 13 for the
656 | specific requirements.
657 |
658 | You should also get your employer (if you work as a programmer) or school,
659 | if any, to sign a "copyright disclaimer" for the program, if necessary.
660 | For more information on this, and how to apply and follow the GNU AGPL, see
661 | .
662 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | [](https://github.com/ItaiShek/CC_Generator/releases)
3 | 
4 | [](https://github.com/ItaiShek/CC_Generator/issues)
5 | [](https://github.com/ItaiShek/CC_Generator/blob/main/LICENSE)
6 |
7 | # Description
8 |
9 | Generate a bunch of random credit card numbers quickly and easily.
10 |
11 | 
12 |
13 | 
14 |
15 | ## Installation
16 |
17 | ### Direct download:
18 | [Windows](https://github.com/ItaiShek/CC_Generator/releases/latest/download/CC_Generator_win.zip)
19 |
20 | [Linux](https://github.com/ItaiShek/CC_Generator/releases/latest/download/CC_Generator_linux.zip)
21 |
22 | ### Try the Online Version
23 | You can also try it in your browser (no installation needed), though it will run significantly slower than the desktop version:
24 |
25 | 👉 https://ItaiShek.GitHub.io/CC_Generator
26 |
27 | ## Disclaimer
28 |
29 | Every credit card that is generated with CC_Generator is **random and fake** and does not hold any value.
30 |
31 | Credit card numbers that are generated with CC_Generator follow the Luhn algorithm for validating identification numbers.
32 |
33 | These credit cards are **not** to be used for harming or deceiving people.
34 |
35 | These credit cards are for educational and data testing purposes only.
36 |
37 | I will not take **any responsibility** for damages that arise from misusing CC_Generator.
38 |
39 | ## Credits
40 | * Names: [GitHub Gist - Elifiner](https://gist.github.com/elifiner/cc90fdd387449158829515782936a9a4)
--------------------------------------------------------------------------------
/extern/sqlite/sqlite3ext.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** 2006 June 7
3 | **
4 | ** The author disclaims copyright to this source code. In place of
5 | ** a legal notice, here is a blessing:
6 | **
7 | ** May you do good and not evil.
8 | ** May you find forgiveness for yourself and forgive others.
9 | ** May you share freely, never taking more than you give.
10 | **
11 | *************************************************************************
12 | ** This header file defines the SQLite interface for use by
13 | ** shared libraries that want to be imported as extensions into
14 | ** an SQLite instance. Shared libraries that intend to be loaded
15 | ** as extensions by SQLite should #include this file instead of
16 | ** sqlite3.h.
17 | */
18 | #ifndef SQLITE3EXT_H
19 | #define SQLITE3EXT_H
20 | #include "sqlite3.h"
21 |
22 | /*
23 | ** The following structure holds pointers to all of the SQLite API
24 | ** routines.
25 | **
26 | ** WARNING: In order to maintain backwards compatibility, add new
27 | ** interfaces to the end of this structure only. If you insert new
28 | ** interfaces in the middle of this structure, then older different
29 | ** versions of SQLite will not be able to load each other's shared
30 | ** libraries!
31 | */
32 | struct sqlite3_api_routines {
33 | void * (*aggregate_context)(sqlite3_context*,int nBytes);
34 | int (*aggregate_count)(sqlite3_context*);
35 | int (*bind_blob)(sqlite3_stmt*,int,const void*,int n,void(*)(void*));
36 | int (*bind_double)(sqlite3_stmt*,int,double);
37 | int (*bind_int)(sqlite3_stmt*,int,int);
38 | int (*bind_int64)(sqlite3_stmt*,int,sqlite_int64);
39 | int (*bind_null)(sqlite3_stmt*,int);
40 | int (*bind_parameter_count)(sqlite3_stmt*);
41 | int (*bind_parameter_index)(sqlite3_stmt*,const char*zName);
42 | const char * (*bind_parameter_name)(sqlite3_stmt*,int);
43 | int (*bind_text)(sqlite3_stmt*,int,const char*,int n,void(*)(void*));
44 | int (*bind_text16)(sqlite3_stmt*,int,const void*,int,void(*)(void*));
45 | int (*bind_value)(sqlite3_stmt*,int,const sqlite3_value*);
46 | int (*busy_handler)(sqlite3*,int(*)(void*,int),void*);
47 | int (*busy_timeout)(sqlite3*,int ms);
48 | int (*changes)(sqlite3*);
49 | int (*close)(sqlite3*);
50 | int (*collation_needed)(sqlite3*,void*,void(*)(void*,sqlite3*,
51 | int eTextRep,const char*));
52 | int (*collation_needed16)(sqlite3*,void*,void(*)(void*,sqlite3*,
53 | int eTextRep,const void*));
54 | const void * (*column_blob)(sqlite3_stmt*,int iCol);
55 | int (*column_bytes)(sqlite3_stmt*,int iCol);
56 | int (*column_bytes16)(sqlite3_stmt*,int iCol);
57 | int (*column_count)(sqlite3_stmt*pStmt);
58 | const char * (*column_database_name)(sqlite3_stmt*,int);
59 | const void * (*column_database_name16)(sqlite3_stmt*,int);
60 | const char * (*column_decltype)(sqlite3_stmt*,int i);
61 | const void * (*column_decltype16)(sqlite3_stmt*,int);
62 | double (*column_double)(sqlite3_stmt*,int iCol);
63 | int (*column_int)(sqlite3_stmt*,int iCol);
64 | sqlite_int64 (*column_int64)(sqlite3_stmt*,int iCol);
65 | const char * (*column_name)(sqlite3_stmt*,int);
66 | const void * (*column_name16)(sqlite3_stmt*,int);
67 | const char * (*column_origin_name)(sqlite3_stmt*,int);
68 | const void * (*column_origin_name16)(sqlite3_stmt*,int);
69 | const char * (*column_table_name)(sqlite3_stmt*,int);
70 | const void * (*column_table_name16)(sqlite3_stmt*,int);
71 | const unsigned char * (*column_text)(sqlite3_stmt*,int iCol);
72 | const void * (*column_text16)(sqlite3_stmt*,int iCol);
73 | int (*column_type)(sqlite3_stmt*,int iCol);
74 | sqlite3_value* (*column_value)(sqlite3_stmt*,int iCol);
75 | void * (*commit_hook)(sqlite3*,int(*)(void*),void*);
76 | int (*complete)(const char*sql);
77 | int (*complete16)(const void*sql);
78 | int (*create_collation)(sqlite3*,const char*,int,void*,
79 | int(*)(void*,int,const void*,int,const void*));
80 | int (*create_collation16)(sqlite3*,const void*,int,void*,
81 | int(*)(void*,int,const void*,int,const void*));
82 | int (*create_function)(sqlite3*,const char*,int,int,void*,
83 | void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
84 | void (*xStep)(sqlite3_context*,int,sqlite3_value**),
85 | void (*xFinal)(sqlite3_context*));
86 | int (*create_function16)(sqlite3*,const void*,int,int,void*,
87 | void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
88 | void (*xStep)(sqlite3_context*,int,sqlite3_value**),
89 | void (*xFinal)(sqlite3_context*));
90 | int (*create_module)(sqlite3*,const char*,const sqlite3_module*,void*);
91 | int (*data_count)(sqlite3_stmt*pStmt);
92 | sqlite3 * (*db_handle)(sqlite3_stmt*);
93 | int (*declare_vtab)(sqlite3*,const char*);
94 | int (*enable_shared_cache)(int);
95 | int (*errcode)(sqlite3*db);
96 | const char * (*errmsg)(sqlite3*);
97 | const void * (*errmsg16)(sqlite3*);
98 | int (*exec)(sqlite3*,const char*,sqlite3_callback,void*,char**);
99 | int (*expired)(sqlite3_stmt*);
100 | int (*finalize)(sqlite3_stmt*pStmt);
101 | void (*free)(void*);
102 | void (*free_table)(char**result);
103 | int (*get_autocommit)(sqlite3*);
104 | void * (*get_auxdata)(sqlite3_context*,int);
105 | int (*get_table)(sqlite3*,const char*,char***,int*,int*,char**);
106 | int (*global_recover)(void);
107 | void (*interruptx)(sqlite3*);
108 | sqlite_int64 (*last_insert_rowid)(sqlite3*);
109 | const char * (*libversion)(void);
110 | int (*libversion_number)(void);
111 | void *(*malloc)(int);
112 | char * (*mprintf)(const char*,...);
113 | int (*open)(const char*,sqlite3**);
114 | int (*open16)(const void*,sqlite3**);
115 | int (*prepare)(sqlite3*,const char*,int,sqlite3_stmt**,const char**);
116 | int (*prepare16)(sqlite3*,const void*,int,sqlite3_stmt**,const void**);
117 | void * (*profile)(sqlite3*,void(*)(void*,const char*,sqlite_uint64),void*);
118 | void (*progress_handler)(sqlite3*,int,int(*)(void*),void*);
119 | void *(*realloc)(void*,int);
120 | int (*reset)(sqlite3_stmt*pStmt);
121 | void (*result_blob)(sqlite3_context*,const void*,int,void(*)(void*));
122 | void (*result_double)(sqlite3_context*,double);
123 | void (*result_error)(sqlite3_context*,const char*,int);
124 | void (*result_error16)(sqlite3_context*,const void*,int);
125 | void (*result_int)(sqlite3_context*,int);
126 | void (*result_int64)(sqlite3_context*,sqlite_int64);
127 | void (*result_null)(sqlite3_context*);
128 | void (*result_text)(sqlite3_context*,const char*,int,void(*)(void*));
129 | void (*result_text16)(sqlite3_context*,const void*,int,void(*)(void*));
130 | void (*result_text16be)(sqlite3_context*,const void*,int,void(*)(void*));
131 | void (*result_text16le)(sqlite3_context*,const void*,int,void(*)(void*));
132 | void (*result_value)(sqlite3_context*,sqlite3_value*);
133 | void * (*rollback_hook)(sqlite3*,void(*)(void*),void*);
134 | int (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*,
135 | const char*,const char*),void*);
136 | void (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*));
137 | char * (*xsnprintf)(int,char*,const char*,...);
138 | int (*step)(sqlite3_stmt*);
139 | int (*table_column_metadata)(sqlite3*,const char*,const char*,const char*,
140 | char const**,char const**,int*,int*,int*);
141 | void (*thread_cleanup)(void);
142 | int (*total_changes)(sqlite3*);
143 | void * (*trace)(sqlite3*,void(*xTrace)(void*,const char*),void*);
144 | int (*transfer_bindings)(sqlite3_stmt*,sqlite3_stmt*);
145 | void * (*update_hook)(sqlite3*,void(*)(void*,int ,char const*,char const*,
146 | sqlite_int64),void*);
147 | void * (*user_data)(sqlite3_context*);
148 | const void * (*value_blob)(sqlite3_value*);
149 | int (*value_bytes)(sqlite3_value*);
150 | int (*value_bytes16)(sqlite3_value*);
151 | double (*value_double)(sqlite3_value*);
152 | int (*value_int)(sqlite3_value*);
153 | sqlite_int64 (*value_int64)(sqlite3_value*);
154 | int (*value_numeric_type)(sqlite3_value*);
155 | const unsigned char * (*value_text)(sqlite3_value*);
156 | const void * (*value_text16)(sqlite3_value*);
157 | const void * (*value_text16be)(sqlite3_value*);
158 | const void * (*value_text16le)(sqlite3_value*);
159 | int (*value_type)(sqlite3_value*);
160 | char *(*vmprintf)(const char*,va_list);
161 | /* Added ??? */
162 | int (*overload_function)(sqlite3*, const char *zFuncName, int nArg);
163 | /* Added by 3.3.13 */
164 | int (*prepare_v2)(sqlite3*,const char*,int,sqlite3_stmt**,const char**);
165 | int (*prepare16_v2)(sqlite3*,const void*,int,sqlite3_stmt**,const void**);
166 | int (*clear_bindings)(sqlite3_stmt*);
167 | /* Added by 3.4.1 */
168 | int (*create_module_v2)(sqlite3*,const char*,const sqlite3_module*,void*,
169 | void (*xDestroy)(void *));
170 | /* Added by 3.5.0 */
171 | int (*bind_zeroblob)(sqlite3_stmt*,int,int);
172 | int (*blob_bytes)(sqlite3_blob*);
173 | int (*blob_close)(sqlite3_blob*);
174 | int (*blob_open)(sqlite3*,const char*,const char*,const char*,sqlite3_int64,
175 | int,sqlite3_blob**);
176 | int (*blob_read)(sqlite3_blob*,void*,int,int);
177 | int (*blob_write)(sqlite3_blob*,const void*,int,int);
178 | int (*create_collation_v2)(sqlite3*,const char*,int,void*,
179 | int(*)(void*,int,const void*,int,const void*),
180 | void(*)(void*));
181 | int (*file_control)(sqlite3*,const char*,int,void*);
182 | sqlite3_int64 (*memory_highwater)(int);
183 | sqlite3_int64 (*memory_used)(void);
184 | sqlite3_mutex *(*mutex_alloc)(int);
185 | void (*mutex_enter)(sqlite3_mutex*);
186 | void (*mutex_free)(sqlite3_mutex*);
187 | void (*mutex_leave)(sqlite3_mutex*);
188 | int (*mutex_try)(sqlite3_mutex*);
189 | int (*open_v2)(const char*,sqlite3**,int,const char*);
190 | int (*release_memory)(int);
191 | void (*result_error_nomem)(sqlite3_context*);
192 | void (*result_error_toobig)(sqlite3_context*);
193 | int (*sleep)(int);
194 | void (*soft_heap_limit)(int);
195 | sqlite3_vfs *(*vfs_find)(const char*);
196 | int (*vfs_register)(sqlite3_vfs*,int);
197 | int (*vfs_unregister)(sqlite3_vfs*);
198 | int (*xthreadsafe)(void);
199 | void (*result_zeroblob)(sqlite3_context*,int);
200 | void (*result_error_code)(sqlite3_context*,int);
201 | int (*test_control)(int, ...);
202 | void (*randomness)(int,void*);
203 | sqlite3 *(*context_db_handle)(sqlite3_context*);
204 | int (*extended_result_codes)(sqlite3*,int);
205 | int (*limit)(sqlite3*,int,int);
206 | sqlite3_stmt *(*next_stmt)(sqlite3*,sqlite3_stmt*);
207 | const char *(*sql)(sqlite3_stmt*);
208 | int (*status)(int,int*,int*,int);
209 | int (*backup_finish)(sqlite3_backup*);
210 | sqlite3_backup *(*backup_init)(sqlite3*,const char*,sqlite3*,const char*);
211 | int (*backup_pagecount)(sqlite3_backup*);
212 | int (*backup_remaining)(sqlite3_backup*);
213 | int (*backup_step)(sqlite3_backup*,int);
214 | const char *(*compileoption_get)(int);
215 | int (*compileoption_used)(const char*);
216 | int (*create_function_v2)(sqlite3*,const char*,int,int,void*,
217 | void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
218 | void (*xStep)(sqlite3_context*,int,sqlite3_value**),
219 | void (*xFinal)(sqlite3_context*),
220 | void(*xDestroy)(void*));
221 | int (*db_config)(sqlite3*,int,...);
222 | sqlite3_mutex *(*db_mutex)(sqlite3*);
223 | int (*db_status)(sqlite3*,int,int*,int*,int);
224 | int (*extended_errcode)(sqlite3*);
225 | void (*log)(int,const char*,...);
226 | sqlite3_int64 (*soft_heap_limit64)(sqlite3_int64);
227 | const char *(*sourceid)(void);
228 | int (*stmt_status)(sqlite3_stmt*,int,int);
229 | int (*strnicmp)(const char*,const char*,int);
230 | int (*unlock_notify)(sqlite3*,void(*)(void**,int),void*);
231 | int (*wal_autocheckpoint)(sqlite3*,int);
232 | int (*wal_checkpoint)(sqlite3*,const char*);
233 | void *(*wal_hook)(sqlite3*,int(*)(void*,sqlite3*,const char*,int),void*);
234 | int (*blob_reopen)(sqlite3_blob*,sqlite3_int64);
235 | int (*vtab_config)(sqlite3*,int op,...);
236 | int (*vtab_on_conflict)(sqlite3*);
237 | /* Version 3.7.16 and later */
238 | int (*close_v2)(sqlite3*);
239 | const char *(*db_filename)(sqlite3*,const char*);
240 | int (*db_readonly)(sqlite3*,const char*);
241 | int (*db_release_memory)(sqlite3*);
242 | const char *(*errstr)(int);
243 | int (*stmt_busy)(sqlite3_stmt*);
244 | int (*stmt_readonly)(sqlite3_stmt*);
245 | int (*stricmp)(const char*,const char*);
246 | int (*uri_boolean)(const char*,const char*,int);
247 | sqlite3_int64 (*uri_int64)(const char*,const char*,sqlite3_int64);
248 | const char *(*uri_parameter)(const char*,const char*);
249 | char *(*xvsnprintf)(int,char*,const char*,va_list);
250 | int (*wal_checkpoint_v2)(sqlite3*,const char*,int,int*,int*);
251 | /* Version 3.8.7 and later */
252 | int (*auto_extension)(void(*)(void));
253 | int (*bind_blob64)(sqlite3_stmt*,int,const void*,sqlite3_uint64,
254 | void(*)(void*));
255 | int (*bind_text64)(sqlite3_stmt*,int,const char*,sqlite3_uint64,
256 | void(*)(void*),unsigned char);
257 | int (*cancel_auto_extension)(void(*)(void));
258 | int (*load_extension)(sqlite3*,const char*,const char*,char**);
259 | void *(*malloc64)(sqlite3_uint64);
260 | sqlite3_uint64 (*msize)(void*);
261 | void *(*realloc64)(void*,sqlite3_uint64);
262 | void (*reset_auto_extension)(void);
263 | void (*result_blob64)(sqlite3_context*,const void*,sqlite3_uint64,
264 | void(*)(void*));
265 | void (*result_text64)(sqlite3_context*,const char*,sqlite3_uint64,
266 | void(*)(void*), unsigned char);
267 | int (*strglob)(const char*,const char*);
268 | /* Version 3.8.11 and later */
269 | sqlite3_value *(*value_dup)(const sqlite3_value*);
270 | void (*value_free)(sqlite3_value*);
271 | int (*result_zeroblob64)(sqlite3_context*,sqlite3_uint64);
272 | int (*bind_zeroblob64)(sqlite3_stmt*, int, sqlite3_uint64);
273 | /* Version 3.9.0 and later */
274 | unsigned int (*value_subtype)(sqlite3_value*);
275 | void (*result_subtype)(sqlite3_context*,unsigned int);
276 | /* Version 3.10.0 and later */
277 | int (*status64)(int,sqlite3_int64*,sqlite3_int64*,int);
278 | int (*strlike)(const char*,const char*,unsigned int);
279 | int (*db_cacheflush)(sqlite3*);
280 | /* Version 3.12.0 and later */
281 | int (*system_errno)(sqlite3*);
282 | /* Version 3.14.0 and later */
283 | int (*trace_v2)(sqlite3*,unsigned,int(*)(unsigned,void*,void*,void*),void*);
284 | char *(*expanded_sql)(sqlite3_stmt*);
285 | /* Version 3.18.0 and later */
286 | void (*set_last_insert_rowid)(sqlite3*,sqlite3_int64);
287 | /* Version 3.20.0 and later */
288 | int (*prepare_v3)(sqlite3*,const char*,int,unsigned int,
289 | sqlite3_stmt**,const char**);
290 | int (*prepare16_v3)(sqlite3*,const void*,int,unsigned int,
291 | sqlite3_stmt**,const void**);
292 | int (*bind_pointer)(sqlite3_stmt*,int,void*,const char*,void(*)(void*));
293 | void (*result_pointer)(sqlite3_context*,void*,const char*,void(*)(void*));
294 | void *(*value_pointer)(sqlite3_value*,const char*);
295 | int (*vtab_nochange)(sqlite3_context*);
296 | int (*value_nochange)(sqlite3_value*);
297 | const char *(*vtab_collation)(sqlite3_index_info*,int);
298 | /* Version 3.24.0 and later */
299 | int (*keyword_count)(void);
300 | int (*keyword_name)(int,const char**,int*);
301 | int (*keyword_check)(const char*,int);
302 | sqlite3_str *(*str_new)(sqlite3*);
303 | char *(*str_finish)(sqlite3_str*);
304 | void (*str_appendf)(sqlite3_str*, const char *zFormat, ...);
305 | void (*str_vappendf)(sqlite3_str*, const char *zFormat, va_list);
306 | void (*str_append)(sqlite3_str*, const char *zIn, int N);
307 | void (*str_appendall)(sqlite3_str*, const char *zIn);
308 | void (*str_appendchar)(sqlite3_str*, int N, char C);
309 | void (*str_reset)(sqlite3_str*);
310 | int (*str_errcode)(sqlite3_str*);
311 | int (*str_length)(sqlite3_str*);
312 | char *(*str_value)(sqlite3_str*);
313 | /* Version 3.25.0 and later */
314 | int (*create_window_function)(sqlite3*,const char*,int,int,void*,
315 | void (*xStep)(sqlite3_context*,int,sqlite3_value**),
316 | void (*xFinal)(sqlite3_context*),
317 | void (*xValue)(sqlite3_context*),
318 | void (*xInv)(sqlite3_context*,int,sqlite3_value**),
319 | void(*xDestroy)(void*));
320 | /* Version 3.26.0 and later */
321 | const char *(*normalized_sql)(sqlite3_stmt*);
322 | /* Version 3.28.0 and later */
323 | int (*stmt_isexplain)(sqlite3_stmt*);
324 | int (*value_frombind)(sqlite3_value*);
325 | /* Version 3.30.0 and later */
326 | int (*drop_modules)(sqlite3*,const char**);
327 | /* Version 3.31.0 and later */
328 | sqlite3_int64 (*hard_heap_limit64)(sqlite3_int64);
329 | const char *(*uri_key)(const char*,int);
330 | const char *(*filename_database)(const char*);
331 | const char *(*filename_journal)(const char*);
332 | const char *(*filename_wal)(const char*);
333 | /* Version 3.32.0 and later */
334 | const char *(*create_filename)(const char*,const char*,const char*,
335 | int,const char**);
336 | void (*free_filename)(const char*);
337 | sqlite3_file *(*database_file_object)(const char*);
338 | /* Version 3.34.0 and later */
339 | int (*txn_state)(sqlite3*,const char*);
340 | /* Version 3.36.1 and later */
341 | sqlite3_int64 (*changes64)(sqlite3*);
342 | sqlite3_int64 (*total_changes64)(sqlite3*);
343 | /* Version 3.37.0 and later */
344 | int (*autovacuum_pages)(sqlite3*,
345 | unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int),
346 | void*, void(*)(void*));
347 | /* Version 3.38.0 and later */
348 | int (*error_offset)(sqlite3*);
349 | int (*vtab_rhs_value)(sqlite3_index_info*,int,sqlite3_value**);
350 | int (*vtab_distinct)(sqlite3_index_info*);
351 | int (*vtab_in)(sqlite3_index_info*,int,int);
352 | int (*vtab_in_first)(sqlite3_value*,sqlite3_value**);
353 | int (*vtab_in_next)(sqlite3_value*,sqlite3_value**);
354 | /* Version 3.39.0 and later */
355 | int (*deserialize)(sqlite3*,const char*,unsigned char*,
356 | sqlite3_int64,sqlite3_int64,unsigned);
357 | unsigned char *(*serialize)(sqlite3*,const char *,sqlite3_int64*,
358 | unsigned int);
359 | const char *(*db_name)(sqlite3*,int);
360 | /* Version 3.40.0 and later */
361 | int (*value_encoding)(sqlite3_value*);
362 | /* Version 3.41.0 and later */
363 | int (*is_interrupted)(sqlite3*);
364 | /* Version 3.43.0 and later */
365 | int (*stmt_explain)(sqlite3_stmt*,int);
366 | };
367 |
368 | /*
369 | ** This is the function signature used for all extension entry points. It
370 | ** is also defined in the file "loadext.c".
371 | */
372 | typedef int (*sqlite3_loadext_entry)(
373 | sqlite3 *db, /* Handle to the database. */
374 | char **pzErrMsg, /* Used to set error string on failure. */
375 | const sqlite3_api_routines *pThunk /* Extension API function pointers. */
376 | );
377 |
378 | /*
379 | ** The following macros redefine the API routines so that they are
380 | ** redirected through the global sqlite3_api structure.
381 | **
382 | ** This header file is also used by the loadext.c source file
383 | ** (part of the main SQLite library - not an extension) so that
384 | ** it can get access to the sqlite3_api_routines structure
385 | ** definition. But the main library does not want to redefine
386 | ** the API. So the redefinition macros are only valid if the
387 | ** SQLITE_CORE macros is undefined.
388 | */
389 | #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
390 | #define sqlite3_aggregate_context sqlite3_api->aggregate_context
391 | #ifndef SQLITE_OMIT_DEPRECATED
392 | #define sqlite3_aggregate_count sqlite3_api->aggregate_count
393 | #endif
394 | #define sqlite3_bind_blob sqlite3_api->bind_blob
395 | #define sqlite3_bind_double sqlite3_api->bind_double
396 | #define sqlite3_bind_int sqlite3_api->bind_int
397 | #define sqlite3_bind_int64 sqlite3_api->bind_int64
398 | #define sqlite3_bind_null sqlite3_api->bind_null
399 | #define sqlite3_bind_parameter_count sqlite3_api->bind_parameter_count
400 | #define sqlite3_bind_parameter_index sqlite3_api->bind_parameter_index
401 | #define sqlite3_bind_parameter_name sqlite3_api->bind_parameter_name
402 | #define sqlite3_bind_text sqlite3_api->bind_text
403 | #define sqlite3_bind_text16 sqlite3_api->bind_text16
404 | #define sqlite3_bind_value sqlite3_api->bind_value
405 | #define sqlite3_busy_handler sqlite3_api->busy_handler
406 | #define sqlite3_busy_timeout sqlite3_api->busy_timeout
407 | #define sqlite3_changes sqlite3_api->changes
408 | #define sqlite3_close sqlite3_api->close
409 | #define sqlite3_collation_needed sqlite3_api->collation_needed
410 | #define sqlite3_collation_needed16 sqlite3_api->collation_needed16
411 | #define sqlite3_column_blob sqlite3_api->column_blob
412 | #define sqlite3_column_bytes sqlite3_api->column_bytes
413 | #define sqlite3_column_bytes16 sqlite3_api->column_bytes16
414 | #define sqlite3_column_count sqlite3_api->column_count
415 | #define sqlite3_column_database_name sqlite3_api->column_database_name
416 | #define sqlite3_column_database_name16 sqlite3_api->column_database_name16
417 | #define sqlite3_column_decltype sqlite3_api->column_decltype
418 | #define sqlite3_column_decltype16 sqlite3_api->column_decltype16
419 | #define sqlite3_column_double sqlite3_api->column_double
420 | #define sqlite3_column_int sqlite3_api->column_int
421 | #define sqlite3_column_int64 sqlite3_api->column_int64
422 | #define sqlite3_column_name sqlite3_api->column_name
423 | #define sqlite3_column_name16 sqlite3_api->column_name16
424 | #define sqlite3_column_origin_name sqlite3_api->column_origin_name
425 | #define sqlite3_column_origin_name16 sqlite3_api->column_origin_name16
426 | #define sqlite3_column_table_name sqlite3_api->column_table_name
427 | #define sqlite3_column_table_name16 sqlite3_api->column_table_name16
428 | #define sqlite3_column_text sqlite3_api->column_text
429 | #define sqlite3_column_text16 sqlite3_api->column_text16
430 | #define sqlite3_column_type sqlite3_api->column_type
431 | #define sqlite3_column_value sqlite3_api->column_value
432 | #define sqlite3_commit_hook sqlite3_api->commit_hook
433 | #define sqlite3_complete sqlite3_api->complete
434 | #define sqlite3_complete16 sqlite3_api->complete16
435 | #define sqlite3_create_collation sqlite3_api->create_collation
436 | #define sqlite3_create_collation16 sqlite3_api->create_collation16
437 | #define sqlite3_create_function sqlite3_api->create_function
438 | #define sqlite3_create_function16 sqlite3_api->create_function16
439 | #define sqlite3_create_module sqlite3_api->create_module
440 | #define sqlite3_create_module_v2 sqlite3_api->create_module_v2
441 | #define sqlite3_data_count sqlite3_api->data_count
442 | #define sqlite3_db_handle sqlite3_api->db_handle
443 | #define sqlite3_declare_vtab sqlite3_api->declare_vtab
444 | #define sqlite3_enable_shared_cache sqlite3_api->enable_shared_cache
445 | #define sqlite3_errcode sqlite3_api->errcode
446 | #define sqlite3_errmsg sqlite3_api->errmsg
447 | #define sqlite3_errmsg16 sqlite3_api->errmsg16
448 | #define sqlite3_exec sqlite3_api->exec
449 | #ifndef SQLITE_OMIT_DEPRECATED
450 | #define sqlite3_expired sqlite3_api->expired
451 | #endif
452 | #define sqlite3_finalize sqlite3_api->finalize
453 | #define sqlite3_free sqlite3_api->free
454 | #define sqlite3_free_table sqlite3_api->free_table
455 | #define sqlite3_get_autocommit sqlite3_api->get_autocommit
456 | #define sqlite3_get_auxdata sqlite3_api->get_auxdata
457 | #define sqlite3_get_table sqlite3_api->get_table
458 | #ifndef SQLITE_OMIT_DEPRECATED
459 | #define sqlite3_global_recover sqlite3_api->global_recover
460 | #endif
461 | #define sqlite3_interrupt sqlite3_api->interruptx
462 | #define sqlite3_last_insert_rowid sqlite3_api->last_insert_rowid
463 | #define sqlite3_libversion sqlite3_api->libversion
464 | #define sqlite3_libversion_number sqlite3_api->libversion_number
465 | #define sqlite3_malloc sqlite3_api->malloc
466 | #define sqlite3_mprintf sqlite3_api->mprintf
467 | #define sqlite3_open sqlite3_api->open
468 | #define sqlite3_open16 sqlite3_api->open16
469 | #define sqlite3_prepare sqlite3_api->prepare
470 | #define sqlite3_prepare16 sqlite3_api->prepare16
471 | #define sqlite3_prepare_v2 sqlite3_api->prepare_v2
472 | #define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2
473 | #define sqlite3_profile sqlite3_api->profile
474 | #define sqlite3_progress_handler sqlite3_api->progress_handler
475 | #define sqlite3_realloc sqlite3_api->realloc
476 | #define sqlite3_reset sqlite3_api->reset
477 | #define sqlite3_result_blob sqlite3_api->result_blob
478 | #define sqlite3_result_double sqlite3_api->result_double
479 | #define sqlite3_result_error sqlite3_api->result_error
480 | #define sqlite3_result_error16 sqlite3_api->result_error16
481 | #define sqlite3_result_int sqlite3_api->result_int
482 | #define sqlite3_result_int64 sqlite3_api->result_int64
483 | #define sqlite3_result_null sqlite3_api->result_null
484 | #define sqlite3_result_text sqlite3_api->result_text
485 | #define sqlite3_result_text16 sqlite3_api->result_text16
486 | #define sqlite3_result_text16be sqlite3_api->result_text16be
487 | #define sqlite3_result_text16le sqlite3_api->result_text16le
488 | #define sqlite3_result_value sqlite3_api->result_value
489 | #define sqlite3_rollback_hook sqlite3_api->rollback_hook
490 | #define sqlite3_set_authorizer sqlite3_api->set_authorizer
491 | #define sqlite3_set_auxdata sqlite3_api->set_auxdata
492 | #define sqlite3_snprintf sqlite3_api->xsnprintf
493 | #define sqlite3_step sqlite3_api->step
494 | #define sqlite3_table_column_metadata sqlite3_api->table_column_metadata
495 | #define sqlite3_thread_cleanup sqlite3_api->thread_cleanup
496 | #define sqlite3_total_changes sqlite3_api->total_changes
497 | #define sqlite3_trace sqlite3_api->trace
498 | #ifndef SQLITE_OMIT_DEPRECATED
499 | #define sqlite3_transfer_bindings sqlite3_api->transfer_bindings
500 | #endif
501 | #define sqlite3_update_hook sqlite3_api->update_hook
502 | #define sqlite3_user_data sqlite3_api->user_data
503 | #define sqlite3_value_blob sqlite3_api->value_blob
504 | #define sqlite3_value_bytes sqlite3_api->value_bytes
505 | #define sqlite3_value_bytes16 sqlite3_api->value_bytes16
506 | #define sqlite3_value_double sqlite3_api->value_double
507 | #define sqlite3_value_int sqlite3_api->value_int
508 | #define sqlite3_value_int64 sqlite3_api->value_int64
509 | #define sqlite3_value_numeric_type sqlite3_api->value_numeric_type
510 | #define sqlite3_value_text sqlite3_api->value_text
511 | #define sqlite3_value_text16 sqlite3_api->value_text16
512 | #define sqlite3_value_text16be sqlite3_api->value_text16be
513 | #define sqlite3_value_text16le sqlite3_api->value_text16le
514 | #define sqlite3_value_type sqlite3_api->value_type
515 | #define sqlite3_vmprintf sqlite3_api->vmprintf
516 | #define sqlite3_vsnprintf sqlite3_api->xvsnprintf
517 | #define sqlite3_overload_function sqlite3_api->overload_function
518 | #define sqlite3_prepare_v2 sqlite3_api->prepare_v2
519 | #define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2
520 | #define sqlite3_clear_bindings sqlite3_api->clear_bindings
521 | #define sqlite3_bind_zeroblob sqlite3_api->bind_zeroblob
522 | #define sqlite3_blob_bytes sqlite3_api->blob_bytes
523 | #define sqlite3_blob_close sqlite3_api->blob_close
524 | #define sqlite3_blob_open sqlite3_api->blob_open
525 | #define sqlite3_blob_read sqlite3_api->blob_read
526 | #define sqlite3_blob_write sqlite3_api->blob_write
527 | #define sqlite3_create_collation_v2 sqlite3_api->create_collation_v2
528 | #define sqlite3_file_control sqlite3_api->file_control
529 | #define sqlite3_memory_highwater sqlite3_api->memory_highwater
530 | #define sqlite3_memory_used sqlite3_api->memory_used
531 | #define sqlite3_mutex_alloc sqlite3_api->mutex_alloc
532 | #define sqlite3_mutex_enter sqlite3_api->mutex_enter
533 | #define sqlite3_mutex_free sqlite3_api->mutex_free
534 | #define sqlite3_mutex_leave sqlite3_api->mutex_leave
535 | #define sqlite3_mutex_try sqlite3_api->mutex_try
536 | #define sqlite3_open_v2 sqlite3_api->open_v2
537 | #define sqlite3_release_memory sqlite3_api->release_memory
538 | #define sqlite3_result_error_nomem sqlite3_api->result_error_nomem
539 | #define sqlite3_result_error_toobig sqlite3_api->result_error_toobig
540 | #define sqlite3_sleep sqlite3_api->sleep
541 | #define sqlite3_soft_heap_limit sqlite3_api->soft_heap_limit
542 | #define sqlite3_vfs_find sqlite3_api->vfs_find
543 | #define sqlite3_vfs_register sqlite3_api->vfs_register
544 | #define sqlite3_vfs_unregister sqlite3_api->vfs_unregister
545 | #define sqlite3_threadsafe sqlite3_api->xthreadsafe
546 | #define sqlite3_result_zeroblob sqlite3_api->result_zeroblob
547 | #define sqlite3_result_error_code sqlite3_api->result_error_code
548 | #define sqlite3_test_control sqlite3_api->test_control
549 | #define sqlite3_randomness sqlite3_api->randomness
550 | #define sqlite3_context_db_handle sqlite3_api->context_db_handle
551 | #define sqlite3_extended_result_codes sqlite3_api->extended_result_codes
552 | #define sqlite3_limit sqlite3_api->limit
553 | #define sqlite3_next_stmt sqlite3_api->next_stmt
554 | #define sqlite3_sql sqlite3_api->sql
555 | #define sqlite3_status sqlite3_api->status
556 | #define sqlite3_backup_finish sqlite3_api->backup_finish
557 | #define sqlite3_backup_init sqlite3_api->backup_init
558 | #define sqlite3_backup_pagecount sqlite3_api->backup_pagecount
559 | #define sqlite3_backup_remaining sqlite3_api->backup_remaining
560 | #define sqlite3_backup_step sqlite3_api->backup_step
561 | #define sqlite3_compileoption_get sqlite3_api->compileoption_get
562 | #define sqlite3_compileoption_used sqlite3_api->compileoption_used
563 | #define sqlite3_create_function_v2 sqlite3_api->create_function_v2
564 | #define sqlite3_db_config sqlite3_api->db_config
565 | #define sqlite3_db_mutex sqlite3_api->db_mutex
566 | #define sqlite3_db_status sqlite3_api->db_status
567 | #define sqlite3_extended_errcode sqlite3_api->extended_errcode
568 | #define sqlite3_log sqlite3_api->log
569 | #define sqlite3_soft_heap_limit64 sqlite3_api->soft_heap_limit64
570 | #define sqlite3_sourceid sqlite3_api->sourceid
571 | #define sqlite3_stmt_status sqlite3_api->stmt_status
572 | #define sqlite3_strnicmp sqlite3_api->strnicmp
573 | #define sqlite3_unlock_notify sqlite3_api->unlock_notify
574 | #define sqlite3_wal_autocheckpoint sqlite3_api->wal_autocheckpoint
575 | #define sqlite3_wal_checkpoint sqlite3_api->wal_checkpoint
576 | #define sqlite3_wal_hook sqlite3_api->wal_hook
577 | #define sqlite3_blob_reopen sqlite3_api->blob_reopen
578 | #define sqlite3_vtab_config sqlite3_api->vtab_config
579 | #define sqlite3_vtab_on_conflict sqlite3_api->vtab_on_conflict
580 | /* Version 3.7.16 and later */
581 | #define sqlite3_close_v2 sqlite3_api->close_v2
582 | #define sqlite3_db_filename sqlite3_api->db_filename
583 | #define sqlite3_db_readonly sqlite3_api->db_readonly
584 | #define sqlite3_db_release_memory sqlite3_api->db_release_memory
585 | #define sqlite3_errstr sqlite3_api->errstr
586 | #define sqlite3_stmt_busy sqlite3_api->stmt_busy
587 | #define sqlite3_stmt_readonly sqlite3_api->stmt_readonly
588 | #define sqlite3_stricmp sqlite3_api->stricmp
589 | #define sqlite3_uri_boolean sqlite3_api->uri_boolean
590 | #define sqlite3_uri_int64 sqlite3_api->uri_int64
591 | #define sqlite3_uri_parameter sqlite3_api->uri_parameter
592 | #define sqlite3_uri_vsnprintf sqlite3_api->xvsnprintf
593 | #define sqlite3_wal_checkpoint_v2 sqlite3_api->wal_checkpoint_v2
594 | /* Version 3.8.7 and later */
595 | #define sqlite3_auto_extension sqlite3_api->auto_extension
596 | #define sqlite3_bind_blob64 sqlite3_api->bind_blob64
597 | #define sqlite3_bind_text64 sqlite3_api->bind_text64
598 | #define sqlite3_cancel_auto_extension sqlite3_api->cancel_auto_extension
599 | #define sqlite3_load_extension sqlite3_api->load_extension
600 | #define sqlite3_malloc64 sqlite3_api->malloc64
601 | #define sqlite3_msize sqlite3_api->msize
602 | #define sqlite3_realloc64 sqlite3_api->realloc64
603 | #define sqlite3_reset_auto_extension sqlite3_api->reset_auto_extension
604 | #define sqlite3_result_blob64 sqlite3_api->result_blob64
605 | #define sqlite3_result_text64 sqlite3_api->result_text64
606 | #define sqlite3_strglob sqlite3_api->strglob
607 | /* Version 3.8.11 and later */
608 | #define sqlite3_value_dup sqlite3_api->value_dup
609 | #define sqlite3_value_free sqlite3_api->value_free
610 | #define sqlite3_result_zeroblob64 sqlite3_api->result_zeroblob64
611 | #define sqlite3_bind_zeroblob64 sqlite3_api->bind_zeroblob64
612 | /* Version 3.9.0 and later */
613 | #define sqlite3_value_subtype sqlite3_api->value_subtype
614 | #define sqlite3_result_subtype sqlite3_api->result_subtype
615 | /* Version 3.10.0 and later */
616 | #define sqlite3_status64 sqlite3_api->status64
617 | #define sqlite3_strlike sqlite3_api->strlike
618 | #define sqlite3_db_cacheflush sqlite3_api->db_cacheflush
619 | /* Version 3.12.0 and later */
620 | #define sqlite3_system_errno sqlite3_api->system_errno
621 | /* Version 3.14.0 and later */
622 | #define sqlite3_trace_v2 sqlite3_api->trace_v2
623 | #define sqlite3_expanded_sql sqlite3_api->expanded_sql
624 | /* Version 3.18.0 and later */
625 | #define sqlite3_set_last_insert_rowid sqlite3_api->set_last_insert_rowid
626 | /* Version 3.20.0 and later */
627 | #define sqlite3_prepare_v3 sqlite3_api->prepare_v3
628 | #define sqlite3_prepare16_v3 sqlite3_api->prepare16_v3
629 | #define sqlite3_bind_pointer sqlite3_api->bind_pointer
630 | #define sqlite3_result_pointer sqlite3_api->result_pointer
631 | #define sqlite3_value_pointer sqlite3_api->value_pointer
632 | /* Version 3.22.0 and later */
633 | #define sqlite3_vtab_nochange sqlite3_api->vtab_nochange
634 | #define sqlite3_value_nochange sqlite3_api->value_nochange
635 | #define sqlite3_vtab_collation sqlite3_api->vtab_collation
636 | /* Version 3.24.0 and later */
637 | #define sqlite3_keyword_count sqlite3_api->keyword_count
638 | #define sqlite3_keyword_name sqlite3_api->keyword_name
639 | #define sqlite3_keyword_check sqlite3_api->keyword_check
640 | #define sqlite3_str_new sqlite3_api->str_new
641 | #define sqlite3_str_finish sqlite3_api->str_finish
642 | #define sqlite3_str_appendf sqlite3_api->str_appendf
643 | #define sqlite3_str_vappendf sqlite3_api->str_vappendf
644 | #define sqlite3_str_append sqlite3_api->str_append
645 | #define sqlite3_str_appendall sqlite3_api->str_appendall
646 | #define sqlite3_str_appendchar sqlite3_api->str_appendchar
647 | #define sqlite3_str_reset sqlite3_api->str_reset
648 | #define sqlite3_str_errcode sqlite3_api->str_errcode
649 | #define sqlite3_str_length sqlite3_api->str_length
650 | #define sqlite3_str_value sqlite3_api->str_value
651 | /* Version 3.25.0 and later */
652 | #define sqlite3_create_window_function sqlite3_api->create_window_function
653 | /* Version 3.26.0 and later */
654 | #define sqlite3_normalized_sql sqlite3_api->normalized_sql
655 | /* Version 3.28.0 and later */
656 | #define sqlite3_stmt_isexplain sqlite3_api->stmt_isexplain
657 | #define sqlite3_value_frombind sqlite3_api->value_frombind
658 | /* Version 3.30.0 and later */
659 | #define sqlite3_drop_modules sqlite3_api->drop_modules
660 | /* Version 3.31.0 and later */
661 | #define sqlite3_hard_heap_limit64 sqlite3_api->hard_heap_limit64
662 | #define sqlite3_uri_key sqlite3_api->uri_key
663 | #define sqlite3_filename_database sqlite3_api->filename_database
664 | #define sqlite3_filename_journal sqlite3_api->filename_journal
665 | #define sqlite3_filename_wal sqlite3_api->filename_wal
666 | /* Version 3.32.0 and later */
667 | #define sqlite3_create_filename sqlite3_api->create_filename
668 | #define sqlite3_free_filename sqlite3_api->free_filename
669 | #define sqlite3_database_file_object sqlite3_api->database_file_object
670 | /* Version 3.34.0 and later */
671 | #define sqlite3_txn_state sqlite3_api->txn_state
672 | /* Version 3.36.1 and later */
673 | #define sqlite3_changes64 sqlite3_api->changes64
674 | #define sqlite3_total_changes64 sqlite3_api->total_changes64
675 | /* Version 3.37.0 and later */
676 | #define sqlite3_autovacuum_pages sqlite3_api->autovacuum_pages
677 | /* Version 3.38.0 and later */
678 | #define sqlite3_error_offset sqlite3_api->error_offset
679 | #define sqlite3_vtab_rhs_value sqlite3_api->vtab_rhs_value
680 | #define sqlite3_vtab_distinct sqlite3_api->vtab_distinct
681 | #define sqlite3_vtab_in sqlite3_api->vtab_in
682 | #define sqlite3_vtab_in_first sqlite3_api->vtab_in_first
683 | #define sqlite3_vtab_in_next sqlite3_api->vtab_in_next
684 | /* Version 3.39.0 and later */
685 | #ifndef SQLITE_OMIT_DESERIALIZE
686 | #define sqlite3_deserialize sqlite3_api->deserialize
687 | #define sqlite3_serialize sqlite3_api->serialize
688 | #endif
689 | #define sqlite3_db_name sqlite3_api->db_name
690 | /* Version 3.40.0 and later */
691 | #define sqlite3_value_encoding sqlite3_api->value_encoding
692 | /* Version 3.41.0 and later */
693 | #define sqlite3_is_interrupted sqlite3_api->is_interrupted
694 | /* Version 3.43.0 and later */
695 | #define sqlite3_stmt_explain sqlite3_api->stmt_explain
696 | #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
697 |
698 | #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
699 | /* This case when the file really is being compiled as a loadable
700 | ** extension */
701 | # define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0;
702 | # define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v;
703 | # define SQLITE_EXTENSION_INIT3 \
704 | extern const sqlite3_api_routines *sqlite3_api;
705 | #else
706 | /* This case when the file is being statically linked into the
707 | ** application */
708 | # define SQLITE_EXTENSION_INIT1 /*no-op*/
709 | # define SQLITE_EXTENSION_INIT2(v) (void)v; /* unused parameter */
710 | # define SQLITE_EXTENSION_INIT3 /*no-op*/
711 | #endif
712 |
713 | #endif /* SQLITE3EXT_H */
714 |
--------------------------------------------------------------------------------
/images/Console.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ItaiShek/CC_Generator/2387c66ea1be18d411854bd5b5e9a6baabf099e1/images/Console.gif
--------------------------------------------------------------------------------
/images/GUI.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ItaiShek/CC_Generator/2387c66ea1be18d411854bd5b5e9a6baabf099e1/images/GUI.gif
--------------------------------------------------------------------------------
/include/API/Card.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | /**
9 | * @class Card
10 | * @brief Represents a credit card with issuer information, length, and prefixes.
11 | *
12 | * The Card class provides functionality to parse numeric ranges and generate
13 | * random valid card numbers based on predefined parameters.
14 | */
15 | class Card
16 | {
17 | public:
18 | // constructors
19 | Card() = default;
20 |
21 | /**
22 | * @brief Parameterized constructor.
23 | * @param issuer The issuer of the card.
24 | * @param len The length of the card number.
25 | * @param prefixes The numeric prefixes associated with the card.
26 | */
27 | Card(const std::string &issuer, int len, const std::string &prefixes) : m_issuer{issuer}, m_len{len}, m_prefixes{prefixes} { parse_ranges(prefixes); }
28 |
29 | // getters
30 | const std::string get_issuer() const { return m_issuer; }
31 | const int get_len() const { return m_len; }
32 | const std::string get_prefixes() const { return m_prefixes; }
33 |
34 | // setters
35 | void set_issuer(const std::string &issuer) { m_issuer = issuer; }
36 | void set_len(int len) { m_len = len; }
37 | void set_prefixes(const std::string &prefixes) { m_prefixes = prefixes; }
38 |
39 | // other methods
40 | bool empty() const { return m_issuer.empty() || m_prefixes.empty() || m_len == 0; }
41 |
42 | bool operator==(const Card &c) const
43 | {
44 | return (c.m_issuer == m_issuer && c.m_len == m_len && c.m_prefixes == m_prefixes);
45 | }
46 |
47 | // Parses a string representing numeric ranges and populates the Card object.
48 | void parse_ranges(const std::string &ranges_str);
49 |
50 | // Generates a random card number based on predefined ranges and Luhn's algorithm.
51 | // Appends the generated card number to the provided std::ostringstream.
52 | void generate_card(std::ostringstream &oss) const;
53 |
54 | // Validates a credit card based on issuer, length, and prefixes.
55 | static bool validate_card(const std::string &issuer, int length, const std::string &prefixes);
56 |
57 | // Validates the issuer of a credit card.
58 | static bool validate_issuer(const std::string &issuer);
59 |
60 | // Validates the prefix of a credit card based on its length.
61 | static bool validate_prefix(const std::string &prefix, int len);
62 |
63 | // Validates the length of a credit card number.
64 | static bool validate_length(int len);
65 |
66 | static void generate_cvv(const char delimiter, std::ostringstream &oss);
67 | static void generate_date(const char delimiter, std::chrono::year_month_day start, std::chrono::year_month_day end, std::ostringstream &oss);
68 |
69 | private:
70 | std::string m_issuer{}; // The issuer of the card.
71 | int m_len{}; // The length of the card number.
72 | std::string m_prefixes{}; // The numeric prefixes associated with the card.
73 | std::vector> m_ranges; // Parsed numeric ranges.
74 | static std::mt19937 m_rng;
75 | };
--------------------------------------------------------------------------------
/include/API/DB_API.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 |
7 | #include "sqlite3.h"
8 | #include "Card.h"
9 |
10 | /**
11 | * @namespace DB_API
12 | * @brief Provides functions for interacting with an SQLite database and managing credit card data.
13 | *
14 | * The DB_API namespace contains functions for various database-related operations
15 | * such as checking file existence, reading an SQLite database, and writing/reading
16 | * credit card data. It encapsulates all related database utilities in a single, logical scope.
17 | */
18 | namespace DB_API
19 | {
20 | // Checks if a file exists.
21 | bool check_file_exists(const std::string &filename);
22 |
23 | // Reads an SQLite database and returns a shared pointer to it.
24 | std::shared_ptr read_db(const std::string &db_path);
25 |
26 | // Writes credit card data to the database, updating existing entries.
27 | int write_cards(std::shared_ptr db, const std::vector &data, std::string &error_msg);
28 |
29 | // Reads credit card data from the database and stores it in a vector.
30 | int read_cards(std::shared_ptr db, std::vector &data, std::string &error_msg);
31 |
32 | // Reads a random first and last name and returns it as a string.
33 | std::string get_random_name(std::shared_ptr db);
34 | };
--------------------------------------------------------------------------------
/include/API/Date.h:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | /**
5 | * @namespace Date
6 | * @brief Provides utility functions for working with dates, including validation, conversion, and date calculations.
7 | *
8 | * This namespace contains functions for handling dates, such as determining the number of days in a month,
9 | * validating if one date is earlier than another, converting a date to a string, and constructing date objects
10 | * from day, month, and year values.
11 | */
12 | namespace Date
13 | {
14 | // Returns the number of days in a given month and year.
15 | int days_in_month(int year, int month);
16 |
17 | // Constructs a std::chrono::year_month_day object from day, month, and year values.
18 | std::chrono::year_month_day get_date_from_ymd(unsigned int d, unsigned int m, int y);
19 |
20 | // Validates that a second date is not earlier than the first date.
21 | bool vali_date(int d1, int m1, int y1, int d2, int m2, int y2);
22 |
23 | // Converts a std::chrono::year_month_day object to a string.
24 | std::string string_from_date(std::chrono::year_month_day date);
25 | }
--------------------------------------------------------------------------------
/include/API/File.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #ifdef __EMSCRIPTEN__
15 | #include
16 | #endif
17 |
18 | #include "sqlite3.h"
19 | #include "Card.h"
20 | #include "DB_API.h"
21 |
22 | extern std::atomic g_paused;
23 | extern std::atomic g_started;
24 | extern std::atomic g_progress;
25 | std::atomic export_finished = false;
26 |
27 | /**
28 | * @struct date_struct
29 | * @brief Represents a date range with a generation flag.
30 | *
31 | * This structure holds a flag that determines whether a date range should be generated, along with the
32 | * start and end dates of the range. The dates are represented using `std::chrono::year_month_day`.
33 | */
34 | struct date_struct
35 | {
36 | /**
37 | * @brief Start date of the range.
38 | *
39 | * This field holds the start date of the range, represented as `std::chrono::year_month_day`.
40 | */
41 | std::chrono::year_month_day start{std::chrono::year_month_day{std::chrono::floor(std::chrono::system_clock::now())}}; // current date
42 |
43 | /**
44 | * @brief End date of the range.
45 | *
46 | * This field holds the end date of the range, represented as `std::chrono::year_month_day`.
47 | */
48 | std::chrono::year_month_day end{start + std::chrono::years{3}}; // 3 years from now
49 | };
50 |
51 | /**
52 | * @class File
53 | * @brief Represents a file-related utility class.
54 | *
55 | * This class provides methods for exporting cards, estimating time, and estimating size.
56 | */
57 | class File
58 | {
59 | public:
60 | /**
61 | * @brief Retrieves the indices of true values in a boolean vector.
62 | *
63 | * This function takes a boolean vector as input and returns a vector containing the indices
64 | * of the true values in the input vector.
65 | *
66 | * @param vec A boolean vector to process.
67 | * @return A vector containing the indices of true values in the input vector.
68 | *
69 | */
70 | static std::vector get_true_vec(const std::vector &vec)
71 | {
72 | std::vector true_vec;
73 |
74 | for (int i{}; i < vec.size(); i++)
75 | {
76 | if (vec[i])
77 | {
78 | true_vec.push_back(i);
79 | }
80 | }
81 | return true_vec;
82 | }
83 |
84 | /**
85 | * @brief Chooses a random index from a vector of integers.
86 | *
87 | * This function takes a vector of integers as input and returns a randomly chosen index
88 | * from that vector. The randomness is determined using a uniform distribution.
89 | *
90 | * @param vec A vector of integers from which to choose a random index.
91 | * @return A randomly selected index from the input vector.
92 | *
93 | */
94 | static int choose_random_index(const std::vector &vec)
95 | {
96 | if (vec.empty())
97 | {
98 | return -1;
99 | }
100 |
101 | std::uniform_int_distribution dist(0, static_cast(vec.size() - 1));
102 | return vec[dist(m_gen)];
103 | }
104 |
105 | /**
106 | * @brief Exports a specified number of randomly selected cards to a file.
107 | *
108 | * This templated function exports a specified number of randomly selected cards from
109 | * the provided vector to the given file. It uses a selection vector to determine which
110 | * cards to export. The export is performed in chunks to enhance performance.
111 | *
112 | * @tparam T The type of the amount parameter.
113 | * @param file An output file stream to write the exported cards.
114 | * @param cards_vec A vector containing the cards to choose from.
115 | * @param selection_vec A vector of boolean values indicating the selection status of cards.
116 | * @param amount The number of cards to export.
117 | * @param db A shared pointer to the database.
118 | *
119 | */
120 | template
121 | static void export_cards(std::ofstream &file, const std::vector &cards_vec, const std::vector &selection_vec, T amount, std::shared_ptr db)
122 | {
123 | constexpr int chunk = 4096;
124 | std::vector indexes_vec{get_true_vec(selection_vec)};
125 | std::ostringstream oss(std::ios_base::ate);
126 | T size{};
127 | int rnd_idx{};
128 | T i;
129 | for (i = 0; i < amount; i++)
130 | {
131 | while (g_paused)
132 | {
133 | std::this_thread::sleep_for(std::chrono::milliseconds(250));
134 | if (g_started == false)
135 | {
136 | break;
137 | }
138 | }
139 | if (g_started == false)
140 | {
141 | break;
142 | }
143 | rnd_idx = choose_random_index(indexes_vec);
144 | cards_vec[rnd_idx].generate_card(oss);
145 |
146 | if (m_cvv_flag)
147 | {
148 | Card::generate_cvv(m_delimiter, oss);
149 | }
150 |
151 | if (m_date_flag)
152 | {
153 | Card::generate_date(m_delimiter, m_date.start, m_date.end, oss);
154 | }
155 |
156 | if (m_name_flag and db != nullptr)
157 | {
158 | std::string name = DB_API::get_random_name(db);
159 | if (name.empty() == false)
160 | {
161 | oss << m_delimiter;
162 | oss << name;
163 | }
164 | }
165 |
166 | oss << "\n";
167 |
168 | // write chunk to file
169 | if (oss.tellp() > chunk)
170 | {
171 | // Extract and write the first "chunk" bytes
172 | file << oss.str().substr(0, chunk);
173 |
174 | // Remove the bytes from the stringstream
175 | oss.str(oss.str().substr(chunk));
176 |
177 | // update the progress bar value
178 | g_progress = static_cast(i) / amount;
179 | }
180 | }
181 |
182 | // Write any remaining content in the stringstream
183 | if (g_started)
184 | {
185 | // int size = oss.tellp();
186 | std::streamoff size = oss.tellp();
187 |
188 | if (size > 0)
189 | {
190 | size -= 1;
191 | oss.str(oss.str().substr(0, size));
192 | }
193 | file << oss.str();
194 | g_progress = static_cast(i) / amount;
195 | }
196 |
197 | file.close();
198 | g_started = false;
199 | }
200 |
201 | /**
202 | * @brief Estimates the time taken to generate a single card.
203 | *
204 | * This templated function estimates the time taken to generate a single card
205 | * using a temporary card object and a specified number of iterations. The time
206 | * is calculated by measuring the duration it takes to generate the card the
207 | * specified number of times and then dividing by the number of iterations.
208 | *
209 | * @tparam T The duration type (e.g., std::chrono::milliseconds, std::chrono::seconds).
210 | * @return The estimated time taken to generate a single card.
211 | *
212 | */
213 | template
214 | static T estimate_time()
215 | {
216 | Card temp_card = Card{"temp", 16, "1,2,3,4,5-6"};
217 | size_t div{1000};
218 | size_t i{};
219 | T duration{};
220 | std::ostringstream temp_oss;
221 | auto start{std::chrono::high_resolution_clock::now()};
222 | for (i = 0; i < div; i++)
223 | {
224 | temp_card.generate_card(temp_oss);
225 | }
226 | auto end{std::chrono::high_resolution_clock::now()};
227 |
228 | return std::chrono::duration_cast(end - start) / div;
229 | }
230 |
231 | /**
232 | * @brief Estimates the average time to generate a CVV using the Card::generate_cvv function.
233 | *
234 | * This function measures the time taken to generate a CVV using the `Card::generate_cvv`
235 | * function multiple times (defaulted to 1000 iterations). It calculates the average time
236 | * per CVV generation and returns it in the specified duration type.
237 | *
238 | * @tparam T The type of duration to return (e.g., std::chrono::milliseconds).
239 | * @return The average time taken to generate a CVV, in the specified duration type.
240 | *
241 | * @see Card::generate_cvv
242 | */
243 | template
244 | static T estimate_cvv_time()
245 | {
246 | size_t div{1000};
247 | size_t i{};
248 | T duration{};
249 | std::ostringstream temp_oss;
250 | auto start{std::chrono::high_resolution_clock::now()};
251 | for (i = 0; i < div; i++)
252 | {
253 | Card::generate_cvv(m_delimiter, temp_oss);
254 | }
255 | auto end{std::chrono::high_resolution_clock::now()};
256 |
257 | return std::chrono::duration_cast(end - start) / div;
258 | }
259 |
260 | /**
261 | * @brief Estimates the average time to generate a date using the Card::generate_date function.
262 | *
263 | * This function measures the time taken to generate a date using the `Card::generate_date`
264 | * function multiple times (defaulted to 1000 iterations). It calculates the average time
265 | * per generation and returns it in the specified duration type.
266 | *
267 | * @tparam T The type of duration to return (e.g., std::chrono::milliseconds).
268 | * @return The average time taken to generate a date, in the specified duration type.
269 | *
270 | * @see Card::generate_date
271 | */
272 | template
273 | static T estimate_date_time()
274 | {
275 | size_t div{1000};
276 | size_t i{};
277 | T duration{};
278 | std::ostringstream temp_oss;
279 | auto start{std::chrono::high_resolution_clock::now()};
280 | for (i = 0; i < div; i++)
281 | {
282 | Card::generate_date(m_delimiter, m_date.start, m_date.end, temp_oss);
283 | }
284 | auto end{std::chrono::high_resolution_clock::now()};
285 |
286 | return std::chrono::duration_cast(end - start) / div;
287 | }
288 |
289 | /**
290 | * @brief Estimates the average time to retrieve a random name from the database.
291 | *
292 | * This function measures the time taken to retrieve a random name from the
293 | * database multiple times (defaulted to 10 iterations). It calculates the
294 | * average time per retrieval and returns it in the specified duration type.
295 | * If any condition fails (e.g., the database does not exist, cannot be opened,
296 | * or no names are found), it returns a zero duration.
297 | *
298 | * @tparam T The type of duration to return (e.g., std::chrono::milliseconds).
299 | * @param db_path The path to the database file.
300 | * @return The average time taken to retrieve a random name from the database, in the specified duration type.
301 | *
302 | * @see DB_API::check_file_exists
303 | * @see DB_API::read_db
304 | * @see DB_API::get_random_name
305 | */
306 | template
307 | static T estimate_name_time(std::string db_path)
308 | {
309 | size_t div{10};
310 | size_t i{};
311 | T duration{};
312 | std::ostringstream temp_oss;
313 |
314 | if (DB_API::check_file_exists(db_path) == false)
315 | {
316 | return std::chrono::duration_cast(T{0});
317 | }
318 |
319 | std::shared_ptr db{DB_API::read_db(db_path)};
320 |
321 | if (db == nullptr)
322 | {
323 | return std::chrono::duration_cast(T{0});
324 | }
325 |
326 | if (DB_API::get_random_name(db).empty())
327 | {
328 | return std::chrono::duration_cast(T{0});
329 | }
330 |
331 | auto start{std::chrono::high_resolution_clock::now()};
332 | for (i = 0; i < div; i++)
333 | {
334 | DB_API::get_random_name(db);
335 | }
336 | auto end{std::chrono::high_resolution_clock::now()};
337 |
338 | return std::chrono::duration_cast(end - start) / div;
339 | }
340 |
341 | /**
342 | * @brief Formats a time string for a given duration.
343 | *
344 | * This function takes a std::chrono::... as input and returns a formatted string of it.
345 | *
346 | * @param duration The duration to format.
347 | * @return The formatted duration string as "X Years Y Months Z Days Hours:Minutes:Seconds:Milliseconds".
348 | */
349 | template
350 | static inline std::string format_time(T duration)
351 | {
352 | std::ostringstream estimated_time;
353 |
354 | auto years{std::chrono::duration_cast>>(duration)};
355 | duration -= std::chrono::duration_cast>>(years);
356 |
357 | auto months{std::chrono::duration_cast>>(duration)};
358 | duration -= std::chrono::duration_cast(months);
359 |
360 | auto days{std::chrono::duration_cast>>(duration)};
361 | duration -= std::chrono::duration_cast(days);
362 |
363 | auto hours{std::chrono::duration_cast(duration)};
364 | duration -= std::chrono::duration_cast(hours);
365 |
366 | auto minutes{std::chrono::duration_cast(duration)};
367 | duration -= std::chrono::duration_cast(minutes);
368 |
369 | auto seconds{std::chrono::duration_cast(duration)};
370 | duration -= std::chrono::duration_cast(seconds);
371 |
372 | auto milliseconds{std::chrono::duration_cast(duration)};
373 |
374 | if (years.count() > 0)
375 | {
376 | estimated_time << std::to_string(years.count()) << " years ";
377 | }
378 | if (months.count() > 0)
379 | {
380 | estimated_time << std::to_string(months.count()) << " months ";
381 | }
382 | if (days.count() > 0)
383 | {
384 | estimated_time << std::to_string(days.count()) << " days ";
385 | }
386 |
387 | estimated_time
388 | << std::setw(2) << std::setfill('0') << hours.count() << ":"
389 | << std::setw(2) << std::setfill('0') << minutes.count() << ":"
390 | << std::setw(2) << std::setfill('0') << seconds.count() << ":"
391 | << std::setw(3) << std::setfill('0') << milliseconds.count();
392 |
393 | return estimated_time.str();
394 | }
395 |
396 | /**
397 | * @brief Estimates the size in human-readable format based on the given amount.
398 | *
399 | * This templated function estimates the size in a human-readable format (e.g., B, KB, MB)
400 | * based on the provided amount. The size is calculated by multiplying the amount with the
401 | * size of a representative string and then converting it to a suitable unit.
402 | *
403 | * @tparam T The type of the amount parameter.
404 | * @param amount The amount for which to estimate the size.
405 | * @return A string representing the estimated size in human-readable format.
406 | *
407 | */
408 | template
409 | static inline std::string estimate_size(T amount)
410 | {
411 | constexpr double name_size{15};
412 | constexpr double cvv_size{4};
413 | constexpr double date_size{11};
414 | constexpr double card_size{17};
415 |
416 | double total_size = card_size;
417 | total_size += m_cvv_flag ? cvv_size : 0;
418 | total_size += m_name_flag ? name_size : 0;
419 | total_size += m_date_flag ? date_size : 0;
420 |
421 | double size{amount * total_size};
422 | static std::array sizes{"B", "KB", "MB", "GB", "TB"};
423 | size_t si{};
424 |
425 | for (si = 0; si < sizes.size(); si++)
426 | {
427 | if (size < 1024)
428 | {
429 | break;
430 | }
431 | size /= 1024.0f;
432 | }
433 | si = si < sizes.size() ? si : sizes.size() - 1;
434 |
435 | return std::to_string(size) + " [" + sizes[si] + "]";
436 | }
437 |
438 | #ifdef __EMSCRIPTEN__
439 |
440 | /**
441 | * @brief Holds the state for an ongoing export operation.
442 | *
443 | * This structure stores all necessary information required to manage
444 | * the asynchronous export process, including output buffering,
445 | * progress tracking, card selection, and file destination.
446 | */
447 | struct ExportState
448 | {
449 | std::ostringstream oss; ///< Output buffer used to accumulate export content.
450 | int i = 0; ///< Current export iteration index.
451 | int amount; ///< Total number of cards to export.
452 | std::vector cards_vec; ///< Vector of available cards to export from.
453 | std::vector selection_vec; ///< Selection vector indicating which cards are selected.
454 | std::shared_ptr db; ///< Shared pointer to the SQLite database for name generation.
455 | std::vector indexes_vec; ///< Precomputed list of selected indexes for efficient access.
456 | std::string vfs_path; ///< Virtual filesystem path where the output file will be written.
457 | };
458 |
459 | /**
460 | * @brief Performs a single asynchronous step in the card export process.
461 | *
462 | * This function is designed to be repeatedly scheduled with `emscripten_async_call`
463 | * to allow non-blocking export of card data to the virtual file system (VFS).
464 | *
465 | * It checks for pause and stop signals, writes data in chunks to avoid memory issues,
466 | * and finalizes the export by flushing the remaining content once all items are processed.
467 | *
468 | * @param Unused A dummy pointer required by `emscripten_async_call`. Ignored in this implementation.
469 | */
470 | static void export_step(void *)
471 | {
472 | if (g_started == false || export_state == nullptr)
473 | return;
474 |
475 | constexpr int chunk = 4096;
476 | auto &s = *export_state;
477 |
478 | if (g_paused)
479 | {
480 | emscripten_async_call(export_step, nullptr, 250);
481 | return;
482 | }
483 |
484 | if (s.i >= s.amount)
485 | {
486 | // Write any remaining content in the stringstream before closing file
487 | std::streamoff size = s.oss.tellp();
488 |
489 | if (size > 0)
490 | {
491 | size -= 1;
492 | std::ofstream file(s.vfs_path, std::ios::app); // append mode
493 | s.oss.str(s.oss.str().substr(0, size));
494 | file << s.oss.str();
495 | file.close();
496 | }
497 |
498 | export_finished = true;
499 | g_progress = 1.0f;
500 | g_started = false;
501 | delete export_state;
502 | export_state = nullptr;
503 | return;
504 | }
505 |
506 | int rnd_idx = choose_random_index(s.indexes_vec);
507 | s.cards_vec[rnd_idx].generate_card(s.oss);
508 |
509 | if (m_cvv_flag)
510 | Card::generate_cvv(m_delimiter, s.oss);
511 | if (m_date_flag)
512 | Card::generate_date(m_delimiter, m_date.start, m_date.end, s.oss);
513 | if (m_name_flag && s.db)
514 | {
515 | std::string name = DB_API::get_random_name(s.db);
516 | if (name.empty() == false)
517 | {
518 | s.oss << m_delimiter << name;
519 | }
520 | }
521 |
522 | s.oss << "\n";
523 |
524 | if (s.oss.tellp() > chunk)
525 | {
526 | std::ofstream file(s.vfs_path, std::ios::app);
527 | file << s.oss.str().substr(0, chunk);
528 | file.close();
529 | s.oss.str(s.oss.str().substr(chunk));
530 | }
531 |
532 | g_progress = static_cast(s.i) / s.amount;
533 | s.i++;
534 |
535 | emscripten_async_call(export_step, nullptr, 0); // Schedule next chunk
536 | }
537 |
538 | /**
539 | * @brief Initializes and starts the asynchronous export process.
540 | *
541 | * This function prepares the internal export state, clears the target file in the virtual file system (VFS),
542 | * and begins the asynchronous card export routine via `emscripten_async_call`.
543 | *
544 | * @param cards A vector of `Card` objects used to generate the exported data.
545 | * @param selection A vector of booleans indicating which cards are selected for export.
546 | * @param amount The number of cards to export.
547 | * @param db A shared pointer to the SQLite3 database used for generating additional card data (e.g., names).
548 | * @param vfs_path The VFS path where the export file will be written. This file is truncated at the beginning.
549 | */
550 | static void start_export(const std::vector &cards, const std::vector &selection, int amount, std::shared_ptr db, const std::string &vfs_path)
551 | {
552 | // Overwrite (truncate) the file at the start
553 | std::ofstream truncate_file(vfs_path);
554 | truncate_file.close();
555 |
556 | export_state = new ExportState{
557 | std::ostringstream(std::ios_base::ate),
558 | 0,
559 | amount,
560 | cards,
561 | selection,
562 | db,
563 | get_true_vec(selection),
564 | vfs_path};
565 |
566 | g_started = true;
567 | export_finished = false;
568 | emscripten_async_call(export_step, nullptr, 0);
569 | }
570 |
571 | static inline ExportState *export_state{nullptr};
572 | #endif
573 |
574 | static std::mt19937 m_gen;
575 | static inline date_struct m_date;
576 | static inline char m_delimiter{';'};
577 | static inline bool m_date_flag{false};
578 | static inline bool m_cvv_flag{false};
579 | static inline bool m_name_flag{false};
580 | File() = delete;
581 | };
582 |
--------------------------------------------------------------------------------
/include/Console/Console.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 |
4 | namespace console
5 | {
6 | /**
7 | * @brief Function signature for the console application entry point.
8 | *
9 | * This function is the entry point for the console application and is meant
10 | * to be called from external code to start the application.
11 | *
12 | * @param version A string representing the version information.
13 | * @param url A string containing the URL information.
14 | * @param license A string containing the license information.
15 | */
16 | void run(const std::string& version, const std::string& url, const std::string& license);
17 | }
--------------------------------------------------------------------------------
/include/GUI/GUI.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 |
4 | namespace gui
5 | {
6 | /**
7 | * @brief Function signature for the GUI application entry point.
8 | *
9 | * This function is the entry point for the GUI application and is meant
10 | * to be called from external code to start the application.
11 | *
12 | * @param version A string representing the version information.
13 | * @param url A string containing the URL information.
14 | * @param license A string containing the license information.
15 | */
16 | void run(const std::string& version, const std::string& url, const std::string& license);
17 | }
--------------------------------------------------------------------------------
/src/API/Card.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include "Card.h"
5 |
6 | std::mt19937 Card::m_rng{std::random_device{}()};
7 |
8 | /**
9 | * @brief Parses a string representing numeric ranges and populates the Card object.
10 | *
11 | * This function takes a string containing comma-separated numeric ranges and parses
12 | * them, populating the Card object with the extracted ranges.
13 | *
14 | * The input string should have the format "start-end,start-end,..." where start and
15 | * end are integers defining a numeric range. If a single number is provided without
16 | * a dash, it is considered a range with the same start and end values.
17 | *
18 | * @param ranges_str A string containing comma-separated numeric ranges.
19 | *
20 | * @note The function assumes a valid input format. No input validation is performed.
21 | *
22 | * @see Card
23 | */
24 | void Card::parse_ranges(const std::string &ranges_str)
25 | {
26 | std::istringstream iss(ranges_str);
27 | std::string range_token;
28 | while (std::getline(iss, range_token, ','))
29 | {
30 | std::istringstream range_stream(range_token);
31 | int start, end;
32 | char dash;
33 | range_stream >> start;
34 | if (range_stream >> dash >> end)
35 | {
36 | // range case
37 | m_ranges.emplace_back(start, end);
38 | }
39 | else
40 | {
41 | // single number case
42 | m_ranges.emplace_back(start, start);
43 | }
44 | }
45 | }
46 |
47 | /**
48 | * @brief Generates a random card number based on predefined ranges and Luhn's algorithm.
49 | *
50 | * This function generates a random card number within the predefined numeric ranges
51 | * associated with the Card object. It utilizes a combination of random number generation,
52 | * Luhn's algorithm, and predefined ranges to create a valid card number.
53 | *
54 | * The generated card number is appended to the provided std::ostringstream.
55 | *
56 | * @param oss The std::ostringstream to which the generated card number is appended.
57 | *
58 | * @note The function assumes that the Card object has valid ranges and length parameters.
59 | * It uses a random number generator (m_rng) associated with the Card object.
60 | * The generated card number adheres to Luhn's algorithm for validity.
61 | *
62 | * @see Card
63 | * @see parse_ranges()
64 | */
65 | void Card::generate_card(std::ostringstream &oss) const
66 | {
67 | // Randomly select a range
68 | std::uniform_int_distribution range_dist(0, m_ranges.size() - 1);
69 | const auto &range = m_ranges[range_dist(m_rng)];
70 |
71 | // Generate a random number within the selected range
72 | std::uniform_int_distribution num_dist(range.first, range.second);
73 | int prefix{num_dist(m_rng)};
74 |
75 | // Generate a random card
76 | std::string rnd_card{std::to_string(prefix)};
77 | std::uniform_int_distribution dis(0, 9);
78 |
79 | // Reserve memory for the string to avoid reallocations
80 | rnd_card.reserve(m_len);
81 |
82 | for (int i = rnd_card.size(); i < m_len - 1; i++)
83 | {
84 | rnd_card += '0' + dis(m_rng);
85 | }
86 |
87 | // Apply Luhn's algorithm to generate the last digit
88 | int sum{0};
89 | bool double_digit{true};
90 |
91 | for (int i{m_len - 2}; i >= 0; i--)
92 | {
93 | int digit = rnd_card[i] - '0';
94 |
95 | if (double_digit && (digit *= 2) >= 10)
96 | {
97 | digit -= 9;
98 | }
99 |
100 | sum += digit;
101 | double_digit = !double_digit;
102 | }
103 |
104 | // Calculate the last digit to make the entire number valid
105 | rnd_card += '0' + ((10 - (sum % 10)) % 10);
106 | oss << rnd_card;
107 | }
108 |
109 | /**
110 | * @brief Validates the issuer string.
111 | *
112 | * This function checks if the provided issuer string contains at least one non-whitespace character.
113 | * Whitespace characters include space, tab, newline, vertical tab, form feed, and carriage return.
114 | *
115 | * @param issuer The issuer string to be validated.
116 | * @return true if the issuer string contains at least one non-whitespace character, false otherwise.
117 | *
118 | * @note This function considers whitespace characters to be any of the following: space, tab, newline,
119 | * vertical tab, form feed, or carriage return.
120 | */
121 | bool Card::validate_issuer(const std::string &issuer)
122 | {
123 | return issuer.find_first_not_of(" \t\n\v\f\r") != std::string::npos;
124 | }
125 |
126 | /**
127 | * @brief Validates a comma-separated string of numeric prefixes according to specific rules.
128 | *
129 | * This function validates a comma-separated string of numeric prefixes based on the following rules:
130 | * 1. Each token separated by a comma must be a non-empty string.
131 | * 2. Tokens cannot end with a comma.
132 | * 3. Each token must represent either a single numeric value or a numeric range in the format "start-end".
133 | * 4. Numeric ranges must be in increasing order.
134 | * 5. Numeric values and ranges must be positive integers and must not exceed the specified length.
135 | *
136 | * @param prefix The comma-separated string of numeric prefixes to be validated.
137 | * @param len The maximum length that a valid prefix can have.
138 | * @return true if the input string conforms to the specified rules, false otherwise.
139 | *
140 | * @details This function takes a comma-separated string of numeric prefixes and validates each token
141 | * separately. It checks if each token is a valid positive integer or a valid numeric range with a
142 | * start value less than or equal to the end value. It also ensures that the length of the prefix does
143 | * not exceed the specified maximum length.
144 | *
145 | */
146 | bool Card::validate_prefix(const std::string &prefix, int len)
147 | {
148 | if (prefix.empty())
149 | {
150 | return false;
151 | }
152 | if (prefix[prefix.size() - 1] == ',')
153 | {
154 | return false;
155 | }
156 |
157 | std::stringstream ss(prefix);
158 | std::string token;
159 |
160 | while (std::getline(ss, token, ','))
161 | {
162 | size_t start{token.find_first_not_of(" ")};
163 | size_t end{token.find_last_not_of(" ")};
164 |
165 | // if it's empty return false
166 | if (start == std::string::npos || end == std::string::npos)
167 | {
168 | return false;
169 | }
170 |
171 | token = token.substr(start, end - start + 1);
172 |
173 | // range
174 | if (std::regex_match(token, std::regex(R"(\d+\-\d+)")))
175 | {
176 | std::istringstream iss(token);
177 | int start, end;
178 | char dash;
179 | iss >> start >> dash >> end;
180 | // Range is not in increasing order
181 | if (end < start)
182 | {
183 | return false;
184 | }
185 | // the prefix is larger than the length
186 | if (std::to_string(start).length() > len || std::to_string(end).length() > len || start == 0)
187 | {
188 | return false;
189 | }
190 | }
191 | // digit
192 | else if (std::regex_match(token, std::regex(R"(\d+)")))
193 | {
194 | // the prefix is larger than the length or if it's zero
195 | if (token.size() > len || std::stoi(token.c_str()) == 0)
196 | {
197 | return false;
198 | }
199 | }
200 | // NaN or negative number
201 | else
202 | {
203 | return false;
204 | }
205 | }
206 |
207 | return true;
208 | }
209 |
210 | /**
211 | * @brief Validates the length of a credit card number.
212 | *
213 | * This function checks whether the provided length is within the valid range
214 | * for a credit card number. Credit card numbers typically have lengths between
215 | * 2 and 32 characters (inclusive).
216 | *
217 | * @param len The length of the credit card number to be validated.
218 | * @return True if the length is within the valid range, false otherwise.
219 | */
220 | bool Card::validate_length(int len)
221 | {
222 | return len >= 2 && len <= 32;
223 | }
224 |
225 | /**
226 | * @brief Validates a credit card based on issuer, length, and prefixes.
227 | *
228 | * This function checks whether a credit card is valid by validating the issuer,
229 | * length, and prefixes. It combines three validation checks: issuer validation,
230 | * length validation, and prefix validation.
231 | *
232 | * @param issuer The issuer of the credit card.
233 | * @param length The expected length of the credit card number.
234 | * @param prefixes The valid prefixes for the credit card.
235 | * @return True if the credit card is valid, false otherwise.
236 | *
237 | * @see DB_API::validate_issuer() For issuer validation.
238 | * @see DB_API::validate_length() For length validation.
239 | * @see DB_API::validate_prefix() For prefix validation.
240 | *
241 | * @note This function assumes that the individual validation functions are
242 | * implemented and correctly check the issuer, length, and prefixes.
243 | */
244 | bool Card::validate_card(const std::string &issuer, int length, const std::string &prefixes)
245 | {
246 | return (Card::validate_issuer(issuer) &&
247 | Card::validate_length(length) &&
248 | Card::validate_prefix(prefixes, length));
249 | }
250 |
251 | /**
252 | * @brief Generates a 3-digit CVV and appends it to the provided string stream.
253 | *
254 | * This function generates a 3-digit CVV using random numbers between 0 and 9, appends
255 | * it to the given string stream (`std::ostringstream`), and separates the CVV with the
256 | * specified delimiter.
257 | *
258 | * @param delimiter The character used to separate the CVV from other content in the stream.
259 | * @param oss The output string stream where the generated CVV will be appended.
260 | *
261 | * @see std::uniform_int_distribution
262 | */
263 | void Card::generate_cvv(const char delimiter, std::ostringstream &oss)
264 | {
265 | std::uniform_int_distribution dis(0, 9);
266 | oss << delimiter;
267 | for (size_t i{0}; i < 3; i++)
268 | {
269 | oss << dis(m_rng);
270 | }
271 | }
272 |
273 | /**
274 | * @brief Generates a random date between the given start and end dates and appends it to the provided string stream.
275 | *
276 | * This function calculates a random date within the range specified by `start` and `end`
277 | * using a random number generator. The generated date is then appended to the given string
278 | * stream (`std::ostringstream`) with the specified delimiter.
279 | *
280 | * @param delimiter The character used to separate the date from other content in the stream.
281 | * @param start The starting date of the range.
282 | * @param end The ending date of the range.
283 | * @param oss The output string stream where the generated date will be appended.
284 | *
285 | * @see std::chrono::sys_days
286 | * @see std::uniform_int_distribution
287 | */
288 | void Card::generate_date(const char delimiter, std::chrono::year_month_day start, std::chrono::year_month_day end, std::ostringstream &oss)
289 | {
290 | // Convert to sys_days (number of days since 1970-01-01)
291 | std::chrono::sys_days start_days{start};
292 | std::chrono::sys_days end_days{end};
293 |
294 | // Calculate range in days
295 | auto days_range = (end_days - start_days).count();
296 |
297 | // Random number generator
298 | std::uniform_int_distribution dis(0, days_range);
299 |
300 | // Random offset from start
301 | std::chrono::sys_days random_day = start_days + std::chrono::days{dis(m_rng)};
302 | std::chrono::year_month_day random_date{random_day};
303 |
304 | oss << delimiter;
305 | oss << random_date;
306 | }
--------------------------------------------------------------------------------
/src/API/DB_API.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include "DB_API_.h"
5 | #include "DB_API.h"
6 |
7 | /**
8 | * @brief Checks if the provided SQLite database is valid and accessible.
9 | *
10 | * This function executes a simple query on the given SQLite database to check its validity.
11 | * If the database is valid and accessible, it returns true. If any error occurs during
12 | * the query execution or if the database is not valid, it returns false.
13 | *
14 | * @param db A reference to the SQLite database object to be checked for validity.
15 | * @return True if the database is valid and accessible; false otherwise.
16 | */
17 | bool DB_API::is_sqlite_database(sqlite3 *&db)
18 | {
19 | // Execute a simple query to check if the database is valid
20 | const char *query{"SELECT name FROM sqlite_master WHERE type='table' LIMIT 1;"};
21 | char *err_msg{nullptr};
22 | int result = sqlite3_exec(db, query, nullptr, nullptr, &err_msg);
23 |
24 | if (result != SQLITE_OK)
25 | {
26 | // Print error message
27 | std::cerr << "Error executing query: " << err_msg << std::endl;
28 | sqlite3_free(err_msg); // Free the error message
29 | sqlite3_close(db); // Close the database immediately after error
30 | return false;
31 | }
32 |
33 | return true;
34 | }
35 |
36 | /**
37 | * @brief Reads an SQLite database from the specified path.
38 | *
39 | * This function attempts to open an SQLite database located at the given
40 | * file path. If the database opens successfully and is a valid SQLite database,
41 | * it returns a shared pointer to the opened database. If any error occurs during
42 | * the opening process, or if the file is not a valid SQLite database, it returns nullptr.
43 | *
44 | * @param db_path The path to the SQLite database file to be opened.
45 | * @return A shared pointer to the opened SQLite database if successful; nullptr otherwise.
46 | *
47 | * @see DB_API::is_sqlite_database(sqlite3* db)
48 | */
49 | std::shared_ptr DB_API::read_db(const std::string &db_path)
50 | {
51 | sqlite3 *db;
52 | if (sqlite3_open(db_path.c_str(), &db) != SQLITE_OK)
53 | {
54 | return nullptr;
55 | }
56 | if (DB_API::is_sqlite_database(db) == false)
57 | {
58 | return nullptr;
59 | }
60 | return std::shared_ptr{db, [](sqlite3 *ptr)
61 | {if (ptr) { sqlite3_close(ptr); } }};
62 | }
63 |
64 | /**
65 | * @brief Checks if a file exists in the file system.
66 | *
67 | * This function determines whether a file with the given filename exists
68 | * in the file system. It checks the existence of the file by using the stat
69 | * system call. The function returns true if the file exists and is accessible,
70 | * and false otherwise.
71 | *
72 | * @param filename The path to the file to be checked for existence.
73 | * @return True if the file exists and is accessible; false otherwise.
74 | */
75 | bool DB_API::check_file_exists(const std::string &filename)
76 | {
77 | struct stat buffer;
78 | return ((filename.empty() == false) &&
79 | (stat(filename.c_str(), &buffer) == 0));
80 | }
81 |
82 | /**
83 | * @brief Reads credit card data from the database.
84 | *
85 | * This function retrieves credit card data from the database and populates
86 | * a vector with Card objects containing valid card information.
87 | *
88 | * @param db A shared pointer to the SQLite database.
89 | * @param data A vector to store Card objects with valid credit card information.
90 | * @param error_msg A string reference to store error messages, if any.
91 | * @return An SQLite error code. SQLITE_OK if successful, otherwise an error code.
92 | *
93 | */
94 | int DB_API::read_cards(std::shared_ptr db, std::vector &data, std::string &error_msg)
95 | {
96 | const char *selectStatement = "SELECT Issuer, Length, Prefixes FROM cards_table;";
97 | sqlite3_stmt *stmt = nullptr;
98 | data.clear(); // Ensure the output vector is empty on entry
99 |
100 | int rc = sqlite3_prepare_v2(db.get(), selectStatement, -1, &stmt, nullptr);
101 | if (rc != SQLITE_OK)
102 | {
103 | // Check if the table exists
104 | sqlite3_stmt *check_stmt = nullptr;
105 | const char *check_table = "SELECT name FROM sqlite_master WHERE type='table' AND name='cards_table';";
106 |
107 | if (sqlite3_prepare_v2(db.get(), check_table, -1, &check_stmt, nullptr) == SQLITE_OK)
108 | {
109 | if (sqlite3_step(check_stmt) != SQLITE_ROW)
110 | {
111 | // Table does not exist — allow graceful fallback (e.g., empty DB)
112 | sqlite3_finalize(check_stmt);
113 | return SQLITE_OK;
114 | }
115 | sqlite3_finalize(check_stmt);
116 | }
117 |
118 | error_msg = "Prepare statement error: " + std::string(sqlite3_errmsg(db.get()));
119 | return rc;
120 | }
121 |
122 | // Table exists — proceed to fetch data
123 | while ((rc = sqlite3_step(stmt)) == SQLITE_ROW)
124 | {
125 | const char *issuer_c = reinterpret_cast(sqlite3_column_text(stmt, 0));
126 | int length = sqlite3_column_int(stmt, 1);
127 | const char *prefixes_c = reinterpret_cast(sqlite3_column_text(stmt, 2));
128 |
129 | if (issuer_c && prefixes_c)
130 | {
131 | std::string issuer{issuer_c};
132 | std::string prefixes{prefixes_c};
133 |
134 | if (Card::validate_card(issuer, length, prefixes))
135 | {
136 | data.emplace_back(issuer, length, prefixes);
137 | }
138 | }
139 | }
140 |
141 | if (rc != SQLITE_DONE)
142 | {
143 | error_msg = "Step statement error: " + std::string(sqlite3_errmsg(db.get()));
144 | sqlite3_finalize(stmt);
145 | return rc;
146 | }
147 |
148 | sqlite3_finalize(stmt);
149 | return SQLITE_OK;
150 | }
151 |
152 | /**
153 | * @brief Writes credit card data to the database, updating existing entries.
154 | *
155 | * This function creates a table for credit card data if it doesn't exist,
156 | * then updates existing entries and inserts new ones based on the provided data.
157 | *
158 | * @param db A shared pointer to the SQLite database.
159 | * @param data A vector of Card objects containing credit card information.
160 | * @param error_msg A string reference to store error messages, if any.
161 | * @return An SQLite error code. SQLITE_OK if successful, otherwise an error code.
162 | *
163 | * @note The function assumes that the Card class has methods such as `get_issuer()`,
164 | * `get_len()`, and `get_prefixes()` to retrieve the respective card details.
165 | */
166 | int DB_API::write_cards(std::shared_ptr db, const std::vector &data, std::string &error_msg)
167 | {
168 | char *err = nullptr;
169 | int rc;
170 |
171 | // Step 1: Ensure main table exists
172 | rc = sqlite3_exec(db.get(),
173 | "CREATE TABLE IF NOT EXISTS cards_table (Issuer TEXT, Length INTEGER, Prefixes TEXT);",
174 | nullptr, nullptr, &err);
175 | if (rc != SQLITE_OK)
176 | {
177 | error_msg = "Failed to create cards_table: " + std::string(err);
178 | sqlite3_free(err);
179 | return rc;
180 | }
181 |
182 | // Step 2: Start transaction
183 | rc = sqlite3_exec(db.get(), "BEGIN TRANSACTION;", nullptr, nullptr, &err);
184 | if (rc != SQLITE_OK)
185 | {
186 | error_msg = "Failed to begin transaction: " + std::string(err);
187 | sqlite3_free(err);
188 | return rc;
189 | }
190 |
191 | // Step 3: Create temporary table
192 | rc = sqlite3_exec(db.get(),
193 | "DROP TABLE IF EXISTS temp_cards;"
194 | "CREATE TEMP TABLE temp_cards (Issuer TEXT, Length INTEGER, Prefixes TEXT);",
195 | nullptr, nullptr, &err);
196 | if (rc != SQLITE_OK)
197 | {
198 | error_msg = "Failed to create temp table: " + std::string(err);
199 | sqlite3_free(err);
200 | sqlite3_exec(db.get(), "ROLLBACK;", nullptr, nullptr, nullptr);
201 | return rc;
202 | }
203 |
204 | // Step 4: Prepare insert into temp_cards
205 | sqlite3_stmt *insert_stmt = nullptr;
206 | rc = sqlite3_prepare_v2(db.get(),
207 | "INSERT INTO temp_cards (Issuer, Length, Prefixes) VALUES (?, ?, ?);",
208 | -1, &insert_stmt, nullptr);
209 | if (rc != SQLITE_OK)
210 | {
211 | error_msg = "Failed to prepare insert into temp_cards: " + std::string(sqlite3_errmsg(db.get()));
212 | sqlite3_exec(db.get(), "ROLLBACK;", nullptr, nullptr, nullptr);
213 | return rc;
214 | }
215 |
216 | for (const auto &card : data)
217 | {
218 | std::string issuer = card.get_issuer();
219 | std::string prefixes = card.get_prefixes();
220 | int length = card.get_len();
221 |
222 | sqlite3_bind_text(insert_stmt, 1, issuer.c_str(), -1, SQLITE_TRANSIENT);
223 | sqlite3_bind_int(insert_stmt, 2, length);
224 | sqlite3_bind_text(insert_stmt, 3, prefixes.c_str(), -1, SQLITE_TRANSIENT);
225 |
226 | rc = sqlite3_step(insert_stmt);
227 | if (rc != SQLITE_DONE)
228 | {
229 | error_msg = "Failed to insert into temp_cards: " + std::string(sqlite3_errmsg(db.get()));
230 | sqlite3_finalize(insert_stmt);
231 | sqlite3_exec(db.get(), "ROLLBACK;", nullptr, nullptr, nullptr);
232 | return rc;
233 | }
234 |
235 | sqlite3_reset(insert_stmt);
236 | sqlite3_clear_bindings(insert_stmt);
237 | }
238 | sqlite3_finalize(insert_stmt);
239 |
240 | // Step 5: Delete cards not in the new input
241 | rc = sqlite3_exec(db.get(),
242 | "DELETE FROM cards_table "
243 | "WHERE NOT EXISTS ("
244 | " SELECT 1 FROM temp_cards "
245 | " WHERE temp_cards.Issuer = cards_table.Issuer "
246 | " AND temp_cards.Length = cards_table.Length "
247 | " AND temp_cards.Prefixes = cards_table.Prefixes"
248 | ");",
249 | nullptr, nullptr, &err);
250 | if (rc != SQLITE_OK)
251 | {
252 | error_msg = "Failed to delete outdated cards: " + std::string(err);
253 | sqlite3_free(err);
254 | sqlite3_exec(db.get(), "ROLLBACK;", nullptr, nullptr, nullptr);
255 | return rc;
256 | }
257 |
258 | // Step 6: Insert new records that are not already in cards_table
259 | rc = sqlite3_exec(db.get(),
260 | "INSERT INTO cards_table (Issuer, Length, Prefixes) "
261 | "SELECT Issuer, Length, Prefixes FROM temp_cards "
262 | "WHERE NOT EXISTS ("
263 | " SELECT 1 FROM cards_table "
264 | " WHERE cards_table.Issuer = temp_cards.Issuer "
265 | " AND cards_table.Length = temp_cards.Length "
266 | " AND cards_table.Prefixes = temp_cards.Prefixes"
267 | ");",
268 | nullptr, nullptr, &err);
269 | if (rc != SQLITE_OK)
270 | {
271 | error_msg = "Failed to insert new cards: " + std::string(err);
272 | sqlite3_free(err);
273 | sqlite3_exec(db.get(), "ROLLBACK;", nullptr, nullptr, nullptr);
274 | return rc;
275 | }
276 |
277 | // Step 7: Drop the temp table and commit
278 | sqlite3_exec(db.get(), "DROP TABLE IF EXISTS temp_cards;", nullptr, nullptr, nullptr);
279 | rc = sqlite3_exec(db.get(), "COMMIT;", nullptr, nullptr, &err);
280 | if (rc != SQLITE_OK)
281 | {
282 | error_msg = "Failed to commit transaction: " + std::string(err);
283 | sqlite3_free(err);
284 | return rc;
285 | }
286 |
287 | return SQLITE_OK;
288 | }
289 |
290 | /**
291 | * @brief Retrieves a random full name from the database.
292 | *
293 | * This function selects a random first name from the "Fnames" table and a random
294 | * last name from the "Lnames" table in the SQLite database, then concatenates
295 | * them into a full name. If either query fails or returns no result, an empty
296 | * string is returned.
297 | *
298 | * @param db A shared pointer to an open SQLite3 database connection.
299 | * The database must contain "Fnames" and "Lnames" tables,
300 | * each with a "name" column.
301 | *
302 | * @return A string containing the random full name (e.g., "John Doe"),
303 | * or an empty string if an error occurs or no name is found.
304 | */
305 | std::string DB_API::get_random_name(std::shared_ptr db)
306 | {
307 | const char *f_name_statement = "SELECT name FROM Fnames ORDER BY RANDOM() LIMIT 1;";
308 | const char *l_name_statement = "SELECT name FROM Lnames ORDER BY RANDOM() LIMIT 1;";
309 | sqlite3_stmt *stmt = nullptr;
310 |
311 | // Helper lambda to get a name
312 | auto get_name = [&](const char *sql_query) -> std::string
313 | {
314 | sqlite3_stmt *local_stmt = nullptr;
315 | if (sqlite3_prepare_v2(db.get(), sql_query, -1, &local_stmt, nullptr) != SQLITE_OK)
316 | {
317 | sqlite3_finalize(local_stmt);
318 | return "";
319 | }
320 |
321 | std::string result;
322 | if (sqlite3_step(local_stmt) == SQLITE_ROW)
323 | {
324 | const unsigned char *text = sqlite3_column_text(local_stmt, 0);
325 | if (text)
326 | {
327 | result = reinterpret_cast(text);
328 | }
329 | }
330 |
331 | sqlite3_finalize(local_stmt);
332 | return result;
333 | };
334 |
335 | std::string first_name{get_name(f_name_statement)};
336 | std::string last_name{get_name(l_name_statement)};
337 |
338 | if (first_name.empty() || last_name.empty())
339 | {
340 | return "";
341 | }
342 |
343 | return first_name + " " + last_name;
344 | }
--------------------------------------------------------------------------------
/src/API/DB_API_.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "sqlite3.h"
3 |
4 | /**
5 | * @namespace DB_API
6 | * @brief Provides functions for interacting with an SQLite database and managing credit card data.
7 | *
8 | * The DB_API namespace contains functions for various database-related operations
9 | * such as checking file existence, reading an SQLite database, and writing/reading
10 | * credit card data. It encapsulates all related database utilities in a single, logical scope.
11 | */
12 | namespace DB_API
13 | {
14 | // Checks if the provided object is an SQLite database.
15 | bool is_sqlite_database(sqlite3 *&db);
16 | };
--------------------------------------------------------------------------------
/src/API/Date.cpp:
--------------------------------------------------------------------------------
1 | #include "Date.h"
2 |
3 | /**
4 | * @brief Returns the number of days in a given month and year.
5 | *
6 | * This function accounts for leap years when determining the number of days
7 | * in February. For all other months, it returns the standard number of days.
8 | *
9 | * @param year The year used to determine if February has 28 or 29 days.
10 | * @param month The month (1–12) for which to retrieve the number of days.
11 | * @return The number of days in the specified month.
12 | */
13 | int Date::days_in_month(int year, int month)
14 | {
15 | // Array of days for each month (February will be adjusted for leap year)
16 | static const int days_in_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
17 |
18 | // Adjust February for leap year
19 | if (month == 2)
20 | {
21 | if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
22 | {
23 | return 29; // Leap year
24 | }
25 | }
26 |
27 | return days_in_month[month - 1];
28 | }
29 |
30 | /**
31 | * @brief Constructs a std::chrono::year_month_day object from day, month, and year values.
32 | *
33 | * This function creates a date representation using the C++20 library types.
34 | * It does not perform validation on the input values.
35 | *
36 | * @param d The day of the month (1–31, depending on the month).
37 | * @param m The month of the year (1–12).
38 | * @param y The year.
39 | * @return A std::chrono::year_month_day object representing the given date.
40 | *
41 | * @see std::chrono::year_month_day
42 | */
43 | std::chrono::year_month_day Date::get_date_from_ymd(unsigned int d, unsigned int m, int y)
44 | {
45 | return std::chrono::year_month_day{std::chrono::year{y}, std::chrono::month{m}, std::chrono::day{d}};
46 | }
47 |
48 | /**
49 | * @brief Validates that a second date is not earlier than the first date.
50 | *
51 | * This function checks whether the second date (d2, m2, y2) is greater than
52 | * or equal to the first date (d1, m1, y1). It uses std::chrono::year_month_day
53 | * for comparison and assumes all date components are valid.
54 | *
55 | * @param d1 Day of the first date.
56 | * @param m1 Month of the first date.
57 | * @param y1 Year of the first date.
58 | * @param d2 Day of the second date.
59 | * @param m2 Month of the second date.
60 | * @param y2 Year of the second date.
61 | * @return true if the second date is the same or later than the first date, false otherwise.
62 | *
63 | * @see Date::get_date_from_ymd
64 | * @see std::chrono::year_month_day
65 | */
66 | bool Date::vali_date(int d1, int m1, int y1, int d2, int m2, int y2) // pun
67 | {
68 | std::chrono::year_month_day date1{get_date_from_ymd(d1, m1, y1)};
69 | std::chrono::year_month_day date2{get_date_from_ymd(d2, m2, y2)};
70 |
71 | return date2 >= date1;
72 | }
73 |
74 | /**
75 | * @brief Converts a std::chrono::year_month_day object to a string.
76 | *
77 | * This function formats a given date into a string using the default
78 | * output format of std::ostringstream for std::chrono::year_month_day.
79 | *
80 | * @param date The date to convert.
81 | * @return A string representation of the date.
82 | *
83 | * @see std::chrono::year_month_day
84 | */
85 | std::string Date::string_from_date(std::chrono::year_month_day date)
86 | {
87 | std::ostringstream oss;
88 | oss << date;
89 | return oss.str();
90 | }
--------------------------------------------------------------------------------
/src/CC_Generator/ProjectInfo_.h:
--------------------------------------------------------------------------------
1 | namespace ProjectInfo {
2 | const char* version = "2.0.2";
3 | const char* project_url = "https://github.com/ItaiShek/CC_Generator";
4 | const char* license = "AGPL V3";
5 | }
--------------------------------------------------------------------------------
/src/CC_Generator/console_main.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * @file main.cpp
3 | * @brief Entry point for the console application.
4 | *
5 | * This file contains the main function which initializes the console application.
6 | * It calls the `console::run` function to start the application with version, URL, and license information.
7 | *
8 | * @see Console.h for the declaration of the console::run function.
9 | * @see ProjectInfo_ for version, project URL, and license details.
10 | */
11 |
12 | #include "Console.h"
13 | #include "ProjectInfo_.h"
14 |
15 | /**
16 | * @brief Main function to run the console version of the application.
17 | *
18 | * The main function retrieves version, project URL, and license information from
19 | * the `ProjectInfo` class and then calls the `console::run` function to start
20 | * the console application.
21 | *
22 | * @param argc The number of command-line arguments.
23 | * @param argv The array of command-line argument strings.
24 | *
25 | * @return Returns 0 if the application runs successfully.
26 | */
27 | int main(int argc, char* argv[])
28 | {
29 | // Run the console application with the specified project details
30 | console::run(ProjectInfo::version, ProjectInfo::project_url, ProjectInfo::license);
31 | return 0;
32 | }
--------------------------------------------------------------------------------
/src/CC_Generator/gui_main.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * @file main.cpp
3 | * @brief Entry point for the GUI application.
4 | *
5 | * This file contains the main function for running the GUI version of the application.
6 | * It handles platform-specific entry points for both Windows and Linux.
7 | *
8 | * On Windows, the `WinMain` function is used as the entry point, while on Linux,
9 | * the regular `main` function is used.
10 | *
11 | * @see GUI.h for the declaration of the gui::run function.
12 | * @see ProjectInfo_ for version, project URL, and license details.
13 | */
14 |
15 | #if defined(_WIN64) || defined(_WIN32)
16 | #include
17 | #undef MOUSE_MOVED
18 | #endif
19 |
20 | #include "GUI.h"
21 | #include "ProjectInfo_.h"
22 |
23 | /**
24 | * @brief Main function to run the GUI version of the application.
25 | *
26 | * On Windows, this function uses the `WinMain` entry point, while on Linux it uses the regular `main`.
27 | * It initializes the GUI application by calling the `gui::run` function with version, project URL, and license
28 | * information retrieved from the `ProjectInfo` class.
29 | *
30 | * @param hInstance The handle to the application instance (Windows only).
31 | * @param hPrevInstance The handle to the previous instance (Windows only).
32 | * @param lpCmdLine Command line arguments (Windows only).
33 | * @param nCmdShow Controls how the window is shown (Windows only).
34 | * @param argc The number of command-line arguments (Linux only).
35 | * @param argv The array of command-line argument strings (Linux only).
36 | *
37 | * @return Returns 0 if the application runs successfully.
38 | */
39 | #if defined(_WIN64) || defined(_WIN32)
40 | int WINAPI WinMain(
41 | HINSTANCE hInstance,
42 | HINSTANCE hPrevInstance,
43 | LPSTR lpCmdLine,
44 | int nCmdShow)
45 | #else
46 | int main(int argc, char *argv[])
47 | #endif
48 | {
49 | // Run the GUI application with the specified project details
50 | gui::run(ProjectInfo::version, ProjectInfo::project_url, ProjectInfo::license);
51 | return 0;
52 | }
--------------------------------------------------------------------------------
/src/Console/Console_.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | #if defined(_WIN64) || defined(_WIN32)
9 | #define NOMINMAX
10 | #include
11 | #undef MOUSE_MOVED
12 | #include "curses.h"
13 | #else
14 | #include
15 | #include
16 | #define MAX_PATH PATH_MAX
17 | #endif
18 |
19 | #include "sqlite3.h"
20 | #include "Card.h"
21 | // #include "DB_API.h"
22 |
23 | #if defined(__x86_64) || defined(_M_X64)
24 | #define DATATYPE unsigned long long
25 | #elif defined(__i386) || defined(_M_IX86)
26 | #define DATATYPE unsigned int
27 | #endif
28 |
29 | // global variables
30 | extern std::atomic g_paused;
31 | extern std::atomic g_started;
32 | extern std::atomic g_progress;
33 |
34 | namespace console
35 | {
36 | // Represents a button with a label and associated action.
37 | class Button
38 | {
39 | public:
40 | Button(std::string label, int action) : m_label(label), m_action(action) {}
41 | std::string m_label;
42 | int m_action;
43 | };
44 |
45 | // Internal utility functions for the console application.
46 |
47 | // Prints a banner with version and URL information.
48 | void print_banner(const std::string &version, const std::string &url);
49 |
50 | // Checks if two strings are equal in a case-insensitive manner.
51 | inline bool case_insensitive_equals(const std::string &input, const std::string &comp);
52 |
53 | // Checks if the input string indicates a quit command.
54 | bool check_quit(const std::string &input);
55 |
56 | // Gets a SQLite database and returns it along with potential error messages.
57 | std::shared_ptr get_db(std::string &db_path, std::string &err_msg);
58 |
59 | // Draws buttons on the console.
60 | void draw_buttons(const std::vector &buttons, size_t curr_btn_idx);
61 |
62 | // Displays a yes/no prompt on the console and returns the user's choice.
63 | int yes_no(const std::string &str);
64 |
65 | // Adds a card with user-inputted details.
66 | Card add_card();
67 |
68 | // Gets a formatted string representation of a card.
69 | inline std::string get_card_string(int max_length, const Card &card);
70 |
71 | // Draws a list of cards on the console.
72 | void draw_cards(const std::vector &cards_vec, int start_row, int visible_rows, int max_offset, int curr_row_idx, const std::vector &selected_rows);
73 |
74 | // Guides the user in choosing cards and returns the user's action.
75 | int choose_cards(std::shared_ptr db, const std::string &db_path, std::vector &cards_vec, std::vector &cards_selection);
76 |
77 | // Guides the user in choosing the amount of data to generate and returns the user's action.
78 | int choose_amount(DATATYPE &amount, const std::string &db_path);
79 |
80 | // Gets a valid file path from the user.
81 | void get_path(std::string &path);
82 |
83 | // Guides the user in choosing a file and returns the user's action.
84 | int choose_file(std::string &exp_path);
85 |
86 | // Guides the user in generating data and returns the user's action.
87 | int generate(const std::string &exp_path, const std::vector &cards_vec, const std::vector &cards_selection, DATATYPE amount, std::shared_ptr db);
88 |
89 | // Let the user to enable/disable CVV, name, and date.
90 | int choose_options();
91 |
92 | // Let the user to choose expiration date range
93 | int choose_date();
94 | }
--------------------------------------------------------------------------------
/src/GUI/GUI.cpp:
--------------------------------------------------------------------------------
1 | #ifdef __EMSCRIPTEN__
2 | #include "emscripten_funcs.h"
3 | #endif
4 |
5 | #include "GUI.h"
6 | #include "GUI_.h"
7 | #include "Date.h"
8 |
9 | std::mt19937 File::m_gen(std::random_device{}());
10 | std::atomic g_paused{false};
11 | std::atomic g_started{false};
12 | std::atomic g_progress{0.0f};
13 | std::string g_current_db_path = "Cards.db";
14 |
15 | // emscripten flags
16 | bool g_emscripten_open_flag = false;
17 | bool g_emscripten_save_db_flag = false;
18 | bool g_emscripten_generate_flag = false;
19 | extern std::atomic export_finished;
20 |
21 | /**
22 | * @brief Initializes a vector of Card objects from a database.
23 | *
24 | * This function initializes a vector of Card objects by reading data from a database file.
25 | * If the database file does not exist or there is an issue reading the database, an empty
26 | * vector is returned.
27 | *
28 | * @return A vector of Card objects initialized from the database.
29 | */
30 | std::vector initialize_cards_vec()
31 | {
32 | std::vector temp_vec{};
33 |
34 | if (DB_API::check_file_exists(g_current_db_path) == false)
35 | {
36 | return temp_vec;
37 | }
38 |
39 | std::shared_ptr db{DB_API::read_db(g_current_db_path)};
40 |
41 | if (db == nullptr)
42 | {
43 | return temp_vec;
44 | }
45 |
46 | std::string err_msg{};
47 | DB_API::read_cards(db, temp_vec, err_msg);
48 |
49 | return temp_vec;
50 | }
51 |
52 | class App : public gui::GuiApp
53 | {
54 | public:
55 | App(const std::string &title, const std::string &url, const std::string &license, const int window_w, const int window_h) : GuiApp{title, url, window_w, window_h}, m_title{title}, m_url{url}, m_license{license} {};
56 | ~App() = default;
57 |
58 | void set_duration()
59 | {
60 | File::m_cvv_flag = false;
61 | File::m_name_flag = false;
62 | File::m_date_flag = false;
63 | m_duration = File::estimate_time();
64 | m_cvv_duration = File::estimate_cvv_time();
65 | m_date_duration = File::estimate_date_time();
66 | m_name_duration = File::estimate_name_time(g_current_db_path);
67 |
68 | m_disable_name_option = m_name_duration == std::chrono::duration_cast(std::chrono::nanoseconds{0});
69 | }
70 |
71 | void startup()
72 | {
73 | m_window_flags |= ImGuiWindowFlags_NoDecoration;
74 | m_window_flags |= ImGuiWindowFlags_NoMove;
75 | m_window_flags |= ImGuiWindowFlags_NoCollapse;
76 | m_window_flags |= ImGuiWindowFlags_NoTitleBar;
77 | set_duration();
78 | glfwSwapInterval(1); // idling
79 | }
80 |
81 | void update()
82 | {
83 | const ImGuiViewport *viewport = ImGui::GetMainViewport();
84 | ImGui::SetNextWindowPos(viewport->WorkPos);
85 | ImGui::SetNextWindowSize(viewport->WorkSize);
86 |
87 | static bool disable_start_btn;
88 |
89 | // ImGui content
90 | ImGui::Begin("MainWindow", NULL, m_window_flags);
91 |
92 | ImVec2 main_window_size{ImGui::GetWindowSize()};
93 | ImVec2 popup_min_window_size{ImVec2(main_window_size.x * 0.5f, main_window_size.y * 0.5f)};
94 |
95 | static std::vector cards_vec{initialize_cards_vec()};
96 | static std::vector cards_selection(cards_vec.size(), false);
97 | static int current_card{-1};
98 |
99 | ImGui::BeginDisabled(g_started);
100 | // Child 1 - Database
101 | {
102 | static ImGuiTextFilter db_filter{};
103 | ImVec2 child_window_size{ImGui::GetContentRegionAvail()};
104 | ImGui::BeginChild("Child_L", ImVec2(child_window_size.x * 0.5f, child_window_size.y), false, ImGuiWindowFlags_NoDecoration);
105 | // Child 1.1 - Database list
106 | {
107 | ImGui::BeginChild("Child_L_1", ImVec2(0, ImGui::GetContentRegionAvail().y - ImGui::GetFrameHeightWithSpacing()), false, ImGuiWindowFlags_HorizontalScrollbar);
108 |
109 | if (ImGui::BeginTable("cards_columns", 4, ImGuiTableFlags_Resizable | ImGuiTableFlags_NoSavedSettings | ImGuiTableFlags_Borders))
110 | {
111 | static std::array table_header{"", "Issuer", "Length", "Prefixes"};
112 | for (const auto &header_col : table_header)
113 | {
114 | ImGui::TableNextColumn();
115 | ImGui::TextColored(ImVec4(255, 0, 0, 1), "%s", header_col);
116 | }
117 |
118 | bool sel{};
119 | disable_start_btn = false;
120 | for (size_t i{}; i < cards_vec.size(); i++)
121 | {
122 | std::string issuer_str{cards_vec[i].get_issuer()};
123 | std::string length_str{std::to_string(cards_vec[i].get_len())};
124 | std::string prefixes_str{cards_vec[i].get_prefixes()};
125 |
126 | const char *issuer{issuer_str.c_str()};
127 | const char *length{length_str.c_str()};
128 | const char *prefixes{prefixes_str.c_str()};
129 | if (db_filter.PassFilter(issuer) || db_filter.PassFilter(length) || db_filter.PassFilter(prefixes))
130 | {
131 | ImGui::TableNextRow();
132 | ImGui::TableNextColumn();
133 | // if you have a better and more efficient solution then please suggest it =)
134 | sel = cards_selection[i];
135 | ImGui::Checkbox(("##checkbox_" + std::to_string(i)).c_str(), &sel);
136 | cards_selection[i] = sel;
137 | disable_start_btn |= sel;
138 |
139 | ImGui::TableNextColumn();
140 | if (ImGui::Selectable(issuer, current_card == i, ImGuiSelectableFlags_SpanAllColumns))
141 | {
142 | if (current_card == i)
143 | {
144 | current_card = -1; // deselect
145 | }
146 | else
147 | {
148 | current_card = static_cast(i); // select
149 | }
150 | }
151 |
152 | ImGui::TableNextColumn();
153 | ImGui::Text("%s", length);
154 | ImGui::TableNextColumn();
155 | ImGui::Text("%s", prefixes);
156 | }
157 | }
158 | disable_start_btn = !disable_start_btn;
159 | ImGui::EndTable();
160 | }
161 | ImGui::EndChild();
162 | }
163 | ImGui::Separator();
164 | // Child 1.2 - Filter
165 | {
166 | ImGui::BeginChild("Child_L_2", ImVec2(0, 0), false, ImGuiWindowFlags_NoDecoration);
167 | ImGui::Text("Filter:");
168 | ImGui::SameLine();
169 | db_filter.Draw("##db_filter");
170 | ImGui::EndChild();
171 | }
172 | ImGui::EndChild();
173 | }
174 | ImGui::EndDisabled();
175 |
176 | ImGui::SameLine();
177 |
178 | // Child 2 - Actions
179 | {
180 | ImGui::BeginChild("Child_R", ImVec2(0, ImGui::GetContentRegionAvail().y), false, ImGuiWindowFlags_HorizontalScrollbar);
181 | ImGui::SeparatorText("Database Actions");
182 | // Child 2.1 - Database actions
183 | {
184 | ImGui::BeginChild("Child_R1", ImVec2(0, ImGui::GetContentRegionAvail().y * 0.3f), false, ImGuiWindowFlags_HorizontalScrollbar);
185 | static const std::array db_actions{
186 | "Clear",
187 | "Open",
188 | "Save",
189 | "Add",
190 | "Edit",
191 | "Remove",
192 | "Check all",
193 | "Uncheck all",
194 | };
195 | static std::string err_msg{};
196 | static size_t action;
197 | action = db_actions.size();
198 | static constexpr const char *filters{"Sqlite database files (*.db){.db},All files (*.*){.*}"};
199 |
200 | ImVec2 window_size{ImGui::GetContentRegionAvail()};
201 | ImVec2 button_size{-FLT_MIN, window_size.y * 0.175f};
202 | if (ImGui::BeginTable("Database_actions", 3, ImGuiTableFlags_SizingStretchSame))
203 | {
204 | for (size_t i{}; i < db_actions.size(); i++)
205 | {
206 | ImGui::TableNextColumn();
207 | ImGui::BeginDisabled(g_started);
208 | if (ImGui::Button(db_actions[i], button_size))
209 | {
210 | action = i;
211 | }
212 | ImGui::EndDisabled();
213 | }
214 | ImGui::EndTable();
215 | }
216 |
217 | // Handle db actions
218 | switch (action)
219 | {
220 | case 0: // clear cards
221 | if (cards_vec.empty() == false)
222 | {
223 | ImGui::OpenPopup("Clear");
224 | }
225 | break;
226 | case 1: // open database
227 | {
228 | #ifdef __EMSCRIPTEN__
229 | open_file_dialog("'.db'");
230 | #else
231 | IGFD::FileDialogConfig config;
232 | config.path = ".";
233 | config.fileName = "";
234 | config.countSelectionMax = 1;
235 | config.flags = ImGuiFileDialogFlags_Modal;
236 | ImGuiFileDialog::Instance()->OpenDialog(
237 | "OpenDlg", // vKey
238 | "Open Database", // vTitle
239 | filters, // vFilters
240 | config);
241 | #endif
242 | }
243 | break;
244 | case 2: // save database
245 | {
246 | #ifdef __EMSCRIPTEN__
247 | g_emscripten_save_db_flag = true;
248 | #else
249 | IGFD::FileDialogConfig config;
250 | config.path = ".";
251 | config.fileName = "";
252 | config.countSelectionMax = 1;
253 | config.flags = ImGuiFileDialogFlags_Modal | ImGuiFileDialogFlags_ConfirmOverwrite;
254 | ImGuiFileDialog::Instance()->OpenDialog(
255 | "SaveDlg", // vKey
256 | "Save Database", // vTitle
257 | filters, // vFilters
258 | config);
259 | #endif
260 | }
261 | break;
262 | case 3: // add new card
263 | ImGui::OpenPopup("Add");
264 | break;
265 | case 4: // edit card
266 | if (current_card < cards_vec.size())
267 | {
268 | ImGui::OpenPopup("Edit");
269 | }
270 | break;
271 | case 5: // remove card
272 | if (current_card < cards_vec.size())
273 | {
274 | cards_vec.erase(std::next(cards_vec.begin(), current_card), std::next(cards_vec.begin(), current_card + 1));
275 | cards_selection.erase(std::next(cards_selection.begin(), current_card), std::next(cards_selection.begin(), current_card + 1));
276 | }
277 | break;
278 | case 6: // select all
279 | std::fill(cards_selection.begin(), cards_selection.end(), true);
280 | break;
281 | case 7:
282 | std::fill(cards_selection.begin(), cards_selection.end(), false);
283 | break;
284 | default:
285 | break;
286 | }
287 |
288 | // clear
289 | ImGui::SetNextWindowSizeConstraints(ImVec2(main_window_size.x * 0.25f, main_window_size.y * 0.25f), ImVec2(FLT_MAX, FLT_MAX));
290 | if (ImGui::BeginPopupModal("Clear"))
291 | {
292 | ImVec2 popup_window_size{ImGui::GetWindowSize()};
293 | ImVec2 button_size{ImVec2(popup_window_size.x * 0.3f, popup_window_size.y * 0.15f)};
294 | ImGui::TextWrapped("Do you want to clear the current database?");
295 | ImGui::SetCursorPos(ImVec2(popup_window_size.x / 2 - button_size.x, popup_window_size.y - button_size.y * 2));
296 |
297 | if (ImGui::Button("Yes", button_size))
298 | {
299 | cards_vec.clear();
300 | cards_selection.clear();
301 | ImGui::CloseCurrentPopup();
302 | }
303 | ImGui::SameLine();
304 | if (ImGui::Button("No", button_size))
305 | {
306 | ImGui::CloseCurrentPopup();
307 | }
308 | ImGui::EndPopup();
309 | }
310 |
311 | // open database
312 | if (ImGuiFileDialog::Instance()->Display("OpenDlg", ImGuiWindowFlags_NoCollapse, popup_min_window_size) || g_emscripten_open_flag)
313 | {
314 |
315 | // action if OK
316 | if (ImGuiFileDialog::Instance()->IsOk() || g_emscripten_open_flag)
317 | {
318 | #ifdef __EMSCRIPTEN__
319 | std::string db_path = get_selected_file_path_from_js("selectedFilePath");
320 | g_emscripten_open_flag = false;
321 | #else
322 | std::string db_path = ImGuiFileDialog::Instance()->GetFilePathName();
323 | #endif
324 |
325 | if (DB_API::check_file_exists(db_path) == false)
326 | {
327 | ImGui::OpenPopup("DB Error");
328 | err_msg = "File not found.";
329 | }
330 | else
331 | {
332 | std::shared_ptr db{DB_API::read_db(db_path)};
333 |
334 | if (db == nullptr)
335 | {
336 | ImGui::OpenPopup("DB Error");
337 | err_msg = "Failed to open the database.";
338 | }
339 | else
340 | {
341 | if (DB_API::read_cards(db, cards_vec, err_msg) == 0)
342 | {
343 | cards_selection = std::vector(cards_vec.size(), false);
344 | g_current_db_path = db_path;
345 | set_duration();
346 | }
347 | else
348 | {
349 | ImGui::OpenPopup("DB Error");
350 | }
351 | }
352 | }
353 | }
354 | ImGuiFileDialog::Instance()->Close();
355 |
356 | action = db_actions.size();
357 | }
358 |
359 | // save database
360 | if (ImGuiFileDialog::Instance()->Display("SaveDlg", ImGuiWindowFlags_NoCollapse, popup_min_window_size) || g_emscripten_save_db_flag)
361 | {
362 | if (ImGuiFileDialog::Instance()->IsOk() || g_emscripten_save_db_flag)
363 | {
364 | std::string db_path = ImGuiFileDialog::Instance()->GetFilePathName();
365 |
366 | std::shared_ptr db{DB_API::read_db(db_path)};
367 |
368 | if (db == nullptr)
369 | {
370 | ImGui::OpenPopup("DB Error");
371 | err_msg = "Failed to open the database.";
372 | }
373 | else
374 | {
375 | if (DB_API::write_cards(db, cards_vec, err_msg) != 0)
376 | {
377 | ImGui::OpenPopup("DB Error");
378 | }
379 | else
380 | {
381 | #ifdef __EMSCRIPTEN__
382 | download_file(g_current_db_path, "Cards.db", g_emscripten_save_db_flag);
383 | #endif
384 | }
385 | }
386 | }
387 | ImGuiFileDialog::Instance()->Close();
388 | action = db_actions.size();
389 | }
390 |
391 | // add new card
392 | static bool first_time{true};
393 | static std::string issuer_add{};
394 | static int length_add{};
395 | static std::string prefixes_add{};
396 |
397 | ImGui::SetNextWindowSizeConstraints(ImVec2(main_window_size.x * 0.25f, main_window_size.y * 0.25f), ImVec2(FLT_MAX, FLT_MAX));
398 | if (ImGui::BeginPopupModal("Add"))
399 | {
400 | ImVec2 popup_window_size{ImGui::GetWindowSize()};
401 | ImVec2 button_size{ImVec2(popup_window_size.x * 0.3f, popup_window_size.y * 0.15f)};
402 |
403 | if (first_time)
404 | {
405 | issuer_add = "";
406 | length_add = 16;
407 | prefixes_add = "";
408 | first_time = false;
409 | }
410 |
411 | ImGui::Text("Issuer: ");
412 | ImGui::SameLine();
413 | ImGui::InputText("##issuer_input", &issuer_add);
414 |
415 | ImGui::Text("Length: ");
416 | ImGui::SameLine();
417 | ImGui::DragInt("##length_input", &length_add, 1.0f, 2, 32, "%d", ImGuiSliderFlags_AlwaysClamp);
418 |
419 | ImGui::Text("Prefixes:");
420 | ImGui::SameLine();
421 | ImGui::InputText("##prefixes_input", &prefixes_add);
422 | if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNormal))
423 | {
424 | ImGui::SetTooltip("Comma delimited, either digits and/or ascending ranges larger then the length.\ne.g.: 1,2,4-5,7,89-1000");
425 | }
426 |
427 | ImGui::SetCursorPos(ImVec2(popup_window_size.x / 2 - button_size.x, popup_window_size.y - button_size.y * 2));
428 | ImGui::BeginDisabled(Card::validate_card(issuer_add, length_add, prefixes_add) == false);
429 | if (ImGui::Button("Add", button_size))
430 | {
431 | Card new_card{std::string(issuer_add), length_add, std::string(prefixes_add)};
432 | auto it = std::find(cards_vec.begin(), cards_vec.end(), new_card);
433 | if (it == cards_vec.end())
434 | {
435 | cards_vec.push_back(new_card);
436 | cards_selection.push_back(false);
437 | }
438 | first_time = true;
439 | ImGui::CloseCurrentPopup();
440 | action = db_actions.size();
441 | }
442 | ImGui::EndDisabled();
443 | if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNormal))
444 | {
445 | ImGui::SetTooltip("Duplicates will be ignored");
446 | }
447 | ImGui::SameLine();
448 | if (ImGui::Button("Cancel", button_size))
449 | {
450 | ImGui::CloseCurrentPopup();
451 | action = db_actions.size();
452 | first_time = true;
453 | }
454 | ImGui::EndPopup();
455 | }
456 |
457 | // edit card
458 | ImGui::SetNextWindowSizeConstraints(ImVec2(main_window_size.x * 0.25f, main_window_size.y * 0.25f), ImVec2(FLT_MAX, FLT_MAX));
459 | if (ImGui::BeginPopupModal("Edit"))
460 | {
461 | ImVec2 popup_window_size{ImGui::GetWindowSize()};
462 | ImVec2 button_size{ImVec2(popup_window_size.x * 0.3f, popup_window_size.y * 0.15f)};
463 |
464 | if (first_time)
465 | {
466 | issuer_add = cards_vec[current_card].get_issuer();
467 | length_add = cards_vec[current_card].get_len();
468 | prefixes_add = cards_vec[current_card].get_prefixes();
469 | first_time = false;
470 | }
471 |
472 | ImGui::Text("Issuer: ");
473 | ImGui::SameLine();
474 | ImGui::InputText("##issuer_input", &issuer_add);
475 |
476 | ImGui::Text("Length: ");
477 | ImGui::SameLine();
478 | ImGui::DragInt("##length_input", &length_add, 1.0f, 2, 32, "%d", ImGuiSliderFlags_AlwaysClamp);
479 |
480 | ImGui::Text("Prefixes:");
481 | ImGui::SameLine();
482 | ImGui::InputText("##prefixes_input", &prefixes_add);
483 | if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNormal))
484 | {
485 | ImGui::SetTooltip("Comma delimited, either digits and/or ascending ranges larger then the length.\ne.g.: 1,2,4-5,7,89-1000");
486 | }
487 |
488 | ImGui::SetCursorPos(ImVec2(popup_window_size.x / 2 - button_size.x, popup_window_size.y - button_size.y * 2));
489 | ImGui::BeginDisabled(Card::validate_card(issuer_add, length_add, prefixes_add) == false);
490 | if (ImGui::Button("Save", button_size))
491 | {
492 | bool found = std::any_of(cards_vec.begin(), cards_vec.end(), [](const Card &item) -> bool
493 | { return (item.get_issuer() == issuer_add) && (item.get_len() == length_add) && (item.get_prefixes() == prefixes_add); });
494 |
495 | if (found == false)
496 | {
497 | cards_vec[current_card].set_issuer(issuer_add);
498 | cards_vec[current_card].set_len(length_add);
499 | cards_vec[current_card].set_prefixes(prefixes_add);
500 | }
501 | ImGui::CloseCurrentPopup();
502 | action = db_actions.size();
503 | first_time = true;
504 | }
505 | ImGui::EndDisabled();
506 | if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNormal))
507 | {
508 | ImGui::SetTooltip("Duplicates will be ignored");
509 | }
510 | ImGui::SameLine();
511 | if (ImGui::Button("Cancel", button_size))
512 | {
513 | ImGui::CloseCurrentPopup();
514 | action = db_actions.size();
515 | first_time = true;
516 | }
517 | ImGui::EndPopup();
518 | }
519 |
520 | // error message box
521 | ImGui::SetNextWindowSizeConstraints(ImVec2(main_window_size.x * 0.25f, main_window_size.y * 0.25f), ImVec2(FLT_MAX, FLT_MAX));
522 | if (ImGui::BeginPopupModal("DB Error"))
523 | {
524 | ImVec2 popup_window_size{ImGui::GetWindowSize()};
525 | ImVec2 button_size{ImVec2(popup_window_size.x * 0.3f, popup_window_size.y * 0.15f)};
526 | ImGui::TextWrapped("%s", err_msg.c_str());
527 | ImGui::SetCursorPos(ImVec2(popup_window_size.x / 2 - button_size.x / 2, popup_window_size.y - button_size.y * 2));
528 |
529 | if (ImGui::Button("OK", button_size))
530 | {
531 | ImGui::CloseCurrentPopup();
532 | }
533 | ImGui::EndPopup();
534 | }
535 |
536 | ImGui::EndChild();
537 | }
538 |
539 | static constexpr DATATYPE min_amount{1};
540 | static constexpr DATATYPE max_amount{std::numeric_limits::max() / 2};
541 | static DATATYPE amount{min_amount};
542 |
543 | // Child 2.2 - Database input
544 | ImGui::Separator();
545 | ImGui::BeginDisabled(g_started);
546 | {
547 |
548 | ImGui::BeginChild("Child_R2", ImVec2(0, ImGui::GetContentRegionAvail().y * 0.5f), false, ImGuiWindowFlags_HorizontalScrollbar);
549 | {
550 | static bool options_changed{false};
551 |
552 | ImGui::Text("Amount:");
553 | ImGui::SameLine();
554 | static std::string f_time{File::format_time(std::chrono::duration_cast(m_duration * amount))};
555 | ImGui::DragScalar("##amount_slider", imgui_data_type, &amount, 1.0f, &min_amount, &max_amount, 0, ImGuiSliderFlags_AlwaysClamp);
556 | static std::string size_str{File::estimate_size(amount)};
557 |
558 | // Calculate the total size of the file including newline characters
559 | if (ImGui::IsItemEdited() || options_changed)
560 | {
561 | options_changed = false;
562 | size_str = File::estimate_size(amount);
563 | f_time = File::format_time(std::chrono::duration_cast(m_duration * amount));
564 | }
565 |
566 | if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNormal))
567 | {
568 | ImGui::SetTooltip("Hold and drag, or double click to enter a value.");
569 | }
570 |
571 | // print estimated file size
572 | ImGui::Text("Approximate size:");
573 | ImGui::SameLine();
574 | ImGui::TextColored(ImVec4(255, 0, 0, 1), "%s", size_str.c_str());
575 |
576 | // print estimated time
577 | ImGui::Text("ETA:");
578 | ImGui::SameLine();
579 | ImGui::TextColored(ImVec4(255, 0, 0, 1), "%s", f_time.c_str());
580 |
581 | if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNormal))
582 | {
583 | ImGui::SetTooltip("HH:mm:ss:ms");
584 | }
585 |
586 | ImGui::SetNextItemWidth(20.0f);
587 | static char inputBuffer[2] = {File::m_delimiter, '\0'};
588 | if (ImGui::InputText("Delimiter", inputBuffer, sizeof(inputBuffer)))
589 | {
590 | // If the user entered something, store the first character
591 | if (inputBuffer[0] != '\0')
592 | {
593 | File::m_delimiter = inputBuffer[0];
594 | }
595 | }
596 |
597 | if (ImGui::Checkbox("Include CVV", &File::m_cvv_flag))
598 | {
599 | m_duration += File::m_cvv_flag ? m_cvv_duration : -m_cvv_duration;
600 | options_changed = true;
601 | }
602 |
603 | ImGui::BeginDisabled(m_disable_name_option);
604 | if (ImGui::Checkbox("Include name", &File::m_name_flag))
605 | {
606 | m_duration += File::m_name_flag ? m_name_duration : -m_name_duration;
607 | options_changed = true;
608 | }
609 | ImGui::EndDisabled();
610 | if (ImGui::Checkbox("Include expiration date", &File::m_date_flag))
611 | {
612 | m_duration += File::m_date_flag ? m_date_duration : -m_date_duration;
613 | options_changed = true;
614 | }
615 |
616 | static int start_day = static_cast(File::m_date.start.day()), start_month = static_cast(File::m_date.start.month()), start_year = static_cast(File::m_date.start.year());
617 | static int end_day = static_cast(File::m_date.end.day()), end_month = static_cast(File::m_date.end.month()), end_year = static_cast(File::m_date.end.year());
618 |
619 | if (ImGui::Button("Set Date Range"))
620 | {
621 | ImGui::OpenPopup("Date Range Picker");
622 | }
623 |
624 | if (ImGui::BeginPopupModal("Date Range Picker", nullptr, ImGuiWindowFlags_AlwaysAutoResize))
625 | {
626 | ImGui::Text("Start Date:");
627 | ImGui::InputInt("Day##Start", &start_day);
628 | ImGui::InputInt("Month##Start", &start_month);
629 | start_month = std::clamp(start_month, 1, 12);
630 | ImGui::InputInt("Year##Start", &start_year);
631 | start_year = std::clamp(start_year, 0, std::numeric_limits::max());
632 | start_day = std::clamp(start_day, 1, Date::days_in_month(start_year, start_month));
633 |
634 | ImGui::Separator();
635 |
636 | ImGui::Text("End Date:");
637 | ImGui::InputInt("Day##End", &end_day);
638 | ImGui::InputInt("Month##End", &end_month);
639 | end_month = std::clamp(end_month, 1, 12);
640 | ImGui::InputInt("Year##End", &end_year);
641 | end_year = std::clamp(end_year, start_year, std::numeric_limits::max());
642 | end_day = std::clamp(end_day, 1, Date::days_in_month(end_year, end_month));
643 |
644 | bool is_valid = Date::vali_date(start_day, start_month, start_year, end_day, end_month, end_year);
645 |
646 | ImGui::Spacing();
647 |
648 | if (!is_valid)
649 | {
650 | ImGui::TextColored(ImVec4(1, 0, 0, 1), "End date must be after start date.");
651 | }
652 |
653 | ImGui::Spacing();
654 | ImGui::Separator();
655 |
656 | if (ImGui::Button("OK"))
657 | {
658 | if (is_valid)
659 | {
660 | File::m_date.start = Date::get_date_from_ymd(start_day, start_month, start_year);
661 | File::m_date.end = Date::get_date_from_ymd(end_day, end_month, end_year);
662 |
663 | ImGui::CloseCurrentPopup();
664 | }
665 | }
666 |
667 | ImGui::SameLine();
668 | if (ImGui::Button("Cancel"))
669 | {
670 | ImGui::CloseCurrentPopup();
671 | }
672 |
673 | ImGui::EndPopup();
674 | }
675 | }
676 |
677 | ImGui::EndChild();
678 | }
679 | ImGui::EndDisabled();
680 |
681 | // Child 2.3 - Generate widgets
682 | {
683 | ImGui::SeparatorText("Generate");
684 | ImGui::BeginChild("Child_R3", ImVec2(0, ImGui::GetContentRegionAvail().y * 0.5f), false, ImGuiWindowFlags_HorizontalScrollbar);
685 | {
686 | ImVec2 window_size{ImGui::GetContentRegionAvail()};
687 | ImVec2 button_size{ImVec2(window_size.x * 0.2f, window_size.y * 0.35f)};
688 |
689 | static std::string start_button_text{"Start"};
690 |
691 | ImGui::BeginDisabled(disable_start_btn);
692 | if (ImGui::Button(start_button_text.c_str(), button_size))
693 | {
694 | if (g_started)
695 | {
696 | g_paused = !g_paused;
697 | if (g_paused)
698 | {
699 | start_button_text = "Resume";
700 | }
701 | else
702 | {
703 | start_button_text = "Pause";
704 | }
705 | }
706 | else
707 | {
708 | #ifdef __EMSCRIPTEN__
709 | g_emscripten_generate_flag = true;
710 | #else
711 | IGFD::FileDialogConfig config;
712 | config.path = ".";
713 | config.fileName = "";
714 | config.countSelectionMax = 1;
715 | config.flags = ImGuiFileDialogFlags_Modal | ImGuiFileDialogFlags_ConfirmOverwrite;
716 | ImGuiFileDialog::Instance()->OpenDialog(
717 | "GenerateDlg", // vKey
718 | "Save Cards", // vTitle
719 | "Text Documents (*.txt){.txt},All files (*.*){.*}", // vFilters
720 | config);
721 | #endif
722 | }
723 | }
724 | ImGui::EndDisabled();
725 | if (ImGuiFileDialog::Instance()->Display("GenerateDlg", ImGuiWindowFlags_NoCollapse, popup_min_window_size) || g_emscripten_generate_flag)
726 | {
727 |
728 | if (ImGuiFileDialog::Instance()->IsOk() || g_emscripten_generate_flag)
729 | {
730 | #ifdef __EMSCRIPTEN__
731 | std::string exp_path = "/tmp/temp_output.txt";
732 | g_emscripten_generate_flag = false;
733 | #else
734 | std::string exp_path = ImGuiFileDialog::Instance()->GetFilePathName();
735 | #endif
736 | static std::ofstream output_file;
737 | output_file.open(exp_path.c_str(), std::ios::trunc);
738 |
739 | if (output_file.is_open())
740 | {
741 | start_button_text = "Pause";
742 | g_started = true;
743 | g_progress = 0.0f;
744 | std::shared_ptr db{DB_API::read_db(g_current_db_path)};
745 |
746 | #ifdef __EMSCRIPTEN__
747 | File::start_export(cards_vec, cards_selection, amount, db, "/tmp/temp_output.txt");
748 | #else
749 | std::thread write_thread(&File::export_cards, std::ref(output_file), cards_vec, cards_selection, amount, db);
750 | write_thread.detach();
751 | #endif
752 | }
753 | else
754 | {
755 | ImGui::OpenPopup("File Error");
756 | }
757 | }
758 | ImGuiFileDialog::Instance()->Close();
759 | }
760 | #ifdef __EMSCRIPTEN__
761 | if (export_finished.load())
762 | {
763 |
764 | download_file("/tmp/temp_output.txt", "Cards_output.txt", g_emscripten_generate_flag); // dummy flag
765 | export_finished = false;
766 | }
767 | #endif
768 |
769 | ImGui::SetNextWindowSizeConstraints(ImVec2(main_window_size.x * 0.25f, main_window_size.y * 0.25f), ImVec2(FLT_MAX, FLT_MAX));
770 | if (ImGui::BeginPopupModal("File Error"))
771 | {
772 | ImVec2 popup_window_size{ImGui::GetWindowSize()};
773 | ImVec2 button_size{ImVec2(popup_window_size.x * 0.3f, popup_window_size.y * 0.15f)};
774 | ImGui::TextWrapped("Couldn't open file");
775 | ImGui::SetCursorPos(ImVec2(popup_window_size.x / 2 - button_size.x / 2, popup_window_size.y - button_size.y * 2));
776 |
777 | if (ImGui::Button("OK", button_size))
778 | {
779 | ImGui::CloseCurrentPopup();
780 | }
781 | ImGui::EndPopup();
782 | }
783 |
784 | ImGui::SameLine();
785 | ImGui::BeginDisabled(g_started == false);
786 | static bool old_pause;
787 | if (ImGui::Button("Stop", button_size))
788 | {
789 | old_pause = g_paused;
790 | g_paused = true;
791 | ImGui::OpenPopup("Stop");
792 | }
793 | ImGui::EndDisabled();
794 |
795 | ImGui::SetNextWindowSizeConstraints(ImVec2(main_window_size.x * 0.25f, main_window_size.y * 0.25f), ImVec2(FLT_MAX, FLT_MAX));
796 | if (ImGui::BeginPopupModal("Stop"))
797 | {
798 | ImVec2 popup_window_size{ImGui::GetWindowSize()};
799 | ImVec2 button_size{ImVec2(popup_window_size.x * 0.3f, popup_window_size.y * 0.15f)};
800 | ImGui::TextWrapped("Are you sure you want to stop?");
801 | ImGui::SetCursorPos(ImVec2(popup_window_size.x / 2 - button_size.x, popup_window_size.y - button_size.y * 2));
802 |
803 | if (ImGui::Button("Yes", button_size))
804 | {
805 | g_started = false;
806 | ImGui::CloseCurrentPopup();
807 | }
808 | ImGui::SameLine();
809 | if (ImGui::Button("No", button_size))
810 | {
811 | g_paused = old_pause;
812 | ImGui::CloseCurrentPopup();
813 | }
814 | ImGui::EndPopup();
815 | }
816 |
817 | if (g_started == false)
818 | {
819 | g_paused = false;
820 | start_button_text = "Start";
821 | }
822 |
823 | // Calculate the Y position to align the progress bar
824 | ImVec2 progress_bar_size{-1, window_size.y * 0.35f};
825 | ImGui::SetCursorPosY(ImGui::GetCursorPosY() + ImGui::GetContentRegionAvail().y - progress_bar_size.y);
826 | ImGui::ProgressBar(g_progress, progress_bar_size);
827 | }
828 | ImGui::EndChild();
829 | }
830 |
831 | // Child 2.4 - Style and about widgets
832 | {
833 | ImGui::BeginChild("Child_R4", ImVec2(0, ImGui::GetContentRegionAvail().y), false, ImGuiWindowFlags_HorizontalScrollbar);
834 |
835 | ImVec2 window_size{ImGui::GetContentRegionAvail()};
836 | ImVec2 button_size{ImVec2(window_size.x * 0.25f, window_size.y * 0.4f)};
837 | ImGui::SetCursorPosY(ImGui::GetCursorPosY() + window_size.y - button_size.y);
838 |
839 | static bool enable_dark_mode{true};
840 | static std::string style_button_text{"Light Mode"};
841 | // Style button
842 | if (ImGui::Button(style_button_text.c_str(), button_size))
843 | {
844 | enable_dark_mode = !enable_dark_mode;
845 | if (enable_dark_mode)
846 | {
847 | style_button_text = "Light Mode";
848 | ImGui::StyleColorsDark();
849 | }
850 | else
851 | {
852 | style_button_text = "Dark Mode";
853 | ImGui::StyleColorsLight();
854 | }
855 |
856 | #ifdef __EMSCRIPTEN__
857 | if (enable_dark_mode)
858 | {
859 | set_background_dark_mode();
860 | }
861 | else
862 | {
863 | set_background_light_mode();
864 | }
865 | #endif
866 | }
867 |
868 | ImGui::SameLine();
869 |
870 | // About button
871 | if (ImGui::Button("About", button_size))
872 | {
873 | ImGui::OpenPopup("About");
874 | }
875 |
876 | ImGui::SetNextWindowSizeConstraints(popup_min_window_size, ImVec2(FLT_MAX, FLT_MAX));
877 | if (ImGui::BeginPopupModal("About"))
878 | {
879 | ImGui::Text("%s", m_title.c_str());
880 | ImGui::Separator();
881 | #ifdef __EMSCRIPTEN__
882 | static std::string about_str = "An open-source tool designed to generate random credit card numbers. It operates offline, ensuring your privacy.\nThe database is stored locally in an SQLite3 file.\n\nThe software is released under the " + m_license + " license." + "\n\nThe online version is significantly slower than the desktop app (available in the url below).";
883 | #else
884 | static std::string about_str = "An open-source tool designed to generate random credit card numbers. It operates offline, ensuring your privacy.\nThe database is stored locally in an SQLite3 file.\n\nThe software is released under the " + m_license + " license.";
885 | #endif
886 | ImGui::TextWrapped("%s", about_str.c_str());
887 |
888 | ImVec2 cur_pos = ImGui::GetCursorPos();
889 | ImGui::TextColored(ImVec4(1.0f, 0.0f, 0.0f, 1.0f), "%s", m_url.c_str());
890 | if (ImGui::IsItemHovered())
891 | {
892 | ImGui::SetCursorPos(cur_pos);
893 | ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "%s", m_url.c_str());
894 | }
895 | if (ImGui::IsItemClicked())
896 | {
897 |
898 | #if defined(_WIN64) || defined(_WIN32)
899 | static std::string open_url = "start " + m_url;
900 | #elif __linux__
901 | static std::string open_url = "xdg-open " + m_url;
902 | #elif __APPLE__
903 | static std::string open_url = "open " + m_url;
904 | #endif
905 | #ifdef EMSCRIPTEN
906 | EM_ASM_({
907 | var url = UTF8ToString($0);
908 | window.open(url, '_blank'); }, m_url.c_str());
909 | #else
910 | system(open_url.c_str());
911 | #endif
912 | }
913 | ImVec2 popup_window_size{ImGui::GetWindowSize()};
914 | ImVec2 button_size{ImVec2(popup_window_size.x * 0.25f, popup_window_size.y * 0.1f)};
915 | ImGui::SetCursorPos(ImVec2((popup_window_size.x - button_size.x) / 2, popup_window_size.y - button_size.y * 1.5f));
916 |
917 | if (ImGui::Button("Close", button_size))
918 | {
919 | ImGui::CloseCurrentPopup();
920 | }
921 | ImGui::EndPopup();
922 | }
923 | ImGui::EndChild();
924 | }
925 | ImGui::EndChild();
926 | }
927 |
928 | // draw a vertical separator in the middle
929 | float spaceBetween = ImGui::GetStyle().ItemSpacing.x;
930 | ImGui::GetWindowDrawList()->AddLine(ImVec2(main_window_size.x * 0.5f + spaceBetween * 0.5f, 0), ImVec2(main_window_size.x * 0.5f + spaceBetween * 0.5f, main_window_size.y), ImGui::GetColorU32(ImGuiCol_Separator));
931 |
932 | ImGui::End();
933 | }
934 |
935 | private:
936 | ImGuiWindowFlags m_window_flags{};
937 | std::string m_title{};
938 | std::string m_url{};
939 | std::string m_license{};
940 | std::chrono::nanoseconds m_cvv_duration{};
941 | std::chrono::nanoseconds m_date_duration{};
942 | std::chrono::nanoseconds m_name_duration{};
943 | std::chrono::nanoseconds m_duration{};
944 | bool m_disable_name_option{false};
945 | };
946 |
947 | // The pointer is just for emscripten
948 | std::unique_ptr app;
949 |
950 | /**
951 | * @brief Runs the GUI application with a specified version and URL.
952 | *
953 | * This function initializes and runs the GUI application using the provided version
954 | * and URL information. It creates an instance of the App class with the specified title,
955 | * URL, and window dimensions and then starts the application loop.
956 | *
957 | * @param version The version information to be displayed in the application title.
958 | * @param url The URL information to be used by the application.
959 | */
960 | void gui::run(const std::string &version, const std::string &url, const std::string &license)
961 | {
962 | const std::string title{"CC_Generator - Version " + version};
963 | app = std::make_unique(title, url, license, 1080, 640);
964 |
965 | #if __EMSCRIPTEN__
966 | static auto main_loop = []()
967 | {
968 | if (app)
969 | {
970 | if (!app->should_close())
971 | app->run_frame();
972 | else
973 | {
974 | emscripten_cancel_main_loop();
975 | app.reset();
976 | }
977 | }
978 | };
979 |
980 | emscripten_set_main_loop(+main_loop, 0, 1);
981 | app->startup();
982 | #else
983 | app->run();
984 | #endif
985 | }
--------------------------------------------------------------------------------
/src/GUI/GUI_.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "imgui.h"
4 | #include "imgui_impl_glfw.h"
5 | #include "imgui_impl_opengl3.h"
6 | #include "GLFW/glfw3.h"
7 |
8 | #include "ImGuiFileDialog.h"
9 | #include "misc/cpp/imgui_stdlib.h"
10 |
11 | #include "DB_API.h"
12 | #include "Card.h"
13 | #include "File.h"
14 |
15 | #if defined(_WIN64) || defined(_WIN32)
16 | #define NOMINMAX
17 | #endif
18 |
19 | #if defined(__x86_64) || defined(_M_X64)
20 | static ImGuiDataType imgui_data_type = ImGuiDataType_U64;
21 | #define DATATYPE ImU64
22 | #elif defined(__i386) || defined(_M_IX86)
23 | static ImGuiDataType imgui_data_type = ImGuiDataType_U32;
24 | #define DATATYPE ImU32
25 | #else
26 | // WASM
27 | static ImGuiDataType imgui_data_type = ImGuiDataType_U32;
28 | #define DATATYPE ImU32
29 | #endif
30 |
31 | // global variables
32 | extern std::atomic g_paused;
33 | extern std::atomic g_started;
34 | extern std::atomic g_progress;
35 |
36 | namespace gui
37 | {
38 | /**
39 | * @brief Template class for creating GUI applications using GLFW and ImGui.
40 | *
41 | * This template provides a basic structure for creating GUI applications using
42 | * GLFW for window management and ImGui for GUI rendering.
43 | *
44 | * @tparam DerivedClass The derived class implementing specific functionality.
45 | */
46 | template
47 | class GuiApp
48 | {
49 | public:
50 | /**
51 | * @brief Constructor for the GuiApp class.
52 | *
53 | * Initializes GLFW, creates a window, and sets up ImGui.
54 | *
55 | * @param title The title of the application window.
56 | * @param url A string containing the URL information.
57 | * @param window_w The width of the application window.
58 | * @param window_h The height of the application window.
59 | */
60 | GuiApp(const std::string &title, const std::string &url, const int window_w, const int window_h)
61 | {
62 | // Initialize GLFW
63 | if (!glfwInit())
64 | {
65 | std::cerr << "Couldn't initialize GLFW" << std::endl;
66 | std::exit(1);
67 | }
68 |
69 | // Create a windowed mode window and its OpenGL context
70 | m_window = glfwCreateWindow(window_w, window_h, title.c_str(), NULL, NULL);
71 | if (m_window == NULL)
72 | {
73 | glfwTerminate();
74 | std::cerr << "Couldn't create window" << std::endl;
75 | std::exit(1);
76 | }
77 |
78 | // center the window
79 | {
80 | // Get the primary monitor
81 | GLFWmonitor *primaryMonitor = glfwGetPrimaryMonitor();
82 |
83 | // Get the video mode of the primary monitor
84 | const GLFWvidmode *mode = glfwGetVideoMode(primaryMonitor);
85 |
86 | // Calculate the center position of the screen
87 | int screenWidth = mode->width;
88 | int screenHeight = mode->height;
89 | int windowWidth, windowHeight;
90 | glfwGetWindowSize(m_window, &windowWidth, &windowHeight);
91 |
92 | int xPos = (screenWidth - windowWidth) / 2;
93 | int yPos = (screenHeight - windowHeight) / 2;
94 |
95 | // Set the window position
96 | glfwSetWindowPos(m_window, xPos, yPos);
97 | }
98 |
99 | // Initialize Dear ImGui
100 | IMGUI_CHECKVERSION();
101 | ImGui::CreateContext();
102 |
103 | glfwMakeContextCurrent(m_window);
104 | ImGui_ImplGlfw_InitForOpenGL(m_window, true);
105 |
106 | ImGuiIO &io = ImGui::GetIO();
107 | (void)io;
108 |
109 | #ifdef __EMSCRIPTEN__
110 | ImGui_ImplOpenGL3_Init("#version 300 es");
111 | #else
112 | ImGui_ImplOpenGL3_Init("#version 330");
113 | #endif
114 | }
115 |
116 | /**
117 | * @brief Destructor for the GuiApp class.
118 | *
119 | * Cleans up resources allocated during the initialization.
120 | */
121 | ~GuiApp()
122 | {
123 | // Cleanup
124 | ImGui_ImplOpenGL3_Shutdown();
125 | ImGui_ImplGlfw_Shutdown();
126 | ImGui::DestroyContext();
127 | glfwDestroyWindow(m_window);
128 | glfwTerminate();
129 | }
130 |
131 | /**
132 | * @brief Main loop of the GUI application.
133 | *
134 | * Enters the main loop where events are polled, ImGui frames are started,
135 | * and rendering is performed until the window is closed.
136 | */
137 | void run()
138 | {
139 | startup();
140 |
141 | // Main loop
142 | while (!glfwWindowShouldClose(m_window))
143 | {
144 | run_frame();
145 | }
146 | }
147 |
148 | /**
149 | * @brief Checks whether the application window should close.
150 | *
151 | * This function queries the underlying GLFW window to determine if a close
152 | * request has been made (e.g., by clicking the window close button).
153 | *
154 | * @return true if the window should close, false otherwise.
155 | */
156 | bool should_close() const
157 | {
158 | return glfwWindowShouldClose(m_window);
159 | }
160 |
161 | /**
162 | * @brief Executes a single frame of the application loop.
163 | *
164 | * This function performs the following operations in order:
165 | * - Polls window events (e.g., keyboard, mouse, window close).
166 | * - Starts a new ImGui frame using OpenGL3 and GLFW backends.
167 | * - Calls the `update()` method to build the ImGui interface.
168 | * - Renders the ImGui draw data using OpenGL.
169 | * - Swaps the front and back buffers to present the rendered frame.
170 | */
171 | void run_frame()
172 | {
173 | // Poll events and handle window close
174 | glfwPollEvents();
175 | if (glfwGetKey(m_window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
176 | {
177 | }
178 | // Start the ImGui frame
179 | ImGui_ImplOpenGL3_NewFrame();
180 | ImGui_ImplGlfw_NewFrame();
181 | ImGui::NewFrame();
182 |
183 | update();
184 |
185 | // Rendering
186 | ImGui::Render();
187 | int display_w, display_h;
188 | glfwGetFramebufferSize(m_window, &display_w, &display_h);
189 | glViewport(0, 0, display_w, display_h);
190 | glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
191 | glClear(GL_COLOR_BUFFER_BIT);
192 | ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
193 |
194 | // Swap buffers
195 | glfwSwapBuffers(m_window);
196 | }
197 |
198 | /**
199 | * @brief Function called to update the GUI application state.
200 | *
201 | * This function should be implemented in the derived class to handle
202 | * application-specific updates.
203 | */
204 | void update()
205 | {
206 | static_cast(this)->update();
207 | }
208 |
209 | /**
210 | * @brief Function called at the start of the GUI application.
211 | *
212 | * This function should be implemented in the derived class to handle
213 | * application-specific startup procedures.
214 | */
215 | void startup()
216 | {
217 | static_cast(this)->startup();
218 | }
219 |
220 | GLFWwindow *m_window{}; ///< Pointer to the GLFW window object.
221 | };
222 | }
--------------------------------------------------------------------------------
/src/GUI/emscripten_funcs.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #ifdef __EMSCRIPTEN__
3 | #include
4 | #include
5 | #include
6 |
7 | extern bool g_emscripten_save_db_flag;
8 | extern bool g_emscripten_open_flag;
9 | extern bool g_emscripten_generate_flag;
10 |
11 | /**
12 | * @brief Retrieves a selected file path from a JavaScript global variable.
13 | *
14 | * This function queries the specified JavaScript variable (e.g., set by a file input dialog)
15 | * and returns its value as a C++ string. If the variable is undefined or null, an empty string is returned.
16 | *
17 | * @param var The name of the global JavaScript variable holding the file path (without `window.` prefix).
18 | * @return The file path as a std::string, or an empty string if not set.
19 | */
20 | std::string get_selected_file_path_from_js(const std::string &var)
21 | {
22 | std::string str = "window." + var + " ? window." + var + " : ''";
23 | const char *path = emscripten_run_script_string(str.c_str());
24 | return std::string(path);
25 | }
26 |
27 | /**
28 | * @brief Opens a file dialog in the browser and loads the selected file into Emscripten's virtual file system (VFS).
29 | *
30 | * This function triggers a file input dialog using JavaScript and, upon file selection, reads the file into memory
31 | * and writes it to the VFS under the `/tmp/` directory. It also sets a global JavaScript variable `window.selectedFilePath`
32 | * and updates a shared C++ boolean flag (`g_emscripten_open_flag`) to signal completion.
33 | *
34 | * @param filter The file type filter (e.g., ".db") to restrict selectable files in the dialog.
35 | */
36 | void open_file_dialog(const std::string &filter)
37 | {
38 | uintptr_t flag_ptr = (uintptr_t)&g_emscripten_open_flag;
39 | const char *filter_cstr = filter.c_str(); // ensure pointer remains valid
40 |
41 | EM_ASM_({
42 | // Reset flag initially (0 = false)
43 | // Write 0 to the C++ bool flag memory
44 | HEAPU8[$0] = 0;
45 |
46 | let input = document.createElement('input');
47 | window.selectedFilePath = null;
48 | input.type = 'file';
49 | // input.accept = '.db';
50 | input.accept = UTF8ToString($1);
51 |
52 | input.onchange = e => {
53 | let file = e.target.files[0];
54 | let reader = new FileReader();
55 |
56 | reader.onload = function () {
57 | let data = new Uint8Array(reader.result);
58 | let filename = "/tmp/" + file.name;
59 |
60 | FS.writeFile(filename, data);
61 | console.log("File written to VFS:", filename);
62 | window.selectedFilePath = filename;
63 | // Set C++ flag to true by writing 1 into the memory location
64 | HEAPU8[$0] = 1;
65 | };
66 |
67 | reader.readAsArrayBuffer(file);
68 | };
69 |
70 | input.click(); }, flag_ptr, filter_cstr);
71 | }
72 |
73 | /**
74 | * @brief Triggers a download of a file from Emscripten's virtual file system (VFS) to the user's local machine.
75 | *
76 | * This function reads the specified file from the VFS, creates a downloadable Blob in the browser,
77 | * and simulates a click to start the download. The download is named according to `download_file`.
78 | * After triggering the download, it sets the referenced C++ flag to `false` (0) to signal completion.
79 | *
80 | * @param vfs_path Path to the file in Emscripten's virtual file system.
81 | * @param download_file Desired name for the downloaded file.
82 | * @param flag Reference to a boolean flag updated after the download is triggered.
83 | */
84 | void download_file(const std::string &vfs_path, const std::string &download_file, bool &flag)
85 | {
86 | uintptr_t flag_ptr = reinterpret_cast(&flag);
87 |
88 | EM_ASM_({
89 | const path = UTF8ToString($0);
90 | const downloadName = UTF8ToString($1);
91 | const flagPtr = $2;
92 |
93 | try
94 | {
95 | const data = FS.readFile(path);
96 | const blob = new Blob([data],
97 | { type: 'application/octet-stream' });
98 | const url = URL.createObjectURL(blob);
99 |
100 | const a = document.createElement('a');
101 | a.href = url;
102 | a.download = downloadName;
103 | a.setAttribute('download', downloadName);
104 | a.click();
105 |
106 | URL.revokeObjectURL(url);
107 | console.log("Download triggered:", path);
108 | }
109 | catch (e)
110 | {
111 | console.error("Failed to download file:", e);
112 | }
113 |
114 | // Set the C++ flag to false (0)
115 | HEAPU8[flagPtr] = 0; }, vfs_path.c_str(), download_file.c_str(), flag_ptr);
116 | }
117 |
118 | /**
119 | * @brief Sets the background color of the HTML and elements.
120 | *
121 | * This function is implemented in JavaScript via Emscripten and modifies the
122 | * background color of both the `` and `` elements using the given
123 | * hexadecimal color code.
124 | *
125 | * @param color A C-style string representing the color in hex format (e.g., "#FFFFFF").
126 | */
127 | EM_JS(void, set_background_color, (const char *color), {
128 | document.documentElement.style.setProperty('background-color', UTF8ToString(color));
129 | document.body.style.setProperty('background-color', UTF8ToString(color));
130 | });
131 |
132 | /**
133 | * @brief Sets the webpage background to a dark color.
134 | *
135 | * Internally calls `set_background_color()` with a dark color value.
136 | * Intended for toggling to dark mode.
137 | */
138 | void set_background_dark_mode()
139 | {
140 | set_background_color("#0E0E0E");
141 | }
142 |
143 | /**
144 | * @brief Sets the webpage background to a light color.
145 | *
146 | * Internally calls `set_background_color()` with a light color value.
147 | * Intended for toggling to light mode.
148 | */
149 | void set_background_light_mode()
150 | {
151 | set_background_color("#F0F0F0");
152 | }
153 |
154 | #endif
--------------------------------------------------------------------------------