10b57cec5SDimitry Andric //===-- GDBRemoteCommunicationHistory.h--------------------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
95ffd83dbSDimitry Andric #ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONHISTORY_H
105ffd83dbSDimitry Andric #define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONHISTORY_H
110b57cec5SDimitry Andric 
120b57cec5SDimitry Andric #include <string>
130b57cec5SDimitry Andric #include <vector>
140b57cec5SDimitry Andric 
159dba64beSDimitry Andric #include "lldb/Utility/GDBRemote.h"
160b57cec5SDimitry Andric #include "lldb/lldb-public.h"
170b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
180b57cec5SDimitry Andric 
190b57cec5SDimitry Andric namespace lldb_private {
200b57cec5SDimitry Andric namespace process_gdb_remote {
210b57cec5SDimitry Andric 
220b57cec5SDimitry Andric /// The history keeps a circular buffer of GDB remote packets. The history is
230b57cec5SDimitry Andric /// used for logging and replaying GDB remote packets.
240b57cec5SDimitry Andric class GDBRemoteCommunicationHistory {
250b57cec5SDimitry Andric public:
260b57cec5SDimitry Andric   GDBRemoteCommunicationHistory(uint32_t size = 0);
270b57cec5SDimitry Andric 
280b57cec5SDimitry Andric   ~GDBRemoteCommunicationHistory();
290b57cec5SDimitry Andric 
300b57cec5SDimitry Andric   // For single char packets for ack, nack and /x03
319dba64beSDimitry Andric   void AddPacket(char packet_char, GDBRemotePacket::Type type,
320b57cec5SDimitry Andric                  uint32_t bytes_transmitted);
330b57cec5SDimitry Andric 
349dba64beSDimitry Andric   void AddPacket(const std::string &src, uint32_t src_len,
359dba64beSDimitry Andric                  GDBRemotePacket::Type type, uint32_t bytes_transmitted);
369dba64beSDimitry Andric 
370b57cec5SDimitry Andric   void Dump(Stream &strm) const;
380b57cec5SDimitry Andric   void Dump(Log *log) const;
DidDumpToLog()390b57cec5SDimitry Andric   bool DidDumpToLog() const { return m_dumped_to_log; }
400b57cec5SDimitry Andric 
410b57cec5SDimitry Andric private:
GetFirstSavedPacketIndex()420b57cec5SDimitry Andric   uint32_t GetFirstSavedPacketIndex() const {
430b57cec5SDimitry Andric     if (m_total_packet_count < m_packets.size())
440b57cec5SDimitry Andric       return 0;
450b57cec5SDimitry Andric     else
460b57cec5SDimitry Andric       return m_curr_idx + 1;
470b57cec5SDimitry Andric   }
480b57cec5SDimitry Andric 
GetNumPacketsInHistory()490b57cec5SDimitry Andric   uint32_t GetNumPacketsInHistory() const {
500b57cec5SDimitry Andric     if (m_total_packet_count < m_packets.size())
510b57cec5SDimitry Andric       return m_total_packet_count;
520b57cec5SDimitry Andric     else
530b57cec5SDimitry Andric       return (uint32_t)m_packets.size();
540b57cec5SDimitry Andric   }
550b57cec5SDimitry Andric 
GetNextIndex()560b57cec5SDimitry Andric   uint32_t GetNextIndex() {
570b57cec5SDimitry Andric     ++m_total_packet_count;
580b57cec5SDimitry Andric     const uint32_t idx = m_curr_idx;
590b57cec5SDimitry Andric     m_curr_idx = NormalizeIndex(idx + 1);
600b57cec5SDimitry Andric     return idx;
610b57cec5SDimitry Andric   }
620b57cec5SDimitry Andric 
NormalizeIndex(uint32_t i)630b57cec5SDimitry Andric   uint32_t NormalizeIndex(uint32_t i) const {
640b57cec5SDimitry Andric     return m_packets.empty() ? 0 : i % m_packets.size();
650b57cec5SDimitry Andric   }
660b57cec5SDimitry Andric 
679dba64beSDimitry Andric   std::vector<GDBRemotePacket> m_packets;
68*fe6060f1SDimitry Andric   uint32_t m_curr_idx = 0;
69*fe6060f1SDimitry Andric   uint32_t m_total_packet_count = 0;
70*fe6060f1SDimitry Andric   mutable bool m_dumped_to_log = false;
710b57cec5SDimitry Andric };
720b57cec5SDimitry Andric 
730b57cec5SDimitry Andric } // namespace process_gdb_remote
740b57cec5SDimitry Andric } // namespace lldb_private
750b57cec5SDimitry Andric 
765ffd83dbSDimitry Andric #endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONHISTORY_H
77