Version 0.1.3 from FTP
[asterisk/asterisk.git] / frame.c
1 /*
2  * Asterisk -- A telephony toolkit for Linux.
3  *
4  * Frame manipulation routines
5  * 
6  * Copyright (C) 1999, Adtran Inc. and Linux Support Services, LLC
7  *
8  * Mark Spencer <markster@linux-support.net>
9  *
10  * This program is free software, distributed under the terms of
11  * the GNU General Public License
12  */
13
14 #include <asterisk/frame.h>
15 #include <asterisk/logger.h>
16 #include <stdlib.h>
17 #include <string.h>
18
19 /*
20  * Important: I should be made more efficient.  Frame headers should
21  * most definitely be cached
22  */
23
24 void ast_frfree(struct ast_frame *fr)
25 {
26         if (fr->mallocd & AST_MALLOCD_DATA) {
27                 if (fr->data) 
28                         free(fr->data - fr->offset);
29         }
30         if (fr->mallocd & AST_MALLOCD_SRC) {
31                 if (fr->src)
32                         free(fr->src);
33         }
34         if (fr->mallocd & AST_MALLOCD_HDR) {
35                 free(fr);
36         }
37 }
38
39 void ast_frchain(struct ast_frame_chain *fc)
40 {
41         struct ast_frame_chain *last;
42         while(fc) {
43                 last = fc;
44                 fc = fc->next;
45                 if (last->fr)
46                         ast_frfree(last->fr);
47                 free(last);
48         }
49 }
50
51 struct ast_frame *ast_frisolate(struct ast_frame *fr)
52 {
53         struct ast_frame *out;
54         if (!(fr->mallocd & AST_MALLOCD_HDR)) {
55                 /* Allocate a new header if needed */
56                 out = malloc(sizeof(struct ast_frame));
57                 if (!out) {
58                         ast_log(LOG_WARNING, "Out of memory\n");
59                         return NULL;
60                 }
61                 out->frametype = fr->frametype;
62                 out->subclass = fr->subclass;
63                 out->datalen = 0;
64                 out->timelen = fr->timelen;
65                 out->offset = 0;
66                 out->src = NULL;
67                 out->data = NULL;
68         } else {
69                 out = fr;
70         }
71         if (!(fr->mallocd & AST_MALLOCD_SRC)) {
72                 if (fr->src)
73                         out->src = strdup(fr->src);
74         } else
75                 out->src = fr->src;
76         if (!(fr->mallocd & AST_MALLOCD_DATA))  {
77                 out->data = malloc(fr->datalen + fr->offset);
78                 out->data += fr->offset;
79                 out->offset = fr->offset;
80                 out->datalen = fr->datalen;
81                 memcpy(out->data, fr->data, fr->datalen);
82                 if (!out->data) {
83                         ast_log(LOG_WARNING, "Out of memory\n");
84                         return NULL;
85                 }
86         }
87         out->mallocd = AST_MALLOCD_HDR | AST_MALLOCD_SRC | AST_MALLOCD_DATA;
88         return out;
89 }