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 <stddef.h>
9#include <windows.h>
10#include <wmistr.h>
11#include <evntrace.h>
12
13#include "base/basictypes.h"
14#include "base/strings/string_piece.h"
15
16namespace 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.
23class MofDataParser {
24 public:
25  explicit MofDataParser(const EVENT_TRACE* event);
26
27  bool ReadDWORD(DWORD* value) {
28    return ReadPrimitive(value);
29  }
30
31  bool ReadInt(int* value) {
32    return ReadPrimitive(value);
33  }
34
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.
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.
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
60  bool empty() { return length_ == 0; }
61
62 private:
63  void Advance(size_t num_bytes) {
64    scan_ += num_bytes;
65    length_ -= num_bytes;
66  }
67
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
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* scan_;
85  uint32 length_;
86};
87
88}  // namespace logging_win
89
90#endif  // CHROME_TEST_LOGGING_WIN_MOF_DATA_PARSER_H_
91