├── .gitattributes
├── .github
└── workflows
│ └── tg-send.yml
├── LICENSE
├── README.md
├── README_EN.md
├── examples
├── test
│ └── test.ino
├── testUnicode
│ └── testUnicode.ino
├── testUrl
│ └── testUrl.ino
└── testUtils
│ └── testUtils.ino
├── keywords.txt
├── library.properties
└── src
├── GParser.h
└── utils
├── parseUtils.cpp
├── parseUtils.h
├── unicode.cpp
├── unicode.h
├── url.cpp
└── url.h
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/.github/workflows/tg-send.yml:
--------------------------------------------------------------------------------
1 |
2 | name: Telegram Message
3 | on:
4 | release:
5 | types: [published]
6 | jobs:
7 | build:
8 | name: Send Message
9 | runs-on: ubuntu-latest
10 | steps:
11 | - name: send telegram message on push
12 | uses: appleboy/telegram-action@master
13 | with:
14 | to: ${{ secrets.TELEGRAM_TO }}
15 | token: ${{ secrets.TELEGRAM_TOKEN }}
16 | disable_web_page_preview: true
17 | message: |
18 | ${{ github.event.repository.name }} v${{ github.event.release.tag_name }}
19 | ${{ github.event.release.body }}
20 | https://github.com/${{ github.repository }}
21 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 AlexGyver
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://github.com/GyverLibs/GParser/releases/latest/download/GParser.zip)
2 | [](https://registry.platformio.org/libraries/gyverlibs/GParser)
3 | [](https://alexgyver.ru/)
4 | [](https://alexgyver.ru/support_alex/)
5 | [](https://github-com.translate.goog/GyverLibs/GParser?_x_tr_sl=ru&_x_tr_tl=en)
6 |
7 | [](https://t.me/GyverLibs)
8 |
9 | |⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
**ВНИМАНИЕ, БИБЛИОТЕКА УСТАРЕЛА! ИСПОЛЬЗУЙ БИБЛИОТЕКУ [StringUtils](https://github.com/GyverLibs/StringUtils), ОНА ИМЕЕТ БОЛЬШЕ ВОЗМОЖНОСТЕЙ**
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️|
10 | | --- |
11 |
12 | # GParser
13 | Простой и быстрый парсер строк в отдельные подстроки и числа для Arduino
14 | - Работает с указанным буфером (строкой), не создаёт свой
15 | - Разделяет строку на подстроки по указанному символу
16 | - Позволяет обращаться к подстрокам, переводить их в числа и сравнивать со строками
17 | - Доступ к подстрокам через []
18 | - Может распарсить строку в массив int или byte
19 |
20 | ### Совместимость
21 | Совместима со всеми Arduino платформами (используются Arduino-функции)
22 |
23 | ## Содержание
24 | - [Установка](#install)
25 | - [Инициализация](#init)
26 | - [Использование](#usage)
27 | - [Пример](#example)
28 | - [Версии](#versions)
29 | - [Баги и обратная связь](#feedback)
30 |
31 |
32 | ## Установка
33 | - Библиотеку можно найти по названию **GParser** и установить через менеджер библиотек в:
34 | - Arduino IDE
35 | - Arduino IDE v2
36 | - PlatformIO
37 | - [Скачать библиотеку](https://github.com/GyverLibs/GParser/archive/refs/heads/main.zip) .zip архивом для ручной установки:
38 | - Распаковать и положить в *C:\Program Files (x86)\Arduino\libraries* (Windows x64)
39 | - Распаковать и положить в *C:\Program Files\Arduino\libraries* (Windows x32)
40 | - Распаковать и положить в *Документы/Arduino/libraries/*
41 | - (Arduino IDE) автоматическая установка из .zip: *Скетч/Подключить библиотеку/Добавить .ZIP библиотеку…* и указать скачанный архив
42 | - Читай более подробную инструкцию по установке библиотек [здесь](https://alexgyver.ru/arduino-first/#%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B1%D0%B8%D0%B1%D0%BB%D0%B8%D0%BE%D1%82%D0%B5%D0%BA)
43 | ### Обновление
44 | - Рекомендую всегда обновлять библиотеку: в новых версиях исправляются ошибки и баги, а также проводится оптимизация и добавляются новые фичи
45 | - Через менеджер библиотек IDE: найти библиотеку как при установке и нажать "Обновить"
46 | - Вручную: **удалить папку со старой версией**, а затем положить на её место новую. "Замену" делать нельзя: иногда в новых версиях удаляются файлы, которые останутся при замене и могут привести к ошибкам!
47 |
48 |
49 |
50 | ## Инициализация
51 | ```cpp
52 | // передать char array строку, можно указать символ разделитель (по умолч ',')
53 | GParser (char* data);
54 | GParser (char* data, char newDiv = ',');
55 | ```
56 |
57 |
58 | ## Использование
59 | ### Класс GParser
60 | ```cpp
61 | void setDiv(char newDiv); // указать символ разделитель
62 | void clear(); // освободить буфер
63 | int amount(); // количество разделённых данных в пакете
64 | int split(); // разделить строку на подстроки
65 | int32_t getInt(int num); // получить инт из выбранной подстроки
66 | float getFloat(int num); // получить float из выбранной подстроки
67 | bool equals(int num, const char* comp); // сравнить подстроку с другой строкой
68 | int parseBytes(byte* data); // распарсить на байты
69 | int parseInts(int* data); // распарсить на инты
70 | int parseLongs(long* data); // распарсить на лонги
71 | void restore(); // восстановить исходный вид строки (вернуть разделители)
72 | ```
73 |
74 | ### Отдельные функции парсинга
75 | См. пример **testUtils**
76 |
77 | ```cpp
78 | // количество подстрок в списке list с разделителем div
79 | uint8_t GP_listSize(char* list, char div = ',');
80 |
81 | // разделить список list с разделителем div на подстроки (см. пример)
82 | char* GP_splitList(char* list, char div = ',');
83 |
84 | // получить номер, под которым name входит в list с разделителем div. -1 если не входит
85 | int8_t GP_inList(char* name, char* list, char div = ',');
86 |
87 | // преобразовать int в строку (работает в 3-10 раз быстрее ltoa + основание)
88 | void GP_numToChar(int32_t n, char* buf, uint8_t base);
89 |
90 | // преобразовать float в строку
91 | void GP_floatToChar(double f, char *buf, uint8_t decimals);
92 |
93 | // преобразовать строку в число
94 | int32_t GP_charToNum(char* buf, uint8_t base);
95 |
96 | // преобразовать строку в float
97 | double GP_charToFloat(char* buf);
98 |
99 | // получить число под индексом idx в списке list с разделителем div
100 | int GP_numFromList(char* list, int idx, char div = ',');
101 |
102 | // переписать список list с разделителем div в массив чисел data размером size
103 | uint8_t GP_listToNum(char* list, int* data, uint8_t size, char div = ',');
104 |
105 | // преобразовать текстовый цвет (0x, #) в число
106 | uint32_t GP_decodeColor(char* hex);
107 | ```
108 |
109 | ### Unicode
110 | См. пример **testUnicode**
111 |
112 | ```cpp
113 | char* GP_uniencode(int32_t c, char* s); // код unicode в char[5]
114 | String GP_uniencode(uint16_t c); // код unicode в String
115 | uint16_t GP_unistrlen(char* data); // длина unicode строки в кол-ве символов
116 | ```
117 |
118 | ### Url encode/decode
119 | См. пример **testUrl**
120 |
121 | ```cpp
122 | void GP_urlencode(const String& s, String& dest); // urlencode из String в String
123 | String GP_urlencode(const String& s); // urlencode из String в String (возврат)
124 | String GP_urldecode(const String& s, String& dest); // urldecode из String в String
125 | String GP_urldecode(const String& s); // urldecode из String в String (возврат)
126 | ```
127 |
128 |
129 | ## Пример
130 | Остальные примеры смотри в **examples**!
131 | ```cpp
132 | // тест парсера строк
133 | #include
134 |
135 | void setup() {
136 | Serial.begin(9600);
137 |
138 | // ==================== ПРИМЕР 1 ======================
139 | // строка для примера
140 | // данные разделены разделителем, например запятой
141 | // могут быть получены из Serial/UDP/TCP/MQTT итд
142 | char str[] = "1234,3.14,hello,4567,lolkek,qwerty";
143 |
144 | // кормим строку парсеру, указываем разделитель (умолч. запятая)
145 | GParser data(str, ',');
146 |
147 | // разделяем
148 | // ВНИМАНИЕ! Операция "ломает" строку, заменяя разделители на NULL
149 | int am = data.split();
150 | // получаем количество данных
151 |
152 | Serial.println(am); // выводим количество
153 |
154 | // можем обратиться к полученным строкам как data[i] или data.str[i]
155 | for (byte i = 0; i < am; i++) Serial.println(data[i]);
156 |
157 | // также можно получить их в виде int и float чисел
158 | // передав индекс строки
159 | Serial.println(data.getInt(0));
160 | Serial.println(data.getFloat(1));
161 |
162 | // можно сравнить со строкой (номер парс строки, строка для сравнения)
163 | if (data.equals(2, "hello")) Serial.println("true");
164 | else Serial.println("false");
165 |
166 | Serial.println();
167 |
168 | // ==================== ПРИМЕР 2 ======================
169 | // быстрый парсинг целочисленных данных с разделителем
170 | char str2[] = "123,456,789,222,333,444";
171 | GParser data2(str2); // кормим строку парсеру
172 |
173 | // создаём массив с количеством ячеек data2.amount() - столько данных в пакете
174 | int ints[data2.amount()];
175 |
176 | int am2 = data2.parseInts(ints); // раскидает в указанный массив и вернёт количество
177 | // фактически тут am2 == data2.amount() - количество данных
178 | // выводим
179 | for (byte i = 0; i < am; i++) Serial.println(ints[i]);
180 | }
181 |
182 | void loop() {
183 | }
184 |
185 | ```
186 |
187 |
188 | ## Версии
189 | - v1.0
190 | - v1.1 - добавлены отдельные инструменты для парсинга
191 | - v1.2 - добавлены ещё инструменты для парсинга
192 | - v1.3 - добавлена возможность восстановить строку
193 | - v1.3.1 - фикс warning
194 | - v1.4 - добавил url и unicode кодирование
195 | - v1.5 - getInt теперь возвращает int32_t
196 |
197 |
198 | ## Баги и обратная связь
199 | При нахождении багов создавайте **Issue**, а лучше сразу пишите на почту [alex@alexgyver.ru](mailto:alex@alexgyver.ru)
200 | Библиотека открыта для доработки и ваших **Pull Request**'ов!
201 |
202 |
203 | При сообщении о багах или некорректной работе библиотеки нужно обязательно указывать:
204 | - Версия библиотеки
205 | - Какой используется МК
206 | - Версия SDK (для ESP)
207 | - Версия Arduino IDE
208 | - Корректно ли работают ли встроенные примеры, в которых используются функции и конструкции, приводящие к багу в вашем коде
209 | - Какой код загружался, какая работа от него ожидалась и как он работает в реальности
210 | - В идеале приложить минимальный код, в котором наблюдается баг. Не полотно из тысячи строк, а минимальный код
211 |
--------------------------------------------------------------------------------
/README_EN.md:
--------------------------------------------------------------------------------
1 | This is an automatic translation, may be incorrect in some places. See sources and examples!
2 |
3 | # Gparser
4 | Simple and fast Parser lines in separate tunes and numbers for Arduino
5 | - works with the indicated buffer (line), does not create its own
6 | - shares the line for tuning according to the specified symbol
7 | - allows you to contact tunes, transfer them into numbers and compare with lines
8 | - Access to tunes through []
9 | - can rinse the line into the INT or BYTE array
10 |
11 | ## compatibility
12 | Compatible with all arduino platforms (used arduino functions)
13 |
14 | ## Content
15 | - [installation] (# Install)
16 | - [initialization] (#init)
17 | - [use] (#usage)
18 | - [Example] (# Example)
19 | - [versions] (#varsions)
20 | - [bugs and feedback] (#fedback)
21 |
22 |
23 | ## Installation
24 | - The library can be found by the name ** gparser ** and installed through the library manager in:
25 | - Arduino ide
26 | - Arduino ide v2
27 | - Platformio
28 | - [download the library] (https://github.com/gyverlibs/gparser/archive/refs/heads/main.zip) .Zip archive for manual installation:
29 | - unpack and put in * C: \ Program Files (X86) \ Arduino \ Libraries * (Windows X64)
30 | - unpack and put in * C: \ Program Files \ Arduino \ Libraries * (Windows X32)
31 | - unpack and put in *documents/arduino/libraries/ *
32 | - (Arduino id) Automatic installation from. Zip: * sketch/connect the library/add .Zip library ... * and specify downloaded archive
33 | - Read more detailed instructions for installing libraries [here] (https://alexgyver.ru/arduino-first/#%D0%A3%D1%81%D1%82%D0%B0%BD%D0%BE%BE%BE%BED0%B2%D0%BA%D0%B0_%D0%B1%D0%B8%D0%B1%D0%BB%D0%B8%D0%BE%D1%82%D0%B5%D0%BA)
34 | ### Update
35 | - I recommend always updating the library: errors and bugs are corrected in the new versions, as well as optimization and new features are added
36 | - through the IDE library manager: find the library how to install and click "update"
37 | - Manually: ** remove the folder with the old version **, and then put a new one in its place.“Replacement” cannot be done: sometimes in new versions, files that remain when replacing are deleted and can lead to errors!
38 |
39 |
40 |
41 | ## initialization
42 | `` `CPP
43 | // Transfer Char Array a line, you can specify the Symbol Separate (by the silence ',')
44 | GParser (Char* Data);
45 | Gparser (Char* Data, Char Newdiv = ',');
46 | `` `
47 |
48 |
49 | ## Usage
50 | ### class GParser
51 | `` `CPP
52 | VOID Setdiv (Char Newdiv);// specify the Symbol Separate
53 | Void Clear ();// Free the buffer
54 | int amount ();// The number of data separated in the package
55 | int split ();// divide the line into tunes
56 | int32_t getint (int num);// Get Inta from the selected tack
57 | Float getfloat (int num);// Get Float from the selected toll
58 | Bool Equals (int num, const char* comp);// Compare the tuning with another line
59 | int Parsebytes (byte* data);// Parish bytes
60 | int parseints (int* data);// Parisulate on Ints
61 | Intselongs (LONG* DATA);// Parish on Longs
62 | VOID restore ();// Restore the original type of line (return the dividers)
63 | `` `
64 |
65 | ### Separate Parsing Functions
66 | See example ** testils **
67 |
68 | `` `CPP
69 | // Number of tuning in the list list with DIV separator
70 | uint8_t gp_listsize (char* list, char div = ',');
71 |
72 | // Divide the list of LIST with the DIV separator into tunes (see example)
73 | Char* gp_splitlist (char* list, char div = ',');
74 |
75 | // Get a number under which NAME is included in LIST with the DIV separator.-1 if not included
76 | int8_t gp_inlist (char* name, char* list, char div = ',');
77 |
78 | // Transform int into a line (it works 3-10 times faster LTOA + base)
79 | VOID gp_numtochar (int32_t n, char* buf, uint8_t base);
80 |
81 | // Transform Float into a line
82 | VOID gp_floattoChar (Double F, Char *Buf, Uint8_T Decimals);
83 |
84 | // Transfer the line to the number
85 | int32_t gp_Chartonum (char* buf, uint8_t base);
86 |
87 | // Transform the line into Float
88 | Double gp_Chartofloat (Char* buf);
89 |
90 | // Get the number under the IDX index in the list list with the DIV separator
91 | Ints_numfromlist (Char* List, Intx, Char Div = ',');
92 |
93 | // Re -rewrite the list of LIST with the DIV separator in the DATA size array of SIZE
94 | uint8_t gp_listonum (char* list, int* data, uint8_t size, char div = ',');
95 |
96 | // Transfer text color (0x, #) to the number
97 | uint32_t gp_decodecolor (char* hex);
98 | `` `
99 |
100 | ### Unicode
101 | See example ** testicode **
102 |
103 | `` `CPP
104 | Char* gp_unencode (int32_t c, char* s);// Unicode code in Char [5]
105 | String gp_unencode (uint16_t c);// Unicode code in String
106 | uint16_t gp_unistrlen (char* data);// UNICODE Length Line in the number of symbols
107 | `` `
108 |
109 | ### url encode/decode
110 | See example ** Testurb **
111 |
112 | `` `CPP
113 | VOID gp_urlencode (Constation String & S, String & Dest);// Urlencode from String to String
114 | String gp_urlencode (const string & s);// Urlencode from String to String (Return)
115 | String GP_urldecode (Constation String & S, String & Dest);// urlDecode from String in String
116 | String GP_urldecode (Const String & S);// urldecode from String to String (Return)
117 | `` `
118 |
119 |
120 | ## Example
121 | The rest of the examples look at ** Examples **!
122 | `` `CPP
123 | // Parser's Test
124 | #include
125 |
126 | VOID setup () {
127 | Serial.Begin (9600);
128 |
129 | // =======================================================
130 | // Line for example
131 | // Data is separated by a divider, for example, a comma
132 | // can be obtained from Serial/UDP/TCP/MQTT etc.
133 | Char Str [] = "1234.3.14, Hello, 4567, Lolkek, Qwerty";
134 |
135 | // feed the line of the parser, indicate the separator (silence)
136 | Gparser data (str, ',');
137 |
138 | // Share
139 | // ATTENTION!The operation "breaks" the line, replacing the dividers with NULL
140 | int am = data.split ();
141 | // Get the amount of data
142 |
143 | Serial.println (AM);// We display the quantity
144 |
145 | // We can turn to the resulting lines as Data [i] or Data.str [i]
146 | for (byte i = 0; i
179 | ## versions
180 | - V1.0
181 | - V1.1 - added individual parsing tools
182 | - V1.2 - Parsing tools added more tools
183 | - v1.3 - added the ability to restore the line
184 | - V1.3.1 - Fix Warning
185 | - v1.4 - added URL and Unicode coding
186 | - V1.5 - Getint now returns int32_t
187 |
188 |
189 | ## bugs and feedback
190 | Create ** Issue ** when you find bugs, but better immediately write to the mail [alex@alexgyver.ru] (mailto: alex@alexgyver.ru)
191 | The library is open for refinement and your ** pull Request ** 'ow!
192 |
193 |
194 | When reporting about bugs or incorrect work of the library, it is necessary to indicate:
195 | - The version of the library
196 | - What is MK used
197 | - SDK version (for ESP)
198 | - version of Arduino ide
199 | - whether the built -in examples work correctly, in which the functions and designs are used, leading to a bug in your code
200 | - what code has been loaded, what work was expected from it and how it works in reality
201 | - Ideally, attach the minimum code in which the bug is observed.Not a canvas of a thousand lines, but a minimum code
--------------------------------------------------------------------------------
/examples/test/test.ino:
--------------------------------------------------------------------------------
1 | // тест парсера строк
2 | #include
3 |
4 | void setup() {
5 | Serial.begin(9600);
6 |
7 | // ==================== ПРИМЕР 1 ======================
8 | // строка для примера
9 | // данные разделены разделителем, например запятой
10 | // могут быть получены из Serial/UDP/TCP/MQTT итд
11 | char str[] = "1234,3.14,hello,4567,lolkek,qwerty";
12 |
13 | // кормим строку парсеру, указываем разделитель (умолч. запятая)
14 | GParser data(str, ',');
15 |
16 | // разделяем
17 | // ВНИМАНИЕ! Операция "ломает" строку, заменяя разделители на NULL
18 | int am = data.split();
19 | // получаем количество данных
20 |
21 | Serial.println(am); // выводим количество
22 |
23 | // можем обратиться к полученным строкам как data[i] или data.str[i]
24 | for (byte i = 0; i < am; i++) Serial.println(data[i]);
25 |
26 | // также можно получить их в виде int и float чисел
27 | // передав индекс строки
28 | Serial.println(data.getInt(0));
29 | Serial.println(data.getFloat(1));
30 |
31 | // можно сравнить со строкой (номер парс строки, строка для сравнения)
32 | if (data.equals(2, "hello")) Serial.println("true");
33 | else Serial.println("false");
34 |
35 | data.restore(); // восстановить исходный вид строки (вернуть разделители)
36 |
37 | Serial.println();
38 |
39 | // ==================== ПРИМЕР 2 ======================
40 | // быстрый парсинг целочисленных данных с разделителем
41 | char str2[] = "123,456,789,222,333,444";
42 | GParser data2(str2); // кормим строку парсеру
43 |
44 | // создаём массив с количеством ячеек data2.amount() - столько данных в пакете
45 | int ints[data2.amount()];
46 |
47 | int am2 = data2.parseInts(ints); // раскидает в указанный массив и вернёт количество
48 | // фактически тут am2 == data2.amount() - количество данных
49 | // выводим
50 | for (byte i = 0; i < am2; i++) Serial.println(ints[i]);
51 | }
52 |
53 | void loop() {
54 | }
55 |
--------------------------------------------------------------------------------
/examples/testUnicode/testUnicode.ino:
--------------------------------------------------------------------------------
1 | // тест утилит для парсинга
2 | #include
3 |
4 | void setup() {
5 | Serial.begin(9600);
6 | // неправильно посчитает длину строки
7 | Serial.println(strlen("Привет!"));
8 | // правильно посчитает длину строки
9 | Serial.println(GP_unistrlen("Привет!"));
10 |
11 | Serial.println(GP_uniencode(0x27A1));
12 | }
13 |
14 | void loop() {
15 | }
16 |
--------------------------------------------------------------------------------
/examples/testUrl/testUrl.ino:
--------------------------------------------------------------------------------
1 | // тест утилит для парсинга
2 | #include
3 |
4 | void setup() {
5 | Serial.begin(9600);
6 | String enc = GP_urlencode("https://kek.ru/#абвг");
7 | Serial.println(enc);
8 | Serial.println(GP_urldecode(enc));
9 | }
10 |
11 | void loop() {
12 | }
13 |
--------------------------------------------------------------------------------
/examples/testUtils/testUtils.ino:
--------------------------------------------------------------------------------
1 | // тест утилит для парсинга
2 | #include
3 |
4 | void setup() {
5 | Serial.begin(9600);
6 |
7 | // список. Данные разделены запятой
8 | char list[] = "123,456,789,abc,def";
9 |
10 | // =====================
11 | Serial.println("Split test");
12 | char* p = list;
13 | GP_splitList(NULL);
14 | while ((p = GP_splitList(list)) != NULL) {
15 | Serial.println(p);
16 | }
17 | Serial.println();
18 |
19 | // =====================
20 | Serial.println("InList test");
21 | Serial.println(GP_inList("abc", list));
22 | Serial.println(GP_inList("kek", list));
23 | Serial.println();
24 |
25 | // =====================
26 | Serial.println("Num list test");
27 | Serial.println(GP_numFromList(list, 2));
28 | Serial.println();
29 |
30 | // =====================
31 | Serial.println("Array list test");
32 | int data[3];
33 | GP_listToNum(list, data, 3);
34 | for (int i = 0; i < 3; i++) {
35 | Serial.print(data[i]);
36 | Serial.print(',');
37 | }
38 | Serial.println();
39 | Serial.println();
40 |
41 | // =====================
42 | Serial.println("Num to char test");
43 | char st[30];
44 |
45 | GP_numToChar(0x123abc, st, HEX);
46 | Serial.println(st);
47 |
48 | GP_numToChar(123456, st, DEC);
49 | Serial.println(st);
50 |
51 | GP_numToChar(0b11100011, st, BIN);
52 | Serial.println(st);
53 |
54 | GP_floatToChar(3.1415, st, 3);
55 | Serial.println(st);
56 | Serial.println();
57 |
58 | // =====================
59 | Serial.println("Char to num test");
60 | int32_t val;
61 |
62 | val = GP_charToNum("AAFF", HEX);
63 | Serial.println(val, HEX);
64 |
65 | val = GP_charToNum("123456", DEC);
66 | Serial.println(val, DEC);
67 |
68 | val = GP_charToNum("11000011", BIN);
69 | Serial.println(val, BIN);
70 |
71 | float valf = GP_charToFloat("3.14");
72 | Serial.println(valf);
73 | Serial.println();
74 |
75 | // =====================
76 | Serial.println("Color test");
77 | Serial.println(GP_decodeColor("0xFF22"), HEX);
78 | Serial.println(GP_decodeColor("#FF22"), HEX);
79 | Serial.println(GP_decodeColor("FF22"), HEX);
80 | }
81 |
82 | void loop() {
83 | }
84 |
--------------------------------------------------------------------------------
/keywords.txt:
--------------------------------------------------------------------------------
1 | #######################################
2 | # Syntax Coloring Map For GParser
3 | #######################################
4 |
5 | #######################################
6 | # Datatypes (KEYWORD1)
7 | #######################################
8 |
9 | GParser KEYWORD1
10 |
11 | #######################################
12 | # Methods and Functions (KEYWORD2)
13 | #######################################
14 |
15 | setDiv KEYWORD2
16 | clear KEYWORD2
17 | amount KEYWORD2
18 | split KEYWORD2
19 | getInt KEYWORD2
20 | getFloat KEYWORD2
21 | equals KEYWORD2
22 | parseInts KEYWORD2
23 | parseBytes KEYWORD2
24 | parseLongs KEYWORD2
25 | buf KEYWORD2
26 | str KEYWORD2
27 | restore KEYWORD2
28 |
29 | GP_listSize KEYWORD2
30 | GP_splitList KEYWORD2
31 | GP_inList KEYWORD2
32 | GP_numToChar KEYWORD2
33 | GP_floatToChar KEYWORD2
34 | GP_charToNum KEYWORD2
35 | GP_charToFloat KEYWORD2
36 | GP_numFromList KEYWORD2
37 | GP_listToNum KEYWORD2
38 | GP_decodeColor KEYWORD2
39 |
40 | GP_urlencode KEYWORD2
41 | GP_urldecode KEYWORD2
42 | GP_uniencode KEYWORD2
43 | GP_unistrlen KEYWORD2
44 |
45 | #######################################
46 | # Constants (LITERAL1)
47 | #######################################
--------------------------------------------------------------------------------
/library.properties:
--------------------------------------------------------------------------------
1 | name=GParser
2 | version=1.5.2
3 | author=AlexGyver
4 | maintainer=AlexGyver
5 | sentence=Fast library for parsing cstring into substrings, urlencode, unicode encode for Arduino
6 | paragraph=Fast library for parsing cstring into substrings, urlencode, unicode encode for Arduino
7 | category=Data Processing
8 | url=https://github.com/GyverLibs/GParser
9 | architectures=*
--------------------------------------------------------------------------------
/src/GParser.h:
--------------------------------------------------------------------------------
1 | /*
2 | Простой и быстрый парсер строк в отдельные подстроки и числа для Arduino
3 | Документация:
4 | GitHub: https://github.com/GyverLibs/GParser
5 | Возможности:
6 | - Работает с указанным буфером (строкой), не создаёт свой
7 | - Разделяет строку на подстроки по указанному символу
8 | - Позволяет обращаться к подстрокам, переводить их в числа и сравнивать со строками
9 | - Доступ к подстрокам через []
10 | - Может распарсить строку в массив int или byte
11 |
12 | AlexGyver, alex@alexgyver.ru
13 | https://alexgyver.ru/
14 | MIT License
15 |
16 | Версии:
17 | v1.0 - релиз
18 | v1.1 - добавлены отдельные инструменты для парсинга
19 | v1.2 - добавлены ещё инструменты для парсинга
20 | v1.3 - добавлена возможность восстановить строку
21 | v1.3.1 - фикс warning
22 | v1.4 - добавил url и unicode кодирование
23 | */
24 |
25 | #ifndef _GParser_h
26 | #define _GParser_h
27 | #include "utils/parseUtils.h"
28 | #include "utils/unicode.h"
29 | #include "utils/url.h"
30 |
31 | class GParser {
32 | public:
33 | // передать char array строку, можно указать символ разделитель
34 | GParser(char* data, char newDiv = ',') {
35 | buf = data;
36 | div = newDiv;
37 | }
38 | ~GParser() {
39 | clear();
40 | }
41 |
42 | // указать символ разделитель
43 | void setDiv(char newDiv) {
44 | div = newDiv;
45 | }
46 |
47 | // освободить буфер
48 | void clear() {
49 | if (str) delete[] str;
50 | str = nullptr;
51 | }
52 |
53 | // количество разделённых данных в пакете
54 | int amount() {
55 | if (!buf) return 0;
56 | int count = 1;
57 | char* p = buf;
58 | while (*p) {
59 | if (*p++ == div) count++; // подсчёт разделителей
60 | }
61 | return count;
62 | }
63 |
64 | // разделить строку на подстроки
65 | int split() {
66 | len = amount(); // количество данных
67 | clear(); // освобождаем буфер
68 | str = new char*[len]; // создаём буфер
69 | if (!str) return 0; // ошибка аллокации
70 | str[0] = buf; // строка 0
71 | int i = 0, j = 0; // счётчики
72 | while (buf[i]) { // пока не NULL
73 | if (buf[i] == div) { // если разделитель
74 | buf[i] = '\0'; // меняем на NULL
75 | str[++j] = buf + i + 1; // запоминаем начало строки
76 | }
77 | i++;
78 | }
79 | return len;
80 | }
81 |
82 | // восстановить строку (вернуть разделители)
83 | void restore() {
84 | for (int i = 0; i < len - 1; i++) str[i][strlen(str[i])] = div;
85 | }
86 |
87 | // получить инт из выбранной подстроки
88 | int32_t getInt(int num) {
89 | return atol(str[num]);
90 | }
91 |
92 | // получить float из выбранной подстроки
93 | float getFloat(int num) {
94 | return atof(str[num]);
95 | }
96 |
97 | // сравнить подстроку с другой строкой
98 | bool equals(int num, const char* comp) {
99 | return !strcmp(str[num], comp);
100 | }
101 |
102 | // распарсить на лонги
103 | int parseLongs(long* data) {
104 | if (!buf) return 0;
105 | int count = 0;
106 | char* offset = buf;
107 | while (true) {
108 | data[count++] = atol(offset);
109 | offset = strchr(offset, div);
110 | if (offset) offset++;
111 | else break;
112 | }
113 | return count;
114 | }
115 |
116 | // распарсить на инты
117 | int parseInts(int* data) {
118 | if (!buf) return 0;
119 | int count = 0;
120 | char* offset = buf;
121 | while (true) {
122 | data[count++] = atol(offset);
123 | offset = strchr(offset, div);
124 | if (offset) offset++;
125 | else break;
126 | }
127 | return count;
128 | }
129 |
130 | // распарсить на байты
131 | int parseBytes(uint8_t* data) {
132 | if (!buf) return 0;
133 | int count = 0;
134 | char* offset = buf;
135 | while (true) {
136 | data[count++] = atoi(offset);
137 | offset = strchr(offset, div);
138 | if (offset) offset++;
139 | else break;
140 | }
141 | return count;
142 | }
143 |
144 | char* buf = nullptr;
145 | char** str = nullptr;
146 |
147 | char* operator[](uint16_t idx) {
148 | return str[idx];
149 | }
150 |
151 | private:
152 | char div;
153 | int len;
154 | };
155 |
156 | #endif
--------------------------------------------------------------------------------
/src/utils/parseUtils.cpp:
--------------------------------------------------------------------------------
1 | #include "parseUtils.h"
2 |
3 | // количество подстрок в списке list с разделителем div
4 | uint8_t GP_listSize(char* list, char div) {
5 | uint16_t i = 0, count = 0;
6 | while (list[i]) if (list[i++] == div) count++;
7 | return ++count;
8 | }
9 |
10 | // разделить список list с разделителем div на подстроки
11 | char* GP_splitList(char* list, char div) {
12 | static uint8_t prev, end;
13 | if (list == NULL) prev = end = 0;
14 | else {
15 | if (prev) *(list + prev - 1) = div;
16 | char* cur = strchr(list + prev, div);
17 | if (cur) {
18 | *cur = '\0';
19 | uint8_t b = prev;
20 | prev = cur - list + 1;
21 | return list + b;
22 | } else if (!end) {
23 | end = 1;
24 | return list + prev;
25 | }
26 | }
27 | return NULL;
28 | }
29 |
30 | // получить номер, под которым name входит в list с разделителем div
31 | int8_t GP_inList(char* name, char* list, char div) {
32 | char* str = list;
33 | int8_t count = 0, pos = -1;
34 | GP_splitList(NULL);
35 | while ((str = GP_splitList(list, div)) != NULL) {
36 | if (!strcmp(str, name)) pos = count;
37 | count++;
38 | }
39 | return pos;
40 | }
41 |
42 | // преобразовать int в строку
43 | // DEC - 46, HEX/BIN - 17 (ltoa: BIN - 480, HEX - 125, DEC - 150)
44 | void GP_numToChar(int32_t n, char* buf, uint8_t base) {
45 | uint8_t l = 2;
46 | if (base != DEC) {
47 | int32_t nn = n;
48 | uint8_t b = (base == HEX) ? 4 : 1;
49 | while (nn >>= b) l++;
50 | char *str = &buf[l];
51 | *--str = '\0';
52 | do {
53 | char c = n & (base - 1);
54 | n >>= b;
55 | *--str = (c < 10) ? (c + '0') : (c + 'A' - 10);
56 | } while(n);
57 | } else {
58 | uint8_t s = 0;
59 | if (n < 0) n = -n, s = 1;
60 | int32_t nn = n;
61 | while (nn /= base) l++;
62 | char *str = &buf[l + s];
63 | *--str = '\0';
64 | do {
65 | _GP_div10 res(n);
66 | n = res.quot;
67 | *--str = (res.rem < 10) ? (res.rem + '0') : (res.rem + 'A' - 10);
68 | } while(n);
69 | if (s) *--str = '-';
70 | }
71 | }
72 |
73 | // преобразовать float в строку
74 | void GP_floatToChar(double f, char *buf, uint8_t decimals) {
75 | dtostrf(f, decimals + 2, decimals, buf);
76 | }
77 |
78 | // преобразовать строку в число
79 | int32_t GP_charToNum(char* buf, uint8_t base) {
80 | if (base == DEC) return atol(buf);
81 | else return strtol(buf, NULL, base);
82 | }
83 |
84 | // преобразовать строку в float
85 | double GP_charToFloat(char* buf) {
86 | return atof(buf);
87 | }
88 |
89 | // получить число под индексом idx в списке list с разделителем div
90 | int GP_numFromList(char* list, int idx, char div) {
91 | uint8_t count = 0;
92 | char* p = list;
93 | while (1) {
94 | if (count++ == idx) return atoi(p);
95 | p = strchr(p, div);
96 | if (!p++) break;
97 | }
98 | return 0;
99 | }
100 |
101 | // переписать список list с разделителем div в массив чисел data размером size
102 | uint8_t GP_listToNum(char* list, int* data, uint8_t size, char div) {
103 | uint8_t count = 0;
104 | char* offset = list;
105 | while (1) {
106 | if (count >= size) break;
107 | data[count++] = atoi(offset);
108 | offset = strchr(offset, div);
109 | if (!offset++) break;
110 | }
111 | return count;
112 | }
113 |
114 | // преобразовать текстовый цвет (0x, #) в число
115 | uint32_t GP_decodeColor(char* hex) {
116 | uint32_t val = 0;
117 | uint8_t i = (hex[0] == '#') ? 1 : ((hex[1] == 'x') ? 2 : 0);
118 | for (; i < strlen(hex); i++) {
119 | val <<= 4;
120 | uint8_t d = hex[i];
121 | d -= (d <= '9') ? 48 : ((d <= 'F') ? 55 : 87);
122 | val |= d;
123 | }
124 | return val;
125 | }
126 |
--------------------------------------------------------------------------------
/src/utils/parseUtils.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 |
4 | // количество подстрок в списке list с разделителем div
5 | uint8_t GP_listSize(char* list, char div = ',');
6 |
7 | // разделить список list с разделителем div на подстроки (см. пример)
8 | char* GP_splitList(char* list, char div = ',');
9 |
10 | // получить номер, под которым name входит в list с разделителем div. -1 если не входит
11 | int8_t GP_inList(char* name, char* list, char div = ',');
12 |
13 | // преобразовать int в строку
14 | void GP_numToChar(int32_t n, char* buf, uint8_t base);
15 |
16 | // преобразовать float в строку
17 | void GP_floatToChar(double f, char *buf, uint8_t decimals);
18 |
19 | // преобразовать строку в число
20 | int32_t GP_charToNum(char* buf, uint8_t base);
21 |
22 | // преобразовать строку в float
23 | double GP_charToFloat(char* buf);
24 |
25 | // получить число под индексом idx в списке list с разделителем div
26 | int GP_numFromList(char* list, int idx, char div = ',');
27 |
28 | // переписать список list с разделителем div в массив чисел data размером size
29 | uint8_t GP_listToNum(char* list, int* data, uint8_t size, char div = ',');
30 |
31 | // преобразовать текстовый цвет (0x, #) в число
32 | uint32_t GP_decodeColor(char* hex);
33 |
34 |
35 | // http://we.easyelectronics.ru/Soft/preobrazuem-v-stroku-chast-1-celye-chisla.html
36 | struct _GP_div10 {
37 | _GP_div10(uint32_t n) {
38 | quot = n >> 1;
39 | quot += quot >> 1;
40 | quot += quot >> 4;
41 | quot += quot >> 8;
42 | quot += quot >> 16;
43 | uint32_t qq = quot;
44 | quot >>= 3;
45 | rem = uint8_t(n - ((quot << 1) + (qq & ~7ul)));
46 | if (rem > 9) rem -= 10, quot++;
47 | }
48 | uint32_t quot;
49 | uint8_t rem;
50 | };
--------------------------------------------------------------------------------
/src/utils/unicode.cpp:
--------------------------------------------------------------------------------
1 | #include "unicode.h"
2 | char* GP_uniencode(int32_t c, char* s) {
3 | if (c < 0x80) {
4 | s[0] = (c & 0x7F) | 0x00;
5 | s[1] = 0;
6 | } else if (c < 0x0800) {
7 | s[0] = (c >> 6 & 0x1F) | 0xC0;
8 | s[1] = (c & 0x3F) | 0x80;
9 | s[2] = 0;
10 | } else if (c < 0x010000) {
11 | s[0] = (c >> 12 & 0x0F) | 0xE0;
12 | s[1] = (c >> 6 & 0x3F) | 0x80;
13 | s[2] = (c & 0x3F) | 0x80;
14 | s[3] = 0;
15 | } else if (c < 0x110000) {
16 | s[0] = (c >> 18 & 0x07) | 0xF0;
17 | s[1] = (c >> 12 & 0x3F) | 0x80;
18 | s[2] = (c >> 6 & 0x3F) | 0x80;
19 | s[3] = (c & 0x3F) | 0x80;
20 | s[4] = 0;
21 | }
22 | return s;
23 | }
24 |
25 | String GP_uniencode(uint16_t c) {
26 | char str[5];
27 | return String(GP_uniencode(c, str));
28 | }
29 |
30 | uint16_t GP_unistrlen(char* data) {
31 | uint16_t i = 0, count = 0;
32 | while (data[i]) {
33 | if ((data[i] & 0xc0) != 0x80) count++;
34 | i++;
35 | }
36 | return count;
37 | }
--------------------------------------------------------------------------------
/src/utils/unicode.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | char* GP_uniencode(int32_t c, char* s);
4 | String GP_uniencode(uint16_t c);
5 | uint16_t GP_unistrlen(char* data);
--------------------------------------------------------------------------------
/src/utils/url.cpp:
--------------------------------------------------------------------------------
1 | #include "url.h"
2 | void GP_urlencode(const String& s, String& dest) {
3 | dest.reserve(s.length());
4 | char c;
5 | for (uint16_t i = 0; i < s.length(); i++) {
6 | c = s[i];
7 | if (c == ' ') dest += '+';
8 | else if (!(
9 | (c >= '0' && c <= '9') ||
10 | (c >= 'a' && c <= 'z') ||
11 | (c >= 'A' && c <= 'Z') ||
12 | c == '-' || c == '_' || c == '.' || c == '!' || c == '~' ||
13 | c == '*' || c == '\'' || c == '(' || c == ')'
14 | )) {
15 | dest += '%';
16 | dest += (char)((c >> 4) + (((c >> 4) > 9) ? 55 : 48));
17 | dest += (char)((c & 0xF) + (((c & 0xF) > 9) ? 55 : 48));
18 | } else dest += c;
19 | }
20 | }
21 |
22 | String GP_urlencode(const String& s) {
23 | String dest;
24 | GP_urlencode(s, dest);
25 | return dest;
26 | }
27 |
28 | void GP_urldecode(const String& s, String& dest) {
29 | dest.reserve(s.length());
30 | char c;
31 | for (uint16_t i = 0; i < s.length(); i++) {
32 | c = s[i];
33 | if (c != '%') dest += (c == '+') ? ' ' : c;
34 | else {
35 | c = s[++i];
36 | uint8_t v1 = c - ((c <= '9') ? 48 : ((c <= 'F') ? 55 : 87));
37 | c = s[++i];
38 | uint8_t v2 = c - ((c <= '9') ? 48 : ((c <= 'F') ? 55 : 87));
39 | dest += char(v2 | (v1 << 4));
40 | }
41 | }
42 | }
43 |
44 | String GP_urldecode(const String& s) {
45 | String dest;
46 | GP_urldecode(s, dest);
47 | return dest;
48 | }
--------------------------------------------------------------------------------
/src/utils/url.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | void GP_urlencode(const String& s, String& dest);
4 | String GP_urlencode(const String& s);
5 | void GP_urldecode(const String& s, String& dest);
6 | String GP_urldecode(const String& s);
--------------------------------------------------------------------------------