-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathStreamCollection.cs
132 lines (100 loc) · 3.99 KB
/
StreamCollection.cs
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
/*
The contents of this file are subject to the Mozilla Public License
Version 1.1 (the "License"); you may not use this file except in
compliance with the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
License for the specific language governing rights and limitations
under the License.
The Original Code is DataMangler Key-Value Store.
The Initial Developer of the Original Code is Mozilla Corporation.
Original Author: Kevin Gadd (kevin.gadd@gmail.com)
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace Squared.Data.Mangler {
public abstract class StreamSource : IDisposable {
abstract internal Internal.StreamRef Open (string streamName);
abstract public void Dispose ();
}
public abstract class CachingStreamSourceBase : StreamSource {
protected readonly Dictionary<string, FileStream> Streams = new Dictionary<string, FileStream>();
override internal Internal.StreamRef Open (string streamName) {
FileStream result;
if (!Streams.TryGetValue(streamName, out result)) {
result = OpenStream(streamName);
Streams[streamName] = result;
}
return new Internal.StreamRef(result, false);
}
protected abstract FileStream OpenStream (string streamName);
override public void Dispose () {
foreach (var stream in Streams.Values)
stream.Dispose();
Streams.Clear();
}
}
public class SubStreamSource : StreamSource {
private readonly StreamSource Inner;
public readonly string Prefix;
public readonly bool OwnsInnerSource;
public SubStreamSource (StreamSource inner, string prefix, bool ownsInnerSource=true) {
Inner = inner;
Prefix = prefix;
OwnsInnerSource = ownsInnerSource;
}
internal override Internal.StreamRef Open (string streamName) {
return Inner.Open(Prefix + streamName);
}
public override void Dispose () {
if (OwnsInnerSource)
Inner.Dispose();
}
}
public class AlternateStreamSource : CachingStreamSourceBase {
public readonly string Filename;
public AlternateStreamSource (string filename) {
Filename = filename;
}
protected override FileStream OpenStream (string streamName) {
return Internal.Native.OpenAlternateStream(Filename, streamName);
}
}
public class FolderStreamSource : CachingStreamSourceBase {
private string _Folder;
public FolderStreamSource (string folder) {
_Folder = folder;
}
protected static string GetPath (string folder, string streamName) {
return Path.Combine(folder, streamName);
}
protected override FileStream OpenStream (string streamName) {
var path = GetPath(_Folder, streamName);
return File.Open(path, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Delete | FileShare.ReadWrite);
}
public string Folder {
get {
return _Folder;
}
set {
if (value == _Folder)
return;
var oldFolder = _Folder;
Dispose();
Directory.CreateDirectory(value);
foreach (var filename in Directory.GetFiles(oldFolder)) {
var newFilename = Path.Combine(value, Path.GetFileName(filename));
if (File.Exists(newFilename))
File.Delete(newFilename);
File.Move(filename, newFilename);
}
_Folder = value;
Directory.Delete(oldFolder, true);
}
}
}
}