コード例 #1
0
        public static DataContext CreateContext(IDataFileProvider dataFileProvider)
        {
            // Look for classes that extend DataContext
            var types = Assembly.GetExecutingAssembly().GetTypes().Where(t => t.IsSubclassOf(typeof(DataContext)));

            foreach (var type in types)
            {
                // having attribute DataContextAttribute
                var dataContextAttribute = (DataContextAttribute)type.GetCustomAttributes(typeof(DataContextAttribute), false).FirstOrDefault();
                if (dataContextAttribute != null)
                {
                    DataContext context = (DataContext)Activator.CreateInstance(type);

                    // Look for plugin specified by the attribute
                    if (dataFileProvider.GetDataFile(FileMode.Open, dataContextAttribute.PluginFileName).Exists() && dataFileProvider.DataFolderPath.Contains(context.GetGameInstallPath()))
                    {
                        // Pass data provider to the context
                        context.DataFileProvider = dataFileProvider;
                        return(context);
                    }
                }
            }

            throw new InvalidDataException("Unable to determine a suitable data context.");
        }
コード例 #2
0
ファイル: DataFile.cs プロジェクト: tstavrianos/patcher
        /// <summary>
        /// Copies a stream into the current data file, optionally only if does not exists and contains different data.
        /// </summary>
        /// <param name="input">The Stream to copy data from.</param>
        /// <param name="updateOnly">If true, file will not be recreated if already exists and contains the same data.</param>
        /// <returns>Returns true if file has been created or updated.</returns>
        public bool CopyFrom(Stream input, bool updateOnly)
        {
            if (mode == FileMode.Open)
            {
                throw new InvalidOperationException("Cannot write into data file retrieved using the FileMode.Open mode.");
            }

            // Non-data files such as plugin.txt do not have a request path relative to the data folder
            // TODO: Do not provide non-data files via DataFileProvider
            if (RequestedPath == null)
            {
                throw new InvalidOperationException("Cannot write into a special data file.");
            }

            if (updateOnly)
            {
                // Look if file already exists
                // To check whether it needs to be updated
                // Retreive new file from the provider with FileMode.Open
                var existingFile = provider.GetDataFile(FileMode.Open, RequestedPath);
                if (existingFile.Exists())
                {
                    using (var existingStream = existingFile.Open())
                    {
                        // If input is not memory stream, create one and copy the data from the input stream into it
                        MemoryStream memoryStream = input as MemoryStream;
                        if (memoryStream == null)
                        {
                            // Initialize memory stream as big as the existing stream length if imput steam is not seekable
                            int initialMemoryStreamLength = input.CanSeek ? (int)input.Length : (int)existingStream.Length;
                            memoryStream = new MemoryStream(initialMemoryStreamLength);
                            input.CopyTo(memoryStream);
                            memoryStream.Position = 0;
                        }

                        // Compare existing stream with input stream (or memory stream where input stream was copied into)
                        if (StreamComparer.Compare(existingStream, memoryStream))
                        {
                            Log.Fine("Cached file {0} is up to date.", existingFile.FullPath);
                            return(false);
                        }

                        // Reset memeory stream after comparison
                        memoryStream.Position = 0;

                        // Use memory stream (where input stream has been copied into) instead of input stream
                        // when updating existing file
                        if (input != memoryStream)
                        {
                            input = memoryStream;
                        }

                        Log.Fine("Cached file {0} exists but is no longer valid and will be updated.", existingFile.FullPath);
                    }
                }
                else
                {
                    Log.Fine("File {0} is not cached and will be created.", existingFile.FullPath);
                }
            }

            using (var newStream = Open())
            {
                input.CopyTo(newStream);
            }

            return(true);
        }