/// <summary> /// Saves the current file to disk. /// </summary> public override void Save() { try { byte[] xmlData; // Saving XML then re-building config file _Doc.Save(_WorkingFileName); using ( BinaryReader reader = new BinaryReader(new FileStream(_WorkingFileName, FileMode.Open, FileAccess.Read))) { xmlData = reader.ReadBytes((int)reader.BaseStream.Length); } using ( BinaryWriter writer = new BinaryWriter(new FileStream(_WorkingFileName, FileMode.Create, FileAccess.Write))) { writer.Write(xmlData); writer.Write(_DirtyData); } // File encryption File2.RemoveAttribute(_FileName, FileAttributes.ReadOnly); XTEAEncryption.Encrypt(_WorkingFileName, _FileName); } catch (Exception ex) { throw new Exception("Unable to save file: " + _FileName, ex); } }
/// <summary> /// Reads file data. This method should not be called from subclasses ! /// </summary> protected override void _ReadData() { try { // File decryption string tempFolder = File2.SetTemporaryFolder(null, LibraryConstants.FOLDER_TEMP, true); _WorkingFileName = string.Concat(tempFolder, FILE_AICONFIG_XML); XTEAEncryption.Decrypt(_FileName, _WorkingFileName); // Extracting xml and dirty data byte[] xmlData; using (BinaryReader reader = new BinaryReader(new FileStream(_WorkingFileName, FileMode.Open, FileAccess.Read))) { // Finding 0x00 0x00 sequence byte readByte = 0xAA; while (readByte != 0x00) { readByte = reader.ReadByte(); } long xmlPartLength = reader.BaseStream.Position; reader.BaseStream.Seek(0, SeekOrigin.Begin); xmlData = reader.ReadBytes((int)(xmlPartLength - 1)); _DirtyData = reader.ReadBytes((int)(reader.BaseStream.Length - xmlData.Length)); } // Loading xml... _Doc = new XmlDocument(); File2.WriteBytesToFile(_WorkingFileName, xmlData); _Doc.Load(_WorkingFileName); // Locating zones const string xRequest = "/AICONFIG/VEHICLE_REPARTITION/ZONE"; _ZoneNodes = _Doc.SelectNodes(xRequest); if (_ZoneNodes == null || _ZoneNodes.Count == 0) { throw new Exception("Invalid zoning data in AIConfig.xml: see " + xRequest); } } catch (Exception ex) { throw new Exception("Unable to read file: " + _FileName, ex); } }
/// <summary> /// Saves the current file to disk. To implement if necessary. /// </summary> public override void Save() { // Preparing destination string tempFolder = File2.SetTemporaryFolder(null, LibraryConstants.FOLDER_TEMP, true); FileInfo fi = new FileInfo(_FileName); string tempFile = tempFolder + @"\" + fi.Name + ".OK"; // Saving data using (TextWriter writer = new StreamWriter(new FileStream(tempFile, FileMode.Create, FileAccess.Write))) { // Header comments writer.Write(_HeaderComments); // Column list StringBuilder sbFileRef = new StringBuilder(); sbFileRef.Append(_CHAR_START_TEXT); sbFileRef.Append("TDU_"); sbFileRef.Append(_CurrentTopic.ToString()); sbFileRef.Append(_CHAR_END_TEXT); sbFileRef.Append(' '); sbFileRef.Append(_FileReference); writer.WriteLine(sbFileRef.ToString()); foreach (Cell anotherColumn in _Structure) { StringBuilder sbColumn = new StringBuilder(); sbColumn.Append(_CHAR_START_TEXT); sbColumn.Append(anotherColumn.name); sbColumn.Append(_CHAR_END_TEXT); sbColumn.Append(' '); sbColumn.Append(_GetSymbolByValueType(anotherColumn.valueType)); if (anotherColumn.valueType == ValueType.Reference || anotherColumn.valueType == ValueType.ReferenceL) { sbColumn.Append(' '); sbColumn.Append(anotherColumn.optionalRef); } writer.WriteLine(sbColumn.ToString()); } // Count comment string countComment = string.Format(_FORMAT_COMMENT_COUNT, _Entries.Count); writer.WriteLine(countComment); // Entries foreach (Entry anotherEntry in _Entries) { StringBuilder sbEntry = new StringBuilder(); foreach (Cell anotherCell in anotherEntry.cells) { sbEntry.Append(anotherCell.value); sbEntry.Append(_CHAR_VALUE_SEPARATOR); } writer.WriteLine(sbEntry.ToString()); } } // Encrypting needed XTEAEncryption.Encrypt(tempFile, _FileName); }
/// <summary> /// Lit les données du fichier. A implémenter si nécessaire /// </summary> protected override sealed void _ReadData() { // Decrypting needed string tempFolder = File2.SetTemporaryFolder(null, LibraryConstants.FOLDER_TEMP, true); FileInfo fi = new FileInfo(_FileName); string tempFile = tempFolder + @"\" + fi.Name + ".OK"; XTEAEncryption.Decrypt(_FileName, tempFile); // Parsing clear file using (TextReader reader = new StreamReader(new FileStream(tempFile, FileMode.Open, FileAccess.Read))) { // Clearing all data _Entries.Clear(); _EntriesByPrimaryKey.Clear(); // First lines = header comments StringBuilder sbHeader = new StringBuilder(); string currentLine = reader.ReadLine(); while (currentLine != null && currentLine.StartsWith(_CHAR_COMMENTS)) { sbHeader.AppendLine(currentLine); currentLine = reader.ReadLine(); } _HeaderComments = sbHeader.ToString(); // Column list _Structure = new List <Cell>(); int count = 0; int unicityCounter = 1; while (currentLine != null && currentLine[0] == _CHAR_START_TEXT) { // Parsing column description int nameEndPosition = currentLine.IndexOf(_CHAR_END_TEXT); string name = currentLine.Substring(1, nameEndPosition - 1); if (count++ == 0) { // First column is just file reference _CurrentTopic = _GetTopicByName(name); _FileReference = currentLine.Substring(nameEndPosition + 2); } else { Cell currentCell = new Cell(); // Regular column description string type = currentLine.Substring(nameEndPosition + 2, 1); currentCell.name = name; currentCell.valueType = _GetValueTypeBySymbol(type); currentCell.index = count - 2; if (currentCell.valueType == ValueType.Reference || currentCell.valueType == ValueType.ReferenceL) { string reference = currentLine.Substring(nameEndPosition + 4); currentCell.optionalRef = reference; } _Structure.Add(currentCell); // Index update // BUGFIX: on TDU_PNJ, 6 columns have the same name // Column name is suffixed by a counter if (_ColumnIndexByName.ContainsKey(currentCell.name)) { currentCell.name = currentCell.name + "_" + unicityCounter; unicityCounter++; } _ColumnIndexByName.Add(currentCell.name, currentCell.index); } currentLine = reader.ReadLine(); } // Comment for line count string countComment = currentLine; currentLine = reader.ReadLine(); // Values int entryCount = 0; int maxEntryCount = _GetMaxEntryCount(countComment); string separator = new string(_CHAR_VALUE_SEPARATOR, 1); // BUGFIX: does not take entries when count is higher than expected while (currentLine != null && currentLine.Contains(separator)) { if (entryCount > maxEntryCount) { break; } // Getting all values by splitting between ; string[] allValues = currentLine.Split(_CHAR_VALUE_SEPARATOR); // BUG_65: ensure current line is valid. If last separator is missing, entry is also considered as OK. if (allValues.Length < _Structure.Count || allValues.Length > _Structure.Count + 1) { Log.Info("Current DB entry is invalid (" + _FileName + "):\r\n" + currentLine); break; } Entry currentEntry = new Entry(); string primaryKey = null; currentEntry.index = entryCount; currentEntry.cells = new List <Cell>(); for (int i = 0; i < allValues.Length - 1; i++) { Cell currentCell = _Structure[i]; currentCell.value = allValues[i]; currentCell.index = i; currentCell.entryIndex = entryCount; currentEntry.cells.Add(currentCell); if (currentCell.valueType == ValueType.PrimaryKey) { primaryKey = currentCell.value; } } // If no REF column found, primary key is automatically built with contents of first 2 columns if (primaryKey == null && currentEntry.cells.Count >= 2) { primaryKey = string.Format(DatabaseHelper.FORMAT_COMPLEX_PK, currentEntry.cells[0].value, currentEntry.cells[1].value); } currentEntry.primaryKey = primaryKey; _Entries.Add(currentEntry); // Debug only - very slow ! //Log.Info("primary key = " + primaryKey); // TODO potential problem with Elise duplicated rims 1297992029 // Duplicate risk with TDU_Achievements if (primaryKey != null && !_EntriesByPrimaryKey.ContainsKey(primaryKey)) { _EntriesByPrimaryKey.Add(primaryKey, currentEntry); } currentLine = reader.ReadLine(); entryCount++; } } // Adding current reference to global association if (_FileReference != null && !_DBFilesByReference.ContainsKey(_FileReference)) { _DBFilesByReference.Add(_FileReference, _CurrentTopic.ToString()); } // EVO_65: Properties Property.ComputeValueDelegate encryptedDelegate = (() => "Yes"); Properties.Add(new Property("Encrypted ?", "Database", encryptedDelegate)); }