bool Architecture::FormatCharacter( Document const& rDoc, Address const& rAddr, Character const& rChar, PrintData & rPrintData) const { auto const& rBinStrm = rDoc.GetBinaryStream(); std::ostringstream oss; TOffset Off; if (!rDoc.ConvertAddressToFileOffset(rAddr, Off)) return false; switch (rChar.GetSubType()) { case Character::AsciiCharacterType: default: { s8 Char; if (!rBinStrm.Read(Off, Char)) return false; switch (Char) { case '\0': oss << "\\0"; break; case '\a': oss << "\\a"; break; case '\b': oss << "\\b"; break; case '\t': oss << "\\t"; break; case '\n': oss << "\\n"; break; case '\v': oss << "\\v"; break; case '\f': oss << "\\f"; break; case '\r': oss << "\\r"; break; default: oss << Char; break; } } } rPrintData.AppendCharacter(oss.str()); return true; }
bool Architecture::FormatValue( Document const& rDoc, Address const& rAddr, Value const& rVal, PrintData & rPrintData) const { auto const& rBinStrm = rDoc.GetBinaryStream(); TOffset Off; u8 ValueModifier = rVal.GetSubType() & ValueDetail::ModifierMask; u8 ValueType = rVal.GetSubType() & ValueDetail::BaseMask; std::string BasePrefix = ""; bool IsUnk = false; switch (rVal.GetLength()) { case 1: rPrintData.AppendKeyword("db").AppendSpace(); break; case 2: rPrintData.AppendKeyword("dw").AppendSpace(); break; case 4: rPrintData.AppendKeyword("dd").AppendSpace(); break; case 8: rPrintData.AppendKeyword("dq").AppendSpace(); break; default: rPrintData.AppendKeyword("d?").AppendSpace(); break; } if (!rDoc.ConvertAddressToFileOffset(rAddr, Off)) { rPrintData.AppendOperator("(?)"); return true; } ValueDetail ValDtl("", Id(), static_cast<ValueDetail::Type>(rVal.GetSubType()), Id()); return FormatValueDetail(rDoc, rAddr, rVal.GetLength() * 8, ValDtl, rPrintData); }
bool Architecture::FormatCharacter( Document const& rDoc, BinaryStream const& rBinStrm, Address const& rAddr, Character const& rChar, std::string & rStrCell, Cell::Mark::List & rMarks) const { std::ostringstream oss; TOffset Off; if (!rDoc.ConvertAddressToFileOffset(rAddr, Off)) return false; switch (rChar.GetSubType()) { case Character::AsciiCharacterType: default: { s8 Char; if (!rBinStrm.Read(Off, Char)) return false; switch (Char) { case '\0': oss << "\\0"; break; case '\a': oss << "\\a"; break; case '\b': oss << "\\b"; break; case '\t': oss << "\\t"; break; case '\n': oss << "\\n"; break; case '\v': oss << "\\v"; break; case '\f': oss << "\\f"; break; case '\r': oss << "\\r"; break; default: oss << Char; break; } } } rMarks.push_back(Cell::Mark(Cell::Mark::StringType, 1)); rStrCell = oss.str(); return true; }
bool Architecture::FormatString( Document const& rDoc, Address const& rAddr, String const& rStr, PrintData & rPrintData) const { auto const& rBinStrm = rDoc.GetBinaryStream(); TOffset FileOff; size_t StrLen = rStr.GetLength(); StringTrait const* pStrTrait = rStr.GetStringTrait(); if (pStrTrait == nullptr) return false; if (rDoc.ConvertAddressToFileOffset(rAddr, FileOff) == false) return false; char* pStrBuf = new char[StrLen]; if (rDoc.GetBinaryStream().Read(FileOff, pStrBuf, StrLen) == false) { delete[] pStrBuf; return false; } std::string OrgStr = pStrTrait->ConvertToUtf8(pStrBuf, StrLen); delete[] pStrBuf; if (OrgStr.empty()) return false; std::string FmtStr; if (rStr.GetSubType() == String::Utf16Type) rPrintData.AppendKeyword("L"); rPrintData.AppendOperator("\""); auto itCharEnd = std::end(OrgStr); size_t FmtStrBeg = FmtStr.length(); for (auto itChar = std::begin(OrgStr); itChar != itCharEnd; ++itChar) { switch (*itChar) { case '\0': FmtStr += "\\0"; break; case '\\': FmtStr += "\\\\"; break; case '\a': FmtStr += "\\a"; break; case '\b': FmtStr += "\\b"; break; case '\t': FmtStr += "\\t"; break; case '\n': FmtStr += "\\n"; break; case '\v': FmtStr += "\\v"; break; case '\f': FmtStr += "\\f"; break; case '\r': FmtStr += "\\r"; break; default: FmtStr += *itChar; break; } } rPrintData.AppendString(FmtStr); rPrintData.AppendOperator("\""); return true; }
bool Architecture::FormatString( Document const& rDoc, BinaryStream const& rBinStrm, Address const& rAddr, String const& rStr, std::string & rStrMultiCell, Cell::Mark::List & rMarks) const { TOffset FileOff; size_t StrLen = rStr.GetLength(); StringTrait const* pStrTrait = rStr.GetStringTrait(); if (pStrTrait == nullptr) return false; if (rDoc.ConvertAddressToFileOffset(rAddr, FileOff) == false) return false; char* pStrBuf = new char[StrLen]; if (rDoc.GetBinaryStream().Read(FileOff, pStrBuf, StrLen) == false) { delete[] pStrBuf; return false; } std::string OrgStr = pStrTrait->ConvertToUtf8(pStrBuf, StrLen); delete[] pStrBuf; if (OrgStr.empty()) return false; std::string FmtStr; if (rStr.GetSubType() == String::Utf16Type) { FmtStr += "L"; rMarks.push_back(Cell::Mark(Cell::Mark::KeywordType, 1)); } FmtStr += std::string("\""); rMarks.push_back(Cell::Mark(Cell::Mark::OperatorType, 1)); auto itCharEnd = std::end(OrgStr); size_t FmtStrBeg = FmtStr.length(); for (auto itChar = std::begin(OrgStr); itChar != itCharEnd; ++itChar) { switch (*itChar) { case '\0': FmtStr += "\\0"; break; case '\\': FmtStr += "\\\\"; break; case '\a': FmtStr += "\\a"; break; case '\b': FmtStr += "\\b"; break; case '\t': FmtStr += "\\t"; break; case '\n': FmtStr += "\\n"; break; case '\v': FmtStr += "\\v"; break; case '\f': FmtStr += "\\f"; break; case '\r': FmtStr += "\\r"; break; default: FmtStr += *itChar; break; } } FmtStr += std::string("\""); rMarks.push_back(Cell::Mark(Cell::Mark::StringType, FmtStr.length() - FmtStrBeg - 1)); rMarks.push_back(Cell::Mark(Cell::Mark::OperatorType, 1)); rStrMultiCell.swap(FmtStr); return true; }
bool Architecture::FormatValue( Document const& rDoc, BinaryStream const& rBinStrm, Address const& rAddr, Value const& rVal, std::string & rStrCell, Cell::Mark::List & rMarks) const { std::ostringstream oss; TOffset Off; u8 ValueType = rVal.GetSubType(); std::string BasePrefix = ""; bool IsUnk = false; auto const& rCurBinStrm = rDoc.GetBinaryStream(); if (!rDoc.ConvertAddressToFileOffset(rAddr, Off)) IsUnk = true; oss << std::setfill('0'); switch (ValueType) { case Value::BinaryType: BasePrefix = "0b"; break; // TODO: Unimplemented case Value::DecimalType: oss << std::dec; BasePrefix = "0n"; break; case Value::HexadecimalType: default: oss << std::hex; BasePrefix = "0x"; break; } Cell::Mark::Type MarkType = Cell::Mark::ImmediateType; switch (rVal.GetLength()) { case 1: default: { if (IsUnk) oss << "db (?)"; else { u8 Data; if (!rCurBinStrm.Read(Off, Data)) return false; oss << "db " << BasePrefix << std::setw(2) << static_cast<u16>(Data); // u8 type would be printed as char by ostream } break; } case 2: { if (IsUnk) oss << "dw (?)"; else { u16 Data; if (!rCurBinStrm.Read(Off, Data)) return false; Label Lbl = rDoc.GetLabelFromAddress(Data); if (Lbl.GetType() == Label::Unknown) oss << "dw " << BasePrefix << std::setw(4) << static_cast<u16>(Data); else { oss << "dw " << Lbl.GetLabel(); MarkType = Cell::Mark::LabelType; } } break; } case 4: { if (IsUnk) oss << "dd (?)"; else { u32 Data; if (!rCurBinStrm.Read(Off, Data)) return false; Label Lbl = rDoc.GetLabelFromAddress(Data); if (Lbl.GetType() == Label::Unknown) oss << "dd " << BasePrefix << std::setw(8) << static_cast<u32>(Data); else { oss << "dd " << Lbl.GetLabel(); MarkType = Cell::Mark::LabelType; } } break; } case 8: { if (IsUnk) oss << "dq (?)"; else { u64 Data; if (!rCurBinStrm.Read(Off, Data)) return false; Label Lbl = rDoc.GetLabelFromAddress(Data); if (Lbl.GetType() == Label::Unknown) oss << "dq " << BasePrefix << std::setw(16) << static_cast<u64>(Data); else { oss << "dq " << Lbl.GetLabel(); MarkType = Cell::Mark::LabelType; } } break; } } rMarks.push_back(Cell::Mark(Cell::Mark::KeywordType, 3)); rMarks.push_back(Cell::Mark(MarkType, oss.str().length() - 3)); rStrCell = oss.str(); return true; }