示例#1
0
        // This is called when reading the circular part of the log to
        // double check that we have a valid record.
        private static bool FlagsAreValid(DataFlags flags)
        {
            if ((flags & DataFlags.InvalidOnes) != DataFlags.None)
            {
                return(false);
            }

            if ((flags & DataFlags.CircularStart) != DataFlags.None)
            {
                // Circular flag should never appear twice.
                return(false);
            }

            if ((flags & DataFlags.LineNumber) != DataFlags.None)
            {
                // LineNumber should never be set in the circular because
                // every record has a record in the circular part includes the line number.
                return(false);
            }

            if ((flags & DataFlags.MethodEntry) == DataFlags.MethodEntry &&
                (flags & DataFlags.MethodExit) == DataFlags.MethodExit)
            {
                // These two should never appear together.
                return(false);
            }

            return(true);
        }
示例#2
0
        public Record(DataFlags dataflags, uint msgNum, DateTime time, ReaderThreadInfo threadInfo, string msg)
        {
            MsgNum     = msgNum;
            Time       = time;
            Thread     = threadInfo.Thread;
            ThreadName = threadInfo.ThreadName;
            Level      = threadInfo.Level;
            Logger     = threadInfo.Logger;
            StackDepth = threadInfo.Depth;
            MethodName = threadInfo.MethodName;

            if ((dataflags & DataFlags.MethodEntry) != DataFlags.None)
            {
                // This is a method entry record.  It always contains exactly one line of text.
                IsEntry = true;
                Lines   = new string[] { string.Format("{{{0}: entered", MethodName) };
            }
            else if ((dataflags & DataFlags.MethodExit) != DataFlags.None)
            {
                // Method exit records always contain exactly one line of text.
                Lines = new string[] { string.Format("}}{0}: exiting", MethodName) };
            }
            else
            {
                // The message text for this record may contain newlines.  Split the
                // message into one or more lines.
                Lines       = msg.Split(_splitArg);
                IsCollapsed = Lines.Length > 1 && !Settings1.Default.ExpandNewlines;
            }

            // Each line also has a bool to indicate if it is bookmarked
            // and a row index it may map to.
            IsBookmarked = new bool[Lines.Length];
            RowIndices   = new int[Lines.Length];
        }
        // Resets all state data that might be associated with an earlier binary file
        // and prepares for the next (specified) opening of the file.
        internal void ResetBinaryFileStateData(int fileNum, DataFlags flags)
        {
            BinaryFileState.LastFileNumber = fileNum;
            BinaryFileState.LastTraceLevel = TraceLevel.Off;
            BinaryFileState.LastThreadName = null;
            BinaryFileState.LastMethod     = string.Empty;
            BinaryFileState.LastLogger     = null;
            BinaryFileState.LastBlock      = 0;

            // For simplicity, abandon the stack rather than deal with the fact that there
            // may be a deep call stack when the file is closed and reopened.

            BinaryFileState.StackDepth = 0;

            for (StackEntry stackEntry = TopStackEntry; stackEntry != null; stackEntry = stackEntry.Caller)
            {
                if (stackEntry.BinaryFileState == BinaryFileState)
                {
                    stackEntry.Destinations   &= ~Destinations.BinaryFile;
                    stackEntry.BinaryFileState = null;
                }
            }

            // I'm not sure why we wouldn't always do this.
            if ((flags & DataFlags.MethodEntry) == 0)
            {
                BinaryFileState.CurrentMethod = string.Empty;
            }
        }
示例#4
0
 /// <summary>
 /// Creates new instance.
 /// </summary>
 /// <param name="buffer">Buffer.</param>
 /// <param name="offset">Offset.</param>
 /// <param name="size">Size.</param>
 /// <param name="flags">Flags.</param>
 public SentReceivedEventArgs(byte[] buffer, int offset, int size, DataFlags flags)
 {
     Buffer     = buffer ?? throw new ArgumentNullException(nameof(buffer));
     DataOffset = offset;
     DataSize   = size;
     DataFlags  = flags;
 }
            // Gets the DataFlags for next record, possibly entering the circular part of the log.
            // Returns DataFlags.None or throws an exception if the last record has been read.
            // Used in file format version 5-.
            private DataFlags GetFlags(out ulong thisRecNum)
            {
                DataFlags flags = DataFlags.None;
                bool      firstCircularRecord = false;

                thisRecNum = LastRecordNum + 1; // for now

                if (_circularStartPos == 0)
                {
                    // Not in circular part yet
                    flags              = (DataFlags)_fileReader.ReadUInt16();
                    _reader.BytesRead += sizeof(DataFlags);

                    if ((flags & DataFlags.CircularStart) != DataFlags.None)
                    {
                        BeginCircular(); // Will set _circularStartPos to non-zero.
                        firstCircularRecord = true;
                    }
                }

                if (_circularStartPos != 0)
                {
                    // We're in the circular part, where every record starts with its
                    // UInt32 record number, before the data flags.
                    thisRecNum         = _fileReader.ReadUInt32();
                    _reader.BytesRead += sizeof(UInt32);
                    if (firstCircularRecord)
                    {
                        // This is the first chronological record in the circular part,
                        // so accept the record number as-is.
                        flags              = (DataFlags)_fileReader.ReadUInt16();
                        _reader.BytesRead += sizeof(DataFlags);
                    }
                    else
                    {
                        // thisRecNum must equal _recordNumber + 1 or we've read past the last record.
                        // If it's a good record, we need to increment _recordNumber.
                        if (thisRecNum == LastRecordNum + 1)
                        {
                            flags              = (DataFlags)_fileReader.ReadUInt16();
                            _reader.BytesRead += sizeof(DataFlags);

                            // There's a slim chance we a read random data that contained the expected
                            // value. Therefore, also check for invalid flags.
                            if (!FlagsAreValid(flags))
                            {
                                flags = DataFlags.None;
                            }
                        }
                        else
                        {
                            // We've already read the last (newest) record, and now we're reading garbage.
                            flags = DataFlags.None;
                        }
                    }
                }

                return(flags);
            }
