Changeset 3971:370e1268ac0e in roaraudio


Ignore:
Timestamp:
06/26/10 13:52:29 (14 years ago)
Author:
phi
Branch:
default
Phase:
public
Message:

some code

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libroar/vio_buffer.c

    r3969 r3971  
    3636#include "libroar.h" 
    3737 
     38int     roar_vio_open_buffer    (struct roar_vio_calls * calls, struct roar_vio_calls * dst, ssize_t minsize, int use_re) { 
     39 struct roar_vio_buffer * self;; 
     40 
     41 if ( calls == NULL || dst == NULL ) 
     42  return -1; 
     43 
     44 if ( (self = roar_mm_malloc(sizeof(struct roar_vio_buffer))) == NULL ) 
     45  return -1; 
     46 
     47 memset(self, 0, sizeof(struct roar_vio_buffer)); 
     48 
     49 self->backend     = dst; 
     50 self->min_bufsize = minsize; 
     51 self->use_re      = use_re; 
     52 
     53 if ( use_re ) { 
     54  if ( roar_vio_open_re(&(self->re_vio), dst) == -1 ) { 
     55   roar_mm_free(self); 
     56   return -1; 
     57  } 
     58 } 
     59 
     60 memset(calls, 0, sizeof(struct roar_vio_calls)); 
     61 
     62 calls->inst     = self; 
     63 calls->close    = roar_vio_buffer_close; 
     64 calls->write    = roar_vio_buffer_write; 
     65 calls->nonblock = roar_vio_buffer_nonblock; 
     66 calls->ctl      = roar_vio_buffer_ctl; 
     67 calls->sync     = roar_vio_buffer_sync; 
     68 calls->lseek    = roar_vio_buffer_lseek; 
     69 
     70 return 0; 
     71} 
     72 
     73int     roar_vio_buffer_close   (struct roar_vio_calls * vio) { 
     74 struct roar_vio_buffer * self = vio->inst; 
     75 int ret; 
     76 
     77 if ( self->buf_old != NULL ) 
     78  roar_buffer_free(self->buf_old); 
     79 
     80 if ( self->buf_cur != NULL ) 
     81  roar_buffer_free(self->buf_cur); 
     82 
     83 if ( self->use_re ) { 
     84  ret = roar_vio_close(&(self->re_vio)); 
     85 } else { 
     86  ret = roar_vio_close(self->backend); 
     87 } 
     88 
     89 roar_mm_free(self); 
     90 
     91 return ret; 
     92} 
     93 
     94ssize_t roar_vio_buffer_read    (struct roar_vio_calls * vio, void *buf, size_t count); 
     95 
     96int     roar_vio_buffer_sync    (struct roar_vio_calls * vio) { 
     97 struct roar_vio_buffer * self = vio->inst; 
     98 struct roar_vio_calls  * backend; 
     99 off_t dst = 0; 
     100 
     101 if ( self->use_re ) { 
     102  backend = &(self->re_vio); 
     103 } else { 
     104  backend = self->backend; 
     105 } 
     106 
     107 // bring backend in sync state, if this fails we do not need to continue... 
     108 if ( self->use_re ) { 
     109  if ( roar_vio_sync(backend) == -1 ) 
     110   return -1; 
     111 } else { 
     112  if ( roar_vio_sync(backend) == -1 ) 
     113   return -1; 
     114 } 
     115 
     116 if ( self->buf_old == NULL && self->buf_cur == NULL ) 
     117  return 0; // we are in sync in case no buffers are currently used. 
     118 
     119 if (self->buf_old != NULL && self->buf_cur == NULL ) { 
     120  // we just finished the segment 
     121  roar_buffer_free(self->buf_old); 
     122  return 0; 
     123 } 
     124 
     125 // calc seek pos: 
     126 if ( self->offset.is_old ) { 
     127  dst = (self->len_cur + self->len_old) - self->offset.offset; 
     128 } else { 
     129  dst = self->len_cur - self->offset.offset; 
     130 } 
     131 
     132 dst = -dst; 
     133 
     134 // do the seek: 
     135 if ( roar_vio_lseek(backend, dst, SEEK_CUR) == (off_t)-1 ) 
     136  return -1; 
     137 
     138 // free all internal buffers: 
     139 if ( self->buf_old != NULL ) 
     140  roar_buffer_free(self->buf_old); 
     141 
     142 if ( self->buf_cur != NULL ) 
     143  roar_buffer_free(self->buf_cur); 
     144 
     145 self->offset.is_old = 0; 
     146 self->offset.offset = 0; 
     147 
     148 // funally bring the backend in sync state again, to be sure all changes are done. 
     149 if ( self->use_re ) { 
     150  if ( roar_vio_sync(backend) == -1 ) 
     151   return -1; 
     152 } else { 
     153  if ( roar_vio_sync(backend) == -1 ) 
     154   return -1; 
     155 } 
     156 
     157 return 0; 
     158} 
     159 
     160off_t   roar_vio_buffer_lseek   (struct roar_vio_calls * vio, off_t offset, int whence) { 
     161 struct roar_vio_buffer * self = vio->inst; 
     162 size_t newoff; 
     163 off_t  ret; 
     164 off_t  invoff; 
     165 
     166 // in-memory seeking is only supported for SEEK_CUR: 
     167 if ( whence == SEEK_CUR ) { 
     168  if ( offset == 0 ) { 
     169   return 0; 
     170  } else if ( offset > 0 ) { 
     171   newoff = self->offset.offset + offset; 
     172 
     173   if ( self->offset.is_old ) { 
     174    if ( newoff == self->len_old ) { 
     175     self->offset.is_old = 0; 
     176     self->offset.offset = 0; 
     177     self->abspos += offset; 
     178     return self->abspos; 
     179    } else if ( newoff < self->len_old ) { 
     180     self->offset.offset = newoff; 
     181     self->abspos += offset; 
     182     return self->abspos; 
     183    } else if ( newoff > self->len_old ) { 
     184     if ( newoff < (self->len_old + self->len_cur ) ) { 
     185      self->offset.is_old = 0; 
     186      self->offset.offset = offset + self->offset.offset - self->len_old; 
     187      self->abspos += offset; 
     188      return self->abspos; 
     189     } 
     190    } 
     191   } else { 
     192    if ( newoff == self->len_cur ) { 
     193     roar_buffer_free(self->buf_old); 
     194     self->buf_old = self->buf_cur; 
     195     self->buf_cur = NULL; 
     196     self->offset.offset = 0; 
     197     self->abspos += offset; 
     198     return self->abspos; 
     199    } else if ( newoff < self->len_cur ) { 
     200     self->offset.offset = newoff; 
     201     self->abspos += offset; 
     202     return self->abspos; 
     203    } 
     204   } 
     205  } else { 
     206   invoff = -offset; 
     207 
     208   if ( invoff <= self->offset.offset ) { 
     209    self->offset.offset = 0; 
     210    self->abspos -= invoff; 
     211    return self->abspos; 
     212   } 
     213 
     214   if ( !self->offset.is_old ) { 
     215    if ( invoff > self->offset.offset ) { 
     216     if ( invoff <= (self->len_old + self->offset.offset) ) { 
     217      self->offset.is_old = 1; 
     218      self->offset.offset = (self->len_old + self->offset.offset) - invoff; 
     219      self->abspos -= invoff; 
     220      return self->abspos; 
     221     } 
     222    } 
     223   } 
     224  } 
     225 } 
     226 
     227 // we need to do a physical seek; 
     228 // get in sync with current possition, flush all buffers,... 
     229 if ( roar_vio_buffer_sync(vio) == -1 ) 
     230  return -1; 
     231 
     232 // do the seek: 
     233 if ( self->use_re ) { 
     234  ret = roar_vio_lseek(&(self->re_vio), offset, whence); 
     235 } else { 
     236  ret = roar_vio_lseek(self->backend, offset, whence); 
     237 } 
     238 
     239 if (ret != (off_t)-1) 
     240  self->abspos = ret; 
     241 
     242 return ret; 
     243} 
     244 
     245int     roar_vio_buffer_ctl     (struct roar_vio_calls * vio, int cmd, void * data) { 
     246 struct roar_vio_buffer * self; 
     247 
     248 if (vio == NULL || cmd == -1) 
     249  return -1; 
     250 
     251 ROAR_DBG("roar_vio_buffer_ctl(vio=%p, cmd=0x%.8x, data=%p) = ?", vio, cmd, data); 
     252 
     253 self = vio->inst; 
     254 
     255 switch (cmd) { 
     256  case ROAR_VIO_CTL_GET_NAME: 
     257    if ( data == NULL ) 
     258     return -1; 
     259 
     260    *(char**)data = "buffer"; 
     261    return 0; 
     262   break; 
     263  case ROAR_VIO_CTL_GET_NEXT: 
     264    if ( self->use_re ) { 
     265     *(struct roar_vio_calls **)data = &(self->re_vio); 
     266    } else { 
     267     *(struct roar_vio_calls **)data = self->backend; 
     268    } 
     269    return 0; 
     270   break; 
     271  case ROAR_VIO_CTL_SET_NEXT: 
     272    if ( self->use_re ) { 
     273     return roar_vio_ctl(&(self->re_vio), ROAR_VIO_CTL_SET_NEXT, data); 
     274    } else { 
     275     self->backend = *(struct roar_vio_calls **)data; 
     276    } 
     277    return 0; 
     278   break; 
     279 } 
     280 
     281 return roar_vio_ctl((struct roar_vio_calls *) vio->inst, cmd, data); 
     282} 
     283 
     284ssize_t roar_vio_buffer_write   (struct roar_vio_calls * vio, void *buf, size_t count) { 
     285 struct roar_vio_buffer * self = vio->inst; 
     286 
     287 if ( self->use_re ) { 
     288  return roar_vio_write(&(self->re_vio), buf, count); 
     289 } else { 
     290  return roar_vio_write(self->backend, buf, count); 
     291 } 
     292} 
     293 
     294int     roar_vio_buffer_nonblock(struct roar_vio_calls * vio, int state) { 
     295 struct roar_vio_buffer * self = vio->inst; 
     296 
     297 if ( self->use_re ) { 
     298  return roar_vio_nonblock(&(self->re_vio), state); 
     299 } else { 
     300  return roar_vio_nonblock(self->backend, state); 
     301 } 
     302} 
     303 
    38304//ll 
Note: See TracChangeset for help on using the changeset viewer.