Jackalope / jlib (public) (License: GPLv3 or later) (since 2019-11-18) (hash sha1)
jlib C++ template library
Used to replace std functionality without exception handling.
- data structures
- filesystem routines
- crossplatform threads interface (currently only pthreads implementation)
- thread pool
- crossplatform dynamic memory functions interface (allocate, reallocate, deallocate) with alignment support
- high percision timer routines based on timespec
List of commits:
Subject Hash Author Date (UTC)
new fs namespace 2e3f4f8f0f615d84b60149d46597bc3724206353 Your Name 2019-11-22 20:08:47
removed dependencies.h file 3cda130126b9a0991458e7ec1f891590ffb0bcf8 Your Name 2019-11-22 20:08:26
recoursive dir search for doxy 36947ece876ddfa84103f75a7e1fb8cd668cf3a9 Your Name 2019-11-22 20:07:11
hidding some headers by moving to staff dir c7a69251dab39db233671ce4efa121907a348b2b Your Name 2019-11-22 01:29:01
array files renamed 39ca4912496c6e49af0d08609b224691bc4be621 Your Name 2019-11-22 01:22:01
new carray, string, string_const templates e194dca9ee1d7844d13b66749f795666cc28df96 Your Name 2019-11-22 01:18:48
grow.h and item_call.h renamed e17eec6aae4ba4083e837534bb2f98cf2b7a6673 Your Name 2019-11-22 00:57:40
io agents renamed 321c4633ba149484d9855c063e80c46ed43ee7e7 Your Name 2019-11-22 00:57:16
renamed arrays a2d0d5706f1131d553cc0d02cf7f714b3ee921c6 Your Name 2019-11-22 00:55:25
new ResizableArray template 26bf1df5faa43acdfb3fef739831f6e5ba1ad37a Your Name 2019-11-21 21:32:41
more documentation for dynamic array 2729fc335189e151aa132be3244cfea6a713896f Your Name 2019-11-21 21:30:37
io_agent interface and etalon realizations 4464bf88e4da18966ad522709f7490c15d3fd3d0 Your Name 2019-11-21 19:33:31
dynamic array bug fixes a558181cb2c9f3e76e928de8be74684e0c14baa2 Your Name 2019-11-21 19:32:37
deallocate func bug fixed b7b6aa7595db24836e78f892cdce9ffa78b15bf8 Your Name 2019-11-21 19:31:53
added dots =) 5272ca044750a014547db3edcde79e2fe6dbb6ca Your Name 2019-11-21 13:59:21
disabled man generation by doxygen 6dbfdbe48c16b07bd8afc247ae2fa995f56a5332 Your Name 2019-11-21 13:39:46
function commentary improved 791e5df05a5bf6acb18984b5d31260e7f9718466 Your Name 2019-11-21 13:38:54
DynamicArray_sorted instert function bug fix 7677fded3f22300d92a497d787b135a2e7ac988a Your Name 2019-11-20 21:25:15
moved doxygen search path 245fc569f64ae36e7fc8ab93ea954e98696512ed Your Name 2019-11-20 19:02:23
renamed jtl to jlib and namespace jl 343794453e4b4643cb53d01d8fde4a2e75d6bdc1 Your Name 2019-11-20 18:53:58
Commit 2e3f4f8f0f615d84b60149d46597bc3724206353 - new fs namespace
Author: Your Name
Author date (UTC): 2019-11-22 20:08
Committer name: Your Name
Committer date (UTC): 2019-11-22 20:08
Parent(s): 3cda130126b9a0991458e7ec1f891590ffb0bcf8
Signer:
Signing key:
Signing status: N
Tree: 916899f9500a2f2afeb4bec2d29c8f80c21ace4e
File Lines added Lines deleted
include/jlib/fs.h 9 0
include/jlib/fs/directory.h 77 0
include/jlib/fs/file.h 159 0
include/jlib/fs/file.hpp 244 0
include/jlib/fs/staff.h 86 0
File include/jlib/fs.h added (mode: 100644) (index 0000000..b045bf4)
1 /**
2 * @file fs.h
3 * @brief Include all fs declarations.
4 */
5 #pragma once
6
7 #include "fs/directory.h"
8 #include "fs/file.h"
9 #include "fs/file.hpp"
File include/jlib/fs/directory.h added (mode: 100644) (index 0000000..1be177e)
1 /**
2 * @file directory.h
3 * @brief fs::dir functions for system directories manipulation.
4 */
5
6 #pragma once
7
8 #include "staff.h"
9
10 #include <libgen.h>
11
12 namespace jl
13 {
14 namespace fs
15 {
16 /**
17 * @brief Namespace with functions for system directories manipulation.
18 */
19 namespace dir
20 {
21 /**
22 * @brief Create directory.
23 *
24 * @param[in] path C-string relative or absolute path to directory.
25 * @param[in] perms Permissions of type fs::perm.
26 *
27 * @return True if succces, overwise false is returned,
28 * to get informaition about error, use fs::error_no
29 *
30 * @see fs::perm
31 * @see fs::error_no
32 */
33 [[nodiscard]] inline bool create(const char *path, perm perms) { return mkdir(path, perms) == 0; }
34
35 /**
36 * @brief Change current working directory.
37 *
38 * @param[in] path C-string relative or absolute path to directory.
39 *
40 * @return True if succces, overwise false is returned,
41 * to get informaition about error, use fs::error_no
42 *
43 * @see fs::error_no
44 */
45 [[nodiscard]] inline bool change(const char *path) { return chdir(path) == 0; }
46
47 /**
48 * @brief Get current working directory.
49 *
50 * @param[out] p_dst Pointer to memory with at least limit size, for placing directory path.
51 * @param[in] limit Maximum size in bytes can be readed to p_dst memory.
52 * @return True if succces, overwise false is returned,
53 * to get informaition about error, use fs::error_no
54 *
55 * @see fs::error_no
56 */
57 [[nodiscard]] inline bool current(char *p_dst, uint64_t limit) { return getcwd(p_dst, limit) != nullptr; }
58
59 /**
60 * @brief Modify file path to be directory path where this file is.
61 *
62 *
63 * @param[in,out] path Pointer to c-string with file path, can be modified,
64 * must not be deallocated while returned directory path is in use.
65 * @return Pointer to c-string with directory path.
66 */
67 [[nodiscard]] inline char* path_dir_part(char *path) { return dirname(const_cast<char*>(path)); }
68
69 /// @brief Check if file or directory by this path exist. @see fs::exist
70 [[nodiscard]] inline bool exist(const char *path) { return fs::exist(path); }
71
72 /// @brief Get directory or file modification time by path. @see fs::modification_time
73 [[nodiscard]] inline bool mtime(const char *path, time_t *p_dst)
74 { return fs::modification_time (path, p_dst); }
75 };
76 }
77 }
File include/jlib/fs/file.h added (mode: 100644) (index 0000000..f09343a)
1 /**
2 * @file file.h
3 * @brief fs::stream declaration.
4 */
5
6 #pragma once
7
8 #include "staff.h"
9 #include <cstdio>
10 #include "../allocate.h"
11
12 namespace jl
13 {
14 namespace fs
15 {
16 /**
17 * @brief Wrapper for FILE stream
18 *
19 * Locked versions of functions for case when same fs::stream object will be used in several threads.
20 */
21 struct stream
22 {
23 /// @brief File open flags
24 enum flag : uint8_t {
25 READ_BIT = 0b00000001, ///< reading allowed
26 WRITE_BIT = 0b00000010, ///< writing allowed
27 CLEAN_BIT = 0b00000100, ///< if file exist, rewrite allowed.
28 WRITE_TO_END_BIT = 0b00001000, ///< writing to the end of stream
29 TEXT_BIT = 0b00010000, ///< operate as text stream
30 };
31
32 /**
33 * @brief Open file
34 *
35 * After successful file opening, stream::close must be used when file is not needed.
36 *
37 * @param[in] path C-string file path.
38 * @param[in] flags Bist from flag enum, file opening options.
39 *
40 * @return True if file is opened, overwise false and error can be checked by fs::error_no.
41 *
42 * @see fs::error_no
43 * @see stream::close
44 */
45 [[nodiscard]] bool open_file(const char *path, flag flags);
46
47 /**
48 * @brief Close stream
49 *
50 * Must be used only if stream is opened.
51 * Failing of closing stream means that chached data and operations on stream cannot be flushed.
52 *
53 * @return True if stream is closed, overwise false and error can be checked by fs::error_no.
54 *
55 * @see fs::error_no
56 * @see stream::close
57 */
58 bool close();
59
60 /**
61 * @brief Set position for reading/writing.
62 * @param[in] offs Offset from the beginning of the stream.
63 * @return True if success, overwise false and error can be checked by fs::error_no.
64 * @see fs::error_no
65 */
66 [[nodiscard]] bool pos_set (offset offs);
67
68 /**
69 * @brief Set position for reading/writing to the and of stream.
70 * @return True if success, overwise false and error can be checked by fs::error_no.
71 * @see fs::error_no
72 */
73 [[nodiscard]] bool pos_set_to_end();
74
75 /**
76 * @brief Move position for reading/writing.
77 * @param[in] diff Relative offset to move position.
78 * @return True if success, overwise false and error can be checked by fs::error_no.
79 * @see fs::error_no
80 */
81 [[nodiscard]] bool pos_move(offset diff);
82
83 ///@brief Get current position for reading/writing.
84 [[nodiscard]] offset pos();
85
86 ///@brief Check if position is at end of stream.
87 [[nodiscard]] bool pos_at_end();
88
89 ///@see pos_at_end @see fs::stream
90 [[nodiscard]] bool pos_at_end_locked();
91
92 ///@brief Read specified amount of bytes to p_dst from stream. @return Readed amount of bytes.
93 [[nodiscard]] size_t read_bytes (void *p_dst, size_t size);
94
95 ///@see read_bytes @see fs::stream
96 [[nodiscard]] size_t read_bytes_locked (void *p_dst, size_t size);
97
98 ///@brief Write specified amount of bytes from p_src to stream. @return Written amount of bytes.
99 [[nodiscard]] size_t write_bytes (const void *p_src, size_t size);
100
101 ///@see write_bytes @see fs::stream
102 [[nodiscard]] size_t write_bytes_locked(const void *p_src, size_t size);
103
104 /// @brief Read c-string to p_dst from stream, with less or equal size than limit size of bytes.
105 /// @return bool - string readed or not.
106 [[nodiscard]] bool read_string (char *p_dst, int limit);
107
108 ///@see read_string @see fs::stream
109 [[nodiscard]] bool read_string_locked(char *p_dst, int limit);
110
111 /// @brief Write c-string from p_src to stream. @return bool - string written to stream or not
112 [[nodiscard]] bool write_string (const char *p_src);
113
114 ///@see write_string @see fs::stream
115 [[nodiscard]] bool write_string_locked(const char *p_src);
116
117 /// @brief Read count of items from stream to p_dst. @return Readed item count.
118 template<typename T> [[nodiscard]] size_t read_items(T *p_dst, size_t count);
119
120 ///@see read_items @see fs::stream
121 template<typename T> [[nodiscard]] size_t read_items_locked(T *p_dst, size_t count);
122
123 /// @brief Write count of items to stream from p_src. @return Written item count.
124 template<typename T> [[nodiscard]] size_t write_items(const T *p_src, size_t count);
125
126 ///@see write_items @see fs::stream
127 template<typename T> [[nodiscard]] size_t write_items_locked(const T *p_src, size_t count);
128
129 /// @brief Read single item from stream. @return bool - item readed.
130 template<typename T> [[nodiscard]] bool read_item(T *p_dst);
131
132 ///@see read_item @see fs::stream
133 template<typename T> [[nodiscard]] bool read_item_locked(T *p_dst);
134
135 /// @brief Write single item to stream. @return bool - item written.
136 template<typename T> [[nodiscard]] bool write_item(const T *p_src);
137
138 ///@see write_item @see fs::stream
139 template<typename T> [[nodiscard]] bool write_item_locked(const T *p_src);
140
141 FILE *p_file;
142 };
143
144 /**
145 * @brief Get whole file content.
146 *
147 * After this function call is successfull, memory must be deallocated by jl::deallocate, when no longer needed.
148 *
149 * @param[in] filename C-string with file path.
150 * @param[out] pp_dst Pointer to pointer for allocating memory and placing file content.
151 * @param[out] p_size Pointer to 64-bit signed iteger for storring readed conent size in bytes.
152 *
153 * @return On success file readed and data written to allocated memory, if false,
154 * error can be checked by fs::error_no.
155 * @see fs::error_no
156 */
157 [[nodiscard]] bool read_file(const char *filename, uint8_t **pp_dst, uint64_t *p_size);
158 }
159 }
File include/jlib/fs/file.hpp added (mode: 100644) (index 0000000..813e543)
1 #pragma once
2
3 #include "file.h"
4
5 namespace jl
6 {
7 namespace fs
8 {
9 namespace details
10 {
11 template<bool locked>
12 [[nodiscard]] size_t read(FILE *f, void *p_dst, size_t item_size, size_t item_count)
13 {
14 #ifndef __MINGW32__
15 if (not locked)
16 return fread_unlocked(p_dst, item_size, item_count, f);
17 #endif
18 return fread(p_dst, item_size, item_count, f);
19 }
20
21 template<bool locked>
22 [[nodiscard]] size_t write(FILE *f, const void *p_src, size_t item_size, size_t item_count)
23 {
24 #ifndef __MINGW32__
25 if (not locked)
26 return fwrite_unlocked(p_src, item_size, item_count, f);
27 #endif
28 return fwrite(p_src, item_size, item_count, f);
29 }
30
31 template<bool locked>
32 [[nodiscard]] bool read_str(FILE *f, char *p_dst, int limit)
33 {
34 #ifndef __MINGW32__
35 if (not locked)
36 return fgets_unlocked(p_dst, limit, f) != nullptr;
37 #endif
38 return fgets(p_dst, limit, f) != nullptr;
39 }
40
41 template<bool locked>
42 [[nodiscard]] bool write_str(FILE *f, const char *p_src)
43 {
44 #ifndef __MINGW32__
45 if (not locked)
46 return fputs_unlocked(p_src, f) >= 0;
47 #endif
48 return fputs(p_src, f) >= 0;
49 }
50
51
52 /// Struct with c-string type mode for file opening.
53 struct mode {
54 constexpr mode(stream::flag flags);
55 char str[4];
56 };
57
58 [[nodiscard]] inline FILE* open_file(const char *path, mode mode)
59 {
60 return fopen(path, mode.str);
61 }
62 }
63
64 constexpr details::mode::mode(stream::flag flags) : str()
65 {
66 int str_size = 0;
67 if (flags & stream::READ_BIT) {
68 if (flags & stream::CLEAN_BIT) {
69 str[0] = 'w';
70 str[1] = '+';
71 str_size = 2;
72 }
73 else if (flags & stream::WRITE_TO_END_BIT) {
74 str[0] = 'a';
75 str[1] = '+';
76 str_size = 2;
77 }
78 else if (flags & stream::WRITE_BIT) {
79 str[0] = 'r';
80 str[1] = '+';
81 str_size = 2;
82 }
83 else {
84 str[0] = 'r';
85 str_size = 1;
86 }
87 }
88 else if (flags & stream::WRITE_TO_END_BIT) {
89 str[0] = 'a';
90 str_size = 1;
91 }
92 else if (flags & stream::CLEAN_BIT) {
93 str[0] = 'w';
94 str_size = 1;
95 }
96 if (not (flags & stream::TEXT_BIT))
97 str[str_size++] = 'b';
98 }
99
100
101
102 [[nodiscard]] inline bool stream::open_file(const char *path, flag flags)
103 {
104 details::mode mode(flags);
105 p_file = fopen(path, mode.str);
106 return p_file != nullptr;
107 }
108
109 bool inline stream::close()
110 {
111 return fclose(p_file) == 0;
112 }
113
114 [[nodiscard]] inline bool stream::pos_set (offset off) { return fseek(p_file, off, SEEK_SET) == 0; }
115 [[nodiscard]] inline bool stream::pos_set_to_end() { return fseek(p_file, 0, SEEK_END) == 0; }
116 [[nodiscard]] inline bool stream::pos_move(offset diff) { return fseek(p_file, diff, SEEK_CUR) == 0; }
117 [[nodiscard]] inline offset stream::pos() { return ftell(p_file); }
118
119 [[nodiscard]] inline bool stream::pos_at_end()
120 {
121 #ifdef __MINGW32__
122 return position_at_end_locked();
123 #else
124 return feof_unlocked(p_file) == EOF;
125 #endif
126 }
127 [[nodiscard]] inline bool stream::pos_at_end_locked() { return feof(p_file) == EOF; }
128
129
130 [[nodiscard]] inline size_t stream::read_bytes(void *p_dst, size_t size)
131 {
132 return details::read<false>(p_file, p_dst, size, 1);
133 }
134 [[nodiscard]] inline size_t stream::read_bytes_locked ( void *p_dst, size_t size)
135 {
136 return details::read<true>(p_file, p_dst, size, 1);
137 }
138 [[nodiscard]] inline size_t stream::write_bytes (const void *p_src, size_t size)
139 {
140 return details::write<false>(p_file, p_src, size, 1);
141 }
142 [[nodiscard]] inline size_t stream::write_bytes_locked(const void *p_src, size_t size)
143 {
144 return details::write<true>(p_file, p_src, size, 1);
145 }
146
147 template<typename T>
148 [[nodiscard]] inline size_t stream::read_items(T *p_dst, size_t count)
149 {
150 return details::read<false>(p_file, p_dst, sizeof(T), count);
151 }
152 template<typename T>
153 [[nodiscard]] inline bool stream::read_item(T *p_dst)
154 {
155 return details::read<false>(p_file, p_dst, sizeof(T), 1) == 1;
156 }
157 template<typename T>
158 [[nodiscard]] inline size_t stream::read_items_locked(T *p_dst, size_t count)
159 {
160 return details::read<true>(p_file, p_dst, sizeof(T), count);
161 }
162 template<typename T>
163 [[nodiscard]] inline bool stream::read_item_locked(T *p_dst)
164
165 { return details::read<true>(p_file, p_dst, sizeof(T), 1) == 1;
166 }
167
168 template<typename T>
169 [[nodiscard]] inline size_t stream::write_items(const T *p_src, size_t count)
170 {
171 return details::write<false>(p_file, p_src, sizeof(T), count);
172 }
173 template<typename T>
174 [[nodiscard]] inline bool stream::write_item(const T *p_src)
175 {
176 return details::write<false>(p_file, p_src, sizeof(T), 1) == 1;
177 }
178 template<typename T>
179 [[nodiscard]] inline size_t stream::write_items_locked(const T *p_src, size_t count)
180 {
181 return details::write<true>(p_file, p_src, sizeof(T), count);
182 }
183 template<typename T>
184 [[nodiscard]] inline bool stream::write_item_locked(const T *p_src)
185 {
186 return details::write<true>(p_file, p_src, sizeof(T), 1) == 1;
187 }
188
189
190 [[nodiscard]] inline bool stream::read_string(char *p_dst, int limit)
191 {
192 return details::read_str<false>(p_file, p_dst, limit);
193 }
194 [[nodiscard]] inline bool stream::read_string_locked(char *p_dst, int limit)
195 {
196 return details::read_str<true>(p_file, p_dst, limit);
197 }
198 [[nodiscard]] inline bool stream::write_string(const char *p_src)
199 {
200 return details::write_str<false>(p_file, p_src);
201 }
202 [[nodiscard]] inline bool stream::write_string_locked(const char *p_src)
203 {
204 return details::write_str<true>(p_file, p_src);
205 }
206
207
208 [[nodiscard]] inline stream::flag operator | (stream::flag _1, stream::flag _2)
209 {
210 return stream::flag(uint8_t(_1) | _2);
211 }
212
213 [[nodiscard]] inline bool read_file(const char *filename, char **pp_dst, uint64_t *p_size)
214 {
215 stream file;
216
217 if (not file.open_file(filename, stream::flag::READ_BIT))
218 return false;
219
220 if (file.pos_set_to_end())
221 {
222 size_t size = (*p_size) = size_t(file.pos());
223
224 if (not file.pos_set(0))
225 goto CANCEL;
226
227 if (not jl::allocate_bytes(pp_dst, size))
228 goto CANCEL;
229
230 if (not file.read_bytes(*pp_dst, size))
231 {
232 free(*pp_dst);
233 goto CANCEL;
234 }
235
236 file.close();
237 return true;
238 }
239
240 CANCEL: file.close();
241 return false;
242 }
243 }
244 }
File include/jlib/fs/staff.h added (mode: 100644) (index 0000000..d506070)
1 /**
2 * @file staff.h
3 * @brief Misc declarations in fs namespace.
4 */
5 #pragma once
6
7 #include <sys/stat.h>
8
9 #include <linux/limits.h>
10 #include <cinttypes>
11 #include <unistd.h>
12 #include <cstring>
13 #include <cerrno>
14
15 namespace jl
16 {
17 /**
18 * @brief Utilities for working with file-systems.
19 */
20 namespace fs
21 {
22 /// @brief Type of file offsets
23 using offset = off_t;
24
25 /// @brief Permission mode bits.
26 enum class mode : mode_t
27 {
28 READ = 0b100,
29 WRITE = 0b10,
30 EXECUTE = 0b1,
31 READ_WRITE = READ | WRITE,
32 READ_EXECUTE = READ | EXECUTE,
33 WRITE_EXECUTE = WRITE | EXECUTE,
34 READ_WRITE_EXECUTE = READ | WRITE | EXECUTE
35 };
36
37 /// @brief File permissions type.
38 using perm = mode_t;
39
40 /// @brief Construct permissions for user, group and others from mode bits to permission type value.
41 [[nodiscard]] constexpr perm permissions(mode user, mode group = mode::READ, mode other = mode::READ)
42 {
43 return perm(perm(user) << 6 | perm(group) << 3 | perm(other));
44 }
45
46 namespace details
47 {
48 [[nodiscard]] inline bool fs_info(const char *fname, int type, uint64_t *p_dst)
49 {
50 auto length = pathconf(fname, type);
51 if (length < 0)
52 return false;
53 *p_dst = uint64_t(length);
54 return true;
55 }
56 }
57 /// @brief Get max file path length
58 [[nodiscard]] inline bool max_path_length(const char *fname, uint64_t *p_dst)
59 { return details::fs_info(fname, _PC_PATH_MAX, p_dst); }
60
61 /// @brief Get max file name length
62 [[nodiscard]] inline bool max_name_length(const char *fname, uint64_t *p_dst)
63 { return details::fs_info(fname, _PC_NAME_MAX, p_dst); }
64
65
66 /// @brief Get file or directory modification time.
67 [[nodiscard]] inline bool modification_time(const char *path, time_t *p_dst)
68 {
69 struct stat statbuf;
70 if (stat(path, &statbuf) == -1)
71 return false;
72 *p_dst = statbuf.st_mtime;
73 return true;
74 }
75
76 /// @brief Check if file or directory exist.
77 [[nodiscard]] inline bool exist(const char *path) { return access(path, F_OK) != -1; }
78
79 /// @brief Get errno.
80 [[nodiscard]] inline int error_no() { return errno; }
81 /// @brief Get string error description.
82 [[nodiscard]] inline const char* error_str(int err) { return strerror(err); }
83 /// @brief Get string errno description.
84 [[nodiscard]] inline const char* error_str() { return strerror(errno); }
85 }
86 }
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/Jackalope/jlib

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/Jackalope/jlib

Clone this repository using git:
git clone git://git.rocketgit.com/user/Jackalope/jlib

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main