1 // Copyright 2020 The Pigweed Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 // use this file except in compliance with the License. You may obtain a copy of 5 // the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 // License for the specific language governing permissions and limitations under 13 // the License. 14 //============================================================================== 15 // 16 17 #pragma once 18 19 #include <stdio.h> 20 21 #include <fstream> 22 23 #include "pw_trace_tokenized/trace_callback.h" 24 25 namespace pw { 26 namespace trace { 27 28 class TraceToFile { 29 public: TraceToFile(const char * file_name)30 TraceToFile(const char* file_name) { 31 Callbacks::Instance() 32 .RegisterSink(TraceSinkStartBlock, 33 TraceSinkAddBytes, 34 TraceSinkEndBlock, 35 &out_, 36 &sink_handle_) 37 .IgnoreError(); // TODO(b/242598609): Handle Status properly 38 out_.open(file_name, std::ios::out | std::ios::binary); 39 } 40 ~TraceToFile()41 ~TraceToFile() { 42 Callbacks::Instance() 43 .UnregisterSink(sink_handle_) 44 .IgnoreError(); // TODO(b/242598609): Handle Status properly 45 out_.close(); 46 } 47 TraceSinkStartBlock(void * user_data,size_t size)48 static void TraceSinkStartBlock(void* user_data, size_t size) { 49 std::ofstream* out = reinterpret_cast<std::ofstream*>(user_data); 50 uint8_t b = static_cast<uint8_t>(size); 51 out->write(reinterpret_cast<const char*>(&b), sizeof(b)); 52 } 53 TraceSinkAddBytes(void * user_data,const void * bytes,size_t size)54 static void TraceSinkAddBytes(void* user_data, 55 const void* bytes, 56 size_t size) { 57 std::ofstream* out = reinterpret_cast<std::ofstream*>(user_data); 58 out->write(reinterpret_cast<const char*>(bytes), size); 59 } 60 TraceSinkEndBlock(void * user_data)61 static void TraceSinkEndBlock(void* user_data) { 62 std::ofstream* out = reinterpret_cast<std::ofstream*>(user_data); 63 out->flush(); 64 } 65 66 private: 67 std::ofstream out_; 68 CallbacksImpl::SinkHandle sink_handle_; 69 }; 70 71 } // namespace trace 72 } // namespace pw 73