- rename log functions to stop conflicts under win32 (wingdi)
[fw/openocd] / src / helper / fileio.c
1 /***************************************************************************
2  *   Copyright (C) 2007 by Dominic Rath                                    *
3  *   Dominic.Rath@gmx.de                                                   *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) any later version.                                   *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19  ***************************************************************************/
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "types.h"
25 #include "replacements.h"
26 #include "log.h"
27 #include "configuration.h"
28
29 #include "fileio.h"
30
31 #include <stdio.h>
32 #include <string.h>
33 #include <unistd.h>
34 #include <stdlib.h>
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include <errno.h>
38 #include <ctype.h>
39
40 int fileio_close(fileio_t *fileio);
41 int fileio_dispatch_read(fileio_t *fileio, u32 size, u8 *buffer, u32 *size_read);
42
43 int fileio_open_local(fileio_t *fileio)
44 {
45         char access[4];
46         
47         switch (fileio->access)
48         {
49                 case FILEIO_READ:
50                         strcpy(access, "r");
51                         break;
52                 case FILEIO_WRITE:
53                         strcpy(access, "w");
54                         break;
55                 case FILEIO_READWRITE:
56                         strcpy(access, "w+");
57                         break;
58                 case FILEIO_APPEND:
59                         strcpy(access, "a");    
60                         break;
61                 case FILEIO_APPENDREAD:
62                         strcpy(access, "a+");   
63                         break;
64                 default:
65                         LOG_ERROR("BUG: access neither read, write nor readwrite");
66                         return ERROR_INVALID_ARGUMENTS;
67         }
68         
69         /* win32 always opens in binary mode */
70 #ifndef _WIN32
71         if (fileio->type == FILEIO_BINARY)
72 #endif
73         {
74                 strcat(access, "b");
75         }
76         
77         if (!(fileio->file = open_file_from_path (fileio->url, access)))
78         {
79                 LOG_ERROR("couldn't open %s", fileio->url);
80                 return ERROR_FILEIO_OPERATION_FAILED;
81         }
82         
83         if ((fileio->access != FILEIO_WRITE) || (fileio->access == FILEIO_READWRITE))
84         {
85                 /* NB! Here we use fseek() instead of stat(), since stat is a
86                  * more advanced operation that might not apply to e.g. a disk path
87                  * that refers to e.g. a tftp client */
88                 int result, result2;
89                 
90                 result = fseek(fileio->file, 0, SEEK_END);
91
92                 fileio->size = ftell(fileio->file);
93                 
94                 result2 = fseek(fileio->file, 0, SEEK_SET); 
95                         
96                 if ((fileio->size<0)||(result<0)||(result2<0))
97                 {
98                         fileio_close(fileio);
99                         return ERROR_FILEIO_OPERATION_FAILED;
100                 }
101         }
102         else
103         {
104                 fileio->size = 0x0;
105         }
106         
107         return ERROR_OK;
108 }
109
110 int fileio_open(fileio_t *fileio, char *url, enum fileio_access access, enum fileio_type type)
111 {
112         int retval = ERROR_OK;
113
114         fileio->type = type;
115         fileio->access = access;
116         fileio->url = strdup(url);
117         
118         retval = fileio_open_local(fileio);
119
120         return retval;
121 }
122
123 int fileio_close_local(fileio_t *fileio)
124 {
125         int retval;
126         if ((retval = fclose(fileio->file)) != 0)
127         {
128                 if (retval == EBADF)
129                 {
130                         LOG_ERROR("BUG: fileio_local->file not a valid file descriptor");
131                 }
132                 else
133                 {
134                         LOG_ERROR("couldn't close %s: %s", fileio->url, strerror(errno));
135                 }
136
137                 return ERROR_FILEIO_OPERATION_FAILED;
138         }
139         
140         return ERROR_OK;
141 }
142
143 int fileio_close(fileio_t *fileio)
144 {
145         int retval;
146         
147         retval = fileio_close_local(fileio);
148         
149         free(fileio->url);
150         fileio->url = NULL;
151         
152         return retval;
153 }
154
155 int fileio_seek(fileio_t *fileio, u32 position)
156 {
157         int retval;
158         if ((retval = fseek(fileio->file, position, SEEK_SET)) != 0)
159         {
160                 LOG_ERROR("couldn't seek file %s: %s", fileio->url, strerror(errno));
161                 return ERROR_FILEIO_OPERATION_FAILED;
162         }
163         
164         return ERROR_OK;
165 }
166
167 int fileio_local_read(fileio_t *fileio, u32 size, u8 *buffer, u32 *size_read)
168 {
169         *size_read = fread(buffer, 1, size, fileio->file);
170         
171         return ERROR_OK;
172 }
173
174 int fileio_read(fileio_t *fileio, u32 size, u8 *buffer, u32 *size_read)
175 {
176         return fileio_local_read(fileio, size, buffer, size_read);
177 }
178
179 int fileio_read_u32(fileio_t *fileio, u32 *data)
180 {
181         u8 buf[4];
182         u32 size_read;
183         int retval;
184         
185         if ((retval = fileio_local_read(fileio, 4, buf, &size_read)) != ERROR_OK)
186                 return retval;
187         *data = be_to_h_u32(buf);
188         
189         return ERROR_OK;
190 }
191
192 int fileio_local_fgets(fileio_t *fileio, u32 size, char *buffer)
193 {
194         if( fgets(buffer, size, fileio->file) == NULL)
195                 return ERROR_FILEIO_OPERATION_FAILED;
196         
197         return ERROR_OK;
198 }
199
200 int fileio_fgets(fileio_t *fileio, u32 size, char *buffer)
201 {
202         return fileio_local_fgets(fileio, size, buffer);
203 }
204
205 int fileio_local_write(fileio_t *fileio, u32 size, u8 *buffer, u32 *size_written)
206 {
207         *size_written = fwrite(buffer, 1, size, fileio->file);
208         
209         return ERROR_OK;
210 }
211
212 int fileio_write(fileio_t *fileio, u32 size, u8 *buffer, u32 *size_written)
213 {
214         int retval;
215         
216         retval = fileio_local_write(fileio, size, buffer, size_written);
217         
218         if (retval == ERROR_OK)
219                 fileio->size += *size_written;
220         
221         return retval;;
222 }
223
224 int fileio_write_u32(fileio_t *fileio, u32 data)
225 {
226         u8 buf[4];
227         u32 size_written;
228         int retval;
229         
230         h_u32_to_be(buf, data);
231         
232         if ((retval = fileio_local_write(fileio, 4, buf, &size_written)) != ERROR_OK)
233                 return retval;
234         
235         return ERROR_OK;
236 }