1 /*
2 * Copyright (C) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "hc_file.h"
17 #include <dirent.h>
18 #include <fcntl.h>
19 #include <sys/types.h>
20 #include <sys/stat.h>
21 #include <unistd.h>
22 #include "hc_log.h"
23 #include "hc_types.h"
24 #include "securec.h"
25
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29
30 #define MAX_FOLDER_NAME_SIZE 128
31
CreateDirectory(const char * filePath)32 static int32_t CreateDirectory(const char *filePath)
33 {
34 int32_t ret;
35 errno_t eno;
36 char *chPtr = NULL;
37 char dirCache[MAX_FOLDER_NAME_SIZE];
38
39 chPtr = (char *)filePath;
40 while ((chPtr = strchr(chPtr, '/')) != NULL) {
41 unsigned long len = (unsigned long)((uintptr_t)chPtr - (uintptr_t)filePath);
42 if (len == 0ul) {
43 chPtr++;
44 continue;
45 }
46 eno = memcpy_s(dirCache, sizeof(dirCache), filePath, len);
47 if (eno != EOK) {
48 LOGE("memory copy failed");
49 return -1;
50 }
51 dirCache[len] = 0;
52 if (access(dirCache, F_OK) != 0) {
53 ret = mkdir(dirCache, S_IRWXU);
54 if (ret != 0) {
55 LOGE("make dir failed, err code %d", ret);
56 return -1;
57 }
58 }
59 chPtr++;
60 }
61 return 0;
62 }
63
HcFileOpenRead(const char * path)64 static FILE *HcFileOpenRead(const char *path)
65 {
66 return fopen(path, "rb");
67 }
68
HcFileOpenWrite(const char * path)69 static FILE *HcFileOpenWrite(const char *path)
70 {
71 if (access(path, F_OK) != 0) {
72 int32_t ret = CreateDirectory(path);
73 if (ret != 0) {
74 return NULL;
75 }
76 }
77 return fopen(path, "w+");
78 }
79
HcFileOpen(const char * path,int mode,FileHandle * file)80 int HcFileOpen(const char *path, int mode, FileHandle *file)
81 {
82 if (path == NULL || file == NULL) {
83 return -1;
84 }
85 if (mode == MODE_FILE_READ) {
86 file->pfd = HcFileOpenRead(path);
87 } else {
88 file->pfd = HcFileOpenWrite(path);
89 }
90 if (file->pfd == NULL) {
91 return -1;
92 } else {
93 return 0;
94 }
95 }
96
HcFileSize(FileHandle file)97 int HcFileSize(FileHandle file)
98 {
99 FILE *fp = (FILE *)file.pfd;
100 if (fp != NULL) {
101 if (fseek(fp, 0L, SEEK_END) != 0) {
102 return -1;
103 }
104 int size = ftell(fp);
105 if (fseek(fp, 0L, SEEK_SET) != 0) {
106 return -1;
107 }
108 return size;
109 } else {
110 return -1;
111 }
112 }
113
HcFileRead(FileHandle file,void * dst,int dstSize)114 int HcFileRead(FileHandle file, void *dst, int dstSize)
115 {
116 FILE *fp = (FILE *)file.pfd;
117 if (fp == NULL || dstSize < 0 || dst == NULL) {
118 return -1;
119 }
120
121 char *dstBuffer = (char *)dst;
122 int total = 0;
123 while (total < dstSize) {
124 int readCount = fread(dstBuffer + total, 1, dstSize - total, fp);
125 if (ferror(fp) != 0) {
126 LOGE("read file error!");
127 }
128 if (readCount == 0) {
129 return total;
130 }
131 total += readCount;
132 }
133
134 return total;
135 }
136
HcFileWrite(FileHandle file,const void * src,int srcSize)137 int HcFileWrite(FileHandle file, const void *src, int srcSize)
138 {
139 FILE *fp = (FILE *)file.pfd;
140 if (fp == NULL || srcSize < 0 || src == NULL) {
141 return -1;
142 }
143
144 const char *srcBuffer = (const char *)src;
145 int total = 0;
146 while (total < srcSize) {
147 int writeCount = fwrite(srcBuffer + total, 1, srcSize - total, fp);
148 if (ferror(fp) != 0) {
149 LOGE("write file error!");
150 }
151 total += writeCount;
152 }
153 return total;
154 }
155
HcFileClose(FileHandle file)156 void HcFileClose(FileHandle file)
157 {
158 FILE *fp = (FILE *)file.pfd;
159 if (fp == NULL) {
160 return;
161 }
162
163 (void)fclose(fp);
164 }
165
HcFileRemove(const char * path)166 void HcFileRemove(const char *path)
167 {
168 if (path == NULL) {
169 LOGE("Invalid file path");
170 return;
171 }
172 (void)remove(path);
173 }
174
HcFileGetSubFileName(const char * path,StringVector * nameVec)175 void HcFileGetSubFileName(const char *path, StringVector *nameVec)
176 {
177 DIR *dir = NULL;
178 struct dirent *entry = NULL;
179 if ((dir = opendir(path)) == NULL) {
180 LOGI("opendir failed!");
181 return;
182 }
183 while ((entry = readdir(dir)) != NULL) {
184 if ((strcmp(entry->d_name, ".") == 0) || (strcmp(entry->d_name, "..") == 0)) {
185 continue;
186 }
187 HcString subFileName = CreateString();
188 if (!StringSetPointer(&subFileName, entry->d_name)) {
189 LOGE("Failed to copy subFileName!");
190 DeleteString(&subFileName);
191 continue;
192 }
193 if (nameVec->pushBackT(nameVec, subFileName) == NULL) {
194 LOGE("Failed to push path to pathVec!");
195 DeleteString(&subFileName);
196 }
197 }
198 if (closedir(dir) < 0) {
199 LOGE("Failed to close file");
200 }
201 }
202
203 #ifdef __cplusplus
204 }
205 #endif
206