public ColorString ToColorString() { if (null == m_cs) { m_cs = new ColorString(); m_cs.Append(DbgProvider.ColorizeModuleName(m_udt.Module.Name)) .Append("!") .Append(m_udt.ColorName) .Append(" (size 0x") .Append(m_udt.Size.ToString("x")) .Append(")"); int widest = 16; foreach (var item in Items) { var ddti = item.Item as DbgDataTypeInfo; if (null != ddti) { widest = Math.Max(widest, ddti.Name.Length); } } widest = Math.Min(widest, 40); foreach (var item in Items) { m_cs.AppendLine() .Append(" +0x") .Append(item.Offset.ToString("x3")) .Append(" "); var ddti = item.Item as DbgDataTypeInfo; if (null != ddti) { m_cs.Append(ColorString.MakeFixedWidth(ddti.Name, widest)) .Append(" : ") .Append(ddti.DataType.ColorName); } else { VTableLayoutItem vli = (VTableLayoutItem)item; var dvti = (DbgVTableTypeInfo)item.Item; m_cs.AppendPushFg(ConsoleColor.DarkGray); if (vli.VTablePath.Count > 1) { m_cs.Append(vli.VTablePath[1].ColorName).Append(": "); } m_cs.Append(dvti.ToColorString()) .AppendPop(); } } m_cs.MakeReadOnly(); } // end if( !m_cs ) return(m_cs); } // end ToColorString()
} // end _FormatBlocks() private ColorString _FormatCharsOnly(uint numColumns, uint bytesPerChar, Func <char, char> toDisplay) { if (0 == numColumns) { numColumns = 32; // documentation says it should be 48, but windbg seems to do 32 instead. } ColorString cs = new ColorString(); StringBuilder sbChars = new StringBuilder((int)numColumns + 8); ulong addr = StartAddress; for (int idx = 0; idx < Count; idx++) { if (0 == (idx % numColumns)) { // This is the beginning of a new line. // First finish off the last line if necessary: if (sbChars.Length > 1) { sbChars.Append('"'); cs.AppendPushPopFg(ConsoleColor.Cyan, sbChars.ToString()); } sbChars.Clear(); sbChars.Append('"'); if (0 != idx) { cs.AppendLine(); } cs.Append(DbgProvider.FormatAddress(addr, m_is32Bit, true, true)).Append(" "); addr += (ulong)numColumns * bytesPerChar; } // end start of new line // Widen to ulong to accommodate largest possible item. ulong val = (ulong)this[idx]; if (0 == val) { break; } sbChars.Append(toDisplay((char)val)); } // end for( idx = 0 .. length ) // Finish off last line. if (sbChars.Length > 1) { sbChars.Append('"'); cs.AppendPushPopFg(ConsoleColor.Cyan, sbChars.ToString()); } return(cs.MakeReadOnly()); } // end _FormatCharsOnly()
} // end _FormatCharsOnly() private ColorString _FormatBits() { ColorString cs = new ColorString(); uint bytesPerValue = sizeof(uint); uint bitsPerValue = bytesPerValue * 8; ulong addr = StartAddress; for (int idx = 0; idx < Count; idx++) { if (0 != idx) { cs.AppendLine(); } cs.Append(DbgProvider.FormatAddress(addr, m_is32Bit, true, true)).Append(" "); addr += (ulong)bytesPerValue; uint val = this[idx]; for (int i = 0; i < bitsPerValue; i++) { if (i % 8 == 0) { cs.Append(" "); } uint mask = 0x80000000 >> i; if ((mask & val) == mask) { cs.AppendPushPopFg(ConsoleColor.Green, "1"); } else { cs.AppendPushPopFg(ConsoleColor.DarkGreen, "0"); } } cs.Append(" " + val.ToString("x").PadLeft(8, '0')); } // end for( idx = 0 .. length ) return(cs.MakeReadOnly()); } // end _FormatBits()
} // end property Signature private ColorString _BuildSignature() { var cs = new ColorString(); if (!IsConstructor && !IsDestructor) { cs.Append(FunctionType.ReturnType.ColorName).Append(" "); } cs.Append(ColorName).Append("("); if ((0 == FunctionType.Arguments.Count) || ((1 == FunctionType.Arguments.Count) && (0 == Util.Strcmp_OI("void", FunctionType.Arguments[0].ArgType.Name)))) { cs.Append(")"); } else { bool first = true; foreach (var fa in FunctionType.Arguments) { if (first) { first = false; } else { cs.Append(","); } cs.Append(" ").Append(fa.ArgType.ColorName); } // end foreach( arg ) cs.Append(" )"); } // end else( there are arguments ) return(cs.MakeReadOnly()); } // end GetSignature()
} // end _ZeroPad() private ColorString _FormatBlocks(int elemSize, int charsPerBlock, uint numColumns, AddtlInfo addtlInfo) { if (0 == numColumns) { numColumns = (uint)(16 / elemSize); } if (addtlInfo.HasFlag(AddtlInfo.Symbols)) { numColumns = 1; } int desiredLen = elemSize * 2; ColorString cs = new ColorString(); StringBuilder sbChars = new StringBuilder(20); ulong addr = StartAddress; cs.AppendPushFg(ConsoleColor.DarkGreen); for (int idx = 0; idx < Count; idx++) { if (0 == (idx % numColumns)) { // This is the beginning of a new line. // First finish off the last line if necessary: if (addtlInfo.HasFlag(AddtlInfo.Ascii)) { if (sbChars.Length > 2) { cs.AppendPushPopFg(ConsoleColor.Cyan, sbChars.ToString()); } sbChars.Clear(); sbChars.Append(" "); } if (0 != idx) { cs.AppendLine(); } cs.Append(DbgProvider.FormatAddress(addr, m_is32Bit, true, true)).Append(" "); addr += (ulong)(numColumns * elemSize); } // end start of new line else { cs.Append(" "); } // Widen to ulong to accommodate largest possible item. ulong val = (ulong)this[idx]; // This highlights the non-zero portion in [bright] green. cs.Append(_ZeroPad(val, desiredLen)); if (addtlInfo.HasFlag(AddtlInfo.Symbols)) { ColorString csSym = ColorString.Empty; if (val > 4096) // don't even bother trying if it's too low. { csSym = m_lookupSymbol(val); if (csSym.Length > 0) { cs.Append(" ").Append(csSym); } } if (addtlInfo.HasFlag(AddtlInfo.Ascii)) { if (0 == csSym.Length) { cs.Append(" "); _AppendChars(sbChars, idx * elemSize, elemSize); } } } // end if( symbols ) else if (addtlInfo.HasFlag(AddtlInfo.Ascii)) { _AppendChars(sbChars, idx * elemSize, elemSize); } // end else if( Ascii ) } // end for( idx = 0 .. length ) // Finish off last line. if (sbChars.Length > 2) { // It could be a partial line, so we may need to adjust for that. int numMissing = (int)numColumns - ((sbChars.Length - 2) / elemSize); Util.Assert(numMissing >= 0); if (numMissing > 0) { cs.Append(new String(' ', numMissing * charsPerBlock)); } cs.AppendPushPopFg(ConsoleColor.Cyan, sbChars.ToString()); } cs.AppendPop(); // pop DarkGreen return(cs.MakeReadOnly()); } // end _FormatBlocks()