1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef CHROME_TEST_LOGGING_WIN_MOF_DATA_PARSER_H_
6 #define CHROME_TEST_LOGGING_WIN_MOF_DATA_PARSER_H_
7 
8 #include <windows.h>
9 #include <evntrace.h>
10 #include <stddef.h>
11 #include <stdint.h>
12 #include <wmistr.h>
13 
14 #include "base/strings/string_piece.h"
15 
16 namespace logging_win {
17 
18 // A parser for Mof data found in an EVENT_TRACE object as formatted by
19 // Chromium-related classes.  Instances have an implicit cursor that scans the
20 // data.  Callers invoke Read* methods to extract primitive data types values or
21 // pointers to complex data types (arrays and strings).  In the latter case, the
22 // pointers are only valid for the lifetime of the underlying event.
23 class MofDataParser {
24  public:
25   explicit MofDataParser(const EVENT_TRACE* event);
26 
ReadDWORD(DWORD * value)27   bool ReadDWORD(DWORD* value) {
28     return ReadPrimitive(value);
29   }
30 
ReadInt(int * value)31   bool ReadInt(int* value) {
32     return ReadPrimitive(value);
33   }
34 
ReadPointer(intptr_t * value)35   bool ReadPointer(intptr_t* value) {
36     return ReadPrimitive(value);
37   }
38 
39   // Populates |values| with a pointer to an array of |size| pointer-sized
40   // values in the data.
ReadPointerArray(DWORD size,const intptr_t ** values)41   bool ReadPointerArray(DWORD size, const intptr_t** values) {
42     return ReadPrimitiveArray(size, values);
43   }
44 
45   // Populates |value| with a pointer to an arbitrary data structure at the
46   // current position.
ReadStructure(const T ** value)47   template<typename T> bool ReadStructure(const T** value) {
48     if (length_ < sizeof(**value))
49       return false;
50     *value = reinterpret_cast<const T*>(scan_);
51     Advance(sizeof(**value));
52     return true;
53   }
54 
55   // Sets |value| such that it points to the string in the data at the current
56   // position.  A trailing newline, if present, is not included in the returned
57   // piece.  The returned piece is not null-terminated.
58   bool ReadString(base::StringPiece* value);
59 
empty()60   bool empty() { return length_ == 0; }
61 
62  private:
Advance(size_t num_bytes)63   void Advance(size_t num_bytes) {
64     scan_ += num_bytes;
65     length_ -= num_bytes;
66   }
67 
ReadPrimitive(T * value)68   template<typename T> bool ReadPrimitive(T* value) {
69     if (length_ < sizeof(*value))
70       return false;
71     *value = *reinterpret_cast<const T*>(scan_);
72     Advance(sizeof(*value));
73     return true;
74   }
75 
ReadPrimitiveArray(DWORD size,const T ** values)76   template<typename T> bool ReadPrimitiveArray(DWORD size, const T** values) {
77     if (length_ < sizeof(**values) * size)
78       return false;
79     *values = reinterpret_cast<const T*>(scan_);
80     Advance(sizeof(**values) * size);
81     return true;
82   }
83 
84   const uint8_t* scan_;
85   uint32_t length_;
86 };
87 
88 }  // namespace logging_win
89 
90 #endif  // CHROME_TEST_LOGGING_WIN_MOF_DATA_PARSER_H_
91