Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit07d64c3

Browse files
committed
sdfat corrections
1 parentd76c4cc commit07d64c3

File tree

6 files changed

+175
-90
lines changed

6 files changed

+175
-90
lines changed

‎examples/device-media-server-sdfat/device-media-server-sdfat.ino‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ void setup() {
111111
}
112112

113113
// Initialize content provider with SD filesystem
114+
contentProvider.setBaseURL(local_ip, port,"/files");
114115
if (!contentProvider.begin(sd,"/")) {
115116
Serial.println("Failed to initialize content provider. Halting.");
116117
while (1)delay(1000);
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#include"DLNA.h"
2+
#include"tools/SdFatParser.h"
3+
#include"tools/TreeNode.h"
4+
#include<SPI.h>
5+
#include"SdFat.h"
6+
#include<string>
7+
8+
// pins for audiokit
9+
#defineMISO2
10+
#defineMOSI15
11+
#defineSCLK14
12+
#defineCS13
13+
14+
SdFs sd;
15+
int count =0;
16+
SdFatParser parser;
17+
18+
// output the file
19+
voidprocessInfo(SdFatFileInfo& info,void* ref) {
20+
Print *p_out = (Print*) ref;
21+
count++;
22+
// indent
23+
for (int j =0; j < info.level; j++) {
24+
p_out->print("");
25+
}
26+
// print name
27+
p_out->println(info.name.c_str());
28+
}
29+
30+
voidsetup() {
31+
Serial.begin(115200);
32+
delay(3000);
33+
Serial.println("starting...");
34+
35+
// start SPI and setup pins
36+
SPI.begin(SCLK, MISO, MOSI);
37+
38+
if (!sd.begin(CS,SD_SCK_MHZ(4))) {
39+
Serial.println("sd.begin() failed");
40+
}
41+
42+
// setup callback
43+
parser.setCallback(processInfo, &Serial);
44+
45+
auto start_ms =millis();
46+
47+
// process ls
48+
sd.ls(&parser, LS_R);
49+
50+
Serial.print("Runtime in ms:");
51+
Serial.println(millis() - start_ms);
52+
Serial.print("Number of files:");
53+
Serial.println(count);
54+
}
55+
56+
voidloop() {}

‎src/dlna/devices/MediaServer/DLNAMediaServer.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -746,7 +746,7 @@ class DLNAMediaServer : public DLNADeviceInfo {
746746
if (get_data_cb) {
747747
MediaItem item;
748748
if (!get_data_cb(idx, item, reference_))break;// end-of-list
749-
total +=streamDIDLItem(out, item);
749+
total +=streamDIDLItem(esc_out, item);
750750
continue;
751751
}
752752
}

‎src/tools/SdFatContentProvider.h‎

Lines changed: 54 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
2+
13
/**
24
* @file SdFatContentProvider.h
35
* @brief DLNA content provider backed by SdFat filesystem directory tree.
@@ -30,6 +32,17 @@ namespace tiny_dlna {
3032
template<typename FS>
3133
classSdFatContentProvider {
3234
public:
35+
/**
36+
* @brief Set the base URL for resource URIs.
37+
* @param ip IP address of the server
38+
* @param port Port number
39+
* @param basePath Base path for files (e.g., "/files")
40+
*/
41+
voidsetBaseURL(const IPAddress& ip,int port,constchar* basePath) {
42+
baseIP_ = ip;
43+
basePort_ = port;
44+
basePath_ = basePath ? basePath :"/";
45+
}
3346
/**
3447
* @brief Initializes the content provider and scans the filesystem.
3548
* @param fs Filesystem instance (e.g., SdFs)
@@ -48,28 +61,6 @@ class SdFatContentProvider {
4861

4962
size_tsize() {return directoryTree.size(); }
5063

51-
protected:
52-
SdFatDirectoryTree<FS> directoryTree;
53-
54-
// Store query parameters for getData
55-
constchar* objectID_ =nullptr;
56-
ContentQueryType queryType_;
57-
constchar* filter_ =nullptr;
58-
int startingIndex_ =0;
59-
int requestedCount_ =0;
60-
constchar* sortCriteria_ =nullptr;
61-
void* reference_ =nullptr;
62-
63-
// Collected results from prepareData
64-
std::vector<TreeNode*, AllocatorPSRAM<TreeNode*>> resultNodes_;
65-
66-
// String storage for MediaItem pointers (lifetime managed by class)
67-
stringPSRAM currentId_;///< Current item ID string
68-
stringPSRAM currentParentId_;///< Current parent ID string
69-
stringPSRAM currentPath_;///< Current resource path string
70-
stringPSRAM currentMime_;///< Current MIME type string
71-
72-
public:
7364
/**
7465
* @brief Prepares data for a DLNA content query.
7566
*
@@ -156,19 +147,6 @@ class SdFatContentProvider {
156147
numberReturned);
157148
}
158149

159-
protected:
160-
/**
161-
* @brief Finds a tree node by its object ID string.
162-
* @param objectID Object ID as string (node's numeric id)
163-
* @return Pointer to the node, or nullptr if not found or invalid
164-
*/
165-
TreeNode*findNodeByObjectID(constchar* objectID) {
166-
if (!objectID)returnnullptr;
167-
uint32_t id =std::stoul(objectID);
168-
return &directoryTree.getTreeNodeById(id);
169-
}
170-
171-
public:
172150
/**
173151
* @brief Retrieves a single media item by index.
174152
*
@@ -229,15 +207,54 @@ class SdFatContentProvider {
229207
item.itemClass = MediaItemClass::Unknown;
230208
}
231209

232-
// Resource URI is the file path
233-
currentPath_ = directoryTree.path(node->id);
210+
// Resource URI: baseURL + basePath + ?ID=id
211+
char urlBuffer[128];
212+
snprintf(urlBuffer,sizeof(urlBuffer),"http://%u.%u.%u.%u:%d%s?ID=%u",
213+
baseIP_[0], baseIP_[1], baseIP_[2], baseIP_[3], basePort_,
214+
basePath_.c_str(), node->id);
215+
currentPath_ = urlBuffer;
234216
item.resourceURI = currentPath_.c_str();
235217
}
236218

237219
item.albumArtURI =nullptr;
238220

239221
returntrue;
240222
}
223+
224+
protected:
225+
IPAddress baseIP_;
226+
int basePort_ =0;
227+
stringPSRAM basePath_ ="/";
228+
SdFatDirectoryTree<FS> directoryTree;
229+
230+
// Store query parameters for getData
231+
constchar* objectID_ =nullptr;
232+
ContentQueryType queryType_;
233+
constchar* filter_ =nullptr;
234+
int startingIndex_ =0;
235+
int requestedCount_ =0;
236+
constchar* sortCriteria_ =nullptr;
237+
void* reference_ =nullptr;
238+
239+
// Collected results from prepareData
240+
std::vector<TreeNode*, AllocatorPSRAM<TreeNode*>> resultNodes_;
241+
242+
// String storage for MediaItem pointers (lifetime managed by class)
243+
stringPSRAM currentId_;///< Current item ID string
244+
stringPSRAM currentParentId_;///< Current parent ID string
245+
stringPSRAM currentPath_;///< Current resource path string
246+
stringPSRAM currentMime_;///< Current MIME type string
247+
248+
/**
249+
* @brief Finds a tree node by its object ID string.
250+
* @param objectID Object ID as string (node's numeric id)
251+
* @return Pointer to the node, or nullptr if not found or invalid
252+
*/
253+
TreeNode*findNodeByObjectID(constchar* objectID) {
254+
if (!objectID)returnnullptr;
255+
uint32_t id =std::stoul(objectID);
256+
return &directoryTree.getTreeNodeById(id);
257+
}
241258
};
242259

