コード例 #1
0
        public async static Task <String> ReadFile(File file)
        {
            using (AtomicFile mFile = new AtomicFile(file))
            {
                // Wait for file to be free
                while (IsFileLocked(file))
                {
                    await Task.Delay(100);
                }

                String data;

                using (BufferedReader reader = new BufferedReader(new InputStreamReader(mFile.OpenRead())))
                {
                    String line = await reader.ReadLineAsync();

                    StringBuilder sBuilder = new StringBuilder();

                    while (line != null)
                    {
                        sBuilder.Append(line).Append("\n");
                        line = await reader.ReadLineAsync();
                    }

                    reader.Dispose();
                    data = sBuilder.ToString();
                }

                return(data);
            }
        }
コード例 #2
0
 public void CanWrite()
 {
     using (var container = TemporaryDirectory.CreateNew())
     {
         var sut = new AtomicFile <int>(container.File("key-path"), new StubSerialiser());
         sut.Write(42);
     }
 }
コード例 #3
0
        public void CanDeleteWrittenValue()
        {
            using (var container = TemporaryDirectory.CreateNew())
            {
                var sut = new AtomicFile <int>(container.File("key-path"), new StubSerialiser());
                sut.Write(42);
                sut.Delete();

                Assert.That(sut.Read(), Is.EqualTo(default(int)));
            }
        }
コード例 #4
0
        public void CanReplaceWrittenValue()
        {
            using (var container = TemporaryDirectory.CreateNew())
            {
                var sut = new AtomicFile <int>(container.File("key-path"), new StubSerialiser());
                sut.Write(42);
                sut.Write(23);

                var value = sut.Read();

                Assert.That(value, Is.EqualTo(23));
            }
        }
コード例 #5
0
        public void FailedWriteDoesNotOverwriteExistingValue()
        {
            using (var container = TemporaryDirectory.CreateNew())
            {
                var sut = new AtomicFile <int>(container.File("key-path"), new StubSerialiser());
                sut.Write(42);
                Assume.That(sut.Read(), Is.EqualTo(42));

                var failing = new AtomicFile <int>(container.File("key-path"), new RandomlyFailingSerialiser <int>(new StubSerialiser(), 1));
                Assume.That(() => failing.Write(23), Throws.InstanceOf <IOException>());

                Assert.That(sut.Read(), Is.EqualTo(42));
            }
        }
