mirror of
https://github.com/openharmony/drivers_framework.git
synced 2026-08-27 20:49:55 -04:00
3e90b3e1df
Signed-off-by: yue <yueyan4@huawei.com>
307 lines
6.0 KiB
C++
307 lines
6.0 KiB
C++
/*
|
|
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
|
*
|
|
* HDF is dual licensed: you can use it either under the terms of
|
|
* the GPL, or the BSD license, at your option.
|
|
* See the LICENSE file in the root of this repository for complete details.
|
|
*/
|
|
|
|
#include "util/file.h"
|
|
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
#include <functional>
|
|
#include <string>
|
|
#include <sys/stat.h>
|
|
#include <unistd.h>
|
|
|
|
#include "util/string_builder.h"
|
|
|
|
namespace OHOS {
|
|
namespace HDI {
|
|
#ifdef __MINGW32__
|
|
constexpr unsigned int File::READ;
|
|
constexpr unsigned int File::WRITE;
|
|
constexpr unsigned int File::APPEND;
|
|
#endif
|
|
|
|
File::File(const String &path, unsigned int mode) : mode_(mode)
|
|
{
|
|
if (path.IsEmpty()) {
|
|
return;
|
|
}
|
|
|
|
if (mode_ & READ) {
|
|
if (!CheckValid(path)) {
|
|
return;
|
|
}
|
|
fd_ = fopen(path.string(), "r");
|
|
} else if (mode_ & WRITE) {
|
|
fd_ = fopen(path.string(), "w+");
|
|
} else if (mode_ & APPEND) {
|
|
fd_ = fopen(path.string(), "a+");
|
|
}
|
|
|
|
if (fd_ != nullptr) {
|
|
#ifndef __MINGW32__
|
|
char *absolutePath = realpath(path.string(), nullptr);
|
|
if (absolutePath != nullptr) {
|
|
path_ = absolutePath;
|
|
free(absolutePath);
|
|
} else {
|
|
path_ = path;
|
|
}
|
|
#else
|
|
char absolutePath[_MAX_PATH];
|
|
_fullpath(absolutePath, path.string(), _MAX_PATH);
|
|
path_ = absolutePath;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
File::~File()
|
|
{
|
|
Close();
|
|
}
|
|
|
|
char File::GetChar()
|
|
{
|
|
char c = PeekChar();
|
|
|
|
if (position_ + 1 <= size_) {
|
|
position_++;
|
|
|
|
if (c != '\n') {
|
|
columnNo_++;
|
|
} else {
|
|
columnNo_ = 1;
|
|
lineNo_++;
|
|
}
|
|
}
|
|
return c;
|
|
}
|
|
|
|
char File::PeekChar()
|
|
{
|
|
if (position_ + 1 > size_) {
|
|
int ret = Read();
|
|
if (ret == -1) {
|
|
isEof_ = true;
|
|
}
|
|
}
|
|
|
|
return buffer_[position_];
|
|
}
|
|
|
|
bool File::IsEof() const
|
|
{
|
|
return isEof_ || buffer_[position_] == -1;
|
|
}
|
|
|
|
int File::Read()
|
|
{
|
|
if (isEof_ || isError_) {
|
|
return -1;
|
|
}
|
|
|
|
(void)memset(buffer_, 0, BUFFER_SIZE);
|
|
size_t count = fread(buffer_, 1, BUFFER_SIZE - 1, fd_);
|
|
if (count < BUFFER_SIZE - 1) {
|
|
isError_ = ferror(fd_) != 0;
|
|
buffer_[count] = -1;
|
|
}
|
|
size_ = count;
|
|
position_ = 0;
|
|
return (count != 0) ? count : -1;
|
|
}
|
|
|
|
size_t File::ReadData(void *data, size_t size) const
|
|
{
|
|
if (data == nullptr || size == 0) {
|
|
return 0;
|
|
}
|
|
|
|
if (fd_ == nullptr) {
|
|
return 0;
|
|
}
|
|
|
|
return fread(data, 1, size, fd_);
|
|
}
|
|
|
|
bool File::WriteData(const void *data, size_t size) const
|
|
{
|
|
if (data == nullptr || size == 0) {
|
|
return true;
|
|
}
|
|
|
|
if (fd_ == nullptr || !(mode_ & (WRITE | APPEND))) {
|
|
return false;
|
|
}
|
|
|
|
size_t count = fwrite(data, size, 1, fd_);
|
|
return count == 1;
|
|
}
|
|
|
|
void File::Flush()
|
|
{
|
|
if ((mode_ & (WRITE | APPEND)) && fd_ != nullptr) {
|
|
fflush(fd_);
|
|
}
|
|
}
|
|
|
|
bool File::Reset()
|
|
{
|
|
if (fd_ == nullptr) {
|
|
return false;
|
|
}
|
|
|
|
return fseek(fd_, 0, SEEK_SET) == 0;
|
|
}
|
|
|
|
bool File::Skip(long size)
|
|
{
|
|
if (fd_ == nullptr) {
|
|
return false;
|
|
}
|
|
|
|
return fseek(fd_, size, SEEK_CUR) == 0;
|
|
}
|
|
|
|
void File::Close()
|
|
{
|
|
if (fd_ != nullptr) {
|
|
fclose(fd_);
|
|
fd_ = nullptr;
|
|
}
|
|
}
|
|
|
|
bool File::CreateParentDir(const String &path)
|
|
{
|
|
if (!access(path.string(), F_OK | R_OK | W_OK)) {
|
|
return true;
|
|
}
|
|
|
|
int pos = 1;
|
|
while ((pos = path.IndexOf(File::separator, pos)) != -1) {
|
|
String partPath = path.Substring(0, pos);
|
|
struct stat st;
|
|
if (stat(partPath.string(), &st) < 0) {
|
|
if (errno != ENOENT) {
|
|
return false;
|
|
}
|
|
|
|
#ifndef __MINGW32__
|
|
if (mkdir(partPath.string(), S_IRWXU | S_IRWXG | S_IRWXO) < 0) {
|
|
#else
|
|
if (mkdir(partPath.string()) < 0) {
|
|
#endif
|
|
return false;
|
|
}
|
|
} else if (!S_ISDIR(st.st_mode)) {
|
|
return false;
|
|
}
|
|
pos += 1;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
String File::AdapterPath(const String &path)
|
|
{
|
|
#ifndef __MINGW32__
|
|
String newPath = path.Replace('\\', '/');
|
|
#else
|
|
String newPath = path.Replace('/', '\\');
|
|
#endif
|
|
|
|
// "foo/v1_0//ifoo.h" -> "foo/v1_0/ifoo.h"
|
|
StringBuilder adapterPath;
|
|
bool hasSep = false;
|
|
for (size_t i = 0; i < newPath.GetLength(); i++) {
|
|
char c = newPath[i];
|
|
if (c == File::separator) {
|
|
if (hasSep) {
|
|
continue;
|
|
}
|
|
adapterPath.Append(c);
|
|
hasSep = false;
|
|
} else {
|
|
adapterPath.Append(c);
|
|
}
|
|
}
|
|
return adapterPath.ToString();
|
|
}
|
|
|
|
String File::RealPath(const String &path)
|
|
{
|
|
if (path.IsEmpty()) {
|
|
return "";
|
|
}
|
|
|
|
String absPath;
|
|
String adapterPath = File::AdapterPath(path);
|
|
#ifdef __MINGW32__
|
|
char absolutePath[_MAX_PATH];
|
|
_fullpath(absolutePath, adapterPath.string(), _MAX_PATH);
|
|
absPath = absolutePath;
|
|
#else
|
|
char *absolutePath = realpath(adapterPath.string(), nullptr);
|
|
if (absolutePath != nullptr) {
|
|
absPath = absolutePath;
|
|
free(absolutePath);
|
|
}
|
|
#endif
|
|
return absPath;
|
|
}
|
|
|
|
bool File::CheckValid(const String &path)
|
|
{
|
|
if (access(path.string(), F_OK | R_OK | W_OK)) {
|
|
return false;
|
|
}
|
|
|
|
struct stat st;
|
|
if (stat(path.string(), &st) < 0) {
|
|
return false;
|
|
}
|
|
|
|
if (S_ISDIR(st.st_mode)) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
String File::Pascal2UnderScoreCase(const String &name)
|
|
{
|
|
if (name.IsNull() || name.IsEmpty()) {
|
|
return name;
|
|
}
|
|
|
|
StringBuilder sb;
|
|
for (int i = 0; i < name.GetLength(); i++) {
|
|
char c = name[i];
|
|
if (isupper(c) != 0) {
|
|
// 2->Index of the last char array.
|
|
if (i > 1) {
|
|
sb.Append('_');
|
|
}
|
|
sb.Append(tolower(c));
|
|
} else {
|
|
sb.Append(c);
|
|
}
|
|
}
|
|
|
|
return sb.ToString();
|
|
}
|
|
|
|
size_t File::GetHashKey()
|
|
{
|
|
StringBuilder fileStr;
|
|
while (!IsEof()) {
|
|
fileStr.Append(GetChar());
|
|
}
|
|
|
|
return std::hash<std::string>()(fileStr.ToString().string());
|
|
}
|
|
} // namespace HDI
|
|
} // namespace OHOS
|