public void ShouldDecryptFile() { using (var fsEncrypted = new FileStream("Resources/encrypted-a.tps", FileMode.Open)) using (var fsUnencrypted = new FileStream("Resources/not-encrypted.tps", FileMode.Open)) { var encryptedFile = new TpsFile(fsEncrypted, new Key("a")); var decryptedFile = new TpsFile(fsUnencrypted); var encryptedDefinitions = encryptedFile.GetTableDefinitions(ignoreErrors: false); var decryptedDefinitions = decryptedFile.GetTableDefinitions(ignoreErrors: false); Assert.AreEqual(decryptedDefinitions.Count, encryptedDefinitions.Count); // Note that record IDs may differ. var encryptedRecords = encryptedFile.GetDataRecords(table: 2, tableDefinition: encryptedDefinitions[2], ignoreErrors: false); var decryptedRecords = decryptedFile.GetDataRecords(table: 1, tableDefinition: decryptedDefinitions[1], ignoreErrors: false); Assert.AreEqual(decryptedRecords.Count(), encryptedRecords.Count()); var zip = decryptedRecords.Zip(encryptedRecords, (d, e) => (dec: d, enc: e)); foreach (var(dec, enc) in zip) { CollectionAssert.AreEqual(dec.Values, enc.Values); } } }
/// <summary> /// Gets a high level representation of the first table in the file. /// </summary> /// <param name="ignoreErrors">If true, the reader will not throw an exception when it encounters unexpected data.</param> /// <returns></returns> public Table BuildTable(bool ignoreErrors = false) { var tableNameDefinitions = TpsFile.GetTableNameRecords(); var tableDefinitions = TpsFile.GetTableDefinitions(ignoreErrors: ignoreErrors); var firstTableDefinition = tableDefinitions.First(); var dataRecords = GatherDataRecords(firstTableDefinition.Key, firstTableDefinition.Value, ignoreErrors); var memoRecords = GatherMemoRecords(firstTableDefinition.Key, firstTableDefinition.Value, ignoreErrors); IEnumerable <(int recordNumber, IReadOnlyDictionary <string, TpsObject> nameValuePairs)> unifiedRecords = Enumerable.Concat(dataRecords, memoRecords) .GroupBy(numberNVPairs => numberNVPairs.recordNumber) .Select(groupedNumberNVPairs => ( recordNumber: groupedNumberNVPairs.Key, nameValuePairs: (IReadOnlyDictionary <string, TpsObject>)groupedNumberNVPairs .SelectMany(pair => pair.nameValuePairs) .ToDictionary(kv => kv.Key, kv => kv.Value))); var rows = unifiedRecords.Select(r => new Row(r.recordNumber, r.nameValuePairs)); string tableName = tableNameDefinitions .First(n => n.TableNumber == firstTableDefinition.Key).Header.Name; var table = new Table(tableName, rows); return(table); }
public void ShouldFailToReadEncryptedFileWithoutPassword() { using (var fsEncrypted = new FileStream("Resources/encrypted-a.tps", FileMode.Open)) { var encryptedFile = new TpsFile(fsEncrypted); Assert.Throws <NotATopSpeedFileException>(() => encryptedFile.GetHeader()); } }
internal IEnumerable <T> DeserializeInternal <T>(bool ignoreErrors, CancellationToken ct) where T : class, new() { var firstTableDefinition = TpsFile.GetTableDefinitions(ignoreErrors).First(); var dataRecords = TpsFile.GetDataRecords(firstTableDefinition.Key, firstTableDefinition.Value, ignoreErrors) .ToDictionary(r => r.RecordNumber, r => r.Values); var memoRecords = GatherMemoRecords(firstTableDefinition.Key, firstTableDefinition.Value, ignoreErrors); var columns = BuildColumnLookup(firstTableDefinition.Value.Fields.Select(f => f.Name.ToUpperInvariant())); foreach (var dataRecord in dataRecords) { int recordNumber = dataRecord.Key; var values = dataRecord.Value; T target = new T(); var members = DeserializerContext.GetModelMembers <T>(target); foreach (var member in members) { if (member.IsRecordNumber) { member.SetMember(target, recordNumber); } else { string requestedField = member.FieldAttribute.FieldName.ToUpperInvariant(); if (columns.TryGetValue(requestedField, out int index)) { object interpretedValue = member.FieldAttribute.InterpretValue(member.MemberInfo, values[index]); member.SetMember(target, interpretedValue); } else if (memoRecords.TryGetValue(recordNumber, out var fieldValueDictionary) && fieldValueDictionary.ToDictionary(fv => fv.Key.ToUpperInvariant(), fv => fv.Value).TryGetValue(requestedField, out TpsObject value)) { object interpretedValue = member.FieldAttribute.InterpretValue(member.MemberInfo, value); member.SetMember(target, interpretedValue); } else if (member.FieldAttribute.IsRequired) { throw new TpsParserException($"The required field '{requestedField}' could not be found in record {recordNumber}."); } } ct.ThrowIfCancellationRequested(); } yield return(target); ct.ThrowIfCancellationRequested(); } }
public void ShouldParseHeader() { var file = new TpsFile(new FileStream("Resources/header.dat", FileMode.Open)); var header = file.GetHeader(); Assert.IsTrue(header.IsTopSpeedFile); Assert.AreEqual(383744, header.FileLength1); Assert.AreEqual(5048, header.LastIssuedRow); Assert.AreEqual(15651, header.Changes); Assert.AreEqual(60, header.PageStart.Count); Assert.AreEqual(60, header.PageEnd.Count); }
public void ShouldReadFromFile() { using (var stream = new FileStream("Resources/table-with-time.tps", FileMode.Open)) { var file = new TpsFile(stream); var tableDef = file.GetTableDefinitions(false).First().Value; var record = file.GetDataRecords(1, tableDef, false).First(); var valuePairs = record.GetFieldValuePairs(); Assert.AreEqual(new TimeSpan(0, 6, 23, 15, 0), valuePairs["ClockIn"].Value); Assert.AreEqual(new TimeSpan(0, 12, 59, 59, 0), valuePairs["ClockOut"].Value); } }
public static int Print(Options options) { FileStream file; try { file = File.Open(options.InputFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); } catch (FileNotFoundException) { Console.WriteLine("File '{0}' was not found.", options.InputFile); return(1); } catch (IOException) { Console.WriteLine("Unable to open file '{0}'.", options.InputFile); return(1); } try { var tps = new TpsFile(file); var definitions = tps.GetTableDefinitions(); var map = tps.GetTableNames().ToDictionary(n => n.TableNumber, n => new { n.Name, Definition = definitions.First(d => d.TableNumber == n.TableNumber) }); foreach (var table in map) { Console.WriteLine("Table ID: {0} ({1})", table.Key, table.Value.Name); Console.WriteLine(); foreach (var field in table.Value.Definition.Fields) { Console.WriteLine("{0} ({1})", field.FieldName, field.Type); } } } finally { file.Dispose(); } return(0); }
private IReadOnlyDictionary <int, IReadOnlyDictionary <string, TpsObject> > GatherMemoRecords(int table, ITableDefinitionRecord tableDefinitionRecord, bool ignoreErrors) { return(Enumerable.Range(0, tableDefinitionRecord.Memos.Count()) .SelectMany(index => { var definition = tableDefinitionRecord.Memos[index]; var memoRecordsForIndex = TpsFile.GetMemoRecords(table, index, ignoreErrors); return memoRecordsForIndex.Select(record => (owner: record.Header.OwningRecord, name: definition.Name, value: record.GetValue(definition))); }) .GroupBy(pair => pair.owner, pair => (pair.name, pair.value)) .ToDictionary( groupedPair => groupedPair.Key, groupedPair => (IReadOnlyDictionary <string, TpsObject>)groupedPair .ToDictionary(pair => pair.name, pair => pair.value))); }
public static int Print(Options options) { FileStream file; try { file = File.Open(options.InputFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); } catch (FileNotFoundException) { Console.WriteLine("File '{0}' was not found.", options.InputFile); return 1; } catch (IOException) { Console.WriteLine("Unable to open file '{0}'.", options.InputFile); return 1; } try { var tps = new TpsFile(file); var definitions = tps.GetTableDefinitions(); var map = tps.GetTableNames().ToDictionary(n => n.TableNumber, n => new { n.Name, Definition = definitions.First(d => d.TableNumber == n.TableNumber) }); foreach (var table in map) { Console.WriteLine("Table ID: {0} ({1})", table.Key, table.Value.Name); Console.WriteLine(); foreach (var field in table.Value.Definition.Fields) { Console.WriteLine("{0} ({1})", field.FieldName, field.Type); } } } finally { file.Dispose(); } return 0; }
/// <summary> /// Gets a high level representation of the first table in the file. /// </summary> /// <param name="ignoreErrors">If true, the reader will not throw an exception when it encounters unexpected data.</param> /// <returns></returns> public Table BuildTable(bool ignoreErrors = false) { var tableNameDefinitions = TpsFile.GetTableNameRecords(); var tableDefinitions = TpsFile.GetTableDefinitions(ignoreErrors: ignoreErrors); var firstTableDefinition = tableDefinitions.First(); var dataRecords = GatherDataRecords(firstTableDefinition.Key, firstTableDefinition.Value, ignoreErrors); var memoRecords = GatherMemoRecords(firstTableDefinition.Key, firstTableDefinition.Value, ignoreErrors); var unifiedRecords = new Dictionary <int, Dictionary <string, TpsObject> >(); foreach (var dataKvp in dataRecords) { unifiedRecords.Add(dataKvp.Key, dataKvp.Value.ToDictionary(pair => pair.Key, pair => pair.Value)); } foreach (var memoRecord in memoRecords) { int recordNumber = memoRecord.Key; var dataNameValues = dataRecords[recordNumber]; foreach (var memoNameValue in memoRecord.Value) { unifiedRecords[recordNumber].Add(memoNameValue.Key, memoNameValue.Value); } } var rows = unifiedRecords.Select(r => new Row(DeserializerContext, r.Key, r.Value)); string tableName = tableNameDefinitions .First(n => n.TableNumber == firstTableDefinition.Key).Header.Name; var table = new Table(tableName, rows); return(table); }
public override void ExecuteBuild() { CommandUtils.Log("************************* List Third Party Software"); string ProjectPath = ParseParamValue("Project", String.Empty); //Add quotes to avoid issues with spaces in project path if (ProjectPath != String.Empty) { ProjectPath = "\"" + ProjectPath + "\""; } // Parse the list of targets to list TPS for. Each target is specified by -Target="Name|Configuration|Platform" on the command line. HashSet <FileReference> TpsFiles = new HashSet <FileReference>(); foreach (string Target in ParseParamValues(Params, "Target")) { // Get the path to store the exported JSON target data FileReference OutputFile = FileReference.Combine(CommandUtils.EngineDirectory, "Intermediate", "Build", "ThirdParty.json"); IProcessResult Result; Result = Run(UE4Build.GetUBTExecutable(), String.Format("{0} {1} -jsonexport=\"{2}\" -skipbuild", Target.Replace('|', ' '), ProjectPath, OutputFile.FullName), Options: ERunOptions.Default); if (Result.ExitCode != 0) { throw new AutomationException("Failed to run UBT"); } // Read the exported target info back in JsonObject Object = JsonObject.Read(OutputFile); // Get the project file if there is one FileReference ProjectFile = null; string ProjectFileName; if (Object.TryGetStringField("ProjectFile", out ProjectFileName)) { ProjectFile = new FileReference(ProjectFileName); } // Get the default paths to search HashSet <DirectoryReference> DirectoriesToScan = new HashSet <DirectoryReference>(); DirectoriesToScan.Add(DirectoryReference.Combine(CommandUtils.EngineDirectory, "Shaders")); DirectoriesToScan.Add(DirectoryReference.Combine(CommandUtils.EngineDirectory, "Content")); if (ProjectFile != null) { DirectoriesToScan.Add(DirectoryReference.Combine(ProjectFile.Directory, "Content")); } // Get the variables to be expanded in any runtime dependencies variables Dictionary <string, string> Variables = new Dictionary <string, string>(); Variables.Add("EngineDir", CommandUtils.EngineDirectory.FullName); if (ProjectFile != null) { Variables.Add("ProjectDir", ProjectFile.Directory.FullName); } // Add all the paths for each module, and its runtime dependencies JsonObject Modules = Object.GetObjectField("Modules"); foreach (string ModuleName in Modules.KeyNames) { JsonObject Module = Modules.GetObjectField(ModuleName); DirectoriesToScan.Add(new DirectoryReference(Module.GetStringField("Directory"))); foreach (JsonObject RuntimeDependency in Module.GetObjectArrayField("RuntimeDependencies")) { string RuntimeDependencyPath = RuntimeDependency.GetStringField("Path"); RuntimeDependencyPath = Utils.ExpandVariables(RuntimeDependencyPath, Variables); DirectoriesToScan.Add(new FileReference(RuntimeDependencyPath).Directory); } } // Remove any directories that are under other directories, and sort the output list List <DirectoryReference> SortedDirectoriesToScan = new List <DirectoryReference>(); foreach (DirectoryReference DirectoryToScan in DirectoriesToScan.OrderBy(x => x.FullName)) { if (SortedDirectoriesToScan.Count == 0 || !DirectoryToScan.IsUnderDirectory(SortedDirectoriesToScan[SortedDirectoriesToScan.Count - 1])) { SortedDirectoriesToScan.Add(DirectoryToScan); } } // Get the platforms to exclude List <UnrealTargetPlatform> SupportedPlatforms = new List <UnrealTargetPlatform> { (UnrealTargetPlatform)Enum.Parse(typeof(UnrealTargetPlatform), Object.GetStringField("Platform")) }; FileSystemName[] ExcludePlatformNames = Utils.MakeListOfUnsupportedPlatforms(SupportedPlatforms).Select(x => new FileSystemName(x)).ToArray(); // Find all the TPS files under the engine directory which match foreach (DirectoryReference DirectoryToScan in SortedDirectoriesToScan) { foreach (FileReference TpsFile in DirectoryReference.EnumerateFiles(DirectoryToScan, "*.tps", SearchOption.AllDirectories)) { if (!TpsFile.ContainsAnyNames(ExcludePlatformNames, DirectoryToScan)) { TpsFiles.Add(TpsFile); } } } } // Also add any redirects List <string> OutputMessages = new List <string>(); foreach (FileReference TpsFile in TpsFiles) { string Message = TpsFile.FullName; string[] Lines = FileReference.ReadAllLines(TpsFile); foreach (string Line in Lines) { const string RedirectPrefix = "Redirect:"; int Idx = Line.IndexOf(RedirectPrefix, StringComparison.InvariantCultureIgnoreCase); if (Idx >= 0) { FileReference RedirectTpsFile = FileReference.Combine(TpsFile.Directory, Line.Substring(Idx + RedirectPrefix.Length).Trim()); Message = String.Format("{0} (redirect from {1})", RedirectTpsFile.FullName, TpsFile.FullName); break; } } OutputMessages.Add(Message); } OutputMessages.Sort(); // Print them all out foreach (string OutputMessage in OutputMessages) { CommandUtils.Log(OutputMessage); } }
public static int Export(Options options) { FileStream file; try { file = File.Open(options.InputFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); } catch (FileNotFoundException) { Console.WriteLine("File '{0}' was not found.", options.InputFile); return(1); } catch (IOException) { Console.WriteLine("Unable to open file '{0}'.", options.InputFile); return(1); } try { var tps = new TpsFile(file); var definitions = tps.GetTableDefinitions(); if (definitions.Count > 1) { Console.WriteLine("Unable to export TPS files with multiple tables to CSV."); return(1); } using (var writer = File.CreateText(options.OutputFile)) using (var csv = new CsvWriter(writer)) { foreach (var field in definitions[0].Fields) { var name = field.FieldName.Substring(field.FieldName.IndexOf(":") + 1); if (field.IsArray()) { for (var i = 0; i < field.Elements; i++) { csv.WriteField(name + "[" + i + "]"); } continue; } csv.WriteField(name); } csv.NextRecord(); foreach (var record in tps.GetDataRecords(definitions[0])) { foreach (var value in record.Values) { var array = value as IEnumerable <object>; if (array == null) { csv.WriteField(value); } else { foreach (var arrayValue in array) { csv.WriteField(arrayValue); } } } csv.NextRecord(); } } } catch (Exception ex) { Console.WriteLine("ERROR: {0}", ex); return(1); } finally { file.Dispose(); } return(0); }
/// <summary> /// Instantiates a new parser. /// </summary> /// <param name="stream">The stream from which to read the TopSpeed file.</param> public TpsParser(Stream stream) { Stream = stream ?? throw new ArgumentNullException(nameof(stream)); TpsFile = new TpsFile(Stream); }
public override void ExecuteBuild() { CommandUtils.Log("************************* List Third Party Software"); bool DebugRun = ParseParam("Debug"); // first get a list of all TPS files available (as a lookup of Dir -> List of TPS files in Dir). var AllTPSFiles = Directory.EnumerateFiles(CombinePaths(CmdEnv.LocalRoot), "*.tps", SearchOption.AllDirectories) .ToLookup(TPSFile => Path.GetDirectoryName(TPSFile), StringComparer.InvariantCultureIgnoreCase); ParseParamValues(Params, "Target") // Grab all the Target params. .Select(TargetArg => TargetArg.Split(new[] { '|' }, 3)) // split the arg up by | .Where(Target => Target.Length == 3) // ensure it has three parts .Select(Target => new // strongly name the parts of the target and { Name = Target[0], Configuration = Target[1], Platform = Target[2], // create a list of unsupported platform strings for that target, which we'll use later to cull out irrelvant TPS files UnsupportedSubstrings = Utils.MakeListOfUnsupportedPlatforms(new List <UnrealTargetPlatform> { (UnrealTargetPlatform)Enum.Parse(typeof(UnrealTargetPlatform), Target[2]) }) .Select(PlatformName => Path.DirectorySeparatorChar + PlatformName + Path.DirectorySeparatorChar) // convert to /Platform/ .ToList(), // project to list }) .SelectMany(Target => // run UBT on each target to get the build folders, add a few hard-coded paths, then search for TPS files in relevant folders to them EnumerateBuildFolders(Target.Name, Target.Configuration, Target.Platform, DebugRun) // tack on the target content directory, which we could infer from one of a few places .Concat(new[] { Path.Combine(Path.GetDirectoryName(Target.Name), "Content"), // The target could be a .uproject, so look for a content folder there Path.Combine(CmdEnv.LocalRoot, Target.Name, "Content"), // the target could be a root project, so look for a content folder there }.Where(Folder => Directory.Exists(Folder)) // only accept Content folders that actually exist. ) // tack on hard-coded engine shaders and content folder .Concat(new List <string> { "Shaders", "Content", }.Select(Folder => Path.Combine(CmdEnv.LocalRoot, "Engine", Folder))) // canonicalize the path and convert separators. We do string compares below, so we need separators to be in consistent formats. .Select(FolderToScan => CombinePaths(FolderToScan)) // scan each folder for TPS files that appear relevant to that folder .SelectMany(FolderToScan => AllTPSFiles // A relevant folder is one that is in a subfolders or parent folder to that folder .Where(TPSFileDir => FolderToScan.StartsWith(TPSFileDir.Key, StringComparison.InvariantCultureIgnoreCase) || TPSFileDir.Key.StartsWith(FolderToScan, StringComparison.InvariantCultureIgnoreCase)) // flatten the list of all the TPS files in any folders we found (remember we were just looking at folders above, which could have a list of TPS files) .SelectMany(TPSFileDir => TPSFileDir) // filter out TPS from unwanted platforms for the current target. // This is a bit hard to follow, but we are only looking for unsupported platform names INSIDE the folder to search. // for instance, if the folder is Foo/PS4/Plugins/PadSupport and we are building for windows, we don't want to filter it out even though it has PS4 in the name. // but if the TPS file is Foo/PS4/Plugins/PadSupport/Android/TPS.TPS, then we do want to filter out because of the Android folder. // this basically checks if an unsupported platform string is found AFTER the original folder we are looking in. .Where(TpsFile => Target.UnsupportedSubstrings.Max(PlatformDir => TpsFile.IndexOf(PlatformDir, StringComparison.InvariantCultureIgnoreCase)) < FolderToScan.Length) ) ) .Distinct() // remove duplicate TPS files. // pull out the redirect if present (but leave a breadcrumb to where the redirect came from) .Select(TPSFile => // read all the lines in the file File.ReadAllLines(TPSFile) // look for a line with a redirect .Where(Line => Line.IndexOf("Redirect:", StringComparison.InvariantCultureIgnoreCase) >= 0) // grab the redirect file and canonicalize it, tacking on some info on where the redirect was from. .Select(Line => CombinePaths(Path.GetFullPath(Path.Combine(Path.GetDirectoryName(TPSFile), Line.Split(new[] { ':' }, 2)[1].Trim()))) + " (redirect from " + TPSFile + ")") // take the first one found, or just use the TPS file directly if no redirect was present. .SingleOrDefault() ?? TPSFile) .OrderBy(TPSFile => TPSFile) // sort them. .ToList().ForEach(TPSFile => UnrealBuildTool.Log.WriteLine(0, string.Empty, LogEventType.Console, TPSFile)); // log them. }
private IReadOnlyDictionary <int, IReadOnlyDictionary <string, TpsObject> > GatherDataRecords(int table, ITableDefinitionRecord tableDefinitionRecord, bool ignoreErrors) { var dataRecords = TpsFile.GetDataRecords(table, tableDefinitionRecord: tableDefinitionRecord, ignoreErrors); return(dataRecords.ToDictionary(r => r.RecordNumber, r => r.GetFieldValuePairs())); }
internal TpsParser(TpsFile tpsFile) : this() { TpsFile = tpsFile ?? throw new ArgumentNullException(nameof(tpsFile)); }
/// <summary> /// Instantiates a new parser. /// </summary> /// <param name="stream">The stream from which to read the TopSpeed file.</param> /// <param name="password">The password or "owner" to use to decrypt the file.</param> public TpsParser(Stream stream, string password) { Stream = stream ?? throw new ArgumentNullException(nameof(stream)); TpsFile = new TpsFile(Stream, new Key(password)); }
public void ShouldNotParseHeaderIfNotTopSpeed() { var file = new TpsFile(new FileStream("Resources/bad-header.dat", FileMode.Open)); Assert.Throws <NotATopSpeedFileException>(() => file.GetHeader()); }
public static int Export(Options options) { FileStream file; try { file = File.Open(options.InputFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); } catch (FileNotFoundException) { Console.WriteLine("File '{0}' was not found.", options.InputFile); return 1; } catch (IOException) { Console.WriteLine("Unable to open file '{0}'.", options.InputFile); return 1; } try { var tps = new TpsFile(file); var definitions = tps.GetTableDefinitions(); if (definitions.Count > 1) { Console.WriteLine("Unable to export TPS files with multiple tables to CSV."); return 1; } using (var writer = File.CreateText(options.OutputFile)) using (var csv = new CsvWriter(writer)) { foreach (var field in definitions[0].Fields) { var name = field.FieldName.Substring(field.FieldName.IndexOf(":") + 1); if (field.IsArray()) { for (var i = 0; i < field.Elements; i++) { csv.WriteField(name + "[" + i + "]"); } continue; } csv.WriteField(name); } csv.NextRecord(); foreach (var record in tps.GetDataRecords(definitions[0])) { foreach (var value in record.Values) { var array = value as IEnumerable<object>; if (array == null) csv.WriteField(value); else { foreach (var arrayValue in array) csv.WriteField(arrayValue); } } csv.NextRecord(); } } } catch (Exception ex) { Console.WriteLine("ERROR: {0}", ex); return 1; } finally { file.Dispose(); } return 0; }
/// <summary> /// Instantiates a new parser. /// </summary> /// <param name="filename">The filename of the TopSpeed file.</param> public TpsParser(string filename) { Stream = new FileStream(filename, FileMode.Open); TpsFile = new TpsFile(Stream); }
private IEnumerable <(int recordNumber, IReadOnlyDictionary <string, TpsObject> nameValuePairs)> GatherDataRecords(int table, TableDefinitionRecord tableDefinitionRecord, bool ignoreErrors) { var dataRecords = TpsFile.GetDataRecords(table, tableDefinition: tableDefinitionRecord, ignoreErrors); return(dataRecords.Select(r => (r.RecordNumber, r.GetFieldValuePairs()))); }
/// <summary> /// Instantiates a new parser. /// </summary> /// <param name="filename">The filename of the TopSpeed file.</param> /// <param name="password">The password or "owner" to use to decrypt the file.</param> public TpsParser(string filename, string password) { Stream = new FileStream(filename, FileMode.Open); TpsFile = new TpsFile(Stream, new Key(password)); }