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/example/sample_app.h" 24 #include "pw_trace_tokenized/trace_callback.h" 25 26 namespace pw { 27 namespace trace { 28 29 class TraceToFile { 30 public: TraceToFile(const char * file_name)31 TraceToFile(const char* file_name) { 32 Callbacks::Instance() 33 .RegisterSink(TraceSinkStartBlock, 34 TraceSinkAddBytes, 35 TraceSinkEndBlock, 36 &out_, 37 &sink_handle_) 38 .IgnoreError(); // TODO(pwbug/387): Handle Status properly 39 out_.open(file_name, std::ios::out | std::ios::binary); 40 } 41 ~TraceToFile()42 ~TraceToFile() { 43 Callbacks::Instance() 44 .UnregisterSink(sink_handle_) 45 .IgnoreError(); // TODO(pwbug/387): Handle Status properly 46 out_.close(); 47 } 48 TraceSinkStartBlock(void * user_data,size_t size)49 static void TraceSinkStartBlock(void* user_data, size_t size) { 50 std::ofstream* out = reinterpret_cast<std::ofstream*>(user_data); 51 uint8_t b = static_cast<uint8_t>(size); 52 out->write(reinterpret_cast<const char*>(&b), sizeof(b)); 53 } 54 TraceSinkAddBytes(void * user_data,const void * bytes,size_t size)55 static void TraceSinkAddBytes(void* user_data, 56 const void* bytes, 57 size_t size) { 58 std::ofstream* out = reinterpret_cast<std::ofstream*>(user_data); 59 out->write(reinterpret_cast<const char*>(bytes), size); 60 } 61 TraceSinkEndBlock(void * user_data)62 static void TraceSinkEndBlock(void* user_data) { 63 std::ofstream* out = reinterpret_cast<std::ofstream*>(user_data); 64 out->flush(); 65 } 66 67 private: 68 std::ofstream out_; 69 CallbacksImpl::SinkHandle sink_handle_; 70 }; 71 72 } // namespace trace 73 } // namespace pw 74