-
-
Notifications
You must be signed in to change notification settings - Fork 21
/
dir_list.hpp
149 lines (127 loc) · 3.94 KB
/
dir_list.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#pragma once
//=====================================================================//
/*! @file
@brief ディレクトリ・リスト・クラス @n
@author 平松邦仁 ([email protected])
@copyright Copyright (C) 2019 Kunihito Hiramatsu @n
Released under the MIT license @n
https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include <cstring>
#include <functional>
#include "common/format.hpp"
#include "common/string_utils.hpp"
#include "ff14/source/ff.h"
namespace utils {
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/*!
@brief SD カード・ディレクトリー・リスト・クラス
*/
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
class dir_list {
public:
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/*!
@brief DIR リスト関数型
*/
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
typedef std::function<void (const char* name, const FILINFO* fi, bool dir, void* option)> loop_func;
private:
DIR dir_;
uint32_t total_;
char nmb_[256];
bool start_;
public:
//-----------------------------------------------------------------//
/*!
@brief コンストラクター
*/
//-----------------------------------------------------------------//
dir_list() noexcept : dir_(), total_(0), nmb_{ 0 }, start_(false) { }
//-----------------------------------------------------------------//
/*!
@brief プローブ(状態)
@return 取得中なら「true」
*/
//-----------------------------------------------------------------//
bool probe() const noexcept { return start_; }
//-----------------------------------------------------------------//
/*!
@brief ファイル数を取得 @n
※取得後に確定した値となる。
@return ファイル数
*/
//-----------------------------------------------------------------//
uint32_t get_total() const noexcept { return total_; }
//-----------------------------------------------------------------//
/*!
@brief ディレクトリーリスト開始 @n
※「probe()」関数が「false」になるまで「service()」を呼ぶ
@param[in] root ルート・パス
@return エラー無ければ「true」
*/
//-----------------------------------------------------------------//
bool start(const char* root) noexcept
{
total_ = 0;
auto st = f_opendir(&dir_, root);
if(st != FR_OK) {
return false;
}
start_ = true;
return true;
}
//-----------------------------------------------------------------//
/*!
@brief 取得を停止する
@return 成功なら「true」
*/
//-----------------------------------------------------------------//
bool stop() noexcept
{
if(!start_) return false;
start_ = false;
f_closedir(&dir_);
return true;
}
//-----------------------------------------------------------------//
/*!
@brief ディレクトリーリスト、ループ
@param[in] num ループ回数
@param[in] func 実行関数
@param[in] todir 「true」の場合、ディレクトリーも関数を呼ぶ
@param[in] option オプション・ポインター
@return エラー無ければ「true」
*/
//-----------------------------------------------------------------//
bool service(uint32_t num, loop_func func, bool todir = false, void* option = nullptr) noexcept
{
if(!start_) return false;
for(uint32_t i = 0; i < num; ++i) {
FILINFO fi;
// Read a directory item
if(f_readdir(&dir_, &fi) != FR_OK) {
stop();
return false;
}
if(!fi.fname[0]) {
stop();
break;
}
if(func) {
std::strncpy(nmb_, fi.fname, sizeof(nmb_));
if(fi.fattrib & AM_DIR) {
if(todir) {
func(nmb_, &fi, true, option);
}
} else {
func(nmb_, &fi, false, option);
}
}
++total_;
}
return true;
}
};
}