1// ShareNode.cpp
2
3#include "ShareAttrDir.h"
4#include "ShareNode.h"
5
6// constructor
7ShareDirEntry::ShareDirEntry(ShareDir* directory, const char* name,
8	ShareNode* node)
9	: Referencable(true),
10	  fDirectory(directory),
11	  fName(name),
12	  fNode(node),
13	  fRevision(-1)
14{
15}
16
17// destructor
18ShareDirEntry::~ShareDirEntry()
19{
20}
21
22// InitCheck
23status_t
24ShareDirEntry::InitCheck() const
25{
26	if (fName.GetLength() == 0)
27		return B_NO_MEMORY;
28
29	return B_OK;
30}
31
32// GetDirectory
33ShareDir*
34ShareDirEntry::GetDirectory() const
35{
36	return fDirectory;
37}
38
39// GetName
40const char*
41ShareDirEntry::GetName() const
42{
43	return fName.GetString();
44}
45
46// GetNode
47ShareNode*
48ShareDirEntry::GetNode() const
49{
50	return fNode;
51}
52
53// SetRevision
54void
55ShareDirEntry::SetRevision(int64 revision)
56{
57	fRevision = revision;
58}
59
60// GetRevision
61int64
62ShareDirEntry::GetRevision() const
63{
64	return fRevision;
65}
66
67// IsActualEntry
68bool
69ShareDirEntry::IsActualEntry() const
70{
71	return (fName.GetLength() > 0 && fName != "." && fName != "..");
72}
73
74
75// #pragma mark -
76
77// constructor
78ShareNode::ShareNode(Volume* volume, vnode_id id, const NodeInfo* nodeInfo)
79	: Node(volume, id),
80	  fInfo(),
81	  fReferringEntries(),
82	  fAttrDir(NULL)
83{
84	if (nodeInfo) {
85		fInfo = *nodeInfo;
86	} else {
87		// init the stat data at least a bit, if no node info is given
88		fInfo.st.st_dev = -1;
89		fInfo.st.st_ino = -1;
90		fInfo.st.st_mode = S_IFDIR | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP
91			| S_IROTH | S_IXOTH;
92		fInfo.st.st_nlink = 1;
93		fInfo.st.st_size = 1;
94		fInfo.st.st_blksize = 1024;
95		fInfo.st.st_crtime = 0;
96		fInfo.st.st_ctime = fInfo.st.st_mtime = fInfo.st.st_atime
97			= fInfo.st.st_crtime;
98
99		// negative revision, to make sure it is updated
100		fInfo.revision = -1;
101	}
102}
103
104// destructor
105ShareNode::~ShareNode()
106{
107	delete fAttrDir;
108}
109
110// GetNodeInfo
111const NodeInfo&
112ShareNode::GetNodeInfo() const
113{
114	return fInfo;
115}
116
117// GetRemoteID
118NodeID
119ShareNode::GetRemoteID() const
120{
121	return fInfo.GetID();
122}
123
124// Update
125void
126ShareNode::Update(const NodeInfo& nodeInfo)
127{
128	if (fInfo.revision < nodeInfo.revision)
129		fInfo = nodeInfo;
130}
131
132// AddReferringEntry
133void
134ShareNode::AddReferringEntry(ShareDirEntry* entry)
135{
136	if (entry)
137		fReferringEntries.Insert(entry);
138}
139
140// RemoveReferringEntry
141void
142ShareNode::RemoveReferringEntry(ShareDirEntry* entry)
143{
144	if (entry)
145		fReferringEntries.Remove(entry);
146}
147
148// GetFirstReferringEntry
149ShareDirEntry*
150ShareNode::GetFirstReferringEntry() const
151{
152	return fReferringEntries.GetFirst();
153}
154
155// GetNextReferringEntry
156ShareDirEntry*
157ShareNode::GetNextReferringEntry(ShareDirEntry* entry) const
158{
159	return (entry ? fReferringEntries.GetNext(entry) : NULL);
160}
161
162// GetActualReferringEntry
163ShareDirEntry*
164ShareNode::GetActualReferringEntry() const
165{
166	for (ShareDirEntry* entry = GetFirstReferringEntry();
167		 entry;
168		 entry = GetNextReferringEntry(entry)) {
169		if (entry->IsActualEntry())
170			return entry;
171	}
172
173	return NULL;
174}
175
176// SetAttrDir
177void
178ShareNode::SetAttrDir(ShareAttrDir* attrDir)
179{
180	delete fAttrDir;
181	fAttrDir = attrDir;
182}
183
184// GetAttrDir
185ShareAttrDir*
186ShareNode::GetAttrDir() const
187{
188	return fAttrDir;
189}
190
191
192// #pragma mark -
193
194// constructor
195ShareDirIterator::ShareDirIterator()
196{
197}
198
199// destructor
200ShareDirIterator::~ShareDirIterator()
201{
202}
203
204
205// #pragma mark -
206
207// constructor
208LocalShareDirIterator::LocalShareDirIterator()
209	: fDirectory(NULL),
210	  fCurrentEntry(NULL)
211{
212}
213
214// destructor
215LocalShareDirIterator::~LocalShareDirIterator()
216{
217	SetDirectory(NULL);
218}
219
220// SetDirectory
221void
222LocalShareDirIterator::SetDirectory(ShareDir* directory)
223{
224	// unset the old directory
225	if (fDirectory)
226		fDirectory->RemoveDirIterator(this);
227
228	// set the new directory
229	fDirectory = directory;
230	if (fDirectory) {
231		fDirectory->AddDirIterator(this);
232		fCurrentEntry = fDirectory->GetFirstEntry();
233	}
234}
235
236// GetCurrentEntry
237ShareDirEntry*
238LocalShareDirIterator::GetCurrentEntry() const
239{
240	return fCurrentEntry;
241}
242
243// NextEntry
244void
245LocalShareDirIterator::NextEntry()
246{
247	if (!fDirectory || !fCurrentEntry)
248		return;
249
250	fCurrentEntry = fDirectory->GetNextEntry(fCurrentEntry);
251}
252
253// Rewind
254void
255LocalShareDirIterator::Rewind()
256{
257	fCurrentEntry = (fDirectory ? fDirectory->GetFirstEntry() : NULL);
258}
259
260// IsDone
261bool
262LocalShareDirIterator::IsDone() const
263{
264	return !fCurrentEntry;
265}
266
267
268// #pragma mark -
269
270// constructor
271RemoteShareDirIterator::RemoteShareDirIterator()
272	: fCookie(-1),
273	  fCapacity(kRemoteShareDirIteratorCapacity),
274	  fCount(0),
275	  fIndex(0),
276	  fRevision(-1),
277	  fDone(false),
278	  fRewind(false)
279{
280}
281
282// destructor
283RemoteShareDirIterator::~RemoteShareDirIterator()
284{
285	Clear();
286}
287
288// GetCurrentEntry
289ShareDirEntry*
290RemoteShareDirIterator::GetCurrentEntry() const
291{
292	return (!fRewind && fIndex < fCount ? fEntries[fIndex] : NULL);
293}
294
295// NextEntry
296void
297RemoteShareDirIterator::NextEntry()
298{
299	if (fIndex < fCount)
300		fIndex++;
301}
302
303// Rewind
304void
305RemoteShareDirIterator::Rewind()
306{
307	fRewind = true;
308	fDone = false;
309}
310
311// IsDone
312bool
313RemoteShareDirIterator::IsDone() const
314{
315	return fDone;
316}
317
318// GetCapacity
319int32
320RemoteShareDirIterator::GetCapacity() const
321{
322	return fCapacity;
323}
324
325// SetCookie
326void
327RemoteShareDirIterator::SetCookie(int32 cookie)
328{
329	fCookie = cookie;
330}
331
332// GetCookie
333int32
334RemoteShareDirIterator::GetCookie() const
335{
336	return fCookie;
337}
338
339// Clear
340void
341RemoteShareDirIterator::Clear()
342{
343	for (int32 i = 0; i < fCount; i++)
344		fEntries[i]->RemoveReference();
345	fCount = 0;
346	fIndex = 0;
347	fDone = false;
348	fRewind = false;
349}
350
351// AddEntry
352bool
353RemoteShareDirIterator::AddEntry(ShareDirEntry* entry)
354{
355	if (!entry || fCount >= fCapacity)
356		return false;
357
358	fEntries[fCount++] = entry;
359	entry->AddReference();
360	return true;
361}
362
363// SetRevision
364void
365RemoteShareDirIterator::SetRevision(int64 revision)
366{
367	fRevision = revision;
368}
369
370// GetRevision
371int64
372RemoteShareDirIterator::GetRevision() const
373{
374	return fRevision;
375}
376
377// SetDone
378void
379RemoteShareDirIterator::SetDone(bool done)
380{
381	fDone = done;
382}
383
384// GetRewind
385bool
386RemoteShareDirIterator::GetRewind() const
387{
388	return fRewind;
389}
390
391
392// #pragma mark -
393
394// constructor
395ShareDir::ShareDir(Volume* volume, vnode_id id, const NodeInfo* nodeInfo)
396	: ShareNode(volume, id, nodeInfo),
397	  fEntries(),
398	  fIterators(),
399	  fEntryCreatedEventRevision(-1),
400	  fEntryRemovedEventRevision(-1),
401	  fIsComplete(false)
402{
403}
404
405// destructor
406ShareDir::~ShareDir()
407{
408}
409
410// UpdateEntryCreatedEventRevision
411void
412ShareDir::UpdateEntryCreatedEventRevision(int64 revision)
413{
414	if (revision > fEntryCreatedEventRevision)
415		fEntryCreatedEventRevision = revision;
416}
417
418// GetEntryCreatedEventRevision
419int64
420ShareDir::GetEntryCreatedEventRevision() const
421{
422	return fEntryCreatedEventRevision;
423}
424
425// UpdateEntryRemovedEventRevision
426void
427ShareDir::UpdateEntryRemovedEventRevision(int64 revision)
428{
429	if (revision > fEntryRemovedEventRevision)
430		fEntryRemovedEventRevision = revision;
431}
432
433// GetEntryRemovedEventRevision
434int64
435ShareDir::GetEntryRemovedEventRevision() const
436{
437	return fEntryRemovedEventRevision;
438}
439
440// SetComplete
441void
442ShareDir::SetComplete(bool complete)
443{
444	fIsComplete = complete;
445}
446
447// IsComplete
448bool
449ShareDir::IsComplete() const
450{
451	return fIsComplete;
452}
453
454// AddEntry
455void
456ShareDir::AddEntry(ShareDirEntry* entry)
457{
458	if (entry)
459		fEntries.Insert(entry);
460}
461
462// RemoveEntry
463void
464ShareDir::RemoveEntry(ShareDirEntry* entry)
465{
466	if (entry) {
467		// update the directory iterators pointing to the removed entry
468		for (LocalShareDirIterator* iterator = fIterators.GetFirst();
469			 iterator;
470			 iterator = fIterators.GetNext(iterator)) {
471			if (iterator->GetCurrentEntry() == entry)
472				iterator->NextEntry();
473		}
474
475		fEntries.Remove(entry);
476	}
477}
478
479// GetFirstEntry
480ShareDirEntry*
481ShareDir::GetFirstEntry() const
482{
483	return fEntries.GetFirst();
484}
485
486// GetNextEntry
487ShareDirEntry*
488ShareDir::GetNextEntry(ShareDirEntry* entry) const
489{
490	if (!entry)
491		return NULL;
492
493	return fEntries.GetNext(entry);
494}
495
496// AddDirIterator
497void
498ShareDir::AddDirIterator(LocalShareDirIterator* iterator)
499{
500	if (!iterator)
501		return;
502
503	fIterators.Insert(iterator);
504}
505
506// RemoveDirIterator
507void
508ShareDir::RemoveDirIterator(LocalShareDirIterator* iterator)
509{
510	if (!iterator)
511		return;
512
513	fIterators.Remove(iterator);
514}
515
516