io.c
上传用户:seven77cht
上传日期:2007-01-04
资源大小:486k
文件大小:10k
源码类别:

浏览器

开发平台:

Unix_Linux

  1. /***************************************
  2.   $Header: /home/amb/wwwoffle/RCS/io.c 2.15 1999/11/16 19:36:21 amb Exp $
  3.   WWWOFFLE - World Wide Web Offline Explorer - Version 2.5c.
  4.   Functions for file input and output.
  5.   ******************/ /******************
  6.   Written by Andrew M. Bishop
  7.   This file Copyright 1996,97,98,99 Andrew M. Bishop
  8.   It may be distributed under the GNU Public License, version 2, or
  9.   any higher version.  See section COPYING of the GNU Public license
  10.   for conditions under which this file may be redistributed.
  11.   ***************************************/
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <ctype.h>
  16. #ifdef __STDC__
  17. #include <stdarg.h>
  18. #else
  19. #include <varargs.h>
  20. #endif
  21. #include <sys/time.h>
  22. #include <sys/types.h>
  23. #include <fcntl.h>
  24. #include <unistd.h>
  25. #include <errno.h>
  26. #include "wwwoffle.h"
  27. #include "misc.h"
  28. #define BUFSIZE 64
  29. /*+ The buffer of data from each of the files. +*/
  30. static char **fdbuf=NULL;
  31. /*+ The number of bytes of data buffered for each file. +*/
  32. static int *fdbytes=NULL;
  33. /*+ The number of file buffers allocated. +*/
  34. static int nfdbuf=0;
  35. static int read_into_buffer(int fd);
  36. static int read_into_buffer_with_timeout(int fd,int timeout);
  37. static int read_from_buffer(int fd,char *buffer,int n);
  38. /*++++++++++++++++++++++++++++++++++++++
  39.   Call fgets and realloc the buffer as needed to get a whole line.
  40.   char *fgets_realloc Returns the modified buffer (NULL at the end of the file).
  41.   char *buffer The current buffer.
  42.   FILE *file The file to read from.
  43.   ++++++++++++++++++++++++++++++++++++++*/
  44. char *fgets_realloc(char *buffer,FILE *file)
  45. {
  46.  int n=0;
  47.  char *buf;
  48.  if(!buffer)
  49.     buffer=(char*)malloc((BUFSIZE+1));
  50.  while((buf=fgets(&buffer[n],BUFSIZE,file)))
  51.    {
  52.     int s=strlen(buf);
  53.     n+=s;
  54.     if(buffer[n-1]=='n')
  55.        break;
  56.     else
  57.        buffer=(char*)realloc(buffer,n+(BUFSIZE+1));
  58.    }
  59.  if(!buf)
  60.    {free(buffer);buffer=NULL;}
  61.  return(buffer);
  62. }
  63. /*++++++++++++++++++++++++++++++++++++++
  64.   Initialise the buffer used for this file descriptor.
  65.   int fd The file descriptor to initialise.
  66.   ++++++++++++++++++++++++++++++++++++++*/
  67. void init_buffer(int fd)
  68. {
  69.  if(fd==-1)
  70.     return;
  71.  if(fd>=nfdbuf)
  72.    {
  73.     fdbuf=(char**)realloc((void*)fdbuf,(fd+1)*sizeof(char**));
  74.     fdbytes=(int*)realloc((void*)fdbytes,(fd+1)*sizeof(int));
  75.     for(;nfdbuf<=fd;nfdbuf++)
  76.       {
  77.        fdbuf[nfdbuf]=NULL;
  78.        fdbytes[nfdbuf]=0;
  79.       }
  80.    }
  81.  if(!fdbuf[fd])
  82.     fdbuf[fd]=(char*)malloc(BUFSIZE);
  83.  fdbytes[fd]=0;
  84. }
  85. /*++++++++++++++++++++++++++++++++++++++
  86.   Read all of the data from the file descriptor and dump it.
  87.   int empty_buffer Returns the amount that was read.
  88.   int fd The file descriptor to read from.
  89.   ++++++++++++++++++++++++++++++++++++++*/
  90. int empty_buffer(int fd)
  91. {
  92.  int nr=fdbytes[fd];
  93.  while(1)
  94.    {
  95.     int n;
  96.     fd_set readfd;
  97.     struct timeval tv;
  98.     FD_ZERO(&readfd);
  99.     FD_SET(fd,&readfd);
  100.     tv.tv_sec=tv.tv_usec=0;
  101.     if(select(fd+1,&readfd,NULL,NULL,&tv)<=0)
  102.        return(nr);
  103.     n=read(fd,fdbuf[fd],BUFSIZE);
  104.     if(n>0)
  105.        nr+=n;
  106.     else
  107.        return(nr);
  108.    }
  109.  return(nr);
  110. }
  111. /*++++++++++++++++++++++++++++++++++++++
  112.   Read data from a file descriptor.
  113.   int read_data Returns the number of bytes read or 0 for end of file.
  114.   int fd The file descriptor.
  115.   char *buffer The buffer to put the data into.
  116.   int n The number of bytes read.
  117.   ++++++++++++++++++++++++++++++++++++++*/
  118. int read_data(int fd,char *buffer,int n)
  119. {
  120.  int nr;
  121.  if(fdbytes[fd])
  122.     nr=read_from_buffer(fd,buffer,n);
  123.  else
  124.     nr=read(fd,buffer,n);
  125.  return(nr);
  126. }
  127. /*++++++++++++++++++++++++++++++++++++++
  128.   Read data from a file descriptor, with a timeout.
  129.   int read_or_timeout Returns the number of bytes read or -1 for a timeout.
  130.   int fd The file descriptor.
  131.   char *buffer The buffer to put the data into.
  132.   int n The number of bytes read.
  133.   int timeout The time in seconds to wait for the data.
  134.   ++++++++++++++++++++++++++++++++++++++*/
  135. int read_data_or_timeout(int fd,char *buffer,int n,int timeout)
  136. {
  137.  int nr;
  138.  if(fdbytes[fd])
  139.     nr=read_from_buffer(fd,buffer,n);
  140.  else
  141.    {
  142.     fd_set readfd;
  143.     struct timeval tv;
  144.     FD_ZERO(&readfd);
  145.     FD_SET(fd,&readfd);
  146.     tv.tv_sec=timeout;
  147.     tv.tv_usec=0;
  148.     if(select(fd+1,&readfd,NULL,NULL,&tv)<=0)
  149.        return(-1);
  150.     nr=read(fd,buffer,n);
  151.    }
  152.  return(nr);
  153. }
  154. /*++++++++++++++++++++++++++++++++++++++
  155.   Read a single line of data from a file descriptor.
  156.   char *read_line Returns the modified string or NULL for the end of file.
  157.   int fd The file descriptor.
  158.   char *line The previously allocated line of data.
  159.   This is a replacement for the previous fgets_realloc() function with file descriptors instead of stdio.
  160.   ++++++++++++++++++++++++++++++++++++++*/
  161. char *read_line(int fd,char *line)
  162. {
  163.  int found=0,eof=0;
  164.  int n=0;
  165.  if(!line)
  166.     line=(char*)malloc((BUFSIZE+1));
  167.  do
  168.    {
  169.     int i;
  170.     if(!fdbytes[fd])
  171.        if(read_into_buffer(fd)<=0)
  172.          {eof=1;break;}
  173.     for(i=0;i<fdbytes[fd];i++)
  174.        if(fdbuf[fd][i]=='n')
  175.          {
  176.           found=1;
  177.           n+=read_from_buffer(fd,&line[n],i+1);
  178.           line[n]=0;
  179.           break;
  180.          }
  181.     if(!found)
  182.       {
  183.        n+=read_from_buffer(fd,&line[n],BUFSIZE);
  184.        line=(char*)realloc((void*)line,n+(BUFSIZE+1));
  185.       }
  186.    }
  187.  while(!found && !eof);
  188.  if(eof)
  189.    {free(line);line=NULL;}
  190.  return(line);
  191. }
  192. /*++++++++++++++++++++++++++++++++++++++
  193.   Read a single line of data from a file descriptor with a timeout.
  194.   char *read_line Returns the modified string or NULL for the end of file or timeout.
  195.   int fd The file descriptor.
  196.   char *line The previously allocated line of data.
  197.   int timeout The time in seconds to wait for the data.
  198.   This is a replacement for the previous fgets_realloc() function with file descriptors instead of stdio.
  199.   ++++++++++++++++++++++++++++++++++++++*/
  200. char *read_line_or_timeout(int fd,char *line,int timeout)
  201. {
  202.  int found=0,eof=0;
  203.  int n=0;
  204.  if(!line)
  205.     line=(char*)malloc((BUFSIZE+1));
  206.  do
  207.    {
  208.     int i;
  209.     if(!fdbytes[fd])
  210.        if(read_into_buffer_with_timeout(fd,timeout)<=0)
  211.          {eof=1;break;}
  212.     for(i=0;i<fdbytes[fd];i++)
  213.        if(fdbuf[fd][i]=='n')
  214.          {
  215.           found=1;
  216.           n+=read_from_buffer(fd,&line[n],i+1);
  217.           line[n]=0;
  218.           break;
  219.          }
  220.     if(!found)
  221.       {
  222.        n+=read_from_buffer(fd,&line[n],BUFSIZE);
  223.        line=(char*)realloc((void*)line,n+(BUFSIZE+1));
  224.       }
  225.    }
  226.  while(!found && !eof);
  227.  if(eof)
  228.    {free(line);line=NULL;}
  229.  return(line);
  230. }
  231. /*++++++++++++++++++++++++++++++++++++++
  232.   Read some data from a file descriptor and buffer it.
  233.   int read_and_buffer Returns the number of bytes read.
  234.   int fd The file descriptor to read from.
  235.   ++++++++++++++++++++++++++++++++++++++*/
  236. static int read_into_buffer(int fd)
  237. {
  238.  int n;
  239.  n=read(fd,fdbuf[fd]+fdbytes[fd],BUFSIZE-fdbytes[fd]);
  240.  fdbytes[fd]+=n;
  241.  return(n);
  242. }
  243. /*++++++++++++++++++++++++++++++++++++++
  244.   Read some data from a file descriptor and buffer it with a timeout.
  245.   int read_and_buffer Returns the number of bytes read.
  246.   int fd The file descriptor to read from.
  247.   int timeout The time in seconds to wait for the data.
  248.   ++++++++++++++++++++++++++++++++++++++*/
  249. static int read_into_buffer_with_timeout(int fd,int timeout)
  250. {
  251.  int n;
  252.  fd_set readfd;
  253.  struct timeval tv;
  254.  FD_ZERO(&readfd);
  255.  FD_SET(fd,&readfd);
  256.  tv.tv_sec=timeout;
  257.  tv.tv_usec=0;
  258.  if(select(fd+1,&readfd,NULL,NULL,&tv)<=0)
  259.     return(-1);
  260.  n=read(fd,fdbuf[fd]+fdbytes[fd],BUFSIZE-fdbytes[fd]);
  261.  fdbytes[fd]+=n;
  262.  return(n);
  263. }
  264. /*++++++++++++++++++++++++++++++++++++++
  265.   Read some data from the buffer.
  266.   int read_from_buffer Returns the number of bytes read.
  267.   int fd The file descriptor buffer to read from.
  268.   char *buffer The buffer to copy the data into.
  269.   int n The maximum number of bytes to read.
  270.   ++++++++++++++++++++++++++++++++++++++*/
  271. static int read_from_buffer(int fd,char *buffer,int n)
  272. {
  273.  if(n>=fdbytes[fd])
  274.    {
  275.     memcpy(buffer,fdbuf[fd],fdbytes[fd]);
  276.     n=fdbytes[fd];
  277.     fdbytes[fd]=0;
  278.    }
  279.  else
  280.    {
  281.     memcpy(buffer,fdbuf[fd],n);
  282.     fdbytes[fd]-=n;
  283.     memmove(fdbuf[fd],fdbuf[fd]+n,fdbytes[fd]);
  284.    }
  285.  return(n);
  286. }
  287. /*++++++++++++++++++++++++++++++++++++++
  288.   A function to write binary data to a file descriptor instead of write().
  289.   int write_data Returns the number of bytes written.
  290.   int fd The file descriptor.
  291.   const char *data The data.
  292.   int n The number of bytes of data.
  293.   ++++++++++++++++++++++++++++++++++++++*/
  294. int write_data(int fd,const char *data,int n)
  295. {
  296.  n=write(fd,data,n);
  297.  return(n);
  298. }
  299. /*++++++++++++++++++++++++++++++++++++++
  300.   A function to write a simple string to a file descriptor like fputs does to a FILE*.
  301.   int write_string Returns the number of bytes written.
  302.   int fd The file descriptor.
  303.   const char *str The string.
  304.   ++++++++++++++++++++++++++++++++++++++*/
  305. int write_string(int fd,const char *str)
  306. {
  307.  int n=strlen(str);
  308.  n=write(fd,str,n);
  309.  return(n);
  310. }
  311. /*++++++++++++++++++++++++++++++++++++++
  312.   A function to write a formatted string to a file descriptor like fprintf does to a FILE*.
  313.   int write_formatted Returns the number of bytes written.
  314.   int fd The file descriptor.
  315.   const char *fmt The format string.
  316.   ... The other arguments.
  317.   ++++++++++++++++++++++++++++++++++++++*/
  318. int write_formatted(int fd,const char *fmt,...)
  319. {
  320.  int i,n,width;
  321.  char *str,*strp;
  322.  va_list ap;
  323.  /* Estimate the length of the string. */
  324. #ifdef __STDC__
  325.  va_start(ap,fmt);
  326. #else
  327.  va_start(ap);
  328. #endif
  329.  n=strlen(fmt);
  330.  for(i=0;fmt[i];i++)
  331.     if(fmt[i]=='%')
  332.       {
  333.        i++;
  334.        if(fmt[i]=='%')
  335.           continue;
  336.        width=atoi(fmt+i);
  337.        if(width<0)
  338.           width=-width;
  339.        while(!isalpha(fmt[i]))
  340.           i++;
  341.        switch(fmt[i])
  342.          {
  343.          case 's':
  344.           strp=va_arg(ap,char*);
  345.           if(width && width>strlen(strp))
  346.              n+=width;
  347.           else
  348.              n+=strlen(strp);
  349.           break;
  350.          default:
  351.           (void)va_arg(ap,void*);
  352.           if(width && width>16)
  353.              n+=width;
  354.           else
  355.              n+=16;
  356.          }
  357.       }
  358.  va_end(ap);
  359.  /* Allocate the string and vsprintf into it. */
  360.  str=(char*)malloc(n);
  361. #ifdef __STDC__
  362.  va_start(ap,fmt);
  363. #else
  364.  va_start(ap);
  365. #endif
  366.  n=vsprintf(str,fmt,ap);
  367.  va_end(ap);
  368.  /* Write the string. */
  369.  n=write(fd,str,n);
  370.  free(str);
  371.  return(n);
  372. }