示例#6
0
        /// <summary>
        /// Copies mesh data from one native array to another
        /// </summary>
        public static bool CopyNativeDataToMesh(NativeMeshData from, Mesh to, DataFlags dataFlags)
        {
            if (!from.HasValidData())
            {
                Debug.LogError("Cannot copy data as some of it is invalid");
                return(false);
            }

            if (to == null)
            {
                Debug.LogError("Cannot copy data to null mesh");
                return(false);
            }

            if ((dataFlags & DataFlags.Vertices) != 0)
            {
                to.SetVertices(from.VertexBuffer);
            }
            if ((dataFlags & DataFlags.Normals) != 0)
            {
                to.SetNormals(from.NormalBuffer);
            }
            if ((dataFlags & DataFlags.Tangents) != 0)
            {
                to.SetTangents(from.TangentBuffer);
            }
            if ((dataFlags & DataFlags.UVs) != 0)
            {
                to.SetUVs(0, from.UVBuffer);
            }
            if ((dataFlags & DataFlags.Colors) != 0)
            {
                to.SetColors(from.ColorBuffer);
            }
            if ((dataFlags & DataFlags.Triangles) != 0)
            {
                for (int i = 0; i < to.subMeshCount; i++)
                {
                    var submesh = to.GetSubMesh(i);
                    to.SetIndices
                    (
                        indices:                        from.IndexBuffer,
                        indicesStart:           submesh.indexStart,
                        indicesLength:          submesh.indexCount,
                        topology:                       submesh.topology,
                        submesh:                        i,
                        calculateBounds:        false,
                        baseVertex:             submesh.baseVertex
                    );
                }
            }

            if ((dataFlags & DataFlags.Bounds) != 0)
            {
                to.bounds = from.Bounds[0];
            }

            return(true);
        }
        public object GetDataFlag(string flag)
        {
            var dataFlag = DataFlags?.FirstOrDefault(e => e.Key == flag);

            return((DataFlags != null &&
                    dataFlag.HasValue &&
                    DataFlags.Count > 0) ? dataFlag.Value.Value ?? false : false);
        }
示例#8
0
        public Record(DataFlags dataflags, ulong msgNum, DateTime time, ReaderThreadInfo threadInfo, Reader.Session session, string msg)
        {
            MsgNum     = msgNum;
            Time       = time;
            Thread     = threadInfo.Thread;
            ThreadName = threadInfo.ThreadName;
            TLevel     = threadInfo.TLevel;
            Logger     = threadInfo.Logger;
            StackDepth = threadInfo.Depth;
            MethodName = threadInfo.MethodName;
            Caller     = threadInfo.StackTop;
            Session    = session;

            if ((dataflags & DataFlags.MethodEntry) != DataFlags.None)
            {
                // This is a method entry record.  It always contains exactly one line of text.
                IsEntry = true;
                Lines   = new string[] { string.Format("{{{0}: entered", MethodName.Name) };
            }
            else if ((dataflags & DataFlags.MethodExit) != DataFlags.None)
            {
                // Method exit records always contain exactly one line of text.
                IsExit = true;
                Lines  = new string[] { string.Format("}}{0}: exiting", MethodName.Name) };
            }
            else
            {
                // The message text for this record may contain newlines.  Split the
                // message into one or more lines.
                Lines = msg.Split(_splitArg);

                if (Lines.Length > 1)
                {
                    // It's common for a carriage return to exist at the
                    // end of each line.  Remove them.
                    for (int i = 0; i < Lines.Length; ++i)
                    {
                        Lines[i] = Lines[i].TrimEnd('\r');
                    }

                    // It's common for the last line to be empty.  If so, remove it.
                    if (Lines.Last().Trim() == string.Empty)
                    {
                        Lines = Lines.Take(Lines.Length - 1).ToArray();
                    }
                }

                IsCollapsed = Lines.Length > 1 && !Settings.Default.ExpandNewlines;
            }

            // Each line also has a bool to indicate if it is bookmarked
            // and a row index it may map to.
            IsBookmarked = new bool[Lines.Length];
            RowIndices   = new int[Lines.Length];
        }
