bufio.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  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. /*
  24. * $XConsortium: bufio.c /main/5 1996/11/01 10:11:35 drk $
  25. *
  26. * Copyright 1991 Massachusetts Institute of Technology
  27. *
  28. * Permission to use, copy, modify, distribute, and sell this software and its
  29. * documentation for any purpose is hereby granted without fee, provided that
  30. * the above copyright notice appear in all copies and that both that
  31. * copyright notice and this permission notice appear in supporting
  32. * documentation, and that the name of M.I.T. not be used in advertising or
  33. * publicity pertaining to distribution of the software without specific,
  34. * written prior permission. M.I.T. makes no representations about the
  35. * suitability of this software for any purpose. It is provided "as is"
  36. * without express or implied warranty.
  37. *
  38. * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  39. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
  40. * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  41. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  42. * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  43. * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  44. *
  45. * Author: Keith Packard, MIT X Consortium
  46. */
  47. /* #include "fontmisc.h" */
  48. #include <errno.h>
  49. #include <stdio.h>
  50. #include <stdlib.h>
  51. #include <stdint.h>
  52. #include <unistd.h>
  53. #include "bufioI.h"
  54. #include <X11/Xos.h>
  55. #ifdef X_NOT_STDC_ENV
  56. extern int errno;
  57. #endif
  58. #ifndef MIN
  59. #define MIN(a,b) (((a) < (b)) ? (a) : (b))
  60. #endif
  61. #define FileDes(f) ((intptr_t) (f)->hidden)
  62. #define CompressFileDes(f) (((CECompressInfoPtr) (f)->hidden)->fd)
  63. #define CompressSize(f) (((CECompressInfoPtr) (f)->hidden)->size)
  64. static int
  65. BufFileRawSkip (
  66. BufFilePtr f,
  67. int count )
  68. {
  69. int curoff;
  70. int fileoff;
  71. int todo;
  72. curoff = f->bufp - f->buffer;
  73. fileoff = curoff + f->left;
  74. if (curoff + count <= fileoff) {
  75. f->bufp += count;
  76. f->left -= count;
  77. } else {
  78. todo = count - (fileoff - curoff);
  79. if (lseek (FileDes(f), todo, 1) == -1) {
  80. if (errno != ESPIPE)
  81. return BUFFILEEOF;
  82. while (todo) {
  83. curoff = BUFFILESIZE;
  84. if (curoff > todo)
  85. curoff = todo;
  86. fileoff = read (FileDes(f), f->buffer, curoff);
  87. if (fileoff <= 0)
  88. return BUFFILEEOF;
  89. todo -= fileoff;
  90. }
  91. }
  92. f->left = 0;
  93. }
  94. return count;
  95. }
  96. static int
  97. BufFileRawFlush (
  98. int c,
  99. BufFilePtr f )
  100. {
  101. int cnt;
  102. if (c != BUFFILEEOF)
  103. *f->bufp++ = c;
  104. cnt = f->bufp - f->buffer;
  105. f->bufp = f->buffer;
  106. f->left = BUFFILESIZE;
  107. if (write (FileDes(f), f->buffer, cnt) != cnt)
  108. return BUFFILEEOF;
  109. return c;
  110. }
  111. BufFilePtr
  112. _DtHelpCeBufFileOpenWr (int fd)
  113. {
  114. BufFilePtr f;
  115. f = _DtHelpCeBufFileCreate ((char *) (intptr_t) fd, BufFileRawFlush, NULL, _DtHelpCeBufFileFlush);
  116. f->bufp = f->buffer;
  117. f->left = BUFFILESIZE;
  118. return f;
  119. }
  120. #ifdef obsolete_function
  121. _DtHelpCeBufFileWrite (
  122. BufFilePtr f,
  123. char *b,
  124. int n )
  125. {
  126. int cnt;
  127. cnt = n;
  128. while (cnt--) {
  129. if (BufFilePut (*b++, f) == BUFFILEEOF)
  130. return BUFFILEEOF;
  131. }
  132. return n;
  133. }
  134. #endif
  135. int
  136. _DtHelpCeBufFileFlush (BufFilePtr f, int doClose)
  137. {
  138. if (f->bufp != f->buffer)
  139. (*f->io) (BUFFILEEOF, f);
  140. if (doClose)
  141. return (close (FileDes(f)));
  142. return 0;
  143. }
  144. /*****************************************************************************
  145. * Private Routines
  146. *****************************************************************************/
  147. /*****************************************************************************
  148. * Routines working on a File descriptor
  149. *****************************************************************************/
  150. static int
  151. FdRawRead (BufFilePtr f)
  152. {
  153. int left;
  154. left = read (FileDes(f), f->buffer, BUFFILESIZE);
  155. if (left <= 0) {
  156. f->left = 0;
  157. return BUFFILEEOF;
  158. }
  159. f->left = left - 1;
  160. f->bufp = f->buffer + 1;
  161. return f->buffer[0];
  162. }
  163. static int
  164. FdClose (
  165. BufFilePtr f,
  166. int doClose)
  167. {
  168. if (doClose)
  169. close (FileDes (f));
  170. return 1;
  171. }
  172. /*****************************************************************************
  173. * Routines working on a Raw Compressed file
  174. *****************************************************************************/
  175. static int
  176. CompressRawRead (BufFilePtr f)
  177. {
  178. int left;
  179. left = read (CompressFileDes(f), f->buffer,
  180. MIN(CompressSize(f),BUFFILESIZE));
  181. if (left <= 0) {
  182. f->left = 0;
  183. CompressSize(f) = 0;
  184. return BUFFILEEOF;
  185. }
  186. CompressSize(f) -= left;
  187. f->left = left - 1;
  188. f->bufp = f->buffer + 1;
  189. return f->buffer[0];
  190. }
  191. static int
  192. CompressRawClose (
  193. BufFilePtr f,
  194. int doClose)
  195. {
  196. if (doClose)
  197. close (CompressFileDes (f));
  198. free(f->hidden);
  199. return 1;
  200. }
  201. /*****************************************************************************
  202. * Routines working on a Pipe
  203. *****************************************************************************/
  204. /*****************************************************************************
  205. * Function: int RdPipeStream (BufFilePtr f)
  206. *
  207. * Returns:
  208. *
  209. * Purpose:
  210. *
  211. *****************************************************************************/
  212. static int
  213. RdPipeStream (BufFilePtr f)
  214. {
  215. int left;
  216. left = fread(f->buffer, 1, BUFFILESIZE, FileStream(f));
  217. if (left <= 0)
  218. {
  219. f->left = 0;
  220. return BUFFILEEOF;
  221. }
  222. clearerr(FileStream(f));
  223. f->left = left - 1;
  224. f->bufp = f->buffer + 1;
  225. return f->buffer[0];
  226. }
  227. /*********************************************************************
  228. * Procedure: int ClosePipeStream (BufFilePtr f);
  229. *
  230. * Returns:
  231. *
  232. * Purpose:
  233. *
  234. ********************************************************************/
  235. static int
  236. ClosePipeStream (
  237. BufFilePtr f,
  238. int doClose)
  239. {
  240. if (doClose)
  241. pclose(FileStream(f));
  242. return 1;
  243. }
  244. /*****************************************************************************
  245. * Semi-Public Routines
  246. *****************************************************************************/
  247. /*****************************************************************************
  248. * Function: BufFilePtr _DtHelpCeBufFileCreate (char *hidden,
  249. * int (*io)(), int (*skip)(),
  250. * int (*close)())
  251. *
  252. * Returns: A pointer to malloc'ed memory or NULL.
  253. *
  254. * Purpose: Create a buffered i/o mechanism.
  255. *
  256. *****************************************************************************/
  257. BufFilePtr
  258. _DtHelpCeBufFileCreate (
  259. char *hidden,
  260. int (*io)(),
  261. int (*skip)(),
  262. int (*close)() )
  263. {
  264. BufFilePtr f;
  265. f = (BufFilePtr) malloc (sizeof *f);
  266. if (!f)
  267. return 0;
  268. f->hidden = hidden;
  269. f->bufp = f->buffer;
  270. f->left = 0;
  271. f->io = io;
  272. f->skip = skip;
  273. f->close = close;
  274. return f;
  275. }
  276. /*****************************************************************************
  277. * Function: BufFilePtr _DtHelpCeBufFileRdWithFd (int fd)
  278. *
  279. * Returns: A pointer to malloc'ed memory or NULL.
  280. *
  281. * Purpose: Create a buffered i/o mechanism using a file descriptor
  282. * as private data and attaching a raw read to the i/o
  283. * routine.
  284. *
  285. *****************************************************************************/
  286. BufFilePtr
  287. _DtHelpCeBufFileRdWithFd (int fd)
  288. {
  289. return _DtHelpCeBufFileCreate ((char *) (intptr_t) fd, FdRawRead, BufFileRawSkip, FdClose);
  290. }
  291. /*****************************************************************************
  292. * Function: BufFilePtr _DtHelpCeBufFileRdRawZ (CECompressInfoPtr file)
  293. *
  294. * Returns: A pointer to malloc'ed memory or NULL.
  295. *
  296. * Purpose: Create a buffered i/o mechanism using a file descriptor
  297. * as private data and attaching a raw read of compressed
  298. * data to the i/o routine.
  299. *
  300. *****************************************************************************/
  301. BufFilePtr
  302. _DtHelpCeBufFileRdRawZ (CECompressInfoPtr file)
  303. {
  304. return _DtHelpCeBufFileCreate ((char *) file, CompressRawRead, NULL,
  305. CompressRawClose);
  306. }
  307. /*****************************************************************************
  308. * Function: void _DtHelpCeBufFileClose (BufFilePtr file, int doClose)
  309. *
  310. * Returns: nothing
  311. *
  312. * Purpose: Calls the close routine associated with the pointer.
  313. * Frees the BufFile information.
  314. *
  315. *****************************************************************************/
  316. void
  317. _DtHelpCeBufFileClose (
  318. BufFilePtr f,
  319. int doClose )
  320. {
  321. (void) (*f->close) (f, doClose);
  322. free (f);
  323. }
  324. /*****************************************************************************
  325. * Function: void _DtHelpCeBufFileRd (BufFilePtr file, int doClose)
  326. *
  327. * Returns: nothing
  328. *
  329. * Purpose: Calls the close routine associated with the pointer.
  330. * Frees the BufFile information.
  331. *
  332. *****************************************************************************/
  333. int
  334. _DtHelpCeBufFileRd (
  335. BufFilePtr f,
  336. char *b,
  337. int n )
  338. {
  339. int c, cnt;
  340. cnt = n;
  341. while (cnt--) {
  342. c = BufFileGet (f);
  343. if (c == BUFFILEEOF)
  344. break;
  345. *b++ = c;
  346. }
  347. return n - cnt - 1;
  348. }
  349. /*****************************************************************************
  350. * Function: BufFilePtr _DtHelpCeCreatePipeBufFile (FILE *stream)
  351. *
  352. * Returns: A pointer to malloc'ed memory or NULL.
  353. *
  354. * Purpose: Create a buffered i/o mechanism using a pipe descriptor
  355. * as private data and attaching a raw read to the i/o
  356. * routine.
  357. *
  358. *****************************************************************************/
  359. BufFilePtr
  360. _DtHelpCeCreatePipeBufFile (FILE *stream)
  361. {
  362. return _DtHelpCeBufFileCreate ((char *) stream,
  363. RdPipeStream, NULL, ClosePipeStream);
  364. }