Statistics
| Branch: | Revision:

ffmpeg / libavformat / cutils.c @ 916bf03a

History | View | Annotate | Download (6.97 KB)

1
/*
2
 * Various simple utilities for ffmpeg system
3
 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
4
 *
5
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with FFmpeg; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21
#include "avformat.h"
22

    
23
#if !defined(CONFIG_NOCUTILS)
24
/**
25
 * Return TRUE if val is a prefix of str. If it returns TRUE, ptr is
26
 * set to the next character in 'str' after the prefix.
27
 *
28
 * @param str input string
29
 * @param val prefix to test
30
 * @param ptr updated after the prefix in str in there is a match
31
 * @return TRUE if there is a match
32
 */
33
int strstart(const char *str, const char *val, const char **ptr)
34
{
35
    const char *p, *q;
36
    p = str;
37
    q = val;
38
    while (*q != '\0') {
39
        if (*p != *q)
40
            return 0;
41
        p++;
42
        q++;
43
    }
44
    if (ptr)
45
        *ptr = p;
46
    return 1;
47
}
48

    
49
/**
50
 * Return TRUE if val is a prefix of str (case independent). If it
51
 * returns TRUE, ptr is set to the next character in 'str' after the
52
 * prefix.
53
 *
54
 * @param str input string
55
 * @param val prefix to test
56
 * @param ptr updated after the prefix in str in there is a match
57
 * @return TRUE if there is a match */
58
int stristart(const char *str, const char *val, const char **ptr)
59
{
60
    const char *p, *q;
61
    p = str;
62
    q = val;
63
    while (*q != '\0') {
64
        if (toupper(*(const unsigned char *)p) != toupper(*(const unsigned char *)q))
65
            return 0;
66
        p++;
67
        q++;
68
    }
69
    if (ptr)
70
        *ptr = p;
71
    return 1;
72
}
73

    
74
/**
75
 * Copy the string str to buf. If str length is bigger than buf_size -
76
 * 1 then it is clamped to buf_size - 1.
77
 * NOTE: this function does what strncpy should have done to be
78
 * useful. NEVER use strncpy.
79
 *
80
 * @param buf destination buffer
81
 * @param buf_size size of destination buffer
82
 * @param str source string
83
 */
84
void pstrcpy(char *buf, int buf_size, const char *str)
85
{
86
    int c;
87
    char *q = buf;
88

    
89
    if (buf_size <= 0)
90
        return;
91

    
92
    for(;;) {
93
        c = *str++;
94
        if (c == 0 || q >= buf + buf_size - 1)
95
            break;
96
        *q++ = c;
97
    }
98
    *q = '\0';
99
}
100

    
101
/* strcat and truncate. */
102
char *pstrcat(char *buf, int buf_size, const char *s)
103
{
104
    int len;
105
    len = strlen(buf);
106
    if (len < buf_size)
107
        pstrcpy(buf + len, buf_size - len, s);
108
    return buf;
109
}
110

    
111
#endif
112

    
113
/* add one element to a dynamic array */
114
void __dynarray_add(unsigned long **tab_ptr, int *nb_ptr, unsigned long elem)
115
{
116
    int nb, nb_alloc;
117
    unsigned long *tab;
118

    
119
    nb = *nb_ptr;
120
    tab = *tab_ptr;
121
    if ((nb & (nb - 1)) == 0) {
122
        if (nb == 0)
123
            nb_alloc = 1;
124
        else
125
            nb_alloc = nb * 2;
126
        tab = av_realloc(tab, nb_alloc * sizeof(unsigned long));
127
        *tab_ptr = tab;
128
    }
129
    tab[nb++] = elem;
130
    *nb_ptr = nb;
131
}
132

    
133
time_t mktimegm(struct tm *tm)
134
{
135
    time_t t;
136

    
137
    int y = tm->tm_year + 1900, m = tm->tm_mon + 1, d = tm->tm_mday;
138

    
139
    if (m < 3) {
140
        m += 12;
141
        y--;
142
    }
143

    
144
    t = 86400 *
145
        (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 + y / 400 - 719469);
146

    
147
    t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec;
148

    
149
    return t;
150
}
151

    
152
#define ISLEAP(y) (((y) % 4 == 0) && (((y) % 100) != 0 || ((y) % 400) == 0))
153
#define LEAPS_COUNT(y) ((y)/4 - (y)/100 + (y)/400)
154

    
155
/* this is our own gmtime_r. it differs from its POSIX counterpart in a
156
   couple of places, though. */
