diff --git a/README.md b/README.md index 14e1bc9..e2ab5d3 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,9 @@ # ESP32 ESP-IDF component for vector (dynamic array) +## Wiki + +[EN](WIKI_EN.md) | [RU](WIKI_RU.md) + ## Tested on 1. [ESP32 ESP-IDF v6.0.0](https://docs.espressif.com/projects/esp-idf/en/v6.0/esp32/index.html) diff --git a/WIKI_EN.md b/WIKI_EN.md new file mode 100644 index 0000000..ec64466 --- /dev/null +++ b/WIKI_EN.md @@ -0,0 +1,399 @@ +# zh_vector - Vector (Dynamic Array) Component for ESP-IDF + +## Table of Contents + +- [Overview](#overview) +- [Features](#features) +- [Installation](#installation) +- [API Reference](#api-reference) +- [Usage Examples](#usage-examples) +- [Technical Specifications](#technical-specifications) +- [Error Codes](#error-codes) +- [Contributing](#contributing) +- [License](#license) + +--- + +## Overview + +`zh_vector` is a lightweight, efficient vector (dynamic array) component for ESP-IDF (Espressif IoT Development Framework). It provides a flexible container that can store elements of any data type with automatic memory management. The vector automatically resizes as items are added or removed, making it ideal for dynamic data management in embedded systems. + +The component is designed specifically for ESP32 microcontrollers and uses ESP-IDF's heap management functions for optimal memory allocation with different memory caps (internal/external RAM). + +--- + +## Features + +1. **Type Agnostic**: Supports any data type (integers, floats, structs, custom types, etc.) +2. **Automatic Memory Management**: Automatic memory allocation and deallocation +3. **Dynamic Resizing**: Vector capacity grows and shrinks as needed +4. **Maximum Capacity**: Up to 65,535 elements (16-bit index limit) +5. **ESP-IDF Optimized**: Uses heap_caps functions for memory allocation with memory caps +6. **Error Handling**: Comprehensive error checking with detailed logging +7. **Thread-Safe**: Not thread-safe by default (can be made thread-safe with external mutex) +8. **Minimal Overhead**: Low memory and CPU overhead + +--- + +## Installation + +1. Navigate to your project's components directory: + +```bash +cd ../your_project/components +``` + +2. Clone the repository: + +```bash +git clone https://github.com/aZholtikov/zh_vector +``` + +3. In your application, include the header: + +```c +#include "zh_vector.h" +``` + +4. The component will be automatically built with your project. + +--- + +## API Reference + +### zh_vector_t Structure + +```c +typedef struct +{ + void **items; // Array of pointers of vector items + uint16_t capacity; // Maximum capacity of the vector + uint16_t size; // Number of items in the vector + uint16_t unit; // Vector item size (in bytes) + bool is_initialized; // Vector initialization status flag +} zh_vector_t; +``` + +--- + +### zh_vector_init() + +Initializes the vector. + +**Parameters:** + +- `vector` - Pointer to the vector structure +- `unit` - Size of each element in bytes + +**Returns:** + +- `ESP_OK` - Success +- `ESP_ERR_INVALID_ARG` - Invalid argument (NULL vector or zero unit size) +- `ESP_ERR_INVALID_STATE` - Vector already initialized + +**Example:** + +```c +zh_vector_t vector = {0}; +zh_vector_init(&vector, sizeof(int)); // For integers +``` + +--- + +### zh_vector_free() + +Deinitializes the vector and frees all allocated memory. + +**Parameters:** + +- `vector` - Pointer to the vector structure + +**Returns:** + +- `ESP_OK` - Success +- `ESP_ERR_INVALID_ARG` - Invalid argument (NULL vector) +- `ESP_ERR_INVALID_STATE` - Vector not initialized + +**Note:** All dynamically allocated element memory is also freed. + +--- + +### zh_vector_get_size() + +Gets the current number of elements in the vector. + +**Parameters:** + +- `vector` - Pointer to the vector structure + +**Returns:** + +- `>= 0` - Number of elements (success) +- `ESP_FAIL` - Error (NULL vector or not initialized) + +--- + +### zh_vector_push_back() + +Adds an element to the end of the vector. + +**Parameters:** + +- `vector` - Pointer to the vector structure +- `item` - Pointer to the element to add + +**Returns:** + +- `ESP_OK` - Success +- `ESP_ERR_INVALID_ARG` - Invalid argument (NULL vector or item) +- `ESP_ERR_INVALID_STATE` - Vector not initialized +- `ESP_ERR_NO_MEM` - Memory allocation failed + +**Note:** The function allocates memory for a copy of the item and copies the data. + +--- + +### zh_vector_change_item() + +Changes an element at a specific index. + +**Parameters:** + +- `vector` - Pointer to the vector structure +- `index` - Index of the element to change (0-based) +- `item` - Pointer to the new element data + +**Returns:** + +- `ESP_OK` - Success +- `ESP_ERR_INVALID_ARG` - Invalid argument (NULL vector, item, or invalid index) +- `ESP_ERR_INVALID_STATE` - Vector not initialized +- `ESP_FAIL` - Index out of bounds + +--- + +### zh_vector_get_item() + +Gets an element at a specific index. + +**Parameters:** + +- `vector` - Pointer to the vector structure +- `index` - Index of the element to get (0-based) + +**Returns:** + +- Pointer to the element (success) +- `NULL` - Error (NULL vector, not initialized, or invalid index) + +**Note:** Returns a pointer to the internal data. Do not free this pointer. + +--- + +### zh_vector_delete_item() + +Deletes an element at a specific index and shifts all subsequent elements. + +**Parameters:** + +- `vector` - Pointer to the vector structure +- `index` - Index of the element to delete (0-based) + +**Returns:** + +- `ESP_OK` - Success +- `ESP_ERR_INVALID_ARG` - Invalid argument (NULL vector) +- `ESP_ERR_INVALID_STATE` - Vector not initialized +- `ESP_FAIL` - Index out of bounds + +**Note:** All elements after the deleted index are shifted left by one position. + +--- + +## Usage Examples + +### Basic Example: Integer Vector + +```c +#include "zh_vector.h" + +zh_vector_t int_vector = {0}; + +void app_main(void) +{ + // Initialize vector for integers + zh_vector_init(&int_vector, sizeof(int)); + + // Add elements + int val1 = 10; + int val2 = 20; + int val3 = 30; + + zh_vector_push_back(&int_vector, &val1); + zh_vector_push_back(&int_vector, &val2); + zh_vector_push_back(&int_vector, &val3); + + printf("Vector size: %d\n", zh_vector_get_size(&int_vector)); + + // Access elements + for (int i = 0; i < zh_vector_get_size(&int_vector); i++) { + int *item = (int *)zh_vector_get_item(&int_vector, i); + printf("Element %d: %d\n", i, *item); + } + + // Change element + int new_val = 100; + zh_vector_change_item(&int_vector, 1, &new_val); + + // Delete element + zh_vector_delete_item(&int_vector, 0); + + // Cleanup + zh_vector_free(&int_vector); +} +``` + +### Struct Example + +```c +#include "zh_vector.h" + +typedef struct { + int id; + char name[32]; + float value; +} my_struct_t; + +zh_vector_t struct_vector = {0}; + +void app_main(void) +{ + // Initialize vector for structs + zh_vector_init(&struct_vector, sizeof(my_struct_t)); + + // Add struct elements + my_struct_t item1 = {1, "Item 1", 1.5f}; + my_struct_t item2 = {2, "Item 2", 2.5f}; + + zh_vector_push_back(&struct_vector, &item1); + zh_vector_push_back(&struct_vector, &item2); + + // Access and modify + my_struct_t *ptr = (my_struct_t *)zh_vector_get_item(&struct_vector, 0); + ptr->value = 10.5f; + + // Cleanup + zh_vector_free(&struct_vector); +} +``` + +### String Example (Char Arrays) + +```c +#include "zh_vector.h" +#include "string.h" + +zh_vector_t string_vector = {0}; + +void app_main(void) +{ + // Initialize vector for strings (100 char max) + char buffer[100] = {0}; + zh_vector_init(&string_vector, sizeof(buffer)); + + // Add strings + strcpy(buffer, "Hello"); + zh_vector_push_back(&string_vector, &buffer); + + strcpy(buffer, "World"); + zh_vector_push_back(&string_vector, &buffer); + + // Print all strings + for (int i = 0; i < zh_vector_get_size(&string_vector); i++) { + char *str = (char *)zh_vector_get_item(&string_vector, i); + printf("String %d: %s\n", i, str); + } + + // Cleanup + zh_vector_free(&string_vector); +} +``` + +--- + +## Technical Specifications + +| Parameter | Value | +|-----------|-------| +| **Maximum Capacity** | 65,535 elements | +| **Index Type** | uint16_t (16-bit) | +| **Memory Management** | heap_caps_calloc, heap_caps_realloc, heap_caps_free | +| **Memory Caps** | MALLOC_CAP_8BIT | +| **Thread Safety** | Not thread-safe | +| **ESP-IDF Version** | Tested with v6.0.0 | +| **Platform** | ESP32 series | +| **Language** | C (C99) | + +--- + +## Error Codes + +| Error Code | Description | +|------------|-------------| +| `ESP_OK` | Operation successful | +| `ESP_ERR_INVALID_ARG` | Invalid argument (NULL pointer or zero size) | +| `ESP_ERR_INVALID_STATE` | Vector not initialized or already initialized | +| `ESP_ERR_NO_MEM` | Memory allocation failed (out of memory) | +| `ESP_FAIL` | General failure (e.g., index out of bounds) | + +--- + +## Contributing + +Contributions are welcome! To contribute: + +1. Fork the repository +2. Create a feature branch (`git checkout -b feature/AmazingFeature`) +3. Commit your changes (`git commit -m 'Add some AmazingFeature'`) +4. Push to the branch (`git push origin feature/AmazingFeature`) +5. Open a Pull Request + +Please ensure your code follows the existing style and includes appropriate documentation. + +--- + +## License + +This project is licensed under the Apache License, Version 2.0 - see the [LICENSE](LICENSE) file for details. + +### Apache License, Version 2.0 + +Copyright (c) 2026 Alexey Zholtikov + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +--- + +## Additional Notes + +- **Memory Overhead**: Each element requires additional memory for the pointer in the internal pointer array +- **Performance**: O(1) for get/set by index, O(n) for insert/delete in the middle +- **Best Practices**: + - Always initialize the vector before use + - Free the vector when done to avoid memory leaks + - Consider the maximum size limit (65,535 elements) + - For string handling, consider using fixed-size buffers + +--- + +*Generated for zh_vector v1.1.1* diff --git a/WIKI_RU.md b/WIKI_RU.md new file mode 100644 index 0000000..38a278d --- /dev/null +++ b/WIKI_RU.md @@ -0,0 +1,399 @@ +# zh_vector - Компонент вектора (динамического массива) для ESP-IDF + +## Содержание + +- [Обзор](#обзор) +- [Возможности](#возможности) +- [Установка](#установка) +- [Справочник API](#справочник-api) +- [Примеры использования](#примеры-использования) +- [Технические характеристики](#технические-характеристики) +- [Коды ошибок](#коды-ошибок) +- [Вклад в проект](#вклад-в-проект) +- [Лицензия](#лицензия) + +--- + +## Обзор + +`zh_vector` — это легковесный и эффективный компонент вектора (динамического массива) для ESP-IDF (Espressif IoT Development Framework). Он предоставляет гибкий контейнер, который может хранить элементы любого типа данных с автоматическим управлением памятью. Вектор автоматически изменяет размер при добавлении или удалении элементов, что делает его идеальным для динамического управления данными во встраиваемых системах. + +Компонент разработан специально для микроконтроллеров ESP32 и использует функции управления кучей ESP-IDF для оптимального выделения памяти с различными параметрами памяти (внутренняя/внешняя RAM). + +--- + +## Возможности + +1. **Независимость от типа данных**: Поддерживает любой тип данных (целые числа, числа с плавающей точкой, структуры, пользовательские типы и т.д.) +2. **Автоматическое управление памятью**: Автоматическое выделение и освобождение памяти +3. **Динамическое изменение размера**: Емкость вектора увеличивается и уменьшается по мере необходимости +4. **Максимальная емкость**: До 65 535 элементов (ограничение 16-битного индекса) +5. **Оптимизировано под ESP-IDF**: Использует функции heap_caps для выделения памяти с параметрами памяти +6. **Обработка ошибок**: Комплексная проверка ошибок с детальным логированием +7. **Потокобезопасность**: Не является потокобезопасным по умолчанию (можно сделать потокобезопасным с внешним мьютексом) +8. **Минимальные накладные расходы**: Низкие накладные расходы на память и процессор + +--- + +## Установка + +1. Перейдите в каталог компонентов вашего проекта: + +```bash +cd ../ваш_проект/components +``` + +2. Клонируйте репозиторий: + +```bash +git clone https://github.com/aZholtikov/zh_vector +``` + +3. В вашем приложении подключите заголовочный файл: + +```c +#include "zh_vector.h" +``` + +4. Компонент будет автоматически собран вместе с вашим проектом. + +--- + +## Справочник API + +### Структура zh_vector_t + +```c +typedef struct +{ + void **items; // Массив указателей на элементы вектора + uint16_t capacity; // Максимальная емкость вектора + uint16_t size; // Количество элементов в векторе + uint16_t unit; // Размер элемента вектора (в байтах) + bool is_initialized; // Флаг состояния инициализации вектора +} zh_vector_t; +``` + +--- + +### zh_vector_init() + +Инициализирует вектор. + +**Параметры:** + +- `vector` - Указатель на структуру вектора +- `unit` - Размер каждого элемента в байтах + +**Возвращает:** + +- `ESP_OK` - Успех +- `ESP_ERR_INVALID_ARG` - Неверный аргумент (NULL вектор или нулевой размер unit) +- `ESP_ERR_INVALID_STATE` - Вектор уже инициализирован + +**Пример:** + +```c +zh_vector_t vector = {0}; +zh_vector_init(&vector, sizeof(int)); // Для целых чисел +``` + +--- + +### zh_vector_free() + +Деинициализирует вектор и освобождает всю выделенную память. + +**Параметры:** + +- `vector` - Указатель на структуру вектора + +**Возвращает:** + +- `ESP_OK` - Успех +- `ESP_ERR_INVALID_ARG` - Неверный аргумент (NULL вектор) +- `ESP_ERR_INVALID_STATE` - Вектор не инициализирован + +**Примечание:** Вся динамически выделенная память элементов также освобождается. + +--- + +### zh_vector_get_size() + +Получает текущее количество элементов в векторе. + +**Параметры:** + +- `vector` - Указатель на структуру вектора + +**Возвращает:** + +- `>= 0` - Количество элементов (успех) +- `ESP_FAIL` - Ошибка (NULL вектор или не инициализирован) + +--- + +### zh_vector_push_back() + +Добавляет элемент в конец вектора. + +**Параметры:** + +- `vector` - Указатель на структуру вектора +- `item` - Указатель на элемент для добавления + +**Возвращает:** + +- `ESP_OK` - Успех +- `ESP_ERR_INVALID_ARG` - Неверный аргумент (NULL вектор или item) +- `ESP_ERR_INVALID_STATE` - Вектор не инициализирован +- `ESP_ERR_NO_MEM` - Ошибка выделения памяти + +**Примечание:** Функция выделяет память для копии элемента и копирует данные. + +--- + +### zh_vector_change_item() + +Изменяет элемент по определенному индексу. + +**Параметры:** + +- `vector` - Указатель на структуру вектора +- `index` - Индекс элемента для изменения (начиная с 0) +- `item` - Указатель на новые данные элемента + +**Возвращает:** + +- `ESP_OK` - Успех +- `ESP_ERR_INVALID_ARG` - Неверный аргумент (NULL вектор, item или неверный индекс) +- `ESP_ERR_INVALID_STATE` - Вектор не инициализирован +- `ESP_FAIL` - Индекс вне границ + +--- + +### zh_vector_get_item() + +Получает элемент по определенному индексу. + +**Параметры:** + +- `vector` - Указатель на структуру вектора +- `index` - Индекс элемента для получения (начиная с 0) + +**Возвращает:** + +- Указатель на элемент (успех) +- `NULL` - Ошибка (NULL вектор, не инициализирован или неверный индекс) + +**Примечание:** Возвращает указатель на внутренние данные. Не освобождайте этот указатель. + +--- + +### zh_vector_delete_item() + +Удаляет элемент по определенному индексу и сдвигает все последующие элементы. + +**Параметры:** + +- `vector` - Указатель на структуру вектора +- `index` - Индекс элемента для удаления (начиная с 0) + +**Возвращает:** + +- `ESP_OK` - Успех +- `ESP_ERR_INVALID_ARG` - Неверный аргумент (NULL вектор) +- `ESP_ERR_INVALID_STATE` - Вектор не инициализирован +- `ESP_FAIL` - Индекс вне границ + +**Примечание:** Все элементы после удаляемого индекса сдвигаются влево на одну позицию. + +--- + +## Примеры использования + +### Базовый пример: Вектор целых чисел + +```c +#include "zh_vector.h" + +zh_vector_t int_vector = {0}; + +void app_main(void) +{ + // Инициализация вектора для целых чисел + zh_vector_init(&int_vector, sizeof(int)); + + // Добавление элементов + int val1 = 10; + int val2 = 20; + int val3 = 30; + + zh_vector_push_back(&int_vector, &val1); + zh_vector_push_back(&int_vector, &val2); + zh_vector_push_back(&int_vector, &val3); + + printf("Размер вектора: %d\n", zh_vector_get_size(&int_vector)); + + // Доступ к элементам + for (int i = 0; i < zh_vector_get_size(&int_vector); i++) { + int *item = (int *)zh_vector_get_item(&int_vector, i); + printf("Элемент %d: %d\n", i, *item); + } + + // Изменение элемента + int new_val = 100; + zh_vector_change_item(&int_vector, 1, &new_val); + + // Удаление элемента + zh_vector_delete_item(&int_vector, 0); + + // Очистка + zh_vector_free(&int_vector); +} +``` + +### Пример со структурой + +```c +#include "zh_vector.h" + +typedef struct { + int id; + char name[32]; + float value; +} my_struct_t; + +zh_vector_t struct_vector = {0}; + +void app_main(void) +{ + // Инициализация вектора для структур + zh_vector_init(&struct_vector, sizeof(my_struct_t)); + + // Добавление элементов-структур + my_struct_t item1 = {1, "Item 1", 1.5f}; + my_struct_t item2 = {2, "Item 2", 2.5f}; + + zh_vector_push_back(&struct_vector, &item1); + zh_vector_push_back(&struct_vector, &item2); + + // Доступ и модификация + my_struct_t *ptr = (my_struct_t *)zh_vector_get_item(&struct_vector, 0); + ptr->value = 10.5f; + + // Очистка + zh_vector_free(&struct_vector); +} +``` + +### Пример со строками (массивы символов) + +```c +#include "zh_vector.h" +#include "string.h" + +zh_vector_t string_vector = {0}; + +void app_main(void) +{ + // Инициализация вектора для строк (макс. 100 символов) + char buffer[100] = {0}; + zh_vector_init(&string_vector, sizeof(buffer)); + + // Добавление строк + strcpy(buffer, "Привет"); + zh_vector_push_back(&string_vector, &buffer); + + strcpy(buffer, "Мир"); + zh_vector_push_back(&string_vector, &buffer); + + // Печать всех строк + for (int i = 0; i < zh_vector_get_size(&string_vector); i++) { + char *str = (char *)zh_vector_get_item(&string_vector, i); + printf("Строка %d: %s\n", i, str); + } + + // Очистка + zh_vector_free(&string_vector); +} +``` + +--- + +## Технические характеристики + +| Параметр | Значение | +|----------|----------| +| **Максимальная емкость** | 65 535 элементов | +| **Тип индекса** | uint16_t (16-бит) | +| **Управление памятью** | heap_caps_calloc, heap_caps_realloc, heap_caps_free | +| **Параметры памяти** | MALLOC_CAP_8BIT | +| **Потокобезопасность** | Не является потокобезопасным | +| **Версия ESP-IDF** | Тестировалось с v6.0.0 | +| **Платформа** | Серия ESP32 | +| **Язык** | C (C99) | + +--- + +## Коды ошибок + +| Код ошибки | Описание | +|------------|----------| +| `ESP_OK` | Операция выполнена успешно | +| `ESP_ERR_INVALID_ARG` | Неверный аргумент (NULL указатель или нулевой размер) | +| `ESP_ERR_INVALID_STATE` | Вектор не инициализирован или уже инициализирован | +| `ESP_ERR_NO_MEM` | Ошибка выделения памяти (не хватает памяти) | +| `ESP_FAIL` | Общий сбой (например, индекс вне границ) | + +--- + +## Вклад в проект + +Вклад приветствуется! Чтобы внести свой вклад: + +1. Сделайте форк репозитория +2. Создайте ветку функции (`git checkout -b feature/AmazingFeature`) +3. Закоммитьте ваши изменения (`git commit -m 'Add some AmazingFeature'`) +4. Отправьте в ветку (`git push origin feature/AmazingFeature`) +5. Откройте Pull Request + +Пожалуйста, убедитесь, что ваш код следует существующему стилю и включает соответствующую документацию. + +--- + +## Лицензия + +Этот проект лицензирован по лицензии Apache, версия 2.0 - см. файл [LICENSE](LICENSE) для подробной информации. + +### Apache License, Version 2.0 + +Авторское право (c) 2026 Алексей Жолтиков + +Лицензировано по лицензии Apache License, Version 2.0 (далее — "Лицензия"); +вы не можете использовать этот файл, кроме случаев, предусмотренных Лицензией. +Копию Лицензии можно получить по адресу: + + http://www.apache.org/licenses/LICENSE-2.0 + +Если иное не требуется действующим законодательством или не согласовано в письменном виде, +программное обеспечение, распространяемое по Лицензии, распространяется на условиях "КАК ЕСТЬ", +БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, явных или подразумеваемых, включая, но не ограничиваясь, гарантии +ТОВАРНОГО СОСТОЯНИЯ, ПРИГОДНОСТИ ДЛЯ КОНКРЕТНОЙ ЦЕЛИ И НЕНАРУШЕНИЯ ПРАВ. +Смотрите Лицензию для получения конкретных прав и ограничений. + +--- + +## Дополнительные заметки + +- **Накладные расходы памяти**: Каждый элемент требует дополнительной памяти для указателя во внутреннем массиве указателей +- **Производительность**: O(1) для получения/установки по индексу, O(n) для вставки/удаления в середине +- **Лучшие практики**: + - Всегда инициализируйте вектор перед использованием + - Освобождайте вектор по завершении, чтобы избежать утечек памяти + - Учитывайте ограничение максимального размера (65 535 элементов) + - Для обработки строк рассмотрите использование буферов фиксированного размера + +--- + +*Сгенерировано для zh_vector v1.1.1*