示例#9
0
文件: MiscHandler.cs 项目: a-r-t/psa2
        public DataFlags GetDataFlags()
        {
            DataFlags dataFlags = new DataFlags();

            dataFlags.Offset = DataSectionLocation * 4 + 108;
            for (int i = 0; i < 4; i++)
            {
                dataFlags.ActionFlags.Add(PsaFile.DataSection[DataSectionLocation + 27 + i]);
            }
            Console.WriteLine(dataFlags.Offset.ToString("X"));
            dataFlags.ActionFlags.ForEach(x => Console.WriteLine(x.ToString("X8")));
            return(dataFlags);
        }
示例#10
0
 /// <summary>
 /// Imposta valore flag
 /// </summary>
 /// <param name="index"></param>
 /// <param name="flag"></param>
 /// <param name="value"></param>
 internal void SetFlags(int index, DataFlags flags, bool value)
 {
     if (value)
     {
         //Imposta
         this.PropFlags[index] |= flags;
     }
     else
     {
         //Deimposta
         this.PropFlags[index] &= ~flags;
     }
 }
示例#11
0
            // This is called when reading the circular part of the log to
            // double check that we have a valid record.
            private bool FlagsAreValid(DataFlags flags)
            {
                // InvalidOnes are the bits that must always be 0 (record is
                // invalid if any are 1).
                if ((flags & DataFlags.InvalidOnes) != 0)
                {
                    return(false);
                }

                // MethodEntry and MethodExit should never appear together.
                if ((flags & DataFlags.MethodEntry) != 0 &&
                    (flags & DataFlags.MethodExit) != 0)
                {
                    return(false);
                }

                if (_reader.FormatVersion < 6)
                {
                    // Circular flag should never appear in the circular part
                    if (InCircularPart && (flags & DataFlags.CircularStart) != 0)
                    {
                        return(false);
                    }

                    if ((flags & DataFlags.NewSession) != 0)
                    {
                        return(false);
                    }
                }
                else
                {
                    if ((flags & DataFlags.BlockStart) != 0)
                    {
                        // Certain bits must always be set with BlockStart.
                        const DataFlags mustBeSet = DataFlags.Time | DataFlags.StackDepth | DataFlags.MethodName | DataFlags.TraceLevel | DataFlags.ThreadId | DataFlags.LoggerName;

                        if ((flags & mustBeSet) != mustBeSet)
                        {
                            return(false);
                        }
                    }

                    // If NewSession bit is set, it must be the only one.
                    if (((flags & DataFlags.NewSession) != 0) && (flags != DataFlags.NewSession))
                    {
                        return(false);
                    }
                }

                return(true);
            }
示例#12
0
        /// <summary>
        /// Applies the dynamic native data's vertices, normals and bounds to the dynamic mesh.
        /// </summary>
        public void ApplyData(DataFlags dataFlags)
        {
            if (DynamicMesh == null)
            {
                return;
            }

#if UNITY_2019_3_OR_NEWER
            DataUtils.CopyNativeDataToMesh(DynamicNative, DynamicMesh, dataFlags);
#else
            DataUtils.CopyNativeDataToManagedData(DynamicManaged, DynamicNative, dataFlags);
            DataUtils.CopyManagedDataToMesh(DynamicManaged, DynamicMesh, dataFlags);
#endif
        }
        private void SetMaxFFT(DataFlags value)
        {
            switch (value)
            {
            case DataFlags.FFT512:
                _maxHz             = 1024;
                _maxFft            = value;
                _maxFftSampleIndex = byte.MaxValue;
                break;

            case DataFlags.FFT1024:
                _maxHz             = 1024;
                _maxFft            = value;
                _maxFftSampleIndex = 511;
                break;

            case DataFlags.FFT2048:
                _maxHz             = 2048;
                _maxFft            = value;
                _maxFftSampleIndex = 1023;
                break;

            case DataFlags.FFT4096:
                _maxHz             = 4096;
                _maxFft            = value;
                _maxFftSampleIndex = 2047;
                break;

            case DataFlags.FFT8192:
                _maxHz             = 8192;
                _maxFft            = value;
                _maxFftSampleIndex = 4095;
                break;

            default:
                _maxHz             = 4096;
                _maxFft            = DataFlags.FFT4096;
                _maxFftSampleIndex = 2047;
                break;
            }

            if (_maxFrequencySpectrum <= _maxFftSampleIndex)
            {
                return;
            }

            _maxFrequencySpectrum = _maxFftSampleIndex;
        }
