/// <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> /// 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)); }