private Stream EnsureStream() { if (_stream is null) { var name = _heap.GetObjectName(_slot.NameHeapOffset); var filePath = H5Utils.ConstructExternalFilePath(name, _datasetAccess); if (!File.Exists(filePath)) { throw new Exception($"External file '{filePath}' does not exist."); } _stream = File.OpenRead(filePath); _stream.Seek((long)_slot.Offset, SeekOrigin.Begin); } return(_stream); }
private bool TryGetReference(string name, H5LinkAccess linkAccess, out H5NamedReference namedReference) { namedReference = default; /* cached data */ if (_scratchPad != null) { var localHeap = _scratchPad.LocalHeap; this.Context.Reader.Seek((long)_scratchPad.BTree1Address, SeekOrigin.Begin); var tree = new BTree1Node <BTree1GroupKey>(this.Context.Reader, this.Context.Superblock, this.DecodeGroupKey); var b = tree.EnumerateNodes().ToList(); this.Context.Reader.Seek((long)_scratchPad.NameHeapAddress, SeekOrigin.Begin); var heap = new LocalHeap(this.Context.Reader, this.Context.Superblock); var c = heap.GetObjectName(0); var success = _scratchPad .GetBTree1(this.DecodeGroupKey) .TryFindUserData(out var userData, (leftKey, rightKey) => this.NodeCompare3(localHeap, name, leftKey, rightKey), (ulong address, out BTree1SymbolTableUserData userData) => this.NodeFound(localHeap, name, address, out userData)); if (success) { namedReference = this.GetObjectReferencesForSymbolTableEntry(localHeap, userData.SymbolTableEntry, linkAccess); return(true); } } else { var symbolTableHeaderMessages = this.Header.GetMessages <SymbolTableMessage>(); if (symbolTableHeaderMessages.Any()) { /* Original approach. * IV.A.2.r.: The Symbol Table Message * Required for "old style" groups; may not be repeated. */ if (symbolTableHeaderMessages.Count() != 1) { throw new Exception("There may be only a single symbol table header message."); } var smessage = symbolTableHeaderMessages.First(); var localHeap = smessage.LocalHeap; var success = smessage .GetBTree1(this.DecodeGroupKey) .TryFindUserData(out var userData, (leftKey, rightKey) => this.NodeCompare3(localHeap, name, leftKey, rightKey), (ulong address, out BTree1SymbolTableUserData userData) => this.NodeFound(localHeap, name, address, out userData)); if (success) { namedReference = this.GetObjectReferencesForSymbolTableEntry(localHeap, userData.SymbolTableEntry, linkAccess); return(true); } } else { var linkInfoMessages = this.Header.GetMessages <LinkInfoMessage>(); if (linkInfoMessages.Any()) { if (linkInfoMessages.Count() != 1) { throw new Exception("There may be only a single link info message."); } var lmessage = linkInfoMessages.First(); /* New (1.8) indexed format (in combination with Group Info Message) * IV.A.2.c. The Link Info Message * Optional; may not be repeated. */ if (!this.Context.Superblock.IsUndefinedAddress(lmessage.BTree2NameIndexAddress)) { if (this.TryGetLinkMessageFromLinkInfoMessage(lmessage, name, out var linkMessage)) { namedReference = this.GetObjectReference(linkMessage, linkAccess); return(true); } } /* New (1.8) compact format * IV.A.2.g. The Link Message * A group is storing its links compactly when the fractal heap address * in the Link Info Message is set to the "undefined address" value. */ else { var linkMessage = this.Header .GetMessages <LinkMessage>() .FirstOrDefault(message => message.LinkName == name); if (linkMessage != null) { namedReference = this.GetObjectReference(linkMessage, linkAccess); return(true); } } } else { throw new Exception("No link information found in object header."); } } } return(false); }