示例#14
0
            // This reads blocks starting at nextBlockPos and follows the chain of blocks back from there until an invalid block is
            // found.  All parameters are assumed to be valid when called.  Upon returning curFlags is set to the
            // last valid block found in the file.  The file position is left after the flags, block number, and
            // record number of the last valid block.
            // Returns the file position of the DataFlags for the found block.
            // Used in file format version 6+.
            private long FindFirstBlock(long nextBlockPos, ref DataFlags curFlags, ref ulong curRecNum, ref uint curBlockNum)
            {
                // curFilePos is the file position of the last good block, after reading
                // the flags, block num, and record num.
                long curFilePos = _fileReader.BaseStream.Position;
                bool good;

                _fileReader.BaseStream.Position = nextBlockPos;

                try
                {
                    do
                    {
                        good = false;
                        var flags = (DataFlags)_fileReader.ReadUInt16();

                        if (FlagsAreValid(flags))
                        {
                            var blockNum = _fileReader.ReadUInt32();

                            if (blockNum == curBlockNum - 1)
                            {
                                var recNum = _fileReader.ReadUInt64();
                                nextBlockPos = _fileReader.ReadInt64();

                                if (nextBlockPos >= _circularStartPos && nextBlockPos < _fileReader.BaseStream.Position)
                                {
                                    curFlags    = flags;
                                    curRecNum   = recNum;
                                    curBlockNum = blockNum;
                                    curFilePos  = _fileReader.BaseStream.Position;
                                    _fileReader.BaseStream.Position = nextBlockPos;
                                    good = true;
                                }
                            }
                        }
                    } while (good);
                }
                catch (Exception)
                {
                }

                _fileReader.BaseStream.Position = curFilePos;

                // Return the file position of the DataFlags for the found block.
                return(curFilePos - sizeof(DataFlags) - sizeof(UInt32) - sizeof(ulong) - sizeof(long));
            }
示例#15
0
        public static bool CopyManagedDataToMesh(ManagedMeshData from, Mesh to, DataFlags dataFlags)
        {
            if (!from.HasValidData())
            {
                Debug.LogError("Cannot copy data as some of it is invalid");
                return(false);
            }
            if (to == null)
            {
                Debug.LogError("Cannot copy data to null mesh");
                return(false);
            }

            // Send managed data to mesh.
            if ((dataFlags & DataFlags.Vertices) != 0)
            {
                to.vertices = from.Vertices;
            }
            if ((dataFlags & DataFlags.Normals) != 0)
            {
                to.normals = from.Normals;
            }
            if ((dataFlags & DataFlags.Tangents) != 0)
            {
                to.tangents = from.Tangents;
            }
            if ((dataFlags & DataFlags.UVs) != 0)
            {
                to.uv = from.UVs;
            }
            if ((dataFlags & DataFlags.Colors) != 0)
            {
                to.colors = from.Colors;
            }
            if ((dataFlags & DataFlags.Triangles) != 0)
            {
                to.triangles = from.Triangles;
            }
            if ((dataFlags & DataFlags.Bounds) != 0)
            {
                to.bounds = from.Bounds;
            }

            return(true);
        }
示例#16
0
        private TextReader GetAndBackupDataFromFallback(string query, DataFlags flags)
        {
            if (FallbackAccessor == null)
            {
                throw new Exception("Cannot get requested data for " + query);
            }

            if (!Directory.Exists(DataDirectory))
            {
                Directory.CreateDirectory(DataDirectory);
            }

            using (TextReader fallbackReader = FallbackAccessor.GetDataReader(query, flags))
            {
                string fileContent = fallbackReader.ReadToEnd();
                File.WriteAllText(Path.Combine(DataDirectory, query.Replace(":", string.Empty)), fileContent, Encoding.UTF8); // Todo remove hard encoding
                return(new StringReader(fileContent));
            }
        }
示例#17
0
        /// <summary>
        /// Gets data from filesystem or if not available from fallback (e.g. CHPP online connection)
        /// </summary>
        /// <param name="query">data query as defined at chpp API</param>
        /// <param name="flags">flags that give hint about data properties</param>
        /// <returns>TextReader to data</returns>
        public TextReader GetDataReader(string query, DataFlags flags)
        {
            string filepath = Path.Combine(DataDirectory, query.Replace(":", string.Empty)); // TODO use: replace all non filename chars

            if ((flags & DataFlags.Static) == DataFlags.Static ||                            // if data isn't expected to change
                FallbackAccessor == null)                                                    // or if we don't have any fallback (e.g. online)
            {
                if (File.Exists(filepath))
                {
                    using (FileStream fileStream = File.OpenRead(filepath))
                    {
                        MemoryStream memoryStream = new MemoryStream((int)fileStream.Length);
                        fileStream.CopyTo(memoryStream); // copying file to memory allows Dispose of FileStream here
                                                         // this should definitely be done my clients later, not here (TODO)
                        memoryStream.Position = 0;
                        return(new StreamReader(memoryStream));
                    }
                }
            }

            return(GetAndBackupDataFromFallback(query, flags));
        }
示例#18
0
        /// <summary>
        /// Applies the dynamic native data's vertices, normals and bounds to the dynamic mesh.
        /// </summary>
        public void ApplyData(DataFlags dataFlags)
        {
            // Copy the native data into the managed data for efficient transfer into the actual mesh.
            DataUtils.CopyNativeDataToManagedData(dynamicManaged, DynamicNative, dataFlags);

            if (DynamicMesh == null)
            {
                return;
            }
            // Send managed data to mesh.
            if ((dataFlags & DataFlags.Vertices) != 0)
            {
                DynamicMesh.vertices = dynamicManaged.Vertices;
            }
            if ((dataFlags & DataFlags.Normals) != 0)
            {
                DynamicMesh.normals = dynamicManaged.Normals;
            }
            if ((dataFlags & DataFlags.Tangents) != 0)
            {
                DynamicMesh.tangents = dynamicManaged.Tangents;
            }
            if ((dataFlags & DataFlags.UVs) != 0)
            {
                DynamicMesh.uv = dynamicManaged.UVs;
            }
            if ((dataFlags & DataFlags.Colors) != 0)
            {
                DynamicMesh.colors = dynamicManaged.Colors;
            }
            if ((dataFlags & DataFlags.Triangles) != 0)
            {
                DynamicMesh.triangles = dynamicManaged.Triangles;
            }
            if ((dataFlags & DataFlags.Bounds) != 0)
            {
                DynamicMesh.bounds = dynamicManaged.Bounds;
            }
        }
