src/str_utils.c

00001 /*
00002   The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack.
00003   Copyright (C) 2001  Simon MORLAT simon.morlat@linphone.org
00004 
00005   This library is free software; you can redistribute it and/or
00006   modify it under the terms of the GNU Lesser General Public
00007   License as published by the Free Software Foundation; either
00008   version 2.1 of the License, or (at your option) any later version.
00009 
00010   This library is distributed in the hope that it will be useful,
00011   but WITHOUT ANY WARRANTY; without even the implied warranty of
00012   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013   Lesser General Public License for more details.
00014 
00015   You should have received a copy of the GNU Lesser General Public
00016   License along with this library; if not, write to the Free Software
00017   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 */
00019 
00020 #include "ortp/port.h"
00021 #include "ortp/rtp.h"
00022 #include "ortp/str_utils.h"
00023 #include "utils.h"
00024 
00025 void qinit(queue_t *q){
00026         mblk_init(&q->_q_stopper);
00027         q->_q_stopper.b_next=&q->_q_stopper;
00028         q->_q_stopper.b_prev=&q->_q_stopper;
00029         q->q_mcount=0;
00030 }
00031 
00032 void mblk_init(mblk_t *mp)
00033 {
00034         mp->b_cont=mp->b_prev=mp->b_next=NULL;
00035         mp->b_rptr=mp->b_wptr=NULL;
00036         mp->reserved1=0;
00037         mp->reserved2=0;
00038 }
00039 
00040 dblk_t *datab_alloc(int size){
00041         dblk_t *db;
00042         int total_size=sizeof(dblk_t)+size;
00043         db=(dblk_t *) ortp_malloc(total_size);
00044         db->db_base=(uint8_t*)db+sizeof(dblk_t);
00045         db->db_lim=db->db_base+size;
00046         db->db_ref=1;
00047         db->db_freefn=NULL;     /* the buffer pointed by db_base must never be freed !*/
00048         return db;
00049 }
00050 
00051 static inline void datab_ref(dblk_t *d){
00052         d->db_ref++;
00053 }
00054 
00055 static inline void datab_unref(dblk_t *d){
00056         d->db_ref--;
00057         if (d->db_ref==0){
00058                 if (d->db_freefn!=NULL)
00059                         d->db_freefn(d->db_base);
00060                 ortp_free(d);
00061         }
00062 }
00063 
00064 
00065 mblk_t *allocb(int size, int pri)
00066 {
00067         mblk_t *mp;
00068         dblk_t *datab;
00069         
00070         mp=(mblk_t *) ortp_malloc(sizeof(mblk_t));
00071         mblk_init(mp);
00072         datab=datab_alloc(size);
00073         
00074         mp->b_datap=datab;
00075         mp->b_rptr=mp->b_wptr=datab->db_base;
00076         mp->b_next=mp->b_prev=mp->b_cont=NULL;
00077         return mp;
00078 }
00079 
00080 mblk_t *esballoc(uint8_t *buf, int size, int pri, void (*freefn)(void*) )
00081 {
00082         mblk_t *mp;
00083         dblk_t *datab;
00084         
00085         mp=(mblk_t *) ortp_malloc(sizeof(mblk_t));
00086         mblk_init(mp);
00087         datab=(dblk_t *) ortp_malloc(sizeof(dblk_t));
00088         
00089 
00090         datab->db_base=buf;
00091         datab->db_lim=buf+size;
00092         datab->db_ref=1;
00093         datab->db_freefn=freefn;
00094         
00095         mp->b_datap=datab;
00096         mp->b_rptr=mp->b_wptr=buf;
00097         mp->b_next=mp->b_prev=mp->b_cont=NULL;
00098         return mp;
00099 }
00100 
00101         
00102 void freeb(mblk_t *mp)
00103 {
00104         return_if_fail(mp->b_datap!=NULL);
00105         return_if_fail(mp->b_datap->db_base!=NULL);
00106         
00107         datab_unref(mp->b_datap);
00108         ortp_free(mp);
00109 }       
00110 
00111 void freemsg(mblk_t *mp)
00112 {
00113         mblk_t *tmp1,*tmp2;
00114         tmp1=mp;
00115         while(tmp1!=NULL)
00116         {
00117                 tmp2=tmp1->b_cont;
00118                 freeb(tmp1);
00119                 tmp1=tmp2;
00120         }
00121 }
00122 
00123 mblk_t *dupb(mblk_t *mp)
00124 {
00125         mblk_t *newm;
00126         return_val_if_fail(mp->b_datap!=NULL,NULL);
00127         return_val_if_fail(mp->b_datap->db_base!=NULL,NULL);
00128         
00129         datab_ref(mp->b_datap);
00130         newm=(mblk_t *) ortp_malloc(sizeof(mblk_t));
00131         mblk_init(newm);
00132         newm->b_datap=mp->b_datap;
00133         newm->b_rptr=mp->b_rptr;
00134         newm->b_wptr=mp->b_wptr;
00135         return newm;
00136 }
00137 
00138 /* duplicates a complex mblk_t */
00139 mblk_t  *dupmsg(mblk_t* m)
00140 {
00141         mblk_t *newm=NULL,*mp,*prev;
00142         prev=newm=dupb(m);
00143         m=m->b_cont;
00144         while (m!=NULL){
00145                 mp=dupb(m);
00146                 prev->b_cont=mp;
00147                 prev=mp;
00148                 m=m->b_cont;
00149         }
00150         return newm;
00151 }
00152 
00153 void putq(queue_t *q,mblk_t *mp)
00154 {
00155         q->_q_stopper.b_prev->b_next=mp;
00156         mp->b_prev=q->_q_stopper.b_prev;
00157         mp->b_next=&q->_q_stopper;
00158         q->_q_stopper.b_prev=mp;
00159         q->q_mcount++;
00160 }
00161 
00162 mblk_t *getq(queue_t *q)
00163 {
00164         mblk_t *tmp;
00165         tmp=q->_q_stopper.b_next;
00166         if (tmp==&q->_q_stopper) return NULL;
00167         q->_q_stopper.b_next=tmp->b_next;
00168         tmp->b_next->b_prev=&q->_q_stopper;
00169         tmp->b_prev=NULL;
00170         tmp->b_next=NULL;
00171         q->q_mcount--;
00172         return tmp;
00173 }
00174 
00175 mblk_t * peekq(queue_t *q){
00176         mblk_t *tmp;
00177         tmp=q->_q_stopper.b_next;
00178         if (tmp==&q->_q_stopper) return NULL;
00179         return tmp;
00180 }
00181 
00182 /* insert mp in q just before emp */
00183 void insq(queue_t *q,mblk_t *emp, mblk_t *mp)
00184 {
00185         if (emp==NULL){
00186                 putq(q,mp);
00187                 return;
00188         }
00189         q->q_mcount++;
00190         emp->b_prev->b_next=mp;
00191         mp->b_prev=emp->b_prev;
00192         emp->b_prev=mp;
00193         mp->b_next=emp; 
00194 }
00195 
00196 void remq(queue_t *q, mblk_t *mp){
00197         q->q_mcount--;
00198         mp->b_prev->b_next=mp->b_next;
00199         mp->b_next->b_prev=mp->b_prev;
00200         mp->b_next=NULL;
00201         mp->b_prev=NULL;
00202 }
00203 
00204 /* remove and free all messages in the q */
00205 void flushq(queue_t *q, int how)
00206 {
00207         mblk_t *mp;
00208         
00209         while ((mp=getq(q))!=NULL)
00210         {
00211                 freemsg(mp);
00212         }
00213 }
00214 
00215 int msgdsize(const mblk_t *mp)
00216 {
00217         int msgsize=0;
00218         while(mp!=NULL){
00219                 msgsize+=(int) (mp->b_wptr-mp->b_rptr);
00220                 mp=mp->b_cont;
00221         }
00222         return msgsize;
00223 }
00224 
00225 void msgpullup(mblk_t *mp,int len)
00226 {
00227         mblk_t *firstm=mp;
00228         dblk_t *db;
00229         int wlen=0;
00230 
00231         if (mp->b_cont==NULL && len==-1) return;        /*nothing to do, message is not fragmented */
00232 
00233         if (len==-1) len=msgdsize(mp);
00234         db=datab_alloc(len);
00235         while(wlen<len && mp!=NULL){
00236                 int remain=len-wlen;
00237                 int mlen=mp->b_wptr-mp->b_rptr;
00238                 if (mlen<=remain){
00239                         memcpy(&db->db_base[wlen],mp->b_rptr,mlen);
00240                         wlen+=mlen;
00241                         mp=mp->b_cont;
00242                 }else{
00243                         memcpy(&db->db_base[wlen],mp->b_rptr,remain);
00244                         wlen+=remain;
00245                 }
00246         }
00247         /*set firstm to point to the new datab */
00248         freemsg(firstm->b_cont);
00249         firstm->b_cont=NULL;
00250         datab_unref(firstm->b_datap);
00251         firstm->b_datap=db;
00252         firstm->b_rptr=db->db_base;
00253         firstm->b_wptr=firstm->b_rptr+wlen;
00254 }
00255 
00256 
00257 mblk_t *copyb(mblk_t *mp)
00258 {
00259         mblk_t *newm;
00260         int len=(int) (mp->b_wptr-mp->b_rptr);
00261         newm=allocb(len,BPRI_MED);
00262         memcpy(newm->b_wptr,mp->b_rptr,len);
00263         newm->b_wptr+=len;
00264         return newm;
00265 }
00266 
00267 mblk_t *copymsg(mblk_t *mp)
00268 {
00269         mblk_t *newm=0,*m;
00270         m=newm=copyb(mp);
00271         mp=mp->b_cont;
00272         while(mp!=NULL){
00273                 m->b_cont=copyb(mp);
00274                 m=m->b_cont;
00275                 mp=mp->b_cont;
00276         }
00277         return newm;
00278 }
00279 
00280 mblk_t * appendb(mblk_t *mp, const char *data, int size, bool_t pad){
00281         int padcnt=0;
00282         int i;
00283         if (pad){
00284                 padcnt= (int)(4L-( (long)(((long)mp->b_wptr)+size) % 4L)) % 4L;
00285         }
00286         if ((mp->b_wptr + size +padcnt) > mp->b_datap->db_lim){
00287                 /* buffer is not large enough: append a new block (with the same size ?)*/
00288                 int plen=(int)((char*)mp->b_datap->db_lim - (char*) mp->b_datap->db_base);
00289                 mp->b_cont=allocb(MAX(plen,size),0);
00290                 mp=mp->b_cont;
00291         }
00292         if (size) memcpy(mp->b_wptr,data,size);
00293         mp->b_wptr+=size;
00294         for (i=0;i<padcnt;i++){
00295                 mp->b_wptr[0]=0;
00296                 mp->b_wptr++;
00297         }
00298         return mp;
00299 }
00300 
00301 void msgappend(mblk_t *mp, const char *data, int size, bool_t pad){
00302         while(mp->b_cont!=NULL) mp=mp->b_cont;
00303         appendb(mp,data,size,pad);
00304 }
00305 
00306 mblk_t *concatb(mblk_t *mp, mblk_t *newm){
00307         while (mp->b_cont!=NULL) mp=mp->b_cont;
00308         mp->b_cont=newm;
00309         while(newm->b_cont!=NULL) newm=newm->b_cont;
00310         return newm;
00311 }

Generated on Thu Feb 14 16:11:18 2008 for oRTP by  doxygen 1.5.4