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