示例#19
0
        /// <summary>
        /// Copies mesh data from native arrays into managed ones.
        /// </summary>
        public static bool CopyNativeDataToManagedData(ManagedMeshData managed, NativeMeshData native, DataFlags dataFlags)
        {
            var dataIsValid = true;

            if (!managed.HasValidData())
            {
                dataIsValid = false;
                Debug.LogError("Cannot copy data as the managed data is invalid");
            }
            if (!native.HasValidData())
            {
                Debug.LogError("Cannot copy data as the native data is invalid");
                dataIsValid = false;
            }

            if (!dataIsValid)
            {
                return(false);
            }

            if ((dataFlags & DataFlags.Vertices) != 0)
            {
                native.VertexBuffer.MemCpy(managed.Vertices);
            }
            if ((dataFlags & DataFlags.Normals) != 0)
            {
                native.NormalBuffer.MemCpy(managed.Normals);
            }
            if ((dataFlags & DataFlags.Tangents) != 0)
            {
                native.TangentBuffer.MemCpy(managed.Tangents);
            }
            if ((dataFlags & DataFlags.UVs) != 0)
            {
                native.UVBuffer.MemCpy(managed.UVs);
            }
            if ((dataFlags & DataFlags.Colors) != 0)
            {
                native.ColorBuffer.MemCpy(managed.Colors);
            }
            if ((dataFlags & DataFlags.Triangles) != 0)
            {
                native.IndexBuffer.CopyTo(managed.Triangles);
            }
            if ((dataFlags & DataFlags.Bounds) != 0)
            {
                managed.Bounds = native.Bounds[0];
            }

            return(true);
        }
示例#20
0
        // This sets bits in the flags parameter that specify what data to include with the line.
        private DataFlags SetDataFlags(DataFlags flags, ThreadData threadData, BinaryFileState fileThreadState, Logger logger, TraceLevel lineLevel)
        {
            if (_lastBlock != _curBlock)
            {
                // The very first line in each block (regardless of thread)
                // includes the time in case this line ends up being the first line due to wrapping.
                flags |= DataFlags.Time;

                if (CircularStarted)
                {
                    flags |= DataFlags.BlockStart;
                }
            }

            if (fileThreadState.LastBlock != _curBlock)
            {
                // First line in current block for the thread.  Include all per-thread data.
                flags |= DataFlags.StackDepth | DataFlags.MethodName | DataFlags.TraceLevel | DataFlags.ThreadId | DataFlags.LoggerName;

                if (threadData.Name != null)
                {
                    flags |= DataFlags.ThreadName;
                }
            }
            else
            {
                if (_lastThread != threadData)
                {
                    // This line's thread differs from the last line's thread.
                    flags |= DataFlags.ThreadId;
                }

                if (fileThreadState.LastThreadName != threadData.Name)
                {
                    // Thread's name has changed.
                    flags |= DataFlags.ThreadId | DataFlags.ThreadName;
                }

                if (fileThreadState.CurrentMethod != fileThreadState.LastMethod)
                {
                    // We have a new method name for this thread.
                    flags |= DataFlags.MethodName;
                }

                if (fileThreadState.LastTraceLevel != lineLevel)
                {
                    // This line's trace Level differs from the previous line
                    // logged by this thread.
                    flags |= DataFlags.TraceLevel;
                }

                if (fileThreadState.LastLogger != logger)
                {
                    // This line's logger name differs from the previous line
                    // logged by this thread.
                    flags |= DataFlags.LoggerName;
                }
            }

            return(flags);
        }
