file.c
Go to the documentation of this file.
1 
10 #include "mcl_core/mcl_file_util.h"
11 #include "mcl_core/mcl_memory.h"
13 #include "file.h"
14 
15 const char *mcl_file_versions[MCL_FILE_VERSION_END] = { "1.0" };
16 
17 // Function to set file local path.
18 static mcl_error_t _set_file_local_path(mcl_file_t *file, const char *path);
19 
21 {
22 #if 1 == HAVE_FILE_SYSTEM_
23  mcl_error_t code = MCL_OK;
24 
25  MCL_DEBUG_ENTRY("E_MCL_FILE_VERSION version = <%d>, mcl_file_t **file = <%p>", version, file);
26 
27  // Null check.
28  MCL_ASSERT_NOT_NULL(file, code);
29 
30  // Check meta version parameter.
31  MCL_ASSERT_CODE_MESSAGE(MCL_FILE_VERSION_1_0 <= version && MCL_FILE_VERSION_END > version, MCL_INVALID_PARAMETER,
32  "Invalid meta payload version parameter.");
33 
34  // Allocate memory for file.
35  if (MCL_NULL != MCL_NEW(*file))
36  {
37  // Set base parameters for file.
38  (*file)->item_base.preamble = MCL_ITEM_PREAMBLE;
39  (*file)->item_base.type = MCL_ITEM_TYPE_FILE;
40  (*file)->item_base.version = (mcl_uint32_t) version;
41 
42  // Allocate memory for file payload.
43  MCL_NEW((*file)->payload);
44  }
45 
46  // Allocate memory for file payload.
47  if ((MCL_NULL != (*file)) && (MCL_NULL != (*file)->payload))
48  {
49  (*file)->payload->creation_date = MCL_NULL;
50  (*file)->payload->local_path = MCL_NULL;
51  (*file)->payload->remote_name = MCL_NULL;
52  (*file)->payload->size = 0;
53  (*file)->payload->type = MCL_NULL;
54  (*file)->payload->file_descriptor = MCL_NULL;
55  }
56  else
57  {
58  code = MCL_OUT_OF_MEMORY;
59  }
60 
61  if (MCL_OK != code)
62  {
63  mcl_file_destroy(file);
64  }
65 #else
67 
68  MCL_DEBUG_ENTRY("E_MCL_FILE_VERSION version = <%d>, mcl_file_t **file = <%p>", version, file);
69 #endif
70 
72  MCL_DEBUG_LEAVE("retVal = <%d>", code);
73  return code;
74 }
75 
77 {
78 #if 1 == HAVE_FILE_SYSTEM_
79  mcl_error_t code;
80 
81  MCL_DEBUG_ENTRY("mcl_file_t *file = <%p>, E_MCL_FILE_PARAMETER parameter = <%d>, const void *value = <%p>", file, parameter, value);
82 
83  // Null check.
84  MCL_ASSERT_NOT_NULL(file, code);
85  MCL_ASSERT_NOT_NULL(value, code);
86 
87  switch (parameter)
88  {
90 
91  // Set file local path.
92  code = _set_file_local_path(file, (const char *) value);
93  break;
94 
96 
97  // Set file remote name.
98  code = mcl_string_util_reset(value, &file->payload->remote_name);
99  break;
100 
102 
103  // Set file type.
104  code = mcl_string_util_reset(value, &file->payload->type);
105  break;
106 
107  default:
108  code = MCL_INVALID_PARAMETER;
109  }
110 #else
112 
113  MCL_DEBUG_ENTRY("mcl_file_t *file = <%p>, E_MCL_FILE_PARAMETER parameter = <%d>, const void *value = <%p>", file, parameter, value);
114 #endif
115 
117  MCL_DEBUG_LEAVE("retVal = <%d>", code);
118  return code;
119 }
120 
122 {
123  mcl_error_t code;
124 
125  MCL_DEBUG_ENTRY("file_t *file = <%p>", file);
126 
127 #if 1 == HAVE_FILE_SYSTEM_
128  if (MCL_NULL == file->payload->local_path)
129  {
130  code = MCL_INVALID_PARAMETER;
131  }
132  else if (MCL_NULL == file->payload->remote_name)
133  {
134  code = MCL_INVALID_PARAMETER;
135  }
136  else
137  {
138  code = MCL_OK;
139  }
140 #else
141  code = MCL_NO_FILE_SUPPORT;
142 #endif
143 
144  MCL_DEBUG_LEAVE("retVal = <%d>", code);
145  return code;
146 }
147 
149 {
150  MCL_DEBUG_ENTRY("mcl_file_t **file = <%p>", file);
151 
152 #if 1 == HAVE_FILE_SYSTEM_
153  if ((MCL_NULL != file) && (MCL_NULL != *file))
154  {
155  if (MCL_NULL != (*file)->payload)
156  {
157  MCL_FREE((*file)->payload->creation_date);
158  MCL_FREE((*file)->payload->local_path);
159  MCL_FREE((*file)->payload->remote_name);
160  MCL_FREE((*file)->payload->type);
161  (void)mcl_file_util_fclose((*file)->payload->file_descriptor);
162  MCL_FREE((*file)->payload);
163  }
164 
165  MCL_FREE(*file);
166  }
167 #endif
168 
169  MCL_DEBUG_LEAVE("retVal = void");
170 }
171 
172 static mcl_error_t _set_file_local_path(mcl_file_t *file, const char *path)
173 {
174  mcl_error_t code;
175  time_t creation_date;
176 
177  MCL_DEBUG_ENTRY("mcl_file_t *file = <%p>, const void *path = <%p>", file, path);
178 
179  // Close previous file if exists.
180  code = mcl_file_util_fclose(file->payload->file_descriptor);
181  MCL_ASSERT_OK(code);
182 
183  // Set file descriptor of previous file to null.
184  file->payload->file_descriptor = MCL_NULL;
185 
186  // Set file local path.
187  code = mcl_string_util_reset(path, &file->payload->local_path);
188 
189  // Open file.
190  if ((MCL_OK == code) && (MCL_OK != mcl_file_util_fopen((const char *) path, "rb", &file->payload->file_descriptor)))
191  {
193  }
194 
195  // Check if the file is regular.
196  if ((MCL_OK == code) && (MCL_TRUE != mcl_file_util_check_if_regular_file(file->payload->file_descriptor)))
197  {
199  }
200 
201  if (MCL_OK == code)
202  {
203  // Set file size.
204  file->payload->size = mcl_file_util_get_file_size(file->payload->file_descriptor);
205 
206  // Get file creation date.
207  creation_date = mcl_file_util_get_time_of_last_status_change(file->payload->file_descriptor);
208 
209  // If creation_date buffer is NULL, then allocate it. If it is not, continue to use it.
210  if (MCL_NULL == file->payload->creation_date)
211  {
212  file->payload->creation_date = MCL_MALLOC(MCL_TIMESTAMP_LENGTH);
213 
214  if (MCL_NULL == file->payload->creation_date)
215  {
216  code = MCL_OUT_OF_MEMORY;
217  }
218  }
219 
220  // Convert file creation date to ISO 8601 format.
221  if (MCL_OK == code)
222  {
223  code = mcl_time_util_convert_to_iso_8601_format((const time_t *)&creation_date, file->payload->creation_date);
224  }
225  }
226 
227  if (MCL_OK != code)
228  {
229  // Clean up.
230  MCL_FREE(file->payload->local_path);
231  MCL_FREE(file->payload->creation_date);
232  (void)mcl_file_util_fclose(file->payload->file_descriptor);
233  file->payload->file_descriptor = MCL_NULL;
234  file->payload->size = 0;
235  }
236 
238  MCL_DEBUG_LEAVE("retVal = <%d>", code);
239  return code;
240 }
#define MCL_TIMESTAMP_LENGTH
#define MCL_FUNCTION_LEAVE_LABEL
File can not be opened.
MCL_CORE_EXPORT mcl_error_t mcl_file_util_fclose(void *file_descriptor)
MCL_NO_FILE_SUPPORT
MCL_OK
File local path parameter as char*.
Definition: mcl_file.h:50
const char * mcl_file_versions[MCL_FILE_VERSION_END]
Definition: file.c:15
void mcl_file_destroy(mcl_file_t **file)
Definition: file.c:148
file_payload_t * payload
Payload of file.
Definition: file.h:34
MCL_CORE_EXPORT mcl_error_t mcl_string_util_reset(const void *value, char **target)
End of file version enumeration.
Definition: mcl_file.h:42
mcl_int32_t mcl_error_t
MCL_CORE_EXPORT mcl_error_t mcl_time_util_convert_to_iso_8601_format(const time_t *time_value, char *iso8601_formatted_time)
#define MCL_DEBUG_ENTRY(...)
uint32_t mcl_uint32_t
File module header file.
#define MCL_ASSERT_CODE_MESSAGE(condition, return_code,...)
#define MCL_NEW(p)
#define MCL_NULL
char * local_path
Local path of file.
Definition: file.h:21
Definition: file.h:31
MCL_CORE_EXPORT mcl_size_t mcl_file_util_get_file_size(void *file_descriptor)
#define MCL_FREE(p)
E_MCL_FILE_VERSION
Definition: mcl_file.h:39
#define MCL_ASSERT_NOT_NULL(argument, return_variable)
File type parameter as char*.
Definition: mcl_file.h:52
#define MCL_ITEM_PREAMBLE
Definition: item.h:17
char * remote_name
Remote name of file.
Definition: file.h:22
mcl_error_t file_validate(file_t *file)
Definition: file.c:121
mcl_error_t mcl_file_initialize(E_MCL_FILE_VERSION version, mcl_file_t **file)
Definition: file.c:20
MCL_CORE_EXPORT mcl_error_t mcl_file_util_fopen(const char *file_name, const char *mode, void **file_descriptor)
File remote name parameter as char*.
Definition: mcl_file.h:51
static mcl_error_t _set_file_local_path(mcl_file_t *file, const char *path)
Definition: file.c:172
MCL_OUT_OF_MEMORY
#define MCL_ASSERT_OK(code)
Item type file.
Definition: item.h:26
#define MCL_MALLOC(bytes)
mcl_error_t mcl_file_set_parameter(mcl_file_t *file, E_MCL_FILE_PARAMETER parameter, const void *value)
Definition: file.c:76
MCL_INVALID_PARAMETER
struct mcl_file_t mcl_file_t
Definition: mcl_file.h:34
File module interface header file.
#define MCL_DEBUG_LEAVE(...)
#define MCL_TRUE
MCL_CORE_EXPORT mcl_bool_t mcl_file_util_check_if_regular_file(void *file_descriptor)
E_MCL_FILE_PARAMETER
Definition: mcl_file.h:48
MCL_CORE_EXPORT mcl_time_t mcl_file_util_get_time_of_last_status_change(void *file_descriptor)