157
struct tm *brktimegm(time_t secs, struct tm *tm)
158
{
159
    int days, y, ny, m;
160
    int md[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
161

    
162
    days = secs / 86400;
163
    secs %= 86400;
164
    tm->tm_hour = secs / 3600;
165
    tm->tm_min = (secs % 3600) / 60;
166
    tm->tm_sec =  secs % 60;
167

    
168
    /* oh well, may be someone some day will invent a formula for this stuff */
169
    y = 1970; /* start "guessing" */
170
    while (days >= (ISLEAP(y)?366:365)) {
171
        ny = (y + days/366);
172
        days -= (ny - y) * 365 + LEAPS_COUNT(ny - 1) - LEAPS_COUNT(y - 1);
173
        y = ny;
174
    }
175
    md[1] = ISLEAP(y)?29:28;
176
    for (m=0; days >= md[m]; m++)
177
         days -= md[m];
178

    
179
    tm->tm_year = y;  /* unlike gmtime_r we store complete year here */
180
    tm->tm_mon = m+1; /* unlike gmtime_r tm_mon is from 1 to 12 */
181
    tm->tm_mday = days+1;
182

    
183
    return tm;
184
}
185

    
186
/* get a positive number between n_min and n_max, for a maximum length
187
   of len_max. Return -1 if error. */
188
static int date_get_num(const char **pp,
189
                        int n_min, int n_max, int len_max)
190
{
191
    int i, val, c;
192
    const char *p;
193

    
194
    p = *pp;
195
    val = 0;
196
    for(i = 0; i < len_max; i++) {
197
        c = *p;
198
        if (!isdigit(c))
199
            break;
200
        val = (val * 10) + c - '0';
201
        p++;
202
    }
203
    /* no number read ? */
204
    if (p == *pp)
205
        return -1;
206
    if (val < n_min || val > n_max)
207
        return -1;
208
    *pp = p;
209
    return val;
210
}
211

    
212
/* small strptime for ffmpeg */
213
const char *small_strptime(const char *p, const char *fmt,
214
                           struct tm *dt)
215
{
216
    int c, val;
217

    
218
    for(;;) {
219
        c = *fmt++;
220
        if (c == '\0') {
221
            return p;
222
        } else if (c == '%') {
223
            c = *fmt++;
224
            switch(c) {
225
            case 'H':
226
                val = date_get_num(&p, 0, 23, 2);
227
                if (val == -1)
228
                    return NULL;
229
                dt->tm_hour = val;
230
                break;
231
            case 'M':
232
                val = date_get_num(&p, 0, 59, 2);
233
                if (val == -1)
234
                    return NULL;
235
                dt->tm_min = val;
236
                break;
237
            case 'S':
238
                val = date_get_num(&p, 0, 59, 2);
239
                if (val == -1)
240
                    return NULL;
241
                dt->tm_sec = val;
242
                break;
243
            case 'Y':
244
                val = date_get_num(&p, 0, 9999, 4);
245
                if (val == -1)
246
                    return NULL;
247
                dt->tm_year = val - 1900;
248
                break;
249
            case 'm':
250
                val = date_get_num(&p, 1, 12, 2);
251
                if (val == -1)
252
                    return NULL;
253
                dt->tm_mon = val - 1;
254
                break;
255
            case 'd':
256
                val = date_get_num(&p, 1, 31, 2);
257
                if (val == -1)
258
                    return NULL;
259
                dt->tm_mday = val;
260
                break;
261
            case '%':
262
                goto match;
263
            default:
264
                return NULL;
265
            }
266
        } else {
267
        match:
268
            if (c != *p)
269
                return NULL;
270
            p++;
271
        }
272
    }
273
    return p;
274
}
275