示例#21
0
        // This is what actually writes the output. The dataFlags parameter specifies what to write.
        private void WriteData(DataFlags dataFlags, ThreadData threadData, BinaryFileState fileThreadState, Logger logger, TraceLevel lineLevel, string msg)
        {
            ++_lineCnt;

            // Write the flags first so the viewer will know what else the record contains.
            _logfile.Write((ushort)dataFlags);

            if (CircularStarted)
            {
                _logfile.Write(_curBlock);

                if ((dataFlags & DataFlags.BlockStart) != DataFlags.None)
                {
                    // This will be the first record in the block.
                    // This stuff helps the viewer find the first chronological block
                    // even after wrapping.  Writting _lastBlockPosition forms a linked
                    // list of blocks that the viewer can follow.

                    //System.Diagnostics.Debug.Print("Block {0} starting at line {1}, position {2}", _curBlock, _lineCnt, _logfile.BaseStream.Position);
                    _logfile.Write(_lineCnt);
                    _logfile.Write(_lastBlockPosition);
                }
            }

            if ((dataFlags & DataFlags.Time) != DataFlags.None)
            {
                _logfile.Write(_curTime.Ticks);
            }

            if ((dataFlags & DataFlags.ThreadId) != DataFlags.None)
            {
                _logfile.Write(threadData.TracerXID);
            }

            if ((dataFlags & DataFlags.ThreadName) != DataFlags.None)
            {
                // ThreadPool thread names get reset to null when a thread is returned
                // to the pool and reused later.
                if (_hasPassword)
                {
                    _encryptor.Encrypt(threadData.Name ?? string.Empty);
                }
                else
                {
                    _logfile.Write(threadData.Name ?? string.Empty);
                }
            }

            if ((dataFlags & DataFlags.TraceLevel) != DataFlags.None)
            {
                _logfile.Write((byte)lineLevel);
            }

            // In format version 5 and later, the viewer subtracts 1 from the stack depth on
            // MethodExit lines instead of the logger, so just write the depth as-is.
            if ((dataFlags & DataFlags.StackDepth) != DataFlags.None)
            {
                _logfile.Write(fileThreadState.StackDepth);

                if (CircularStarted)
                {
                    // In the circular part, include the thread's call stack with the first line
                    // logged for each thread in each block.  This enables the viewer to
                    // regenerate method entry/exit lines lost due to wrapping.
                    // Added in format version 5.
                    int count = 0;
                    for (StackEntry stackEntry = threadData.TopStackEntry; stackEntry != null; stackEntry = stackEntry.Caller)
                    {
                        if (stackEntry.BinaryFileState == fileThreadState)
                        {
                            ++count;
                            _logfile.Write(stackEntry.EntryLine); // Changed to ulong in version 6.
                            _logfile.Write((byte)stackEntry.Level);

                            if (_hasPassword)
                            {
                                Debug.Assert(stackEntry.Logger.Name != null);
                                _encryptor.Encrypt(stackEntry.Logger.Name);

                                Debug.Assert(stackEntry.MethodName != null);
                                _encryptor.Encrypt(stackEntry.MethodName);
                            }
                            else
                            {
                                _logfile.Write(stackEntry.Logger.Name);
                                _logfile.Write(stackEntry.MethodName);
                            }
                        }
                    }

                    // The StackDepth we wrote previously is how the viewer will know how many
                    // stack entries to read.
                    System.Diagnostics.Debug.Assert(count == fileThreadState.StackDepth);
                }
            }

            if ((dataFlags & DataFlags.LoggerName) != DataFlags.None)
            {
                if (_hasPassword)
                {
                    _encryptor.Encrypt(logger.Name);
                }
                else
                {
                    _logfile.Write(logger.Name);
                }
            }

            if ((dataFlags & DataFlags.MethodName) != DataFlags.None)
            {
                if (_hasPassword)
                {
                    _encryptor.Encrypt(fileThreadState.CurrentMethod);
                }
                else
                {
                    _logfile.Write(fileThreadState.CurrentMethod);
                }

                fileThreadState.LastMethod = fileThreadState.CurrentMethod;
            }

            if ((dataFlags & DataFlags.Message) != DataFlags.None)
            {
                if (_hasPassword)
                {
                    _encryptor.Encrypt(msg ?? "");
                }
                else
                {
                    _logfile.Write(msg);
                }
            }

            _lastBlock  = _curBlock;
            _lastThread = threadData;
            fileThreadState.LastBlock      = _curBlock;
            fileThreadState.LastThreadName = threadData.Name;
            fileThreadState.LastTraceLevel = lineLevel;
            fileThreadState.LastLogger     = logger;
        }
