sffilbuf.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  6. * These libraries and programs are free software; you can
  7. * redistribute them and/or modify them under the terms of the GNU
  8. * Lesser General Public License as published by the Free Software
  9. * Foundation; either version 2 of the License, or (at your option)
  10. * any later version.
  11. *
  12. * These libraries and programs are distributed in the hope that
  13. * they will be useful, but WITHOUT ANY WARRANTY; without even the
  14. * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  15. * PURPOSE. See the GNU Lesser General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with these libraries and programs; if not, write
  20. * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
  21. * Floor, Boston, MA 02110-1301 USA
  22. */
  23. /* $XConsortium: sffilbuf.c /main/3 1995/11/01 18:29:01 rswiston $ */
  24. /***************************************************************
  25. * *
  26. * AT&T - PROPRIETARY *
  27. * *
  28. * THIS IS PROPRIETARY SOURCE CODE LICENSED BY *
  29. * AT&T CORP. *
  30. * *
  31. * Copyright (c) 1995 AT&T Corp. *
  32. * All Rights Reserved *
  33. * *
  34. * This software is licensed by AT&T Corp. *
  35. * under the terms and conditions of the license in *
  36. * http://www.research.att.com/orgs/ssr/book/reuse *
  37. * *
  38. * This software was created by the *
  39. * Software Engineering Research Department *
  40. * AT&T Bell Laboratories *
  41. * *
  42. * For further information contact *
  43. * gsf@research.att.com *
  44. * *
  45. ***************************************************************/
  46. #include "sfhdr.h"
  47. /* Fill the buffer of a stream with data.
  48. ** If n < 0, sffilbuf() attempts to fill the buffer if it's empty.
  49. ** If n == 0, if the buffer is not empty, just return the first byte;
  50. ** otherwise fill the buffer and return the first byte.
  51. ** If n > 0, even if the buffer is not empty, try a read to get as
  52. ** close to n as possible. n is reset to -1 if stack pops.
  53. **
  54. ** Written by Kiem-Phong Vo (06/27/90)
  55. */
  56. #if __STD_C
  57. int _sffilbuf(reg Sfio_t* f, reg int n)
  58. #else
  59. _sffilbuf(f,n)
  60. reg Sfio_t *f; /* fill the read buffer of this stream */
  61. reg int n; /* see above */
  62. #endif
  63. {
  64. reg int r, local, rcrv, rc;
  65. GETLOCAL(f,local);
  66. /* any peek data must be preserved across stacked streams */
  67. rcrv = f->mode&(SF_RC|SF_RV|SF_LOCK);
  68. rc = f->getr;
  69. for(;; f->mode &= ~SF_LOCK)
  70. { /* check mode */
  71. if(SFMODE(f,local) != SF_READ && _sfmode(f,SF_READ,local) < 0)
  72. return -1;
  73. SFLOCK(f,local);
  74. /* current extent of available data */
  75. if((r = f->endb-f->next) > 0)
  76. { if(n <= 0 || (f->flags&SF_STRING))
  77. break;
  78. /* shift left to make room for new data */
  79. if(!(f->flags&SF_MMAP) && n > (f->size - (f->endb-f->data)) )
  80. { memcpy((char*)f->data,(char*)f->next,r);
  81. f->endb = (f->next = f->data)+r;
  82. }
  83. }
  84. else if(!(f->flags&(SF_STRING|SF_MMAP)) )
  85. f->next = f->endb = f->endr = f->data;
  86. if(f->flags&SF_MMAP)
  87. r = n > 0 ? n : f->size;
  88. else if(!(f->flags&SF_STRING) )
  89. { /* make sure we read no more than required */
  90. r = f->size - (f->endb - f->data);
  91. if(n > 0 && r > n && f->extent < 0 && (f->flags&SF_SHARE))
  92. r = n;
  93. }
  94. /* SFRD takes care of discipline read and stack popping */
  95. f->mode |= rcrv;
  96. f->getr = rc;
  97. if((r = SFRD(f,f->endb,r,f->disc)) >= 0)
  98. { r = f->endb - f->next;
  99. break;
  100. }
  101. }
  102. SFOPEN(f,local);
  103. return (n == 0) ? (r > 0 ? (int)(*f->next++) : EOF) : r;
  104. }