コード例 #6
0
        /// <summary>
        /// Enumerate all derived mods from a list of mods
        /// </summary>
        /// <param name="ModList"></param>
        private void EnumerateMods()
        {
            DirectoryInfo    location = new DirectoryInfo(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
            HashSet <string> suppress = AtomicFile.ReadStream(Path.Combine(location.FullName, "loader.suppress"), false).ReadAllText().Split('\n', '\r', ' ', '\t')
                                        .ToSet();

            suppress.RemoveAll((string x) => x.Trim().Length == 0);
            List <Type> ModList = new List <Type>();

            foreach (FileInfo AssemblyDll in location.GetFiles("*.dll").Concat(location.GetFiles("*.exe")))
            {
                HashSet <string>    source    = suppress;
                Func <string, bool> predicate = (string suppression) => AssemblyDll.FullName.IndexOf(suppression, StringComparison.OrdinalIgnoreCase) != -1;
                if (!source.Any(predicate) && File.Exists(Path.ChangeExtension(AssemblyDll.FullName, ".mod")))
                {
                    try
                    {
                        foreach (Type AssemblyType in Assembly.LoadFrom(AssemblyDll.FullName).GetTypes())
                        {
                            if (!AssemblyType.IsAbstract && AssemblyType.IsClass && typeof(SunbeamMod).IsAssignableFrom(AssemblyType))
                            {
                                ModList.Add(AssemblyType);
                            }
                        }
                    }
                    catch (ReflectionTypeLoadException e)
                    {}
                }
            }

            Logger.WriteLine("SunbeamController.EnumerateMods: Found " + ModList.Count + " mods.");

            foreach (Type ModType in ModList)
            {
                try
                {
                    SunbeamMod Mod = (SunbeamMod)Activator.CreateInstance(ModType);
                    Mod.ApplyHarmonyPatches();
                    Mod.Initialize();

                    Logger.WriteLine("SunbeamController.EnumerateMods: Loaded mod '" + Mod.ModIdentifier + "'");
                    this.Mods.Add(Mod);
                }
                catch (Exception e)
                {
                    Logger.WriteLine("SunbeamController.EnumerateMods: Exception thrown - " + e.ToString());
                }
            }
        }
コード例 #7
0
        public async Task FuzzConcurrentAccess()
        {
            const int threadCount             = 5;
            const int iterationCountPerThread = 25;

            var writtenValues = new List <int>();
            var random        = new Random();
            var failures      = new List <Exception>();

            using (var container = TemporaryDirectory.CreateNew())
            {
                var path = container.File("key-path");
                await ConcurrentOperations.Run(threadCount, () => {
                    var sut = new AtomicFile <int>(path, new RandomlyFailingSerialiser <int>(new StubSerialiser(), 0.05));
                    for (var i = 0; i < iterationCountPerThread; i++)
                    {
                        try
                        {
                            var value = random.Next(100);
                            sut.Write(value);
                            lock (writtenValues) writtenValues.Add(value);
                        }
                        catch (FileLockedException)
                        {
                            // We expect locking conflicts to represent the bulk of failures.
                        }
                        catch (Exception ex)
                        {
                            lock (failures) failures.Add(ex);
                        }
                        try
                        {
                            sut.Read();
                        }
                        catch (Exception) { }
                    }
                });

                var finalValue = new AtomicFile <int>(path, new StubSerialiser()).Read();

                // At least one write should succeed.
                Assume.That(writtenValues.Count, Is.GreaterThan(1));

                // Due to races it's not guaranteed that the last entry in the list is the last one successfully written.
                // However, this should be vanishingly unlikely because it would require that another Write call ran to
                // completion between `sut.Write(value);` and `lock (writtenValues)`.
                Assert.That(finalValue, Is.EqualTo(writtenValues.Last()));
            }
        }
コード例 #8
0
        public void CanAccessViaMultipleInstances()
        {
            using (var container = TemporaryDirectory.CreateNew())
            {
                var sut1 = new AtomicFile <int>(container.File("key-path"), new StubSerialiser());
                var sut2 = new AtomicFile <int>(container.File("key-path"), new StubSerialiser());
                var sut3 = new AtomicFile <int>(container.File("key-path"), new StubSerialiser());
                sut1.Write(42);
                sut2.Write(17);
                sut3.Write(23);

                var value = sut2.Read();

                Assert.That(value, Is.EqualTo(23));
            }
        }
コード例 #9
0
        public static Task <T> DeserializerAsync <T>(Java.IO.File file)
#endif
        {
            return(Task.Run(async() =>
            {
                // Wait for file to be free
                while (FileUtils.IsFileLocked(file))
                {
                    await Task.Delay(100).ConfigureAwait(false);
                }

                Stream fStream = null;
                StreamReader sReader = null;
                JsonReader reader = null;
                var obj = default(T);
#if __ANDROID__
                var mFile = new AtomicFile(file);
                try
                {
                    fStream = mFile.OpenRead();
#else
                try
                {
                    fStream = new FileStream(file.Path, FileMode.Open, FileAccess.Read);
#endif
                    sReader = new StreamReader(fStream);
                    reader = new JsonTextReader(sReader);

                    var serializer = JsonSerializer.Create(DefaultSettings);
                    obj = serializer.Deserialize <T>(reader);
                }
                catch (Exception ex)
                {
                    Logger.WriteLine(LoggerLevel.Error, ex, "SimpleWeather: JSONParser: error deserializing or with file");
                    obj = default(T);
                }
                finally
                {
                    reader?.Close();
#if __ANDROID__
                    mFile?.Dispose();
#endif
                }

                return obj;
            }));
        }
コード例 #10
0
        public static void Serializer(Object obj, Java.IO.File file)
        {
            Task.Run(async() =>
            {
                // Wait for file to be free
                while (FileUtils.IsFileLocked(file))
                {
                    await Task.Delay(100).ConfigureAwait(false);
                }

                var mFile             = new AtomicFile(file);
                Stream fStream        = null;
                JsonTextWriter writer = null;

                try
                {
                    fStream = mFile.StartWrite();

                    writer = new JsonTextWriter(new StreamWriter(fStream))
                    {
                        CloseOutput = false,
                    };

                    var serializer = JsonSerializer.Create(DefaultSettings);
                    serializer.Serialize(writer, obj);
                    await writer.FlushAsync().ConfigureAwait(false);
                    mFile.FinishWrite(fStream);
                }
                catch (Exception ex)
                {
                    Logger.WriteLine(LoggerLevel.Error, ex, "SimpleWeather: JSONParser: error serializing or with file");

                    if (mFile != null && fStream != null)
                    {
                        mFile.FailWrite(fStream);
                    }
                }
                finally
                {
                    mFile?.Dispose();
                    writer?.Close();
                }
            }).ConfigureAwait(false);
        }
コード例 #11
0
        public static async Task WriteFile(String data, File file)
        {
            using (AtomicFile mFile = new AtomicFile(file))
            {
                // Wait for file to be free
                while (IsFileLocked(file))
                {
                    await Task.Delay(100);
                }

                using (System.IO.Stream outputStream = mFile.StartWrite())
                    using (System.IO.StreamWriter writer = new System.IO.StreamWriter(outputStream))
                    {
                        // Clear file before writing
                        outputStream.SetLength(0);

                        await writer.WriteAsync(data);

                        await writer.FlushAsync();

                        mFile.FinishWrite(outputStream);
                    }
            }
        }
コード例 #12
0
 /// <summary>
 /// Retrieve a file's content as text from the mod directory
 /// </summary>
 /// <param name="assetPath"></param>
 /// <returns></returns>
 public string ReadFileContent(string assetPath)
 {
     assetPath = Path.GetFullPath(Path.Combine(this.ModDirectory, assetPath));
     return(AtomicFile.ReadText(assetPath, true));
 }