1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
|
#include <pcre2.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../logger.h"
#include "utils.h"
static void print_error(int code) {
PCRE2_UCHAR message[256];
if (pcre2_get_error_message(code, message,
sizeof(message) / sizeof(PCRE2_UCHAR)))
LOG("PCRE2", "Error: %s\n", (const char *)message);
}
int regex_match(const char *subject, str_array_t patterns,
str_array_t *results) {
pcre2_code *re;
int errornumber;
int rc = PCRE2_ERROR_NOMATCH;
PCRE2_SIZE subject_len = strlen(subject);
PCRE2_SIZE offset = 0, erroroffset;
PCRE2_SIZE *ovector;
pcre2_match_data *match_data;
for (unsigned short i = 0; i < patterns.n; i++) {
DEBUG_PRINT("Gets pattern: %s\n", patterns.str[i]);
re = pcre2_compile((PCRE2_SPTR)patterns.str[i], PCRE2_ZERO_TERMINATED, 0,
&errornumber, &erroroffset, NULL);
if (re == NULL) {
PCRE2_UCHAR buffer[256];
pcre2_get_error_message(errornumber, buffer, sizeof(buffer));
LOG("PCRE2", "compilation failed at offset %d: %s\n", (int)erroroffset,
buffer);
return 1;
}
match_data = pcre2_match_data_create_from_pattern(re, NULL);
while (offset < subject_len &&
(rc = pcre2_match(re, (PCRE2_SPTR)subject, (PCRE2_SIZE)subject_len,
offset, 0, match_data, NULL)) > 0) {
// results->str = realloc(results->str, sizeof(char *) * (rc +
// results->n));
int valid_n = results->n;
resize_str_array(results, rc - 1 + results->n);
ovector = pcre2_get_ovector_pointer(match_data);
DEBUG_PRINT("Get %d captures.\n", rc - 1);
DEBUG_PRINT("Match succeeded at offset %d.\n", (int)ovector[0]);
for (unsigned short j = 1; j < rc; j++) {
PCRE2_SIZE substring_length = ovector[2 * j + 1] - ovector[2 * j];
PCRE2_SPTR substring = (PCRE2_SPTR)subject + ovector[2 * j];
/* Here we need to manually control the str array,
* as PCRE2_SPTR == const unsigned char
* (which cannot be directly casted) */
results->str[valid_n + j - 1] = malloc(substring_length + 1);
sprintf(results->str[valid_n + j - 1], "%.*s", (int)substring_length,
substring);
DEBUG_PRINT("index: %2d, substring_length: %d\n", j,
(int)substring_length);
}
offset = ovector[1];
DEBUG_PRINT("offset: %zu, subject_len: %zu\n", offset, subject_len);
}
pcre2_match_data_free(match_data);
pcre2_code_free(re);
if (rc <= 0) {
switch (rc) {
case PCRE2_ERROR_NOMATCH:
DEBUG_PRINT("No match found.\n");
break;
case 0:
LOG("PCRE2",
"ovector was not big enough for all the captured substrings\n");
break;
default:
print_error(rc);
return 1;
}
}
}
return 0;
}
int substitute_str(const char *subject, const char *pattern,
const char *replacement, char **presult) {
pcre2_code *re;
pcre2_match_context *match_context;
int rc, error;
PCRE2_SIZE erroffset, outlength;
PCRE2_UCHAR *outbuf;
re = pcre2_compile((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED,
PCRE2_MULTILINE, &error, &erroffset, 0);
if (!re) {
print_error(error);
return 1;
}
match_context = pcre2_match_context_create(0);
outlength = 0;
rc = pcre2_substitute(re, (PCRE2_SPTR)subject, PCRE2_ZERO_TERMINATED, 0,
PCRE2_SUBSTITUTE_GLOBAL |
PCRE2_SUBSTITUTE_OVERFLOW_LENGTH |
PCRE2_SUBSTITUTE_EXTENDED,
0, match_context, (PCRE2_SPTR)replacement,
PCRE2_ZERO_TERMINATED, 0, &outlength);
if (rc != PCRE2_ERROR_NOMEMORY) {
print_error(rc);
return 1;
}
outbuf = malloc(outlength * sizeof(PCRE2_UCHAR));
rc = pcre2_substitute(re, (PCRE2_SPTR)subject, PCRE2_ZERO_TERMINATED, 0,
PCRE2_SUBSTITUTE_GLOBAL | PCRE2_SUBSTITUTE_EXTENDED,
0, match_context, (PCRE2_SPTR)replacement,
PCRE2_ZERO_TERMINATED, outbuf, &outlength);
if (rc < 0) {
print_error(rc);
return 1;
}
*presult = (char *)outbuf;
pcre2_match_context_free(match_context);
pcre2_code_free(re);
return 0;
}
const char *mimeType2ext(const char *mimeType) {
static char mimeType_l[CHAR_MAX];
strcpy(mimeType_l, mimeType);
const char *exts[2];
size_t extsCount = 0;
char *token = strtok(mimeType_l, "/");
while (token != NULL && extsCount < 2) {
exts[extsCount++] = token;
token = strtok(NULL, "/");
}
if (extsCount == 2) {
return exts[1];
}
return "mp4"; // Cannot parse, use default
}
int repchr(char *str, char t, char r) {
int c = 0;
for (size_t i = 0; str[i] != '\0'; i++) {
if (str[i] == t) {
str[i] = r;
c++;
}
}
return c;
}
|