2 * This file is part of MPlayer.
4 * MPlayer is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * MPlayer is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 #include <libavutil/common.h>
30 int bstrcmp(struct bstr str1
, struct bstr str2
)
32 int ret
= memcmp(str1
.start
, str2
.start
, FFMIN(str1
.len
, str2
.len
));
35 if (str1
.len
== str2
.len
)
37 else if (str1
.len
> str2
.len
)
45 int bstrcasecmp(struct bstr str1
, struct bstr str2
)
47 int ret
= strncasecmp(str1
.start
, str2
.start
, FFMIN(str1
.len
, str2
.len
));
50 if (str1
.len
== str2
.len
)
52 else if (str1
.len
> str2
.len
)
60 int bstrchr(struct bstr str
, int c
)
62 for (int i
= 0; i
< str
.len
; i
++)
63 if (str
.start
[i
] == c
)
68 int bstrrchr(struct bstr str
, int c
)
70 for (int i
= str
.len
- 1; i
>= 0; i
--)
71 if (str
.start
[i
] == c
)
76 int bstrcspn(struct bstr str
, const char *reject
)
79 for (i
= 0; i
< str
.len
; i
++)
80 if (strchr(reject
, str
.start
[i
]))
85 int bstr_find(struct bstr haystack
, struct bstr needle
)
87 for (int i
= 0; i
< haystack
.len
; i
++)
88 if (bstr_startswith(bstr_splice(haystack
, i
, haystack
.len
), needle
))
93 struct bstr
bstr_lstrip(struct bstr str
)
95 while (str
.len
&& isspace(*str
.start
)) {
102 struct bstr
bstr_strip(struct bstr str
)
104 str
= bstr_lstrip(str
);
105 while (str
.len
&& isspace(str
.start
[str
.len
- 1]))
110 struct bstr
bstr_split(struct bstr str
, const char *sep
, struct bstr
*rest
)
113 for (start
= 0; start
< str
.len
; start
++)
114 if (!strchr(sep
, str
.start
[start
]))
116 str
= bstr_cut(str
, start
);
117 int end
= bstrcspn(str
, sep
);
119 *rest
= bstr_cut(str
, end
);
121 return bstr_splice(str
, 0, end
);
125 struct bstr
bstr_splice(struct bstr str
, int start
, int end
)
131 end
= FFMIN(end
, str
.len
);
132 start
= FFMAX(start
, 0);
133 end
= FFMAX(end
, start
);
135 str
.len
= end
- start
;
139 long long bstrtoll(struct bstr str
, struct bstr
*rest
, int base
)
141 str
= bstr_lstrip(str
);
143 int len
= FFMIN(str
.len
, 50);
144 memcpy(buf
, str
.start
, len
);
147 long long r
= strtoll(buf
, &endptr
, base
);
149 *rest
= bstr_cut(str
, endptr
- buf
);
153 double bstrtod(struct bstr str
, struct bstr
*rest
)
155 str
= bstr_lstrip(str
);
157 int len
= FFMIN(str
.len
, 100);
158 memcpy(buf
, str
.start
, len
);
161 double r
= strtod(buf
, &endptr
);
163 *rest
= bstr_cut(str
, endptr
- buf
);
167 struct bstr
*bstr_splitlines(void *talloc_ctx
, struct bstr str
)
172 for (int i
= 0; i
< str
.len
; i
++)
173 if (str
.start
[i
] == '\n')
175 if (str
.start
[str
.len
- 1] != '\n')
177 struct bstr
*r
= talloc_array_ptrtype(talloc_ctx
, r
, count
);
178 unsigned char *p
= str
.start
;
179 for (int i
= 0; i
< count
- 1; i
++) {
181 while (*p
++ != '\n');
182 r
[i
].len
= p
- r
[i
].start
;
184 r
[count
- 1].start
= p
;
185 r
[count
- 1].len
= str
.start
+ str
.len
- p
;
189 struct bstr
bstr_getline(struct bstr str
, struct bstr
*rest
)
191 int pos
= bstrchr(str
, '\n');
195 *rest
= bstr_cut(str
, pos
+ 1);
196 return bstr_splice(str
, 0, pos
+ 1);
199 bool bstr_eatstart(struct bstr
*s
, struct bstr prefix
)
201 if (!bstr_startswith(*s
, prefix
))
203 *s
= bstr_cut(*s
, prefix
.len
);
207 void bstr_lower(struct bstr str
)
209 for (int i
= 0; i
< str
.len
; i
++)
210 str
.start
[i
] = tolower(str
.start
[i
]);
213 int bstr_sscanf(struct bstr str
, const char *format
, ...)
215 char *ptr
= bstrdup0(NULL
, str
);
217 va_start(va
, format
);
218 int ret
= vsscanf(ptr
, format
, va
);
224 int bstr_parse_utf8_code_length(unsigned char b
)
228 int bytes
= 7 - av_log2(b
^ 255);
229 return (bytes
>= 2 && bytes
<= 4) ? bytes
: -1;
232 int bstr_decode_utf8(struct bstr s
, struct bstr
*out_next
)
236 unsigned int codepoint
= s
.start
[0];
238 if (codepoint
>= 128) {
239 int bytes
= bstr_parse_utf8_code_length(codepoint
);
240 if (bytes
< 0 || s
.len
< bytes
- 1)
242 codepoint
&= 127 >> bytes
;
243 for (int n
= 1; n
< bytes
; n
++) {
244 int tmp
= s
.start
[0];
245 if ((tmp
& 0xC0) != 0x80)
247 codepoint
= (codepoint
<< 6) | (tmp
& ~0xC0);