You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

276 lines
7.0KB

  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. #if !defined(CONFIG_NOCUTILS)
  23. /**
  24. * Return TRUE if val is a prefix of str. If it returns TRUE, ptr is
  25. * set to the next character in 'str' after the prefix.
  26. *
  27. * @param str input string
  28. * @param val prefix to test
  29. * @param ptr updated after the prefix in str in there is a match
  30. * @return TRUE if there is a match
  31. */
  32. int strstart(const char *str, const char *val, const char **ptr)
  33. {
  34. const char *p, *q;
  35. p = str;
  36. q = val;
  37. while (*q != '\0') {
  38. if (*p != *q)
  39. return 0;
  40. p++;
  41. q++;
  42. }
  43. if (ptr)
  44. *ptr = p;
  45. return 1;
  46. }
  47. /**
  48. * Return TRUE if val is a prefix of str (case independent). If it
  49. * returns TRUE, ptr is set to the next character in 'str' after the
  50. * prefix.
  51. *
  52. * @param str input string
  53. * @param val prefix to test
  54. * @param ptr updated after the prefix in str in there is a match
  55. * @return TRUE if there is a match */
  56. int stristart(const char *str, const char *val, const char **ptr)
  57. {
  58. const char *p, *q;
  59. p = str;
  60. q = val;
  61. while (*q != '\0') {
  62. if (toupper(*(const unsigned char *)p) != toupper(*(const unsigned char *)q))
  63. return 0;
  64. p++;
  65. q++;
  66. }
  67. if (ptr)
  68. *ptr = p;
  69. return 1;
  70. }
  71. /**
  72. * Copy the string str to buf. If str length is bigger than buf_size -
  73. * 1 then it is clamped to buf_size - 1.
  74. * NOTE: this function does what strncpy should have done to be
  75. * useful. NEVER use strncpy.
  76. *
  77. * @param buf destination buffer
  78. * @param buf_size size of destination buffer
  79. * @param str source string
  80. */
  81. void pstrcpy(char *buf, int buf_size, const char *str)
  82. {
  83. int c;
  84. char *q = buf;
  85. if (buf_size <= 0)
  86. return;
  87. for(;;) {
  88. c = *str++;
  89. if (c == 0 || q >= buf + buf_size - 1)
  90. break;
  91. *q++ = c;
  92. }
  93. *q = '\0';
  94. }
  95. /* strcat and truncate. */
  96. char *pstrcat(char *buf, int buf_size, const char *s)
  97. {
  98. int len;
  99. len = strlen(buf);
  100. if (len < buf_size)
  101. pstrcpy(buf + len, buf_size - len, s);
  102. return buf;
  103. }
  104. #endif
  105. /* add one element to a dynamic array */
  106. void __dynarray_add(unsigned long **tab_ptr, int *nb_ptr, unsigned long elem)
  107. {
  108. int nb, nb_alloc;
  109. unsigned long *tab;
  110. nb = *nb_ptr;
  111. tab = *tab_ptr;
  112. if ((nb & (nb - 1)) == 0) {
  113. if (nb == 0)
  114. nb_alloc = 1;
  115. else
  116. nb_alloc = nb * 2;
  117. tab = av_realloc(tab, nb_alloc * sizeof(unsigned long));
  118. *tab_ptr = tab;
  119. }
  120. tab[nb++] = elem;
  121. *nb_ptr = nb;
  122. }
  123. time_t mktimegm(struct tm *tm)
  124. {
  125. time_t t;
  126. int y = tm->tm_year + 1900, m = tm->tm_mon + 1, d = tm->tm_mday;
  127. if (m < 3) {
  128. m += 12;
  129. y--;
  130. }
  131. t = 86400 *
  132. (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 + y / 400 - 719469);
  133. t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec;
  134. return t;
  135. }
  136. #define ISLEAP(y) (((y) % 4 == 0) && (((y) % 100) != 0 || ((y) % 400) == 0))
  137. #define LEAPS_COUNT(y) ((y)/4 - (y)/100 + (y)/400)
  138. /* this is our own gmtime_r. it differs from its POSIX counterpart in a
  139. couple of places, though. */
  140. struct tm *brktimegm(time_t secs, struct tm *tm)
  141. {
  142. int days, y, ny, m;
  143. int md[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  144. days = secs / 86400;
  145. secs %= 86400;
  146. tm->tm_hour = secs / 3600;
  147. tm->tm_min = (secs % 3600) / 60;
  148. tm->tm_sec = secs % 60;
  149. /* oh well, may be someone some day will invent a formula for this stuff */
  150. y = 1970; /* start "guessing" */
  151. while (days >= (ISLEAP(y)?366:365)) {
  152. ny = (y + days/366);
  153. days -= (ny - y) * 365 + LEAPS_COUNT(ny - 1) - LEAPS_COUNT(y - 1);
  154. y = ny;
  155. }
  156. md[1] = ISLEAP(y)?29:28;
  157. for (m=0; days >= md[m]; m++)
  158. days -= md[m];
  159. tm->tm_year = y; /* unlike gmtime_r we store complete year here */
  160. tm->tm_mon = m+1; /* unlike gmtime_r tm_mon is from 1 to 12 */
  161. tm->tm_mday = days+1;
  162. return tm;
  163. }
  164. /* get a positive number between n_min and n_max, for a maximum length
  165. of len_max. Return -1 if error. */
  166. static int date_get_num(const char **pp,
  167. int n_min, int n_max, int len_max)
  168. {
  169. int i, val, c;
  170. const char *p;
  171. p = *pp;
  172. val = 0;
  173. for(i = 0; i < len_max; i++) {
  174. c = *p;
  175. if (!isdigit(c))
  176. break;
  177. val = (val * 10) + c - '0';
  178. p++;
  179. }
  180. /* no number read ? */
  181. if (p == *pp)
  182. return -1;
  183. if (val < n_min || val > n_max)
  184. return -1;
  185. *pp = p;
  186. return val;
  187. }
  188. /* small strptime for ffmpeg */
  189. const char *small_strptime(const char *p, const char *fmt,
  190. struct tm *dt)
  191. {
  192. int c, val;
  193. for(;;) {
  194. c = *fmt++;
  195. if (c == '\0') {
  196. return p;
  197. } else if (c == '%') {
  198. c = *fmt++;
  199. switch(c) {
  200. case 'H':
  201. val = date_get_num(&p, 0, 23, 2);
  202. if (val == -1)
  203. return NULL;
  204. dt->tm_hour = val;
  205. break;
  206. case 'M':
  207. val = date_get_num(&p, 0, 59, 2);
  208. if (val == -1)
  209. return NULL;
  210. dt->tm_min = val;
  211. break;
  212. case 'S':
  213. val = date_get_num(&p, 0, 59, 2);
  214. if (val == -1)
  215. return NULL;
  216. dt->tm_sec = val;
  217. break;
  218. case 'Y':
  219. val = date_get_num(&p, 0, 9999, 4);
  220. if (val == -1)
  221. return NULL;
  222. dt->tm_year = val - 1900;
  223. break;
  224. case 'm':
  225. val = date_get_num(&p, 1, 12, 2);
  226. if (val == -1)
  227. return NULL;
  228. dt->tm_mon = val - 1;
  229. break;
  230. case 'd':
  231. val = date_get_num(&p, 1, 31, 2);
  232. if (val == -1)
  233. return NULL;
  234. dt->tm_mday = val;
  235. break;
  236. case '%':
  237. goto match;
  238. default:
  239. return NULL;
  240. }
  241. } else {
  242. match:
  243. if (c != *p)
  244. return NULL;
  245. p++;
  246. }
  247. }
  248. return p;
  249. }