• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef ECMASCRIPT_PLATFORM_FILE_H
17 #define ECMASCRIPT_PLATFORM_FILE_H
18 
19 #ifdef PANDA_TARGET_WINDOWS
20 #include <windef.h>
21 #include <winbase.h>
22 #include <winnt.h>
23 #else
24 #include <fcntl.h>
25 #include <dlfcn.h>
26 #endif
27 
28 #include <string>
29 
30 #include "ecmascript/platform/map.h"
31 
32 namespace panda::ecmascript {
33 class JSThread;
34 #ifdef PANDA_TARGET_WINDOWS
35 using fd_t = HANDLE;
36 #define INVALID_FD INVALID_HANDLE_VALUE
37 
38 #define FILE_RDONLY GENERIC_READ
39 #define FILE_WRONLY GENERIC_WRITE
40 #define FILE_RDWR (GENERIC_READ | GENERIC_WRITE)
41 #define FILE_CREAT CREATE_ALWAYS
42 #define FILE_TRUNC TRUNCATE_EXISTING
43 
44 #ifdef ERROR
45 #undef ERROR
46 #endif
47 
48 #ifdef VOID
49 #undef VOID
50 #endif
51 
52 #ifdef CONST
53 #undef CONST
54 #endif
55 #else
56 using fd_t = int;
57 #define INVALID_FD (-1)
58 
59 #define FILE_RDONLY O_RDONLY
60 #define FILE_WRONLY O_WRONLY
61 #define FILE_RDWR O_RDWR
62 #define FILE_CREAT O_CREAT
63 #define FILE_TRUNC O_TRUNC
64 #endif
65 
66 #define FILE_SUCCESS 1
67 #define FILE_FAILED 0
68 
69 #define FILE_MS_SYNC 4 // Synchronous memory sync
70 
71 std::string PUBLIC_API GetFileDelimiter();
72 std::string PUBLIC_API GetPathSeparator();
73 bool PUBLIC_API RealPath(const std::string &path, std::string &realPath, bool readOnly = true);
74 bool PUBLIC_API RealPathByChar(const char *path, char *realPath, int rowLength, bool readOnly);
75 void DPrintf(fd_t fd, const std::string &buffer);
76 void PUBLIC_API FdsanExchangeOwnerTag(fd_t fd);
77 void PUBLIC_API Close(fd_t fd);
78 void FSync(fd_t fd);
79 MemMap PUBLIC_API FileMap(const char *fileName, int flag, int prot, int64_t offset = 0);
80 MemMap PUBLIC_API CreateFileMap([[maybe_unused]] const char *fileName, [[maybe_unused]] int fileSize,
81                                 [[maybe_unused]] int flag, [[maybe_unused]] int prot);
82 MemMap PUBLIC_API FileMapForAlignAddressByFd(const fd_t fd, int prot, int64_t offset, uint32_t offStart);
83 int PUBLIC_API FileUnMap(MemMap addr);
84 int PUBLIC_API FileSync(MemMap addr, int flag);
85 CString ResolveFilenameFromNative(JSThread *thread, const CString &dirname, CString request);
86 bool PUBLIC_API FileExist(const char *filename);
87 int PUBLIC_API Unlink(const char *filename);
88 void *LoadLib(const std::string &libname);
89 void *FindSymbol(void *handle, const char *symbol);
90 int CloseLib(void *handle);
91 char *LoadLibError();
92 void PUBLIC_API DeleteFilesWithSuffix(const std::string &dirPath, const std::string &suffix);
93 
94 class MemMapScope {
95 public:
MemMapScope(MemMap memMap)96     MemMapScope(MemMap memMap) : memMap_(memMap) {}
~MemMapScope()97     ~MemMapScope()
98     {
99         FileUnMap(memMap_);
100     }
101 
102 private:
103     MemMap memMap_ {};
104 };
105 
106 class FileMemMapReader {
107 public:
108     using ReadFailedCallback = std::function<void()>;
FileMemMapReader(const MemMap & memMap,ReadFailedCallback readFailedCallback,CString logTag)109     FileMemMapReader(const MemMap &memMap, ReadFailedCallback readFailedCallback, CString logTag) : memMap_(memMap),
110         readFailedCallback_(std::move(readFailedCallback)), readPtr_(static_cast<uint8_t *>(memMap.GetOriginAddr())),
111         remainingSize_(memMap.GetSize()), fileSize_(memMap.GetSize()), logTag_(std::move(logTag)) {}
112 
113     template<typename T>
ReadSingleData(T * readDst,const size_t readSize,const CString & message)114     bool ReadSingleData(T *readDst, const size_t readSize, const CString &message)
115     {
116         if (remainingSize_ < readSize) {
117             LOG_ECMA(ERROR) << logTag_ << " read " << message << " remainingSize not sufficient";
118             readFailedCallback_();
119             return false;
120         }
121         if (memcpy_s(readDst, readSize, readPtr_, readSize) != EOK) {
122             LOG_ECMA(ERROR) << logTag_ << " memcpy_s read " << message << " failed";
123             readFailedCallback_();
124             return false;
125         }
126         Step(readSize);
127         return true;
128     }
129 
ReadString(CString & readDst,const size_t readSize,const CString & message)130     bool ReadString(CString &readDst, const size_t readSize, const CString &message)
131     {
132         readDst.reserve(readSize);
133         if (remainingSize_ < readSize) {
134             LOG_ECMA(ERROR) << logTag_ << " read " << message << " remainingSize not sufficient";
135             readFailedCallback_();
136             return false;
137         }
138         readDst.assign(reinterpret_cast<const char*>(readPtr_), readSize);
139         Step(readSize);
140         return true;
141     }
142 
143     template<typename T>
ReadFromOffset(T * readDst,const size_t readSize,const size_t offset,const CString & message)144     bool ReadFromOffset(T *readDst, const size_t readSize, const size_t offset, const CString &message)
145     {
146         if (fileSize_ < offset + readSize) {
147             LOG_ECMA(ERROR) << logTag_ << " read " << message << " fileSize_ not sufficient";
148             readFailedCallback_();
149             return false;
150         }
151         uint8_t *readPtr = static_cast<uint8_t *>(memMap_.GetOriginAddr());
152         if (memcpy_s(readDst, readSize, readPtr + offset, readSize) != EOK) {
153             LOG_ECMA(ERROR) << logTag_ << " memcpy_s read " << message << " failed";
154             readFailedCallback_();
155             return false;
156         }
157         return true;
158     }
159 
Step(const size_t stepSize)160     void Step(const size_t stepSize)
161     {
162         readPtr_ += stepSize;
163         remainingSize_ -= stepSize;
164     }
165 
GetReadPtr()166     uint8_t *GetReadPtr() const
167     {
168         return readPtr_;
169     }
170 
171 private:
172     MemMap memMap_ {};
173     ReadFailedCallback readFailedCallback_ {};
174     uint8_t *readPtr_ { nullptr };
175     size_t remainingSize_ { 0 };
176     size_t fileSize_ { 0 };
177     CString logTag_ {};
178 };
179 
180 class FileMemMapWriter {
181 public:
FileMemMapWriter(const MemMap & memMap,CString logTag)182     FileMemMapWriter(const MemMap &memMap, CString logTag) : memMap_(memMap),
183         writePtr_(static_cast<uint8_t *>(memMap.GetOriginAddr())),
184         fileSize_(memMap.GetSize()), logTag_(std::move(logTag)) {}
185 
186     template<typename T>
WriteSingleData(T * writeSrc,const size_t writeSize,const CString & message)187     bool WriteSingleData(T *writeSrc, const size_t writeSize, const CString &message)
188     {
189         if (memcpy_s(writePtr_, writeSize, writeSrc, writeSize) != EOK) {
190             LOG_ECMA(ERROR) << logTag_ << " memcpy_s write " << message << " failed";
191             return false;
192         }
193         writePtr_ += writeSize;
194         return true;
195     }
196 
GetWritePtr()197     uint8_t *GetWritePtr() const
198     {
199         return writePtr_;
200     }
201 
WriteAlignUpPadding(const size_t paddingSize)202     bool WriteAlignUpPadding(const size_t paddingSize)
203     {
204         if (paddingSize <= 0) {
205             return true;
206         }
207         if (memset_s(writePtr_, paddingSize, 0, paddingSize) != EOK) {
208             LOG_ECMA(ERROR) << logTag_ << " memset_s WriteAlignUpPadding " << paddingSize << " failed";
209             return false;
210         }
211         writePtr_ += paddingSize;
212         return true;
213     }
214 
215 private:
216     MemMap memMap_ {};
217     uint8_t *writePtr_ { nullptr };
218     size_t fileSize_ { 0 };
219     CString logTag_ {};
220 };
221 }  // namespace panda::ecmascript
222 #endif  // ECMASCRIPT_PLATFORM_FILE_H
223