示例#22
0
        // Called immediately after writing a line of output in circular mode.
        // This may wrap and/or truncate the file, but does not write any output.
        // This does update the file's LastWriteTime.
        // startPos = the file position of the beginning of the line just written.
        private void ManageCircularPart(long startPos, long startSize, DataFlags dataFlags)
        {
            long endPos = _logfile.BaseStream.Position;

            // Truncate the file if we just overwrote the block that extends past max file size, since
            // the viewer can't access that info, it can be arbitrarily large, and it screws things up
            // if another logging session appends output to the file.
            if (_maxBlockPosition >= startPos && _maxBlockPosition < endPos)
            {
                //System.Diagnostics.Debug.Print("Last physical block start was overwritten at " + _maxBlockPosition + ".  Truncating file at " + endPos);
                _maxBlockPosition = 0;
                _logfile.BaseStream.SetLength(endPos);
            }

            if (endPos >= _maxFilePosition)
            {
                // Since we've reached or exceeded the max file size/position, it's time to wrap and
                // start a new block even if the current block only has one line.
                //System.Diagnostics.Debug.Print("File position exceeded max size.");

                // Remember the file location of this block because it extends
                // past the max file size.
                _maxBlockPosition = _curBlockPosition;

                // Wrap back to the beginning of the circular part.
                _logfile.BaseStream.Position = _positionOfCircularPart;

                // Cause the current block to end and a new block to start.
                EndCurrentBlock();

                if (!_everWrapped)
                {
                    Logger.EventLogging.Log("The output file wrapped for the first time: " + FullPath, Logger.EventLogging.FirstWrap);
                    _everWrapped = true;
                }
            }
            else
            {
                // Keep track of how many bytes are in this block so we can determine
                // if it's time to start a new one based on block size.
                _bytesInBlock += (uint)(endPos - startPos);

                // Now check if the current block has enough bytes to start a new block.
                if (_bytesInBlock >= _blockSize)
                {
                    EndCurrentBlock();
                }
            }

            if (_everWrapped)
            {
                // On XP, the file's LastWriteTime changes automatically when the logger writes to the
                // file ONLY IF the size changes too.  If the file has wrapped (meaning the size rarely changes),
                // we "manually" update the LastWriteTime.  Thus, on XP, both properties change until
                // the file wraps, and then only the LastWriteTime changes.
                // On Vista, the LastWriteTime doesn't change automatically until the logger closes the
                // file (even if the size does change).  However, the size will change until the file wraps,
                // then we start "manually" setting the LastWriteTime.  Thus, on Vista, only the size changes
                // until the file wraps, then only the LastWriteTime changes.  The viewer monitors both properties.

                if (_logfile.BaseStream.Length == startSize && (dataFlags & DataFlags.Time) != DataFlags.None)
                {
                    // The line we just wrote did not change the file size so manually update the file's LastWiteTime.

                    long writeTime = _curTime.ToLocalTime().ToFileTime();
                    SetFileTime(_fileHandle, IntPtr.Zero, IntPtr.Zero, ref writeTime);
                }
            }
        }
