io.c

00001 /*
00002  * Copyright (c) 2005-2012 by KoanLogic s.r.l. <http://www.koanlogic.com>
00003  * All rights reserved.
00004  *
00005  * This file is part of KLone, and as such it is subject to the license stated
00006  * in the LICENSE file which you have received as part of this distribution.
00007  *
00008  * $Id: io.c,v 1.43 2008/10/03 16:03:04 tho Exp $
00009  */
00010 
00011 #include "klone_conf.h"
00012 #include <unistd.h>
00013 #include <u/libu.h>
00014 #include <klone/va.h>
00015 #include <klone/io.h>
00016 #include <klone/ioprv.h>
00017 #include <klone/codec.h>
00018 
00019 enum io_type_e io_type(io_t *io);
00020 
00021 enum { 
00022     IO_RD_BUFSZ = 4096, 
00023     IO_WR_BUFSZ = 4096
00024 };
00025 
00026 #define IO_WBUF_AVAIL(io) (io->wbsz - io->wcount)
00027 #define IO_WBUF_FULL(io) (io->wbsz == io->wcount)
00028 
00029 static inline int io_transform_codec_buffer(io_t *, codec_t *, char *, 
00030         size_t *);
00031 
00043 enum io_type_e io_type(io_t *io)
00044 {
00045     return io->type;
00046 }
00047 
00061 ssize_t io_pipe(io_t *out, io_t *in)
00062 {
00063     enum { BUFSZ = 4096 };
00064     char buf[BUFSZ];
00065     size_t count = 0;   /* # of bytes piped */
00066     ssize_t c;
00067 
00068     dbg_err_if (out == NULL);
00069     dbg_err_if (in == NULL);
00070     
00071     for(;;)
00072     {
00073         c = io_read(in, buf, BUFSZ);
00074         dbg_err_if(c < 0);
00075         if(c == 0)
00076             break; /* eof */
00077 
00078         /* write it out */
00079         dbg_err_if(io_write(out, buf, c) < 0);
00080 
00081         count += c;
00082     }
00083 
00084     return count;
00085 err:
00086     return -1;
00087 }
00088 
00106 int io_dup(io_t *io, io_t **pio)
00107 {
00108     dbg_return_if (io == NULL, ~0);
00109     dbg_return_if (pio == NULL, ~0);
00110     
00111     io->refcnt++;
00112 
00113     *pio = io;
00114 
00115     return 0;
00116 }
00117 
00132 ssize_t io_copy(io_t *out, io_t *in, size_t size)
00133 {
00134     enum { BUFSZ = 4096 };
00135     char buf[BUFSZ];
00136     size_t rem = size;
00137     ssize_t c;
00138 
00139     dbg_err_if (in == NULL);
00140     dbg_err_if (out == NULL);
00141 
00142     while(rem)
00143     {
00144         c = io_read(in, buf, U_MIN(BUFSZ, rem));
00145         dbg_err_if(c < 0);
00146         if(c == 0)
00147             break; /* eof */
00148 
00149         /* write it out */
00150         dbg_err_if(io_write(out, buf, c) < 0);
00151 
00152         rem -= c;
00153     }
00154 
00155     return size - rem;
00156 err:
00157     return -1;
00158 }
00159 
00160 
00175 ssize_t io_seek(io_t *io, size_t off)
00176 {
00177     dbg_err_if (io == NULL);
00178     dbg_err_if (io_flush(io));
00179 
00180     if(io->seek)
00181         return io->seek(io, off);
00182 err:
00183     return -1;
00184 }
00185 
00197 ssize_t io_tell(io_t *io)
00198 {
00199     dbg_err_if (io == NULL);
00200     dbg_err_if (io_flush(io));
00201 
00202     if(io->tell)
00203         return io->tell(io);
00204 err:
00205     return -1;
00206 }
00207 
00208 /* alloc the read buffer */
00209 static int io_rbuf_alloc(io_t *io)
00210 {
00211     dbg_err_if (io == NULL);
00212     
00213     io->rbsz = IO_RD_BUFSZ; /* set the buffer size */
00214 
00215     /* if a dup'd io_t already alloc'd a buffer then use it */
00216     io->rbuf = (char*)u_malloc(io->rbsz);
00217     dbg_err_if(io->rbuf == NULL);
00218     io->roff = 0;
00219 
00220     io->ubuf = (char*)u_malloc(io->rbsz);
00221     dbg_err_if(io->ubuf == NULL);
00222 
00223     return 0;
00224 err:
00225     return ~0;
00226 }
00227 
00228 /* alloc the write buffer */
00229 static int io_wbuf_alloc(io_t *io)
00230 {
00231     dbg_err_if (io == NULL);
00232 
00233     io->wbsz = IO_WR_BUFSZ; /* set the buffer size */
00234 
00235     /* if a dup'd io_t already alloc'd a buffer then use it */
00236     io->wbuf = (char*)u_malloc(io->wbsz);
00237     dbg_err_if(io->wbuf == NULL);
00238 
00239     return 0;
00240 err:
00241     return ~0;
00242 }
00243 
00244 static ssize_t io_transform(io_t *io, codec_t *codec, 
00245     char *dst, size_t *dcount, const char *src, size_t sz)
00246 {
00247     ssize_t c;
00248     size_t cavail, sdcount = *dcount; /* saved dcount */
00249 
00250     dbg_err_if (io == NULL);
00251     dbg_err_if (codec == NULL);
00252     dbg_err_if (src == NULL);
00253     dbg_err_if (dst == NULL);
00254     dbg_err_if (dcount == NULL);
00255 
00256     if(codec == TAILQ_LAST(&io->codec_chain, codec_chain_s))
00257     {
00258         /* last codec in the chain */
00259         c = codec->transform(codec, dst, dcount, src, sz); 
00260         dbg_err_if(c == 0 && *dcount == 0);
00261         return c;
00262     } else {
00263         c = 0;
00264         do
00265         {
00266             *dcount = sdcount;
00267             if(codec->ccount)
00268                 dbg_err_if(io_transform_codec_buffer(io, codec, dst, dcount));
00269             else
00270                 *dcount = 0; /* no bytes written to 'dst' */
00271 
00272             c = 0; /* zero byte of 'src' consumed */
00273             cavail = CODEC_BUFSZ - codec->ccount - codec->coff;
00274             if(sz && cavail)
00275             {
00276                 dbg_err_if((c = codec->transform(codec, 
00277                     codec->cbuf + codec->coff + codec->ccount, 
00278                     &cavail, src, sz)) < 0);
00279 
00280                 codec->ccount += cavail;
00281                 dbg_err_if(c == 0 && cavail == 0);
00282             }
00283         } while(c == 0 && *dcount == 0 && (codec->ccount || sz));
00284 
00285         return c;
00286     }
00287 
00288 err:
00289     return -1;
00290 }
00291 
00292 static inline int io_transform_codec_buffer(io_t *io, codec_t *codec, 
00293     char *dst, size_t *dcount)
00294 {
00295     ssize_t ct;
00296 
00297     dbg_err_if (io == NULL);
00298     dbg_err_if (codec == NULL);
00299     dbg_err_if (dst == NULL);
00300     dbg_err_if (dcount == NULL);
00301 
00302     if(codec->ccount)
00303     {
00304         dbg_err_if((ct = io_transform(io, TAILQ_NEXT(codec, np), 
00305             dst, dcount, codec->cbuf + codec->coff,codec->ccount)) < 0);
00306 
00307         codec->ccount -= ct;
00308 
00309         if(codec->ccount > 0)
00310             codec->coff += ct;
00311         else
00312             codec->coff = 0;
00313     }
00314 
00315     return 0;
00316 err:
00317     return ~0;
00318 }
00319 
00320 static inline ssize_t io_transfer(io_t *io, char *dst, size_t *dcount, 
00321         const char *src, size_t sz)
00322 {
00323     dbg_err_if (io == NULL);
00324     dbg_err_if (src == NULL);
00325     dbg_err_if (dst == NULL);
00326     dbg_err_if (dcount == NULL);
00327 
00328     if(!TAILQ_EMPTY(&io->codec_chain))
00329     {
00330         return io_transform(io, TAILQ_FIRST(&io->codec_chain), 
00331             dst, dcount, src, sz); 
00332     } else {
00333         ssize_t wr = U_MIN(sz, *dcount); 
00334         memcpy(dst, src, wr);
00335         *dcount = wr;
00336         return wr;
00337     }
00338 err:
00339     return -1;
00340 }
00341 
00342 static int io_chain_flush_chunk(io_t *io, char *dst, size_t *dcount)
00343 {
00344     int er;
00345     codec_t *codec;
00346     size_t sz, sdcount;
00347 
00348     dbg_err_if (io == NULL);
00349     dbg_err_if (dst == NULL);
00350     dbg_err_if (dcount == NULL);
00351 
00352     sdcount = *dcount;
00353 
00354     TAILQ_FOREACH(codec, &io->codec_chain, np)
00355     {
00356         *dcount = sdcount;
00357         if(codec == TAILQ_LAST(&io->codec_chain, codec_chain_s))
00358         {
00359             return codec->flush(codec, dst, dcount);
00360         } else {
00361             for(;;)
00362             {
00363                 *dcount = sdcount;
00364                 if(codec->ccount)
00365                 {
00366                     int rc = io_transform_codec_buffer(io, codec, dst, dcount);
00367                     dbg_err_if (rc);
00368 
00369                     if(*dcount)
00370                         return CODEC_FLUSH_CHUNK; /* call flush again */
00371                 } else
00372                     *dcount = 0; /* no bytes written to 'dst' */
00373 
00374                 sz = CODEC_BUFSZ - codec->ccount - codec->coff;
00375                 dbg_err_if((er = codec->flush(codec, 
00376                     codec->cbuf + codec->coff + codec->ccount, &sz)) < 0);
00377 
00378                 codec->ccount += sz;
00379 
00380                 if(er == CODEC_FLUSH_COMPLETE && codec->ccount == 0)
00381                     break; /* flush of this codec completed */
00382             } /* for */
00383         }
00384     }
00385 
00386     return CODEC_FLUSH_COMPLETE;
00387 err:
00388     return -1;
00389 }
00390 
00391 static int io_chain_flush(io_t *io)
00392 {
00393     enum { BUFSZ = 4096 };
00394     int er;
00395     size_t sz, count;
00396     char buf[BUFSZ], *ptr;
00397 
00398     dbg_err_if (io == NULL);
00399 
00400     for(;;)
00401     {
00402         /* note: we cannot write straight to the wbuf otherwise codec 
00403          * transform & flush functions cannot call io_write safely; so we use 
00404          * a temp buffer and memcpy it to the wbuf after flushing */
00405         count = BUFSZ;
00406         if((er = io_chain_flush_chunk(io, buf, &count)) == CODEC_FLUSH_COMPLETE)
00407             break; /* flush complete */
00408         
00409         dbg_err_if(er < 0);
00410 
00411         for(ptr = buf; count; )
00412         {
00413             if(IO_WBUF_FULL(io))
00414                 dbg_err_if(io_flush(io));
00415 
00416             sz = U_MIN(count, IO_WBUF_AVAIL(io));
00417             memcpy(io->wbuf + io->wcount, ptr, sz);
00418 
00419             count -= sz;
00420             io->wcount += sz;
00421             ptr += sz;
00422         }
00423     } 
00424 
00425     return 0;
00426 err:
00427     return ~0;
00428 }
00429 
00442 int io_close(io_t *io)
00443 {
00444     dbg_err_if (io == NULL);
00445 
00446     if(io->close)
00447         dbg_err_if(io->close(io));
00448 
00449     return 0;
00450 err:
00451     return ~0;
00452 }
00453 
00469 int io_free(io_t *io)
00470 {
00471     dbg_err_if (io == NULL);
00472     dbg_err_if (io->refcnt == 0);
00473 
00474     /* skip if this io_t has been dup'd and there are still one or more 
00475        references in use */
00476     if(--io->refcnt)
00477         return 0;
00478 
00479     /* flush, remove and free all codecs */
00480     dbg_if(io_codecs_remove(io));
00481 
00482     dbg_if(io_flush(io));
00483 
00484     /* flush and close the stream (but don't free it) */
00485     dbg_if(io_close(io));
00486 
00487     /* free per-type alloc'ed data */
00488     if(io->free)
00489         dbg_if(io->free(io));
00490 
00491     U_FREE(io->rbuf);
00492     U_FREE(io->ubuf);
00493     U_FREE(io->wbuf);
00494     U_FREE(io->name);
00495     U_FREE(io);
00496 
00497     return 0;
00498 err:
00499     return ~0;
00500 }
00501 
00502 /* refill the read buffer */
00503 static ssize_t io_underflow(io_t *io)
00504 {
00505     ssize_t c;
00506     size_t sz;
00507 
00508     dbg_err_if (io == NULL);
00509 
00510     if(io->rbuf == NULL)
00511         dbg_err_if(io_rbuf_alloc(io)); /* alloc the read buffer */
00512 
00513     while(io->rcount == 0)
00514     {
00515         if(io->ucount == 0)
00516         {   /* fetch some bytes from the device and fill the rbuffer */
00517             dbg_err_if((c = io->read(io, io->ubuf, io->rbsz)) < 0);
00518             if(c == 0)
00519             {   /* eof, try to get some buffered (already transformed) bytes 
00520                    from the codec */
00521                 if(!TAILQ_EMPTY(&io->codec_chain))
00522                 {
00523                     sz = io->rbsz;
00524                     c = io_chain_flush_chunk(io, io->rbuf, &sz);
00525                     dbg_err_if(c < 0);
00526                     io->rcount += sz;
00527                     io->roff = 0;
00528                     if(c == 0)
00529                         io->eof++;
00530                 }
00531                 break;
00532             }
00533             io->ucount += c;
00534         }
00535 
00536         /* transform all data in the buffer */
00537         sz = io->rbsz - io->rcount;
00538         dbg_err_if((c = io_transfer(io, io->rbuf, &sz, 
00539             io->ubuf + io->uoff, io->ucount)) < 0);
00540         dbg_err_if(c < 0);
00541         dbg_err_if(c == 0 && sz == 0);
00542         io->ucount -= c;
00543         if(io->ucount == 0)
00544             io->uoff = 0;
00545         else
00546             io->uoff += c;
00547 
00548         io->rcount = sz;
00549         io->roff = 0;
00550     }
00551 
00552     return io->rcount;
00553 err:
00554     return -1;
00555 }
00556 
00572 ssize_t io_read(io_t *io, char *buf, size_t size)
00573 {
00574     char *out = buf;
00575     size_t wr;
00576     ssize_t c;
00577 
00578     dbg_err_if (io == NULL);
00579     dbg_err_if (buf == NULL);
00580     
00581     if(io->eof)
00582         return 0;
00583 
00584     while(size)
00585     {
00586         if(io->rcount == 0)
00587         {
00588             dbg_err_if((c = io_underflow(io)) < 0);
00589             if(c == 0)
00590                 break;
00591         }
00592         /* copy out data */
00593         wr = U_MIN(io->rcount, size); 
00594         memcpy(out, io->rbuf + io->roff, wr);
00595         io->rcount -= wr;
00596         io->roff += wr;
00597         io->rtot += wr;
00598         out += wr;
00599         size -= wr;
00600     }
00601 
00602     return out - buf;
00603 err:
00604     return -1;
00605 }
00606 
00621 ssize_t io_vprintf(io_t *io, const char *fmt, va_list ap)
00622 {
00623     enum { BUFSZ = 2048 };
00624     char *bbuf = NULL; 
00625     int sz;
00626     char buf[BUFSZ];
00627     va_list apcpy;
00628 
00629     dbg_err_if (io == NULL);
00630     dbg_err_if (fmt == NULL);
00631 
00632 #ifdef VA_COPY_UNAVAIL
00633     u_unused_args(apcpy);
00634 #elif defined(VA_LIST_BY_VALUE)
00635     /* we're sure about vnsprintf not consuming its 'ap' argument, so just do
00636      * simple aliasing here: remember not to va_end() the alias */
00637     apcpy = ap;
00638 #else
00639     /* vnsprintf modifies the va_list so make a copy before using it */
00640     kl_va_copy(apcpy, ap);
00641 #endif
00642 
00643     /* build the message to print */
00644     sz = vsnprintf(buf, BUFSZ, fmt, ap);
00645 
00646     if(sz >= BUFSZ)
00647     {   
00648 #ifndef VA_COPY_UNAVAIL
00649         /* stack buffer too small, alloc a bigger one on the heap */
00650         bbuf = (char*)u_malloc(++sz);
00651         dbg_err_if(bbuf == NULL);
00652 
00653         /* use apcpy in case ap has been consumed by previous vsnprintf */
00654         if((sz = vsnprintf(bbuf, sz, fmt, apcpy)) > 0)
00655             dbg_err_if(io_write(io, bbuf, sz) < 0);
00656 
00657         U_FREE(bbuf);
00658 #else
00659         /* push out all we can (sz-BUFSZ+1 bytes will be lost) */
00660         warn("last %d byte(s) could not be written out", sz - BUFSZ + 1);
00661         dbg_err_if(io_write(io, buf, BUFSZ) < 0);
00662 #endif
00663     } else if(sz > 0) {
00664         dbg_err_if(io_write(io, buf, sz) < 0);
00665     }
00666 
00667 #if !defined(VA_LIST_BY_VALUE) && !defined(VA_COPY_UNAVAIL)
00668     va_end(apcpy);
00669 #endif
00670     return 0;
00671 err:
00672 #if !defined(VA_LIST_BY_VALUE) && !defined(VA_COPY_UNAVAIL)
00673     va_end(apcpy);
00674 #endif
00675     return -1;
00676 }
00677 
00692 ssize_t io_printf(io_t *io, const char *fmt, ...)
00693 {
00694     va_list ap;
00695     ssize_t ret;
00696 
00697     dbg_err_if (io == NULL);
00698     dbg_err_if (fmt == NULL);
00699 
00700     /* build the message to print */
00701     va_start(ap, fmt); /* init variable list arguments */
00702 
00703     ret = io_vprintf(io, fmt, ap);
00704 
00705     va_end(ap);
00706 
00707     return ret;
00708 err:
00709     return -1;
00710 }
00711 
00722 ssize_t io_flush(io_t *io)
00723 {
00724     ssize_t c;
00725     size_t off = 0;
00726 
00727     dbg_err_if (io == NULL);
00728  
00729     while(io->wcount)
00730     {
00731         c = io->write(io, io->wbuf + off, io->wcount);
00732         dbg_err_if(c < 0);
00733         if(c == 0)
00734             break;
00735     
00736         io->wcount -= c;
00737         off += c;
00738     }
00739 
00740     return 0;
00741 err:
00742     return -1;
00743 }
00744 
00757 ssize_t io_write(io_t *io, const char *buf, size_t size)
00758 {
00759     size_t sz = 0, rem = size;
00760     ssize_t c = 0;
00761 
00762     dbg_err_if (io == NULL);
00763     dbg_err_if (buf == NULL);
00764     
00765     if(io->wbuf == NULL)
00766         dbg_err_if(io_wbuf_alloc(io)); /* alloc the write buffer */
00767 
00768     while(rem)
00769     {
00770         if(IO_WBUF_FULL(io)) /* if there's no more free space */
00771             dbg_err_if(io_flush(io));
00772 
00773         sz = IO_WBUF_AVAIL(io);
00774         c = io_transfer(io, io->wbuf + io->wcount, &sz, buf, rem);
00775         dbg_err_if(c < 0);
00776         dbg_err_if(c == 0 && sz == 0); /* some bytes MUST be read or written */
00777 
00778         io->wcount += sz;
00779         buf += c;
00780         rem -= c;
00781     }
00782 
00783     return size;
00784 err:
00785     return -1;
00786 }
00787 
00799 inline ssize_t io_putc(io_t *io, char c)
00800 {
00801     return io_write(io, &c, 1);
00802 }
00803 
00815 inline ssize_t io_getc(io_t *io, char *pc)
00816 {
00817     return io_read(io, pc, 1);
00818 }
00819 
00820 static inline char *io_strnchr(char *buf, size_t sz, char c)
00821 {
00822     register char *p;
00823 
00824     dbg_goto_if (buf == NULL, end);
00825 
00826     p = buf;
00827 
00828     while(sz--)
00829     {
00830         if(*p == c)
00831             return p;
00832         ++p;
00833     }
00834 end:
00835     return NULL;
00836 }
00837 
00853 ssize_t io_get_until(io_t *io, char stop_at, char *buf, size_t size)
00854 {
00855     ssize_t wr, c, len = 0;
00856     char *p, *base = buf;
00857 
00858     dbg_err_if (io == NULL);
00859     dbg_err_if (buf == NULL);
00860 
00861     if(size < 2)
00862         return -1; /* buf too small */
00863 
00864     --size; /* save a char for \0 */
00865 
00866     if(io->rcount == 0)
00867         dbg_err_if(io_underflow(io) < 0);
00868 
00869     if(io->rcount == 0)
00870         return 0;
00871 
00872     for(;;)
00873     {
00874         if((p = io_strnchr(io->rbuf + io->roff, io->rcount, stop_at)) != NULL)
00875         {
00876             p++; /* jump over 'stop_at' char*/
00877             wr = U_MIN(p - (io->rbuf + io->roff), size);
00878             memcpy(buf, io->rbuf + io->roff, wr);
00879             buf[wr] = 0;
00880             io->rcount -= wr;
00881             io->roff += wr;
00882             io->rtot += wr;
00883             len += wr;
00884             break;
00885         } else {
00886             if(size >= io->rcount)
00887             {
00888                 memcpy(buf, io->rbuf + io->roff, io->rcount);
00889                 len += io->rcount;
00890                 buf += io->rcount;
00891                 size -= io->rcount;
00892                 io->rtot += io->rcount;
00893                 io->rcount = 0;
00894                 io->roff = 0;
00895                 dbg_err_if((c = io_underflow(io)) < 0);
00896                 if(c == 0)
00897                     break;
00898             } else {
00899                 /* buffer too small, return a partial line */
00900                 memcpy(buf, io->rbuf + io->roff, size);
00901                 len += size;
00902                 io->rcount -= size;
00903                 io->roff += size;
00904                 io->rtot += size;
00905                 break;
00906             }
00907         }
00908     }
00909 
00910     base[len] = 0;
00911     return len; /* return the # of chars in the line (strlen(line)) */
00912 err:
00913     return -1;
00914 }
00915 
00929 ssize_t io_gets(io_t *io, char *buf, size_t size)
00930 {
00931     return io_get_until(io, '\n', buf, size);
00932 }
00933 
00943 int io_codec_add_head(io_t *io, codec_t* c)
00944 {
00945     dbg_return_if (io == NULL, ~0);
00946     dbg_return_if (c == NULL, ~0);
00947 
00948     /* insert the codec at the head of the chain */
00949     TAILQ_INSERT_HEAD(&io->codec_chain, c, np);
00950 
00951     return 0;
00952 }
00953 
00963 int io_codec_add_tail(io_t *io, codec_t* c)
00964 {
00965     dbg_return_if (io == NULL, ~0);
00966     dbg_return_if (c == NULL, ~0);
00967 
00968     /* insert the codec at the end of the chain */
00969     TAILQ_INSERT_TAIL(&io->codec_chain, c, np);
00970 
00971     return 0;
00972 }
00973 
00982 int io_codecs_remove(io_t *io)
00983 {
00984     codec_t *codec;
00985     int rc = 0;
00986 
00987     dbg_return_if (io == NULL, ~0);
00988 
00989     if(!TAILQ_EMPTY(&io->codec_chain))
00990     {
00991         if(io->wbuf)
00992             dbg_ifb(io_chain_flush(io))
00993                 rc++;
00994 
00995         while((codec = TAILQ_FIRST(&io->codec_chain)) != NULL)
00996         {
00997             TAILQ_REMOVE(&io->codec_chain, codec, np);
00998             codec_free(codec);
00999         }
01000     }
01001 
01002     return rc;
01003 }
01004 
01017 int io_name_set(io_t *io, const char *name)
01018 {
01019     char *n;
01020 
01021     dbg_err_if (io == NULL);
01022     dbg_err_if (name == NULL);
01023     
01024     n = u_strdup(name);
01025     dbg_err_if(n == NULL);
01026 
01027     U_FREE(io->name);
01028 
01029     io->name = n;
01030 
01031     return 0;
01032 err:
01033     return ~0;
01034 }
01035 
01048 int io_name_get(io_t *io, char *name, size_t sz)
01049 {
01050     size_t min = 0;
01051 
01052     dbg_err_if (io == NULL);
01053     dbg_err_if (io->name == NULL);
01054     dbg_err_if (name == NULL);
01055     dbg_err_if (sz < 2);
01056 
01057     min = U_MIN(sz-1, strlen(io->name));
01058 
01059     memcpy(name, io->name, min);
01060     name[min] = 0;
01061     
01062     return 0;
01063 err:
01064     return ~0;
01065 }
01066 
01067 /*
01068  * \ingroup basic
01069  * \brief   Return the secure state of the IO object
01070  *  
01071  *  Return 0 if the connection is not secure (i.e. not encrypted) or not zero
01072  *  otherwise
01073  *
01074  * \param io    io object
01075  *
01076  * \return \c 0 for not secure connections, non-zero otherwise
01077  */
01078 int io_is_secure(io_t *io)
01079 {
01080     dbg_err_if(io == NULL);
01081 
01082     return io->is_secure;
01083 err:
01084     return 0;
01085 }
01086 
01087 
01088 /* used by io devices init functions: alloc (used dev_sz block size) 
01089    and initialize an io_t */
01090 int io_prv_create(size_t dev_sz, io_t **pio)
01091 {
01092     io_t *io = NULL;
01093 
01094     dbg_err_if (pio == NULL);
01095 
01096     io = u_zalloc(dev_sz);
01097     dbg_err_if(io == NULL);
01098 
01099     TAILQ_INIT(&io->codec_chain);
01100 
01101     /* set refcnt to 1 */
01102     io->refcnt++;
01103 
01104     /* size of the io device struct (that's also a 'castable' io_t) */
01105     io->size = dev_sz;
01106 
01107     *pio = io;
01108 
01109     return 0;
01110 err:
01111     U_FREE(io);
01112     return -1;
01113 }

←Products
Copyright © 2005-2012 - KoanLogic S.r.l. - All rights reserved