1 /*
2 * Copyright (c) 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 "util/file.h"
17
18 #include <cstdlib>
19 #include <cstdint>
20 #include <cstring>
21 #include <climits>
22 #include "securec.h"
23
24 namespace OHOS {
25 namespace Idl {
26 #ifdef __MINGW32__
27 constexpr unsigned int File::READ;
28 constexpr unsigned int File::WRITE;
29 constexpr unsigned int File::APPEND;
30 #endif
31
File(const String & path,int mode)32 File::File(const String& path, int mode)
33 : mode_(mode)
34 {
35 if (path.IsEmpty()) {
36 return;
37 }
38
39 String pathTmp = "";
40 #ifndef __MINGW32__
41 char* absolutePath = realpath(path.string(), nullptr);
42 if (absolutePath != nullptr) {
43 pathTmp = absolutePath;
44 free(absolutePath);
45 } else {
46 pathTmp = path;
47 }
48 #else
49 char absolutePath[_MAX_PATH];
50 if (_fullpath(absolutePath, path.string(), _MAX_PATH) == nullptr) {
51 pathTmp = absolutePath;
52 } else {
53 pathTmp = path;
54 }
55 #endif
56
57 if (mode_ & READ) {
58 if (!pathTmp.IsEmpty()) {
59 fd_ = fopen(pathTmp.string(), "r");
60 }
61 } else if (mode_ & WRITE) {
62 fd_ = fopen(path.string(), "w+");
63 } else if (mode_ & APPEND) {
64 fd_ = fopen(path.string(), "a+");
65 }
66
67 if (fd_ != nullptr) {
68 #ifndef __MINGW32__
69 char* absolutePath = realpath(path.string(), nullptr);
70 if (absolutePath != nullptr) {
71 path_ = absolutePath;
72 free(absolutePath);
73 } else {
74 path_ = path;
75 }
76 #else
77 char absolutePath[_MAX_PATH];
78 _fullpath(absolutePath, path.string(), _MAX_PATH);
79 path_ = absolutePath;
80 #endif
81 }
82 }
83
~File()84 File::~File()
85 {
86 Close();
87 }
88
GetChar()89 char File::GetChar()
90 {
91 char c = PeekChar();
92
93 if (position_ + 1 <= size_) {
94 position_++;
95
96 if (c != '\n') {
97 columnNo_++;
98 } else {
99 columnNo_ = 0;
100 lineNo_++;
101 }
102 }
103 return c;
104 }
105
PeekChar()106 char File::PeekChar()
107 {
108 if (position_ + 1 > size_) {
109 int ret = Read();
110 if (ret == -1) {
111 isEof_ = true;
112 }
113 }
114
115 return buffer_[position_];
116 }
117
IsEof() const118 bool File::IsEof() const
119 {
120 return isEof_ || buffer_[position_] == static_cast<char>(-1);
121 }
122
Read()123 int File::Read()
124 {
125 if (isEof_ || isError_) {
126 return -1;
127 }
128
129 (void)memset_s(buffer_, BUFFER_SIZE, 0, BUFFER_SIZE);
130 size_t count = fread(buffer_, 1, BUFFER_SIZE - 1, fd_);
131 if (count < BUFFER_SIZE - 1) {
132 isError_ = ferror(fd_) != 0;
133 buffer_[count] = -1;
134 }
135 size_ = count;
136 position_ = 0;
137 if (count <= 0 || count >= BUFFER_SIZE) {
138 return -1;
139 }
140 return count;
141 }
142
ReadData(void * data,size_t size)143 bool File::ReadData(void* data, size_t size)
144 {
145 if (data == nullptr || size == 0 || size > SIZE_MAX) {
146 return true;
147 }
148
149 if (fd_ == nullptr) {
150 return false;
151 }
152
153 size_t count = fread(data, size, 1, fd_);
154 return count == 1;
155 }
156
WriteData(const void * data,size_t size)157 bool File::WriteData(const void* data, size_t size)
158 {
159 if (data == nullptr || size == 0) {
160 return true;
161 }
162
163 if (fd_ == nullptr || !(mode_ & (WRITE | APPEND))) {
164 return false;
165 }
166
167 size_t count = fwrite(data, size, 1, fd_);
168 return count == 1;
169 }
170
Flush()171 void File::Flush()
172 {
173 if ((mode_ & (WRITE | APPEND)) && fd_ != nullptr) {
174 fflush(fd_);
175 }
176 }
177
Reset()178 bool File::Reset()
179 {
180 if (fd_ == nullptr) {
181 return false;
182 }
183
184 return fseek(fd_, 0, SEEK_SET) == 0;
185 }
186
Skip(long size)187 bool File::Skip(long size)
188 {
189 if (fd_ == nullptr) {
190 return false;
191 }
192
193 return fseek(fd_, size, SEEK_CUR) == 0;
194 }
195
Close()196 void File::Close()
197 {
198 if (fd_ != nullptr) {
199 fclose(fd_);
200 fd_ = nullptr;
201 }
202 }
203 }
204 }
205