示例#23
0
        // Determine what data needs to be written based on dataFlags,
        // whether circular logging has or should be started,
        // and whether we're starting a new circular block.
        // Write the output to the file.  Manage the circular part of the log.
        // Return the line number just written.
        private ulong WriteLine(DataFlags dataFlags, ThreadData threadData, Logger logger, TraceLevel lineLevel, DateTime explicitUtcTime, string msg, bool recursive)
        {
            BinaryFileState fileThreadState = threadData.GetBinaryFileState(this);

            lock (_fileLocker)
            {
                try
                {
                    if (IsOpen)
                    {
                        if (fileThreadState.LastFileNumber != CurrentFile)
                        {
                            // First time writing to this file.
                            threadData.ResetBinaryFileStateData(CurrentFile, dataFlags);
                        }

                        // Calling IsNewTime() can change _curTime.
                        if (IsNewTime(explicitUtcTime) || recursive)
                        {
                            // Time differs from previous line.
                            // Set the flag indicating it will be written
                            dataFlags |= DataFlags.Time;
                        }

                        // Possibly start the circular log based on _curTime and/or file size.
                        // Put this after calling IsNewTime() so _curTime will have
                        // the latest DateTime value.
                        if (FullFilePolicy == FullFilePolicy.Wrap && !recursive && !CircularStarted &&
                            (_curTime >= _circularStartTime || (CircularStartSizeKb > 0 && (_logfile.BaseStream.Position - _openSize) >= CircularStartSizeKb << 10)))
                        {
                            // This will start the circular part of the log if there is enough
                            // room based on current file position and max file size.
                            // It will increment _curBlock if it starts the circular log.
                            // It will also make a recursive call to this method via Metalog.
                            StartCircular(logger, lineLevel);
                        }

                        // Set bits in Flags that indicate what data should be written for this line.
                        dataFlags = SetDataFlags(dataFlags, threadData, fileThreadState, logger, lineLevel);

                        // We need to know the start position of the line we're about
                        // to write to determine if it overwrites the beginning of the oldest block.
                        long startPos = _logfile.BaseStream.Position;

                        // We capture the size of the file before writing the message so we can tell
                        // if the size changes.
                        long startSize = _logfile.BaseStream.Length;

                        // Write the Flags to the file followed by the data the Flags say to log.
                        WriteData(dataFlags, threadData, fileThreadState, logger, lineLevel, msg);

                        // If the file is being viewed, this will notify the viewer that the file was changed.
                        _viewerSignaler.SignalEvents();

                        if (CircularStarted)
                        {
                            ManageCircularPart(startPos, startSize, dataFlags);
                        }
                        else if (_logfile.BaseStream.Position >= _maxFilePosition)
                        {
                            // We can't do any meta-logging here because the viewer expects the first record to reach
                            // _maxFilePosition (which we just wrote) to be the last.  Writing another record would cause errors.

                            switch (FullFilePolicy)
                            {
                            case FullFilePolicy.Close:
                                Close();
                                break;

                            case FullFilePolicy.Roll:
                                // If logging a method-entry or method-exit, wait until the next call
                                // to close and open.
                                if ((dataFlags & (DataFlags.MethodEntry | DataFlags.MethodExit)) == 0)
                                {
                                    // These calls may raise events whose handlers modify our properties.
                                    Close();
                                    Open();
                                }
                                break;

                            case FullFilePolicy.Wrap:
                                // Reaching max file size/position without being in circular mode means we'll never write to
                                // this file again, so we might as well close it.  Since this is probably not what the user intended,
                                // also log an event.
                                string errmsg = "The maximum file size of " + _maxFilePosition + " was reached before circular logging was engaged.  The log file is " + FullPath;
                                Logger.EventLogging.Log(errmsg, Logger.EventLogging.MaxFileSizeReached);
                                Close();
                                break;
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    // Give up!  close the log file, free whatever memory we can.
                    Logger.EventLogging.Log("An exception was thrown while logging: " + ex.ToString(), Logger.EventLogging.ExceptionInLogger);
                    Close();
                }

                return(_lineCnt);
            }
        }
示例#24
0
 public static bool CopyToManagedData(this NativeMeshData from, ManagedMeshData to, DataFlags dataFlags) => CopyNativeDataToManagedData(to, from, dataFlags);
示例#25
0
 /// <summary>
 /// Copies the original native data over the dynamic native data.
 /// </summary>
 public void ResetData(DataFlags dataFlags)
 {
     // Copy the original mesh data into the native data to remove any changes.
     DataUtils.CopyNativeDataToNativeData(OriginalNative, DynamicNative, dataFlags);
 }
示例#26
0
        /// <summary>
        /// Copies mesh data from one native array to another
        /// </summary>
        public static bool CopyNativeDataToNativeData(NativeMeshData from, NativeMeshData to, DataFlags dataFlags)
        {
            if (!to.HasValidData() || !from.HasValidData())
            {
                Debug.LogError("Cannot copy data as some of it is invalid");
                return(false);
            }

            if ((dataFlags & DataFlags.Vertices) != 0)
            {
                from.VertexBuffer.CopyTo(to.VertexBuffer);
            }
            if ((dataFlags & DataFlags.Normals) != 0)
            {
                from.NormalBuffer.CopyTo(to.NormalBuffer);
            }
            if ((dataFlags & DataFlags.MaskVertices) != 0)
            {
                from.MaskVertexBuffer.CopyTo(to.MaskVertexBuffer);
            }
            if ((dataFlags & DataFlags.Tangents) != 0)
            {
                from.TangentBuffer.CopyTo(to.TangentBuffer);
            }
            if ((dataFlags & DataFlags.UVs) != 0)
            {
                from.UVBuffer.CopyTo(to.UVBuffer);
            }
            if ((dataFlags & DataFlags.Colors) != 0)
            {
                from.ColorBuffer.CopyTo(to.ColorBuffer);
            }
            if ((dataFlags & DataFlags.Triangles) != 0)
            {
                from.IndexBuffer.CopyTo(to.IndexBuffer);
            }
            if ((dataFlags & DataFlags.Bounds) != 0)
            {
                from.Bounds.CopyTo(to.Bounds);
            }

            return(true);
        }
示例#27
0
 public static bool CopyToMesh(this NativeMeshData from, Mesh to, DataFlags dataFlags) => CopyNativeDataToMesh(from, to, dataFlags);
示例#28
0
 public static bool CopyToNativeData(this ManagedMeshData from, NativeMeshData to, DataFlags dataFlags) => CopyManagedToNativeMeshData(from, to, dataFlags);
示例#29
0
 public static bool CopyToMesh(ManagedMeshData from, Mesh to, DataFlags dataFlags) => CopyManagedDataToMesh(from, to, dataFlags);
示例#30
0
        /// <summary>
        /// Copies mesh data from managed arrays into native ones.
        /// </summary>
        /// <param name="onlyEssentials">If true, only vertices, normals, bounds, and mask vertices will be copied.</param>
        public static void CopyManagedToNativeMeshData(ManagedMeshData managed, NativeMeshData native, DataFlags dataFlags)
        {
            var dataIsValid = true;

            if (!managed.HasValidData())
            {
                dataIsValid = false;
                Debug.LogError("Cannot copy data as the managed data is invalid");
            }
            if (!native.HasValidData())
            {
                Debug.LogError("Cannot copy data as the native data is invalid");
                dataIsValid = false;
            }

            if (!dataIsValid)
            {
                return;
            }

            if ((dataFlags & DataFlags.Vertices) != 0)
            {
                managed.Vertices.MemCpy(native.VertexBuffer);
            }
            if ((dataFlags & DataFlags.Normals) != 0)
            {
                managed.Normals.MemCpy(native.NormalBuffer);
            }
            if ((dataFlags & DataFlags.MaskVertices) != 0)
            {
                managed.Vertices.MemCpy(native.MaskVertexBuffer);
            }
            if ((dataFlags & DataFlags.Tangents) != 0)
            {
                managed.Tangents.MemCpy(native.TangentBuffer);
            }
            if ((dataFlags & DataFlags.UVs) != 0)
            {
                managed.UVs.MemCpy(native.UVBuffer);
            }
            if ((dataFlags & DataFlags.Colors) != 0)
            {
                managed.Colors.MemCpy(native.ColorBuffer);
            }
            if ((dataFlags & DataFlags.Triangles) != 0)
            {
                managed.Triangles.MemCpy(native.IndexBuffer);
            }
            if ((dataFlags & DataFlags.Bounds) != 0)
            {
                native.Bounds[0] = managed.Bounds;
            }
        }