From 463b74301d84d02885088978b73049f309f49ada Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Mon, 5 Sep 2016 19:59:58 -0400 Subject: [PATCH] Sought to reduce the amount of heap nonsense. --- StaticAnalyser/Acorn/Tape.cpp | 103 ++++++++++++++++++---------------- 1 file changed, 55 insertions(+), 48 deletions(-) diff --git a/StaticAnalyser/Acorn/Tape.cpp b/StaticAnalyser/Acorn/Tape.cpp index fcb893fb5..0e5fc5890 100644 --- a/StaticAnalyser/Acorn/Tape.cpp +++ b/StaticAnalyser/Acorn/Tape.cpp @@ -18,29 +18,7 @@ using namespace StaticAnalyser::Acorn; */ template class TapeParser { public: - TapeParser(const std::shared_ptr &tape) : _tape(tape) {} - - std::unique_ptr get_next_symbol() - { - while(!_tape->is_at_end()) - { - std::unique_ptr symbol = dequeue_next_symbol(_wave_queue); - if(symbol) return symbol; - - while(!_tape->is_at_end()) - { - Storage::Tape::Tape::Pulse next_pulse = _tape->get_next_pulse(); - std::unique_ptr next_wave = get_wave_type_for_pulse(next_pulse); - if(next_wave) - { - _wave_queue.push_back(*next_wave); - break; - } - } - } - - return nullptr; - } + TapeParser(const std::shared_ptr &tape) : _tape(tape), _has_next_symbol(false) {} void reset_error_flag() { _error_flag = false; } bool get_error_flag() { return _error_flag; } @@ -48,11 +26,42 @@ template class TapeParser { protected: bool _error_flag; + void push_wave(WaveType wave) + { + _wave_queue.push_back(wave); + inspect_waves(_wave_queue); + } + + void remove_waves(int number_of_waves) + { + _wave_queue.erase(_wave_queue.begin(), _wave_queue.begin()+number_of_waves); + } + + void push_symbol(SymbolType symbol, int number_of_waves) + { + _has_next_symbol = true; + _next_symbol = symbol; + remove_waves(number_of_waves); + } + + SymbolType get_next_symbol() + { + while(!_has_next_symbol && !is_at_end()) + { + process_pulse(_tape->get_next_pulse()); + } + _has_next_symbol = false; + return _next_symbol; + } private: - virtual std::unique_ptr get_wave_type_for_pulse(Storage::Tape::Tape::Pulse) = 0; - virtual std::unique_ptr dequeue_next_symbol(std::deque &_wave_queue) = 0; - std::deque _wave_queue; + virtual void process_pulse(Storage::Tape::Tape::Pulse pulse) = 0; + virtual void inspect_waves(const std::vector &waves) = 0; + + std::vector _wave_queue; + SymbolType _next_symbol; + bool _has_next_symbol; + std::shared_ptr _tape; }; @@ -70,8 +79,8 @@ class Acorn1200BaudTapeParser: public TapeParser { int get_next_bit() { - std::unique_ptr symbol = get_next_symbol(); - return (symbol && *symbol == SymbolType::One) ? 1 : 0; + SymbolType symbol = get_next_symbol(); + return (symbol == SymbolType::One) ? 1 : 0; } int get_next_byte() @@ -114,47 +123,45 @@ class Acorn1200BaudTapeParser: public TapeParser { uint16_t get_crc() { return _crc; } private: - std::unique_ptr get_wave_type_for_pulse(Storage::Tape::Tape::Pulse pulse) + void process_pulse(Storage::Tape::Tape::Pulse pulse) { - WaveType wave_type = WaveType::Unrecognised; switch(pulse.type) { default: break; case Storage::Tape::Tape::Pulse::High: case Storage::Tape::Tape::Pulse::Low: float pulse_length = pulse.length.get_float(); - if(pulse_length >= 0.35 / 2400.0 && pulse_length < 0.7 / 2400.0) wave_type = WaveType::Short; - if(pulse_length >= 0.35 / 1200.0 && pulse_length < 0.7 / 1200.0) wave_type = WaveType::Long; + if(pulse_length >= 0.35 / 2400.0 && pulse_length < 0.7 / 2400.0) { push_wave(WaveType::Short); return; } + if(pulse_length >= 0.35 / 1200.0 && pulse_length < 0.7 / 1200.0) { push_wave(WaveType::Long); return; } break; } - return std::unique_ptr(new WaveType(wave_type)); + push_wave(WaveType::Unrecognised); } - std::unique_ptr dequeue_next_symbol(std::deque &_wave_queue) + void inspect_waves(const std::vector &waves) { - while(_wave_queue.size() && _wave_queue.front() == WaveType::Unrecognised) + while(waves.size() && waves[0] == WaveType::Unrecognised) { - _wave_queue.pop_front(); + remove_waves(1); + return; } - if(_wave_queue.size() >= 2 && _wave_queue[0] == WaveType::Long && _wave_queue[1] == WaveType::Long) + if(waves.size() >= 2 && waves[0] == WaveType::Long && waves[1] == WaveType::Long) { - _wave_queue.erase(_wave_queue.begin(), _wave_queue.begin()+2); - return std::unique_ptr(new SymbolType(SymbolType::Zero)); + push_symbol(SymbolType::Zero, 2); + return; } - if( _wave_queue.size() >= 4 && - _wave_queue[0] == WaveType::Short && - _wave_queue[1] == WaveType::Short && - _wave_queue[2] == WaveType::Short && - _wave_queue[3] == WaveType::Short) + if( waves.size() >= 4 && + waves[0] == WaveType::Short && + waves[1] == WaveType::Short && + waves[2] == WaveType::Short && + waves[3] == WaveType::Short) { - _wave_queue.erase(_wave_queue.begin(), _wave_queue.begin()+4); - return std::unique_ptr(new SymbolType(SymbolType::One)); + push_symbol(SymbolType::One, 4); + return; } - - return nullptr; } void add_to_crc(uint8_t value)