|
2 | 2 |
|
3 | 3 | [](https://opensource.org/licenses/MIT) |
4 | 4 |  |
| 5 | + |
5 | 6 |  |
| 7 | + |
6 | 8 |
|
7 | | -**NanoDS** is a high-performance, memory-safe, single-header C library. It provides generic, type-safe data structures (Vectors and Hash Maps) with a "zero-dependency" footprint. |
8 | | - |
| 9 | +**NanoDS** is a high-performance, memory-safe, single-header C library providing generic, type-safe data structures (Vectors and Hash Maps) with zero dependencies. |
9 | 10 |
|
| 11 | +--- |
10 | 12 |
|
11 | 13 | ## 🛠 Why NanoDS? |
12 | 14 |
|
13 | 15 | Standard C lacks built-in generic containers. Developers often resort to unsafe `void*` casts or manual memory management. **NanoDS** solves this by using C macros to provide **compile-time type safety** and built-in **security guards**. |
14 | 16 |
|
15 | | -### Key Features: |
16 | | -* **Single-Header:** Just drop `nanods.h` into your project. No build systems required. |
17 | | -* **Type-Safe Vectors:** Generic dynamic arrays for any data type (`int`, `struct`, etc.). |
18 | | -* **Secure Hash Maps:** String-keyed maps using the collision-resistant **FNV-1a** algorithm. |
19 | | -* **Security First:** * **Integer Overflow Protection:** All allocations are checked against `SIZE_MAX`. |
20 | | - * **Safe Realloc:** Prevents memory leaks if `realloc` fails. |
21 | | - * **Secure Free:** Optional zeroing of memory before freeing to protect sensitive data. |
| 17 | +### ✨ Key Features |
| 18 | + |
| 19 | +* 📦 **Single-Header** - Drop `nanods.h` into your project. No build systems required. |
| 20 | +* 🔒 **Type-Safe Vectors** - Generic dynamic arrays for any data type (`int`, `struct`, etc.) |
| 21 | +* 🗺️ **Secure Hash Maps** - String-keyed maps using collision-resistant **FNV-1a** algorithm |
| 22 | +* 🛡️ **Security First** |
| 23 | + * **Integer Overflow Protection** - All allocations checked against `SIZE_MAX` |
| 24 | + * **Safe Realloc** - Prevents memory leaks if `realloc()` fails |
| 25 | + * **Bounds Checking** - Assert-based validation for all index access |
| 26 | + * **Secure Free** - Optional memory zeroing before deallocation |
| 27 | +* ✅ **Zero Memory Leaks** - Valgrind verified |
| 28 | +* 🚀 **Zero Dependencies** - Only requires standard C library |
22 | 29 |
|
23 | 30 | --- |
24 | 31 |
|
25 | 32 | ## 🚀 Quick Start |
26 | 33 |
|
27 | | -### 1. Include the Library |
28 | | -In **exactly one** C file, define `NANODS_IMPLEMENTATION` before including the header to create the logic. In all other files, just include it normally. |
| 34 | +### Installation |
| 35 | + |
| 36 | +**Option 1: Direct Download** |
| 37 | +```bash |
| 38 | +wget https://raw.githubusercontent.com/Nowazish-Nur-Kayef/NanoDS/main/nanods.h |
| 39 | +``` |
| 40 | + |
| 41 | +**Option 2: Clone Repository** |
| 42 | +```bash |
| 43 | +git clone https://github.com/Nowazish-Nur-Kayef/NanoDS.git |
| 44 | +cd NanoDS |
| 45 | +``` |
| 46 | + |
| 47 | +### Usage |
| 48 | + |
| 49 | +#### 1. Include the Library |
| 50 | + |
| 51 | +In **exactly one** C file, define `NANODS_IMPLEMENTATION` before including: |
29 | 52 |
|
30 | 53 | ```c |
31 | 54 | #define NANODS_IMPLEMENTATION |
32 | 55 | #include "nanods.h" |
| 56 | +``` |
33 | 57 |
|
| 58 | +In all other files, just include normally: |
| 59 | + |
| 60 | +```c |
| 61 | +#include "nanods.h" |
34 | 62 | ``` |
35 | 63 |
|
36 | | -### 2. Using Vectors |
| 64 | +#### 2. Using Vectors |
37 | 65 |
|
38 | 66 | ```c |
39 | | -IntVector vec; |
40 | | -nv_init_int(&vec); |
| 67 | +#include <stdio.h> |
| 68 | +#define NANODS_IMPLEMENTATION |
| 69 | +#include "nanods.h" |
41 | 70 |
|
42 | | -nv_push_int(&vec, 42); |
43 | | -nv_push_int(&vec, 100); |
| 71 | +int main(void) { |
| 72 | + // Create an integer vector |
| 73 | + IntVector vec; |
| 74 | + nv_init_int(&vec); |
| 75 | + |
| 76 | + // Add elements |
| 77 | + nv_push_int(&vec, 42); |
| 78 | + nv_push_int(&vec, 100); |
| 79 | + nv_push_int(&vec, 256); |
| 80 | + |
| 81 | + // Access elements |
| 82 | + printf("First element: %d\n", nv_get_int(&vec, 0)); |
| 83 | + printf("Vector size: %zu\n", nv_size_int(&vec)); |
| 84 | + |
| 85 | + // Iterate |
| 86 | + for (size_t i = 0; i < nv_size_int(&vec); i++) { |
| 87 | + printf("%d ", nv_get_int(&vec, i)); |
| 88 | + } |
| 89 | + |
| 90 | + // Clean up |
| 91 | + nv_free_int(&vec); |
| 92 | + return 0; |
| 93 | +} |
| 94 | +``` |
44 | 95 |
|
45 | | -printf("Value at 0: %d\n", nv_get_int(&vec, 0)); |
| 96 | +#### 3. Using Hash Maps |
46 | 97 |
|
47 | | -nv_free_int(&vec); |
| 98 | +```c |
| 99 | +#include <stdio.h> |
| 100 | +#define NANODS_IMPLEMENTATION |
| 101 | +#include "nanods.h" |
48 | 102 |
|
| 103 | +int main(void) { |
| 104 | + NanoMap config; |
| 105 | + nm_init(&config); |
| 106 | + |
| 107 | + // Store configuration |
| 108 | + int port = 8080; |
| 109 | + int max_conn = 100; |
| 110 | + |
| 111 | + nm_set(&config, "port", &port); |
| 112 | + nm_set(&config, "max_connections", &max_conn); |
| 113 | + |
| 114 | + // Retrieve values |
| 115 | + int* result = (int*)nm_get(&config, "port"); |
| 116 | + if (result) { |
| 117 | + printf("Server port: %d\n", *result); |
| 118 | + } |
| 119 | + |
| 120 | + // Check existence |
| 121 | + if (nm_has(&config, "port")) { |
| 122 | + printf("Port is configured\n"); |
| 123 | + } |
| 124 | + |
| 125 | + // Clean up |
| 126 | + nm_free(&config); |
| 127 | + return 0; |
| 128 | +} |
49 | 129 | ``` |
50 | 130 |
|
51 | | -### 3. Using Hash Maps |
| 131 | +#### 4. Custom Data Types |
52 | 132 |
|
53 | 133 | ```c |
54 | | -NanoMap map; |
55 | | -nm_init(&map); |
| 134 | +typedef struct { |
| 135 | + char name[50]; |
| 136 | + int age; |
| 137 | +} Person; |
| 138 | + |
| 139 | +// Define vector for custom type |
| 140 | +NANODS_DEFINE_VECTOR(Person) |
| 141 | + |
| 142 | +int main(void) { |
| 143 | + NanoVector_Person people; |
| 144 | + nv_init_Person(&people); |
| 145 | + |
| 146 | + Person p1 = {"Alice", 25}; |
| 147 | + Person p2 = {"Bob", 30}; |
| 148 | + |
| 149 | + nv_push_Person(&people, p1); |
| 150 | + nv_push_Person(&people, p2); |
| 151 | + |
| 152 | + // Access |
| 153 | + Person first = nv_get_Person(&people, 0); |
| 154 | + printf("%s is %d years old\n", first.name, first.age); |
| 155 | + |
| 156 | + nv_free_Person(&people); |
| 157 | + return 0; |
| 158 | +} |
| 159 | +``` |
| 160 | +
|
| 161 | +--- |
| 162 | +
|
| 163 | +## 🔨 Building |
| 164 | +
|
| 165 | +### Using Make (Recommended) |
| 166 | +
|
| 167 | +```bash |
| 168 | +# Build test suite |
| 169 | +make |
| 170 | +
|
| 171 | +# Run tests |
| 172 | +make run |
| 173 | +
|
| 174 | +# Build with debug symbols |
| 175 | +make debug |
| 176 | +
|
| 177 | +# Check for memory leaks |
| 178 | +make valgrind |
| 179 | +
|
| 180 | +# Clean build files |
| 181 | +make clean |
| 182 | +
|
| 183 | +# See all options |
| 184 | +make help |
| 185 | +``` |
56 | 186 |
|
57 | | -int age = 25; |
58 | | -nm_set(&map, "user_age", &age); |
| 187 | +### Manual Compilation |
59 | 188 |
|
60 | | -int* result = (int*)nm_get(&map, "user_age"); |
61 | | -if (result) printf("Age: %d\n", *result); |
| 189 | +```bash |
| 190 | +# Compile test suite |
| 191 | +gcc -std=c11 -Wall -Wextra test. c -o nanods_test |
62 | 192 |
|
63 | | -nm_free(&map); |
| 193 | +# Run |
| 194 | +./nanods_test |
64 | 195 |
|
| 196 | +# Compile your own code |
| 197 | +gcc -std=c11 -Wall -Wextra your_code.c -o your_program |
65 | 198 | ``` |
66 | 199 |
|
| 200 | +### Requirements |
| 201 | + |
| 202 | +- **C Compiler**: GCC 4.9+, Clang 3.4+, MSVC 2015+ |
| 203 | +- **C Standard**: C11 or later |
| 204 | +- **OS**: Linux, macOS, Windows (cross-platform) |
| 205 | + |
67 | 206 | --- |
68 | 207 |
|
69 | | -## 🛡 Security Specifications |
| 208 | +## 🛡️ Security Specifications |
70 | 209 |
|
71 | 210 | NanoDS is designed for systems where memory safety is critical: |
72 | 211 |
|
73 | | -| Feature | Protection | |
74 | | -| --- | --- | |
75 | | -| **Overflow Check** | Prevents buffer overflows by checking `a * b > SIZE_MAX`. | |
76 | | -| **Bounds Checking** | `assert()` based validation for all index-based access. | |
77 | | -| **Memory Sanitization** | `nv_secure_free` overwrites data with `0x00` to prevent RAM dumping. | |
| 212 | +| Feature | Protection | Implementation | |
| 213 | +|---------|------------|----------------| |
| 214 | +| **Overflow Check** | Prevents buffer overflows | Validates `a * b < SIZE_MAX` before allocation | |
| 215 | +| **Bounds Checking** | Out-of-bounds protection | Assert-based validation on all array access | |
| 216 | +| **Safe Realloc** | Memory leak prevention | Uses temporary pointer before overwriting | |
| 217 | +| **Memory Sanitization** | Data exposure prevention | `nv_secure_free()` zeros memory with `memset()` | |
| 218 | +| **Hash Collision** | DoS attack resistance | FNV-1a algorithm with good distribution | |
| 219 | + |
| 220 | +### Security Example |
| 221 | + |
| 222 | +```c |
| 223 | +// Secure handling of sensitive data |
| 224 | +IntVector passwords; |
| 225 | +nv_init_int(&passwords); |
| 226 | +nv_push_int(&passwords, 12345); |
| 227 | +nv_push_int(&passwords, 67890); |
| 228 | + |
| 229 | +// Zero memory before freeing |
| 230 | +nv_secure_free_int(&passwords); // Memory is overwritten with 0x00 |
| 231 | +``` |
| 232 | +
|
| 233 | +--- |
| 234 | +
|
| 235 | +## 📊 API Reference |
| 236 | +
|
| 237 | +### Vector Operations |
| 238 | +
|
| 239 | +| Function | Description | Returns | |
| 240 | +|----------|-------------|---------| |
| 241 | +| `nv_init_TYPE(&vec)` | Initialize empty vector | void | |
| 242 | +| `nv_push_TYPE(&vec, value)` | Add element to end | 0 on success, -1 on error | |
| 243 | +| `nv_get_TYPE(&vec, index)` | Get element at index | Element value | |
| 244 | +| `nv_set_TYPE(&vec, index, value)` | Set element at index | 0 on success, -1 on error | |
| 245 | +| `nv_pop_TYPE(&vec, &out)` | Remove last element | 0 on success, -1 if empty | |
| 246 | +| `nv_size_TYPE(&vec)` | Get number of elements | size_t | |
| 247 | +| `nv_empty_TYPE(&vec)` | Check if empty | 1 if empty, 0 otherwise | |
| 248 | +| `nv_clear_TYPE(&vec)` | Remove all elements | void | |
| 249 | +| `nv_free_TYPE(&vec)` | Free memory | void | |
| 250 | +| `nv_secure_free_TYPE(&vec)` | Zero and free memory | void | |
| 251 | +
|
| 252 | +### Map Operations |
| 253 | +
|
| 254 | +| Function | Description | Returns | |
| 255 | +|----------|-------------|---------| |
| 256 | +| `nm_init(&map)` | Initialize empty map | void | |
| 257 | +| `nm_set(&map, key, value)` | Set key-value pair | 0 on success, -1 on error | |
| 258 | +| `nm_get(&map, key)` | Get value for key | Pointer or NULL | |
| 259 | +| `nm_has(&map, key)` | Check if key exists | 1 if exists, 0 otherwise | |
| 260 | +| `nm_remove(&map, key)` | Remove key-value pair | 0 on success, -1 if not found | |
| 261 | +| `nm_size(&map)` | Get number of entries | size_t | |
| 262 | +| `nm_empty(&map)` | Check if empty | 1 if empty, 0 otherwise | |
| 263 | +| `nm_clear(&map)` | Remove all entries | void | |
| 264 | +| `nm_free(&map)` | Free memory | void | |
| 265 | +| `nm_secure_free(&map)` | Zero keys and free | void | |
78 | 266 |
|
79 | 267 | --- |
80 | 268 |
|
81 | | -## 🏗 Installation & Testing |
| 269 | +## 🧪 Testing |
82 | 270 |
|
83 | | -Clone the repository and run the automated test suite using the provided Makefile: |
| 271 | +Run the comprehensive test suite: |
84 | 272 |
|
85 | 273 | ```bash |
86 | | -git clone [https://github.com/Nowazish-Nur-Kayef/NanoDS.git](https://github.com/Nowazish-Nur-Kayef/NanoDS.git) |
| 274 | +# Clone and test |
| 275 | +git clone https://github.com/Nowazish-Nur-Kayef/NanoDS.git |
87 | 276 | cd NanoDS |
88 | 277 | make run |
| 278 | +``` |
| 279 | + |
| 280 | +**Memory leak verification:** |
| 281 | +```bash |
| 282 | +make valgrind |
| 283 | +``` |
89 | 284 |
|
| 285 | +Expected output: |
| 286 | +``` |
| 287 | +All heap blocks were freed -- no leaks are possible |
| 288 | +ERROR SUMMARY: 0 errors from 0 contexts |
90 | 289 | ``` |
91 | 290 |
|
92 | 291 | --- |
93 | 292 |
|
94 | | -## 📜 License |
| 293 | +## 📈 Performance |
95 | 294 |
|
96 | | -This project is licensed under the **MIT License** - see the [LICENSE](https://www.google.com/search?q=LICENSE) file for details. |
| 295 | +- **Vector Growth**: Exponential (2x) with overflow protection |
| 296 | +- **Map Hashing**: FNV-1a (O(1) average lookup) |
| 297 | +- **Memory**: Minimal overhead, no hidden allocations |
| 298 | +- **Cache**: Contiguous memory for vectors (cache-friendly) |
| 299 | + |
| 300 | +--- |
97 | 301 |
|
98 | 302 | ## 🤝 Contributing |
99 | 303 |
|
100 | | -Stars are always welcome! If you'd like to contribute (Linked Lists, Queues, etc.), please open an issue or a Pull Request. |
| 304 | +Contributions are welcome! Here's how you can help: |
101 | 305 |
|
102 | | -If you find this library useful, please consider giving it a ⭐ to help others discover it! |
| 306 | +- 🐛 **Report bugs** - Open an issue |
| 307 | +- 💡 **Suggest features** - Linked lists, queues, trees, etc. |
| 308 | +- 📖 **Improve docs** - Fix typos, add examples |
| 309 | +- ⭐ **Star the repo** - Help others discover it |
| 310 | + |
| 311 | +### Development |
| 312 | + |
| 313 | +```bash |
| 314 | +# Fork and clone |
| 315 | +git clone https://github.com/YOUR_USERNAME/NanoDS.git |
| 316 | +cd NanoDS |
| 317 | + |
| 318 | +# Make changes |
| 319 | +# ... edit nanods.h ... |
| 320 | + |
| 321 | +# Test |
| 322 | +make clean && make run |
| 323 | +make valgrind |
| 324 | + |
| 325 | +# Submit PR |
| 326 | +git add . |
| 327 | +git commit -m "Add feature X" |
| 328 | +git push origin main |
| 329 | +``` |
| 330 | + |
| 331 | +--- |
| 332 | + |
| 333 | +## 📜 License |
| 334 | + |
| 335 | +This project is licensed under the **MIT License** - see the [LICENSE](LICENSE) file for details. |
| 336 | + |
| 337 | +--- |
| 338 | + |
| 339 | +## 🙏 Acknowledgments |
| 340 | + |
| 341 | +- Inspired by [stb libraries](https://github.com/nothings/stb) by Sean Barrett |
| 342 | +- FNV-1a hash algorithm by Glenn Fowler, Landon Curt Noll, and Kiem-Phong Vo |
| 343 | + |
| 344 | +--- |
| 345 | + |
| 346 | +## 📞 Contact |
103 | 347 |
|
104 | 348 | **Author:** [Nowazish-Nur-Kayef](https://github.com/Nowazish-Nur-Kayef) |
| 349 | + |
| 350 | +If you find this library useful, please consider giving it a ⭐ to help others discover it! |
| 351 | + |
| 352 | +--- |
| 353 | + |
| 354 | +<p align="center"> |
| 355 | + <b>Made with ❤️ for the C community</b> |
| 356 | +</p> |
0 commit comments