2
2
// SPDX-License-Identifier: MIT
3
3
#include " ../../FileSystemWatcher/FileSystemWatcher.h"
4
4
5
+ #include " ../../Foundation/Assert.h"
5
6
#include " ../../Foundation/Deferred.h"
6
- #include " ../../Memory/Buffer.h"
7
7
#include " ../../Threading/Threading.h"
8
8
9
9
#include < dirent.h> // opendir, readdir, closedir
@@ -29,9 +29,12 @@ struct SC::FileSystemWatcher::FolderWatcherInternal
29
29
Pair notifyHandles[FolderWatcherSizes::MaxNumberOfSubdirs];
30
30
size_t notifyHandlesCount = 0 ;
31
31
32
- Buffer relativePaths;
32
+ char relativePathsStorage[1024 ];
33
+ StringSpan::NativeWritable relativePaths;
33
34
34
35
FolderWatcher* parentEntry = nullptr ; // We could in theory use SC_COMPILER_FIELD_OFFSET somehow to obtain it...
36
+
37
+ FolderWatcherInternal () { relativePaths.writableSpan = {relativePathsStorage}; }
35
38
};
36
39
37
40
struct SC ::FileSystemWatcher::ThreadRunnerInternal
@@ -116,8 +119,8 @@ struct SC::FileSystemWatcher::Internal
116
119
const int res = ::inotify_rm_watch (rootNotifyFd, folderInternal.notifyHandles [idx].notifyID );
117
120
SC_TRY_MSG (res != -1 , " inotify_rm_watch" );
118
121
}
119
- folderInternal.notifyHandlesCount = 0 ; // Reset the count to zero
120
- folderInternal.relativePaths .clear () ;
122
+ folderInternal.notifyHandlesCount = 0 ; // Reset the count to zero
123
+ folderInternal.relativePaths .length = 0 ;
121
124
return Result (true );
122
125
}
123
126
@@ -128,6 +131,11 @@ struct SC::FileSystemWatcher::Internal
128
131
SC_TRY_MSG (entry->path .path .view ().getEncoding () != StringEncoding::Utf16,
129
132
" FolderWatcher on Linux does not support UTF16 encoded paths. Use UTF8 or ASCII encoding instead." );
130
133
FolderWatcherInternal& opaque = entry->internal .get ();
134
+ if (not entry->subFolderRelativePathsBuffer .empty ())
135
+ {
136
+ opaque.relativePaths .writableSpan = entry->subFolderRelativePathsBuffer ;
137
+ }
138
+ opaque.relativePaths .length = 0 ;
131
139
132
140
char currentPath[PATH_MAX];
133
141
::memcpy (currentPath, entry->path.path.view().getNullTerminatedNative(), entry->path.path.view().sizeInBytes());
@@ -247,8 +255,10 @@ struct SC::FileSystemWatcher::Internal
247
255
relativePath++;
248
256
}
249
257
pair.notifyID = newHandle;
250
- pair.nameOffset = opaque.relativePaths .size ();
251
- SC_TRY (opaque.relativePaths .append ({relativePath, ::strlen (relativePath) + 1 }));
258
+ pair.nameOffset = opaque.relativePaths .length == 0 ? 0 : opaque.relativePaths .length + 1 ;
259
+ StringSpan relativePathSpan = StringSpan::fromNullTerminated (relativePath, StringEncoding::Utf8);
260
+ SC_TRY_MSG (relativePathSpan.appendNullTerminatedTo (opaque.relativePaths , false ),
261
+ " Not enough buffer space to hold sub-folders relative paths" );
252
262
253
263
SC_TRY_MSG (opaque.notifyHandlesCount < FolderWatcherSizes::MaxNumberOfSubdirs,
254
264
" Too many subdirectories being watched" );
@@ -375,7 +385,9 @@ struct SC::FileSystemWatcher::Internal
375
385
{
376
386
// Something changed in any of the sub folders of the original root folder being watched
377
387
const FolderWatcherInternal& internal = entry->internal .get ();
378
- const char * dirStart = internal.relativePaths .data () + internal.notifyHandles [foundIndex].nameOffset ;
388
+
389
+ const char * dirStart =
390
+ internal.relativePaths .writableSpan .data () + internal.notifyHandles [foundIndex].nameOffset ;
379
391
380
392
const StringSpan relativeDirectory ({dirStart, ::strlen (dirStart)}, true , StringEncoding::Utf8);
381
393
const StringSpan relativeName ({event->name , event->len - 1 }, true , StringEncoding::Utf8);
0 commit comments