PageRenderTime 60ms CodeModel.GetById 35ms RepoModel.GetById 0ms app.codeStats 0ms

/Source/DOH/file.c

https://github.com/sunaku/swig-ruby-ffi
C | 299 lines | 200 code | 35 blank | 64 comment | 34 complexity | 3fdbd9d81b209ea1f0a5d9286436b155 MD5 | raw file
Possible License(s): 0BSD, GPL-2.0, LGPL-2.1
  1. /* -----------------------------------------------------------------------------
  2. * file.c
  3. *
  4. * This file implements a file-like object that can be built around an
  5. * ordinary FILE * or integer file descriptor.
  6. *
  7. * Author(s) : David Beazley (beazley@cs.uchicago.edu)
  8. *
  9. * Copyright (C) 1999-2000. The University of Chicago
  10. * See the file LICENSE for information on usage and redistribution.
  11. * ----------------------------------------------------------------------------- */
  12. char cvsroot_file_c[] = "$Id$";
  13. #include "dohint.h"
  14. #ifdef DOH_INTFILE
  15. #include <unistd.h>
  16. #endif
  17. #include <errno.h>
  18. typedef struct {
  19. FILE *filep;
  20. int fd;
  21. int closeondel;
  22. } DohFile;
  23. /* -----------------------------------------------------------------------------
  24. * DelFile()
  25. * ----------------------------------------------------------------------------- */
  26. static void DelFile(DOH *fo) {
  27. DohFile *f = (DohFile *) ObjData(fo);
  28. if (f->closeondel) {
  29. if (f->filep) {
  30. fclose(f->filep);
  31. }
  32. #ifdef DOH_INTFILE
  33. if (f->fd) {
  34. close(f->fd);
  35. }
  36. #endif
  37. }
  38. DohFree(f);
  39. }
  40. /* -----------------------------------------------------------------------------
  41. * File_read()
  42. * ----------------------------------------------------------------------------- */
  43. static int File_read(DOH *fo, void *buffer, int len) {
  44. DohFile *f = (DohFile *) ObjData(fo);
  45. if (f->filep) {
  46. return fread(buffer, 1, len, f->filep);
  47. } else if (f->fd) {
  48. #ifdef DOH_INTFILE
  49. return read(f->fd, buffer, len);
  50. #endif
  51. }
  52. return -1;
  53. }
  54. /* -----------------------------------------------------------------------------
  55. * File_write()
  56. * ----------------------------------------------------------------------------- */
  57. static int File_write(DOH *fo, void *buffer, int len) {
  58. DohFile *f = (DohFile *) ObjData(fo);
  59. if (f->filep) {
  60. int ret = (int) fwrite(buffer, 1, len, f->filep);
  61. int err = (ret != len) ? ferror(f->filep) : 0;
  62. return err ? -1 : ret;
  63. } else if (f->fd) {
  64. #ifdef DOH_INTFILE
  65. return write(f->fd, buffer, len);
  66. #endif
  67. }
  68. return -1;
  69. }
  70. /* -----------------------------------------------------------------------------
  71. * File_seek()
  72. * ----------------------------------------------------------------------------- */
  73. static int File_seek(DOH *fo, long offset, int whence) {
  74. DohFile *f = (DohFile *) ObjData(fo);
  75. if (f->filep) {
  76. return fseek(f->filep, offset, whence);
  77. } else if (f->fd) {
  78. #ifdef DOH_INTFILE
  79. return lseek(f->fd, offset, whence);
  80. #endif
  81. }
  82. return -1;
  83. }
  84. /* -----------------------------------------------------------------------------
  85. * File_tell()
  86. * ----------------------------------------------------------------------------- */
  87. static long File_tell(DOH *fo) {
  88. DohFile *f = (DohFile *) ObjData(fo);
  89. if (f->filep) {
  90. return ftell(f->filep);
  91. } else if (f->fd) {
  92. #ifdef DOH_INTFILE
  93. return lseek(f->fd, 0, SEEK_CUR);
  94. #endif
  95. }
  96. return -1;
  97. }
  98. /* -----------------------------------------------------------------------------
  99. * File_putc()
  100. * ----------------------------------------------------------------------------- */
  101. static int File_putc(DOH *fo, int ch) {
  102. DohFile *f = (DohFile *) ObjData(fo);
  103. if (f->filep) {
  104. return fputc(ch, f->filep);
  105. } else if (f->fd) {
  106. #ifdef DOH_INTFILE
  107. char c;
  108. c = (char) ch;
  109. return write(f->fd, &c, 1);
  110. #endif
  111. }
  112. return -1;
  113. }
  114. /* -----------------------------------------------------------------------------
  115. * File_getc()
  116. * ----------------------------------------------------------------------------- */
  117. static int File_getc(DOH *fo) {
  118. DohFile *f = (DohFile *) ObjData(fo);
  119. if (f->filep) {
  120. return fgetc(f->filep);
  121. } else if (f->fd) {
  122. #ifdef DOH_INTFILE
  123. unsigned char c;
  124. if (read(f->fd, &c, 1) < 0)
  125. return EOF;
  126. return c;
  127. #endif
  128. }
  129. return EOF;
  130. }
  131. /* -----------------------------------------------------------------------------
  132. * File_ungetc()
  133. *
  134. * Put a character back onto the input
  135. * ----------------------------------------------------------------------------- */
  136. static int File_ungetc(DOH *fo, int ch) {
  137. DohFile *f = (DohFile *) ObjData(fo);
  138. if (f->filep) {
  139. return ungetc(ch, f->filep);
  140. } else if (f->fd) {
  141. #ifdef DOH_INTFILE
  142. /* Not implemented yet */
  143. #endif
  144. }
  145. return -1;
  146. }
  147. /* -----------------------------------------------------------------------------
  148. * File_close()
  149. *
  150. * Close the file
  151. * ----------------------------------------------------------------------------- */
  152. static int File_close(DOH *fo) {
  153. int ret = 0;
  154. DohFile *f = (DohFile *) ObjData(fo);
  155. if (f->filep) {
  156. ret = fclose(f->filep);
  157. f->filep = 0;
  158. } else if (f->fd) {
  159. #ifdef DOH_INTFILE
  160. ret = close(f->fd);
  161. f->fd = 0;
  162. #endif
  163. }
  164. return ret;
  165. }
  166. static DohFileMethods FileFileMethods = {
  167. File_read,
  168. File_write,
  169. File_putc,
  170. File_getc,
  171. File_ungetc,
  172. File_seek,
  173. File_tell,
  174. File_close, /* close */
  175. };
  176. static DohObjInfo DohFileType = {
  177. "DohFile", /* objname */
  178. DelFile, /* doh_del */
  179. 0, /* doh_copy */
  180. 0, /* doh_clear */
  181. 0, /* doh_str */
  182. 0, /* doh_data */
  183. 0, /* doh_dump */
  184. 0, /* doh_len */
  185. 0, /* doh_hash */
  186. 0, /* doh_cmp */
  187. 0, /* doh_equal */
  188. 0, /* doh_first */
  189. 0, /* doh_next */
  190. 0, /* doh_setfile */
  191. 0, /* doh_getfile */
  192. 0, /* doh_setline */
  193. 0, /* doh_getline */
  194. 0, /* doh_mapping */
  195. 0, /* doh_sequence */
  196. &FileFileMethods, /* doh_file */
  197. 0, /* doh_string */
  198. 0, /* doh_callable */
  199. 0, /* doh_position */
  200. };
  201. /* -----------------------------------------------------------------------------
  202. * NewFile()
  203. *
  204. * Create a new file from a given filename and mode.
  205. * If newfiles is non-zero, the filename is added to the list of new files.
  206. * ----------------------------------------------------------------------------- */
  207. DOH *DohNewFile(DOH *filename, const char *mode, DOHList *newfiles) {
  208. DohFile *f;
  209. FILE *file;
  210. char *filen;
  211. filen = Char(filename);
  212. file = fopen(filen, mode);
  213. if (!file)
  214. return 0;
  215. f = (DohFile *) DohMalloc(sizeof(DohFile));
  216. if (!f) {
  217. fclose(file);
  218. return 0;
  219. }
  220. if (newfiles)
  221. Append(newfiles, filename);
  222. f->filep = file;
  223. f->fd = 0;
  224. f->closeondel = 1;
  225. return DohObjMalloc(&DohFileType, f);
  226. }
  227. /* -----------------------------------------------------------------------------
  228. * NewFileFromFile()
  229. *
  230. * Create a file object from an already open FILE *.
  231. * ----------------------------------------------------------------------------- */
  232. DOH *DohNewFileFromFile(FILE *file) {
  233. DohFile *f;
  234. f = (DohFile *) DohMalloc(sizeof(DohFile));
  235. if (!f)
  236. return 0;
  237. f->filep = file;
  238. f->fd = 0;
  239. f->closeondel = 0;
  240. return DohObjMalloc(&DohFileType, f);
  241. }
  242. /* -----------------------------------------------------------------------------
  243. * NewFileFromFd()
  244. *
  245. * Create a file object from an already open FILE *.
  246. * ----------------------------------------------------------------------------- */
  247. DOH *DohNewFileFromFd(int fd) {
  248. DohFile *f;
  249. f = (DohFile *) DohMalloc(sizeof(DohFile));
  250. if (!f)
  251. return 0;
  252. f->filep = 0;
  253. f->fd = fd;
  254. f->closeondel = 0;
  255. return DohObjMalloc(&DohFileType, f);
  256. }
  257. /* -----------------------------------------------------------------------------
  258. * FileErrorDisplay()
  259. *
  260. * Display cause of one of the NewFile functions failing.
  261. * ----------------------------------------------------------------------------- */
  262. void DohFileErrorDisplay(DOHString * filename) {
  263. Printf(stderr, "Unable to open file %s: %s\n", filename, strerror(errno));
  264. }