243260
}// namespace tiny_dlna

‎src/tools/SdFatDirectoryTree.h‎

Lines changed: 30 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,17 @@ class SdFatDirectoryTree {
3838
* @param beginPath Root path to start scanning from (defaults to "/").
3939
* @return true on success.
4040
*/
41-
42-
/// Starts the processing
4341
boolbegin(FS& SD,constchar* beginPath ="/") {
4442
this->p_sd = &SD;
4543
SD.chdir(beginPath);
46-
root_node.file_name = beginPath;
47-
buildTree(root_node);
44+
// Allocate root node as first entry in tree_nodes
45+
tree_nodes.clear();
46+
auto* root =newTreeNode();
47+
root->file_name = beginPath;
48+
root->parent =nullptr;
49+
root->id =0;
50+
tree_nodes.push_back(root);
51+
buildTree(*root);
4852
returntrue;
4953
}
5054

@@ -61,7 +65,7 @@ class SdFatDirectoryTree {
6165
/**
6266
* @brief Returns the root node of the tree.
6367
*/
64-
TreeNode&root() {returnroot_node; }
68+
TreeNode&root() {return*tree_nodes[0]; }
6569

6670
/**
6771
* @brief Finds a node by its numeric id.
@@ -79,7 +83,7 @@ class SdFatDirectoryTree {
7983
*/
8084
std::vector<TreeNode*, AllocatorPSRAM<TreeNode*>>getAllFiles() {
8185
std::vector<TreeNode*, AllocatorPSRAM<TreeNode*>> result;
82-
collectAllFilesFrom(root_node, result);
86+
if (!tree_nodes.empty())collectAllFilesFrom(*tree_nodes[0], result);
8387
return result;
8488
}
8589

@@ -92,14 +96,10 @@ class SdFatDirectoryTree {
9296
size_tsize() {return tree_nodes.size(); }
9397

9498
protected:
95-
TreeNode root_node;
9699
SdFatParser parser;
97100
FS* p_sd =nullptr;
98101
std::vector<TreeNode*, AllocatorPSRAM<TreeNode*>> tree_nodes;
99-
100-
// Temporary build-time state
101-
std::vector<TreeNode*>
102-
parents_;// parents_[level] holds parent at that level
102+
std::vector<TreeNode*> parent_stack;// stack for parent management
103103

104104
// Recursively collect all file nodes from a tree
105105
voidcollectAllFilesFrom(
@@ -117,59 +117,47 @@ class SdFatDirectoryTree {
117117
staticvoidonParsedCallback(SdFatFileInfo& info,void* ref) {
118118
auto* self =static_cast<SdFatDirectoryTree*>(ref);
119119
if (!self)return;
120+
TreeNode* root = self->tree_nodes[0];
121+
// Initialize stack with root if empty
122+
if (self->parent_stack.empty()) self->parent_stack.push_back(root);
120123

121-
TreeNode* root = &self->root_node;
122-
123-
// Ensure parents_ has at least the root at level 0
124-
if (self->parents_.empty()) self->parents_.push_back(root);
125-
126-
// Clamp/resize parents_ to cover current level
127-
if (info.level >=static_cast<int>(self->parents_.size())) {
128-
self->parents_.resize(static_cast<size_t>(info.level) +1,nullptr);
124+
// Ensure parent_stack has exactly info.level+1 elements (root at 0)
125+
while ((int)self->parent_stack.size() > info.level +1) {
126+
self->parent_stack.pop_back();
129127
}
130-
131-
TreeNode* parent =nullptr;
132-
if (info.level ==0) {
133-
parent = root;
134-
}else {
135-
parent = self->parents_[static_cast<size_t>(info.level)];
136-
if (parent ==nullptr) parent = root;// fallback safety
128+
while ((int)self->parent_stack.size() < info.level +1) {
129+
self->parent_stack.push_back(nullptr);
137130
}
138131

139-
// Create and populate the node
132+
TreeNode* parent = self->parent_stack[info.level];
133+
140134
auto* node =newTreeNode();
141135
assert(node !=nullptr);
142136
node->is_dir = info.is_directory;
143137
node->file_name = info.name;
144-
// Strip trailing '/' for directory names to keep path() consistent
145-
if (node->is_dir && !node->file_name.empty() &&
146-
node->file_name.back() =='/') {
147-
node->file_name.pop_back();
148-
}
149138
node->parent = parent;
150139
node->id =static_cast<uint32_t>(self->tree_nodes.size());
151-
152-
// Link into tree
153-
parent->children.push_back(node);
140+
if (parent !=nullptr) parent->children.push_back(node);
154141
self->tree_nodes.push_back(node);
155142

156-
//Set the parent for the next deeperlevel when thisis a directory
143+
//If this is a directory, ensure parent_stack[info.level+1] is thisnode
157144
if (node->is_dir) {
158-
if (self->parents_.size() <=static_cast<size_t>(info.level +1)) {
159-
self->parents_.resize(static_cast<size_t>(info.level +2),nullptr);
145+
if (self->parent_stack.size() <=static_cast<size_t>(info.level +1)) {
146+
self->parent_stack.resize(static_cast<size_t>(info.level +2),nullptr);
160147
}
161-
self->parents_[static_cast<size_t>(info.level +1)] = node;
148+
self->parent_stack[static_cast<size_t>(info.level +1)] = node;
162149
}
163150
}
164151

165152
voidbuildTree(TreeNode& node) {
166153
// Reset any previous children of the root
167154
node.children.clear();
168-
tree_nodes.clear();
155+
// Do not clear tree_nodes here; root is already allocated and in
156+
// tree_nodes[0]
169157

170158
// Prepare parsing context on this instance
171-
parents_.clear();
172-
parents_.push_back(&root_node);//level 0
159+
parent_stack.clear();
160+
parent_stack.push_back(tree_nodes[0]);//root on stack
173161

174162
parser.setCallback(&SdFatDirectoryTree::onParsedCallback,this);
175163

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp