util.c
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:9k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*
  2.  * FILE: util.c
  3.  * PROGRAM: RAT
  4.  * AUTHOR: Isidor Kouvelas + Colin Perkins + Mark Handley + Orion Hodson
  5.  * 
  6.  * $Revision: 1.3 $
  7.  * $Date: 2002/01/10 23:27:27 $
  8.  *
  9.  * Copyright (c) 1995-2000 University College London
  10.  * All rights reserved.
  11.  *
  12.  * Redistribution and use in source and binary forms, with or without
  13.  * modification, is permitted provided that the following conditions 
  14.  * are met:
  15.  * 1. Redistributions of source code must retain the above copyright
  16.  *    notice, this list of conditions and the following disclaimer.
  17.  * 2. Redistributions in binary form must reproduce the above copyright
  18.  *    notice, this list of conditions and the following disclaimer in the
  19.  *    documentation and/or other materials provided with the distribution.
  20.  * 3. All advertising materials mentioning features or use of this software
  21.  *    must display the following acknowledgement:
  22.  *      This product includes software developed by the Computer Science
  23.  *      Department at University College London
  24.  * 4. Neither the name of the University nor of the Department may be used
  25.  *    to endorse or promote products derived from this software without
  26.  *    specific prior written permission.
  27.  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
  28.  * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  29.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  30.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
  31.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  32.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  33.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  34.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  35.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  36.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  37.  * SUCH DAMAGE.
  38.  */
  39. #include "config_unix.h"
  40. #include "config_win32.h"
  41. #include "debug.h"
  42. #include "memory.h"
  43. #include "util.h"
  44. typedef struct s_block {
  45. struct s_block  *next;
  46. } block;
  47.  
  48. #define BLOCK_SIZE            5
  49. #define SIZE_TO_INDEX(s)      (((s) - 1) >> BLOCK_SIZE)
  50. #define INDEX_TO_SIZE(i)      (((i) + 1) << BLOCK_SIZE)
  51. #define MAX_SIZE              (1 << 17)
  52. #define MAX_INDEX             SIZE_TO_INDEX(MAX_SIZE)
  53.  
  54. static block  *blocks[MAX_INDEX];
  55. static int     blocks_alloced;
  56. #ifdef DEBUG_MEM
  57. /* Block tracking for when things are going wrong */
  58. #define MAX_BLOCKS_OUT 1280
  59. static struct iovec blk_out[MAX_BLOCKS_OUT];
  60. static int          nblks_out;
  61. static int
  62. get_blk_idx_from_ptr(char *addr)
  63. {
  64.         int i;
  65.         for(i = 0; i < nblks_out; i++) {
  66.                 if (blk_out[i].iov_base == addr) {
  67.                         return i;
  68.                 }
  69.         }
  70.         return -1;
  71. }
  72. #endif /* DEBUG_MEM */
  73.  
  74. void *
  75. _block_alloc(unsigned int size, const char *filen, int line)
  76. {
  77. int           i;
  78. unsigned int  *c;
  79. char         *p;
  80. ASSERT(size > 0);
  81. ASSERT(size < MAX_SIZE);
  82. i = SIZE_TO_INDEX(size);
  83.  
  84. if (blocks[i] != NULL) {
  85. p = (char *)blocks[i];
  86. blocks[i] = blocks[i]->next;
  87.                 xclaim((char*)p - 8, filen, line);
  88. } else {
  89. #ifdef DEBUG_MEM_BREAK
  90.                 /* This can only go here if this file is merged with memory.c! [oh] */
  91.                 mem_item[naddr].blen = size;
  92. #endif /* DEBUG_MEM_BREAK */
  93. p = (char *) _xmalloc(INDEX_TO_SIZE(i) + 8,filen,line);
  94. *((int *)p) = INDEX_TO_SIZE(i);
  95. p += 8;
  96.                 blocks_alloced++;
  97. }
  98. c = (unsigned int *)((char *)p - 8);
  99. if (size > *c) {
  100. fprintf(stderr, "block_alloc: block is too small %d %d!n", size, *c);
  101. }
  102. #ifdef DEBUG_MEM
  103.         if (blocks_alloced == MAX_BLOCKS_OUT) {
  104.                 debug_msg("Too many blocks allocated.n");
  105.                 xmemdist(stderr);
  106.                 xmemdmp();
  107.         }
  108.         blk_out[nblks_out].iov_base = (char*)c;
  109.         blk_out[nblks_out].iov_len  = size;
  110.         nblks_out++;
  111. #endif /* DEBUG_MEM */
  112. c++;
  113. *c = size;
  114. ASSERT(p != NULL);
  115. return (void*)p;
  116. }
  117. void
  118. block_trash_check()
  119. {
  120. #ifdef DEBUG_MEM
  121.         int i,n,*c;
  122.         block *b;
  123.         for(i = 0; i<MAX_INDEX;i++) {
  124.                 b = blocks[i];
  125.                 n = 0;
  126.                 while(b) {
  127.                         b = b->next;
  128.                         ASSERT(n++ < blocks_alloced);
  129.                 }
  130.         }
  131.         for (i = 0; i<nblks_out; i++) {
  132.                 c = (int*)blk_out[i].iov_base;
  133.                 c++;
  134.                 ASSERT((unsigned int)*c == (unsigned int)blk_out[i].iov_len);
  135.         }
  136. #endif  /* DEBUG_MEM */
  137. }
  138. void
  139. block_check(char *p)
  140. {
  141. #ifdef DEBUG_MEM
  142.         char *blk_base;
  143.         ASSERT(p!=NULL);
  144.         blk_base = p-8;
  145.         ASSERT(get_blk_idx_from_ptr(blk_base) != -1);
  146. #endif /* DEBUG_MEM */
  147.         UNUSED(p);
  148. }
  149.  
  150. void
  151. _block_free(void *p, int size, int line)
  152. {
  153. int     i, *c;
  154. #ifdef DEBUG_MEM
  155.         block *bp;
  156.         int    n;
  157. #endif /* DEBUG_MEM */
  158.         UNUSED(line);
  159. c = (int *)((char *)p - 8);
  160. #ifdef DEBUG_MEM
  161.         n = get_blk_idx_from_ptr((char*)c);
  162.         if (n == -1) {
  163.                 debug_msg("Freeing block (addr 0x%x, %d bytes) that was not allocated with block_alloc(?)n", (int)c, *(c+1));
  164.                 xfree(c);
  165.                 ASSERT(n != -1);
  166.         }
  167. #endif
  168. if (size > *c) {
  169. fprintf(stderr, "block_free: block was too small! %d %dn", size, *c);
  170. }
  171. c++;
  172. if (size != *c) {
  173. fprintf(stderr, "block_free: Incorrect block size given! %d %dn", size, *c);
  174. ASSERT(size == *c);
  175. }
  176.  
  177. i = SIZE_TO_INDEX(size);
  178. #ifdef DEBUG_MEM
  179.         bp = blocks[i];
  180.         n = 0;
  181.         while(bp) {
  182.                 if (bp == (block*)p) {
  183.                         debug_msg("already freed line %dn", *((int *)p+1));
  184.                         ASSERT(0);
  185.                 }
  186.                 bp = bp->next;
  187.                 n++;
  188.         }
  189.         if (i >= 4) {
  190.                 *((int*)p+1) = line;
  191.         }
  192. #endif /* DEBUG_MEM */
  193. ((block *)p)->next = blocks[i];
  194. blocks[i] = (block *)p;
  195. #ifdef DEBUG_MEM
  196.         c--;
  197.         i = get_blk_idx_from_ptr((char*)c);
  198.         ASSERT(i != -1);
  199.         memmove(blk_out+i, blk_out + i + 1, sizeof(struct iovec) * (nblks_out - i)); 
  200.         nblks_out --;
  201. #endif /* DEBUG_MEM */
  202. }
  203. void
  204. block_release_all(void)
  205. {
  206.     int i;
  207.     char *p,*q;
  208.     printf("Freeing memory: "); fflush(stdout);
  209.     for(i=0;i<MAX_INDEX;i++) {
  210.         p = (char*)blocks[i];
  211.         while(p) {
  212.             q = (char*)((block*)p)->next;
  213.             xfree(p-8);
  214.     printf("+"); fflush(stdout);
  215.             p = q;
  216.         }
  217.     }
  218.     printf("n");
  219. }
  220. void
  221. purge_chars(char *src, char *to_go)
  222. {
  223.         char *r, *w;
  224.         r = w = src;
  225.         while(*r) {
  226.                 *w = *r;
  227.                 if (!strchr(to_go, (int)*r)) {
  228.                         w++;
  229.                 }
  230.                 r++;
  231.         }
  232.         *w = '';
  233. }
  234. static int
  235. string_to_words(char *s, char**w, int max_words)
  236. {
  237.         int n;
  238.         n = 0;
  239.         w[0] = (char *) strtok(s, " ");
  240.         if (w[0] == NULL) {
  241.                 return n;
  242.         }
  243.         while(++n < max_words) {
  244.                 w[n] = (char *) strtok(NULL, " ");
  245.                 if (w[n] == NULL) break;
  246.         }
  247.         return n;
  248. }
  249. int
  250. overlapping_words(const char *s1, const char *s2, int max_words)
  251. {
  252.         char *c1, *c2, **w1, **w2;
  253.         int nw1, nw2, nover, i, j;
  254.         c1 = xstrdup(s1);
  255.         c2 = xstrdup(s2);
  256.         w1 = (char**)xmalloc(sizeof(char*)*max_words);
  257.         w2 = (char**)xmalloc(sizeof(char*)*max_words);
  258.         nw1 = string_to_words(c1, w1, max_words);
  259.         nw2 = string_to_words(c2, w2, max_words);
  260.         nover = 0;
  261.         for(i = 0; i < nw1; i++) {
  262.                 for(j = 0; j < nw2; j++) {
  263.                         if (strcmp(w1[i], w2[j]) == 0) {
  264.                                 nover++;
  265.                                 continue;
  266.                         }
  267.                 }
  268.         }
  269.         xfree(w1);
  270.         xfree(w2);
  271.         xfree(c1);
  272.         xfree(c2);
  273.         
  274.         return nover;
  275. }
  276. int strfind(const char *haystack, const char *needle_start, const char *needle_end)
  277. {
  278. /* Returns TRUE if the string between needle_start and needle_end */
  279. /* is found in haystack. The haystack MUST be zero terminated.    */
  280. const char *n, *h;
  281. const char *h_end = haystack + strlen(haystack);
  282. #ifdef DEBUG
  283. /* Paranoia check that memory between needle_start and needle_end */
  284. /* is a valid string, and doesn't contain a zero byte.            */
  285. for (n = needle_start; n != needle_end; n++) {
  286. ASSERT(*n != '');
  287. }
  288. #endif
  289. n = needle_start;
  290. h = haystack;
  291. do {
  292. if (*n == *h) {
  293. n++;
  294. h++;
  295. } else {
  296. h = h - (n - needle_start) + 1;
  297. n = needle_start;
  298. }
  299. } while ((h < h_end) && (n <= needle_end));
  300. if (n == (needle_end + 1)) {
  301. return TRUE;
  302. }
  303. return FALSE;
  304. }