internal bool TryGetDocument(string fullPath, out DocumentHandle documentHandle) { var fileName = FileNameUtilities.GetFileName(fullPath); KeyValuePair <DocumentNameAndHandle, ImmutableArray <DocumentNameAndHandle> > documents; if (!_map.TryGetValue(fileName, out documents)) { documentHandle = default(DocumentHandle); return(false); } // SymReader first attempts to find the document by the full path, then by file name with extension. if (documents.Key.FileName != null) { // There is only one document with the specified file name. // SymReader returns the document regardless of whether the path matches the name. documentHandle = documents.Key.Handle; return(true); } Debug.Assert(documents.Value.Length > 1); // We have multiple candidates with the same file name. Find the one whose name matches the specified full path. // If none does return the first one. It will be the one with the smallest handle, due to the multi-map construction implementation. // First try to find candidate whose full name is exactly matching. foreach (DocumentNameAndHandle candidate in documents.Value) { if (_reader.StringComparer.Equals(_reader.GetDocument(candidate.Handle).Name, fullPath, ignoreCase: false)) { documentHandle = candidate.Handle; return(true); } } // Then try to find candidate whose full name is matching ignoring case. foreach (DocumentNameAndHandle candidate in documents.Value) { if (_reader.StringComparer.Equals(_reader.GetDocument(candidate.Handle).Name, fullPath, ignoreCase: true)) { documentHandle = candidate.Handle; return(true); } } // Then try to find candidate whose file name is matching exactly. foreach (DocumentNameAndHandle candidate in documents.Value) { if (candidate.FileName == fileName) { documentHandle = candidate.Handle; return(true); } } documentHandle = documents.Value[0].Handle; return(true); }
private static string GetFileName(MetadataReader reader, DocumentHandle documentHandle) { var document = reader.GetDocument(documentHandle); if (document.Name.IsNil) { return(null); } var nameReader = reader.GetBlobReader(document.Name); int separator = nameReader.ReadByte(); if (!FileNameUtilities.IsDirectorySeparator((char)separator)) { return(FileNameUtilities.GetFileName(reader.GetString(document.Name))); } // find the last part handle: BlobHandle partHandle = default(BlobHandle); while (nameReader.RemainingBytes > 0) { partHandle = nameReader.ReadBlobHandle(); } if (partHandle.IsNil) { return(string.Empty); } var partReader = reader.GetBlobReader(partHandle); var part = partReader.ReadUTF8(partReader.Length); if (part.IndexOf('\0') >= 0) { // bad metadata return(null); } // it is valid to encode document name so that the parts contain directory separators: return(FileNameUtilities.GetFileName(part)); }