1cc290419Sopenharmony_ci/*
2cc290419Sopenharmony_ci * Copyright (C) 2023 Huawei Device Co., Ltd.
3cc290419Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4cc290419Sopenharmony_ci * you may not use this file except in compliance with the License.
5cc290419Sopenharmony_ci * You may obtain a copy of the License at
6cc290419Sopenharmony_ci *
7cc290419Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8cc290419Sopenharmony_ci *
9cc290419Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10cc290419Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11cc290419Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12cc290419Sopenharmony_ci * See the License for the specific language governing permissions and
13cc290419Sopenharmony_ci * limitations under the License.
14cc290419Sopenharmony_ci */
15cc290419Sopenharmony_ci//! filemanager
16cc290419Sopenharmony_ci#![allow(missing_docs)]
17cc290419Sopenharmony_ci
18cc290419Sopenharmony_ciuse crate::config::KERNEL_FILE_NODE_SIZE;
19cc290419Sopenharmony_ci#[cfg(not(feature = "host"))]
20cc290419Sopenharmony_ciuse crate::utils::hdc_log::*;
21cc290419Sopenharmony_ciuse std::fs::OpenOptions;
22cc290419Sopenharmony_ciuse std::fs::{self, File};
23cc290419Sopenharmony_ciuse std::io::Read;
24cc290419Sopenharmony_ci
25cc290419Sopenharmony_cipub struct FileManager {
26cc290419Sopenharmony_ci    path: Option<String>,
27cc290419Sopenharmony_ci    file: Option<File>,
28cc290419Sopenharmony_ci}
29cc290419Sopenharmony_ci
30cc290419Sopenharmony_ciimpl FileManager {
31cc290419Sopenharmony_ci    pub fn remove_file(path: &str) -> std::io::Result<()> {
32cc290419Sopenharmony_ci        fs::remove_file(path)
33cc290419Sopenharmony_ci    }
34cc290419Sopenharmony_ci
35cc290419Sopenharmony_ci    pub fn new(file_path: String) -> FileManager {
36cc290419Sopenharmony_ci        FileManager {
37cc290419Sopenharmony_ci            path: Some(file_path),
38cc290419Sopenharmony_ci            file: None,
39cc290419Sopenharmony_ci        }
40cc290419Sopenharmony_ci    }
41cc290419Sopenharmony_ci
42cc290419Sopenharmony_ci    pub fn open(&mut self) -> (bool, String) {
43cc290419Sopenharmony_ci        let mut result = false;
44cc290419Sopenharmony_ci        let mut err_msg = String::from("");
45cc290419Sopenharmony_ci        if let Some(path) = &self.path {
46cc290419Sopenharmony_ci            let mut _file = OpenOptions::new().read(true).open(path);
47cc290419Sopenharmony_ci            match _file {
48cc290419Sopenharmony_ci                Ok(f) => {
49cc290419Sopenharmony_ci                    self.file = Some(f);
50cc290419Sopenharmony_ci                    result = true;
51cc290419Sopenharmony_ci                }
52cc290419Sopenharmony_ci                Err(e) => {
53cc290419Sopenharmony_ci                    err_msg = format!("Transfer {} failed: {:?}.", path, e);
54cc290419Sopenharmony_ci                    crate::error!("{err_msg}");
55cc290419Sopenharmony_ci                    result = false;
56cc290419Sopenharmony_ci                }
57cc290419Sopenharmony_ci            }
58cc290419Sopenharmony_ci        }
59cc290419Sopenharmony_ci        (result, err_msg)
60cc290419Sopenharmony_ci    }
61cc290419Sopenharmony_ci
62cc290419Sopenharmony_ci    pub fn file_size(&self) -> u64 {
63cc290419Sopenharmony_ci        if let Some(f) = &self.file {
64cc290419Sopenharmony_ci            let meta_size: u64 = match f.metadata() {
65cc290419Sopenharmony_ci                Ok(meta) => meta.len(),
66cc290419Sopenharmony_ci                Err(e) => {
67cc290419Sopenharmony_ci                    crate::warn!("failed to get file metadata, error: {:#?}", e);
68cc290419Sopenharmony_ci                    0
69cc290419Sopenharmony_ci                }
70cc290419Sopenharmony_ci            };
71cc290419Sopenharmony_ci            if meta_size == KERNEL_FILE_NODE_SIZE.into() || meta_size == 0 {
72cc290419Sopenharmony_ci                let node_size = self.buffer_read(meta_size) as u64;
73cc290419Sopenharmony_ci                return node_size;
74cc290419Sopenharmony_ci            } else {
75cc290419Sopenharmony_ci                return meta_size;
76cc290419Sopenharmony_ci            }
77cc290419Sopenharmony_ci        }
78cc290419Sopenharmony_ci        0
79cc290419Sopenharmony_ci    }
80cc290419Sopenharmony_ci
81cc290419Sopenharmony_ci    pub fn buffer_read(&self, meta_size: u64) -> usize {
82cc290419Sopenharmony_ci        let mut buf = [0u8; KERNEL_FILE_NODE_SIZE as usize];
83cc290419Sopenharmony_ci        let mut read_len = 0usize;
84cc290419Sopenharmony_ci        if let Some(path) = &self.path {
85cc290419Sopenharmony_ci            let mut _file = File::open(path);
86cc290419Sopenharmony_ci            if let Ok(mut f) = _file {
87cc290419Sopenharmony_ci                loop {
88cc290419Sopenharmony_ci                    let single_len = match f.read(&mut buf[read_len..]) {
89cc290419Sopenharmony_ci                        Ok(len) => len,
90cc290419Sopenharmony_ci                        Err(e) => {
91cc290419Sopenharmony_ci                            crate::warn!(
92cc290419Sopenharmony_ci                                "failed to read kernel file node with buffer, error: {:#?}",
93cc290419Sopenharmony_ci                                e
94cc290419Sopenharmony_ci                            );
95cc290419Sopenharmony_ci                            break;
96cc290419Sopenharmony_ci                        }
97cc290419Sopenharmony_ci                    };
98cc290419Sopenharmony_ci                    read_len += single_len;
99cc290419Sopenharmony_ci                    if single_len == 0 || meta_size == 0 {
100cc290419Sopenharmony_ci                        break;
101cc290419Sopenharmony_ci                    }
102cc290419Sopenharmony_ci                }
103cc290419Sopenharmony_ci            }
104cc290419Sopenharmony_ci        }
105cc290419Sopenharmony_ci        read_len
106cc290419Sopenharmony_ci    }
107cc290419Sopenharmony_ci}
108