public string GetTimestampClockName(CtfIntegerValue timestampField)
        {
            if (String.IsNullOrWhiteSpace(timestampField.MapValue))
            {
                return(null);
            }

            // note: this may be overly cautious making this LTTng specific, but it's not clear to me that the CTF
            // specification mandates this clock reference format. It might just be another "example".

            // LTTng maps are in the form of: clock.<clock_name>.value
            // where <clock_name> is the name of the clock
            // e.g. "clock.monotonic.value"

            string map = timestampField.MapValue;

            int    firstSplitIndex = map.IndexOf('.');
            string clockToken      = map.Substring(0, firstSplitIndex);

            if (!StringComparer.Ordinal.Equals(clockToken, "clock"))
            {
                return(null);
            }

            int    lastSplitIndex = map.LastIndexOf('.');
            string valueToken     = map.Substring(lastSplitIndex + 1);

            if (!StringComparer.Ordinal.Equals(valueToken, "value"))
            {
                return(null);
            }

            return(map.Substring(firstSplitIndex + 1, lastSplitIndex - firstSplitIndex - 1));
        }
        public virtual CtfTimestamp GetTimestampFromEventHeader(ICtfEvent ctfEvent, CtfTimestamp previousTimestamp)
        {
            CtfIntegerValue timestampInteger = null;

            // Hack for perf?
            if (ctfEvent.StreamDefinedEventHeader.FieldType == CtfTypes.Struct)
            {
                var streamDefinedEventHeader = ctfEvent.StreamDefinedEventHeader as CtfStructValue;
                if (streamDefinedEventHeader != null)
                {
                    foreach (var field in streamDefinedEventHeader.Fields)
                    {
                        if ("timestamp".Equals(field.FieldName))
                        {
                            return(new CtfTimestamp(this.MetadataCustomization, (CtfIntegerValue)field));
                        }
                    }
                }
            }

            if (previousTimestamp is null)
            {
                // todo:I think we need to do something else for this case, especially if the integer size is < 64
                // not sure what yet. maybe base it on the clock's offset?

                return(new CtfTimestamp(this.MetadataCustomization, timestampInteger));
            }

            // Timestamps aren't actually absolute values. To quote from CTF spec 1.8.2 section 8:
            //    For a N-bit integer type referring to a clock, if the integer overflows compared to the N low order bits
            //    of the clock prior value found in the same stream, then it is assumed that one, and only one, overflow
            //    occurred. It is therefore important that events encoding time on a small number of bits happen frequently
            //    enough to detect when more than one N-bit overflow occurs.
            // So to determine a timestamp, we must know the previous timestamp. If they're all the same number of bits, it
            // wouldn't be necessary (I don't think so anyways). But some timestamps are smaller than others.
            if (timestampInteger.Descriptor.Size < 64)
            {
                if (!timestampInteger.Value.TryGetInt64(out long thisTimestamp))
                {
                    Debug.Assert(false);
                    throw new CtfPlaybackException("Unable to retrieve timestamp as long.");
                }

                long previous = (long)previousTimestamp.NanosecondsFromClockBase;

                long oneBitBeyondBitsUsed = 1L << (byte)timestampInteger.Descriptor.Size;
                long bitMask = ~(oneBitBeyondBitsUsed - 1);

                long highBitsFromPreviousTimestamp = previous & bitMask;
                long newTimestamp = highBitsFromPreviousTimestamp | thisTimestamp;
                if (newTimestamp < previous)
                {
                    // handle the overflow case
                    newTimestamp += oneBitBeyondBitsUsed;
                    Debug.Assert(newTimestamp > previous);
                }

                return(new CtfTimestamp(this.MetadataCustomization, timestampInteger, newTimestamp));
            }

            return(new CtfTimestamp(this.MetadataCustomization, timestampInteger));
        }
 public string GetTimestampClockName(CtfIntegerValue timestampField)
 {
     throw new NotImplementedException();
 }