protected int ReadInSurrogates(int currentModelVersion) { for (; ; ) // Loop is used to retry if we get a corrupt file and restore backup. { var fileSize = new FileInfo(ProjectId.Path).Length; // This arbitrary length is based on two large databases, one 360M with 474 bytes/object, and one 180M with 541. // It's probably not perfect, but we're mainly trying to prevent fragmenting the large object heap // by growing it MANY times. var estimatedObjectCount = (int)(fileSize/400); m_identityMap.ExpectAdditionalObjects(estimatedObjectCount); if (!FileUtils.SimilarFileExists(ProjectId.Path)) throw new InvalidOperationException("System does not exist."); try { // We need to reorder the entire file to be nice to Mercurial, // but only if the current version is less than "7000048". // Step 0: Get the version number. m_startupVersionNumber = GetActualModelVersionNumber(ProjectId.Path); var useLocalTempFile = !IsLocalDrive(ProjectId.Path); // Step 1: if (m_startupVersionNumber < 7000048) { #if DEBUG var reorderWatch = new Stopwatch(); reorderWatch.Start(); #endif var tempPathname = useLocalTempFile ? Path.GetTempFileName() : Path.ChangeExtension(ProjectId.Path, "tmp"); // Rewrite the file in the prescribed order. using (var writer = FdoXmlServices.CreateWriter(tempPathname)) { FdoXmlServices.WriteStartElement(writer, m_startupVersionNumber); // Use version from old file, so DM can be done, if needed. DataSortingService.SortEntireFile(m_mdcInternal.GetSortableProperties(), writer, ProjectId.Path); writer.WriteEndElement(); // 'languageproject' writer.Close(); } #if DEBUG reorderWatch.Stop(); Debug.WriteLine("Reordering entire file took " + reorderWatch.ElapsedMilliseconds + " ms."); //Debug.Assert(false, "Force a stop."); #endif // Copy reordered file to ProjectId.Path. CopyTempFileToOriginal(useLocalTempFile, ProjectId.Path, tempPathname); } // Step 2: Go on one's merry way.... using (var reader = FdoXmlServices.CreateReader(ProjectId.Path)) { reader.MoveToContent(); m_needConversion = (m_startupVersionNumber != currentModelVersion); // Optional AdditionalFields element. if (reader.Read() && reader.LocalName == "AdditionalFields") { var cfiList = new List<CustomFieldInfo>(); while (reader.Read() && reader.LocalName == "CustomField") { if (!reader.IsStartElement()) continue; var cfi = new CustomFieldInfo(); reader.MoveToAttribute("class"); cfi.m_classname = reader.Value; if (reader.MoveToAttribute("destclass")) cfi.m_destinationClass = Int32.Parse(reader.Value); if (reader.MoveToAttribute("helpString")) cfi.m_fieldHelp = reader.Value; if (reader.MoveToAttribute("label")) cfi.Label = reader.Value; if (reader.MoveToAttribute("listRoot")) cfi.m_fieldListRoot = new Guid(reader.Value); reader.MoveToAttribute("name"); cfi.m_fieldname = reader.Value; reader.MoveToAttribute("type"); cfi.m_fieldType = GetFlidTypeFromString(reader.Value); if (reader.MoveToAttribute("wsSelector")) cfi.m_fieldWs = Int32.Parse(reader.Value); reader.MoveToElement(); cfiList.Add(cfi); } RegisterOriginalCustomProperties(cfiList); } } Stopwatch watch = new Stopwatch(); watch.Start(); using (var er = new ElementReader("<rt ", "</languageproject>", ProjectId.Path, MakeSurrogate)) { er.Run(); } watch.Stop(); Debug.WriteLine("Making surrogates took " + watch.ElapsedMilliseconds + " ms."); } catch (ArgumentException e) { Logger.WriteError(e); // Failed to get a version number from the file! OfferToRestore(Properties.Resources.kstidInvalidFieldWorksXMLFile); continue; // backup restored, if previous call returns. } catch (XmlException e) { Logger.WriteError(e); // The data is not in the format we expect or not even an XML file OfferToRestore(Properties.Resources.kstidInvalidFieldWorksXMLFile); continue; // backup restored, if previous call returns. } catch (IOException e) { Logger.WriteError(e); OfferToRestore(e.Message); continue; // backup restored, if previous call returns. } ReportDuplicateGuidsIfTheyExist(); return m_startupVersionNumber; } }
private void RunElementReaderWithSpecifiedBufferSize(string projPath, int bufferSize) { using (var er = new ElementReader("<rt ", kClosingTag, projPath, bytes => { }, bufferSize)) { er.Run(); } }