"Fossies" - the Fresh Open Source Software Archive 
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
1 /* Copyright (C) 2000-2004 Ghostgum Software Pty Ltd. All rights reserved.
2
3 This software is provided AS-IS with no warranty, either express or
4 implied.
5
6 This software is distributed under licence and may not be copied,
7 modified or distributed except as expressly authorised under the terms
8 of the licence contained in the file LICENCE in this distribution.
9
10 For more information about licensing, please refer to
11 http://www.ghostgum.com.au/ or contact Ghostsgum Software Pty Ltd,
12 218 Gallaghers Rd, Glen Waverley VIC 3150, AUSTRALIA,
13 Fax +61 3 9886 6616.
14 */
15
16 /* $Id: clfile.c,v 1.5 2004/01/16 08:55:37 ghostgum Exp $ */
17
18 /* GFile is similar but not identical to MFC CFile, but is plain C. */
19 /* This implementation uses OS handles, and allows large files.
20 * The large file implementation is for Linux and is not portable.
21 * Use cfile.c if you need portability.
22 */
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <fcntl.h>
30 #ifndef __WIN32__
31 #include <unistd.h>
32 #include <linux/unistd.h>
33 #endif
34 #include "cfile.h"
35
36 int _llseek(unsigned int fd, unsigned long offset_high,
37 unsigned long offset_low, loff_t *result, unsigned int whence);
38 _syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo,
39 loff_t *, res, uint, wh);
40
41 /* These are the private bits */
42 struct GFile_s {
43 int m_fd;
44 time_t m_filetime; /* time/date of selected file */
45 FILE_POS m_length; /* length of selected file */
46 int m_error; /* non-zero if an error */
47 /* error cleared by open, close or seek to 0 */
48 };
49
50 #ifndef ASSERT
51 #ifdef DEBUG
52 static void gfile_assert(const char *file, int line);
53 #define ASSERT(f) if (!(f)) gfile_assert(__FILE__, __LINE__)
54 #else
55 #define ASSERT(f)
56 #endif
57 #endif
58
59 #ifdef DEBUG
60 void gfile_assert(const char *file, int line)
61 {
62 g_print("gfile_assert: file:%s line:%d\n", file, line);
63 }
64 #endif
65
66 int
67 gfile_error(GFile *gf)
68 {
69 ASSERT(gf != NULL);
70 ASSERT(gf->m_fd != 0);
71 return gf->m_error;
72 }
73
74 FILE_POS gfile_get_length(GFile *gf)
75 {
76 loff_t length = 0;
77 loff_t result = 0;
78 unsigned long offset_high;
79 unsigned long offset_low;
80 const int shift = sizeof(unsigned long) * 8;
81 const unsigned long mask = (unsigned long)-1;
82 /* Get the current position */
83 _llseek(gf->m_fd, 0, 0, &result, SEEK_CUR);
84 if (sizeof(FILE_OFFSET) > sizeof(unsigned long)) {
85 offset_high = (result >> shift) & mask;
86 offset_low = result & mask;
87 }
88 else {
89 offset_high = 0;
90 offset_low = result;
91 }
92 /* Seek to the end to get the length */
93 _llseek(gf->m_fd, 0, 0, &length, SEEK_END);
94 /* Seek back to where we were before */
95 _llseek(gf->m_fd, offset_high, offset_low, &result, SEEK_SET);
96 return length;
97 }
98
99 int gfile_get_datetime(GFile *gf, unsigned long *pdt_low,
100 unsigned long *pdt_high)
101 {
102 struct stat fstatus;
103 ASSERT(gf != NULL);
104 fstat(gf->m_fd, &fstatus);
105 *pdt_low = fstatus.st_mtime;
106 *pdt_high = 0;
107 return 1;
108 }
109
110 int gfile_changed(GFile *gf, FILE_POS length,
111 unsigned long dt_low, unsigned long dt_high)
112 {
113 unsigned long this_dt_low, this_dt_high;
114 FILE_POS this_length = gfile_get_length(gf);
115 gfile_get_datetime(gf, &this_dt_low, &this_dt_high);
116 return ( (this_length != length) ||
117 (this_dt_low != dt_low) || (this_dt_high != dt_high));
118 }
119
120 GFile *gfile_open_handle(int hFile, unsigned int nOpenFlags)
121 {
122 /* nOpenFlags ignored */
123 GFile *gf = (GFile *)malloc(sizeof(GFile));
124 if (gf == NULL)
125 return NULL;
126 memset(gf, 0, sizeof(GFile));
127 gf->m_fd = hFile;
128 gf->m_error = 0;
129 return gf;
130 }
131
132 GFile *gfile_open(LPCTSTR lpszFileName, unsigned int nOpenFlags)
133 {
134 GFile *gf;
135 int fd;
136 int flags = O_RDONLY;
137 if ((nOpenFlags & 0xf) == gfile_modeWrite)
138 flags = O_WRONLY;
139 if ((nOpenFlags & 0xf000) == gfile_modeCreate)
140 flags |= O_CREAT | O_TRUNC;
141
142 if (lpszFileName[0] == '\0')
143 fd = 1; /* stdout */
144 else
145 fd = open(lpszFileName, flags,
146 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
147 if (fd == -1)
148 return NULL;
149
150 gf = (GFile *)malloc(sizeof(GFile));
151 if (gf == NULL) {
152 close(fd);
153 return NULL;
154 }
155 memset(gf, 0, sizeof(GFile));
156 gf->m_fd = fd;
157 gf->m_error = 0;
158 return gf;
159 }
160
161 void gfile_close(GFile *gf)
162 {
163 ASSERT(gf != NULL);
164 ASSERT(gf->m_fd != -1);
165 close(gf->m_fd);
166 gf->m_fd = -1;
167 gf->m_error = 0;
168 free(gf);
169 }
170
171
172 unsigned int gfile_read(GFile *gf, void *lpBuf, unsigned int nCount)
173 {
174 int count;
175 ASSERT(gf != NULL);
176 ASSERT(gf->m_fd != -1);
177 count = read(gf->m_fd, lpBuf, nCount);
178 if (count == -1)
179 gf->m_error = 1;
180 return (unsigned int)count;
181 }
182
183 unsigned int gfile_write(GFile *gf, const void *lpBuf, unsigned int nCount)
184 {
185 int count;
186 ASSERT(gf != NULL);
187 ASSERT(gf->m_fd != -1);
188 count = write(gf->m_fd, lpBuf, nCount);
189 if (count == -1)
190 gf->m_error = 1;
191 return (unsigned int)count;
192 }
193
194 /* only works with reading */
195 int gfile_seek(GFile *gf, FILE_OFFSET lOff, unsigned int nFrom)
196 {
197 int code;
198 unsigned int origin;
199 loff_t result = 0;
200 unsigned long offset_high;
201 unsigned long offset_low;
202 const int shift = sizeof(unsigned long) * 8;
203 const unsigned long mask = (unsigned long)-1;
204 ASSERT(gf != NULL);
205 ASSERT(gf->m_fd != -1);
206 if (sizeof(FILE_OFFSET) > sizeof(unsigned long)) {
207 offset_high = (lOff >> shift) & mask;
208 offset_low = lOff & mask;
209 }
210 else {
211 offset_high = 0;
212 offset_low = lOff;
213 }
214
215 switch(nFrom) {
216 default:
217 case gfile_begin:
218 origin = SEEK_SET;
219 break;
220 case gfile_current:
221 origin = SEEK_CUR;
222 break;
223 case gfile_end:
224 origin = SEEK_END;
225 break;
226 }
227 if ((origin == SEEK_SET) && (lOff == 0)) {
228 gf->m_error = 0;
229 }
230 code = _llseek(gf->m_fd, offset_high, offset_low, &result, origin);
231 return code;
232 }
233
234 FILE_POS gfile_get_position(GFile *gf)
235 {
236 int code;
237 loff_t result;
238 ASSERT(gf != NULL);
239 ASSERT(gf->m_fd != 0);
240 code = _llseek(gf->m_fd, 0, 0, &result, SEEK_CUR);
241 return result;
242 }
243
244 int gfile_puts(GFile *gf, const char *str)
245 {
246 return gfile_write(gf, str, strlen(str));
247 }