summaryrefslogtreecommitdiff
path: root/core/fpdfapi/parser/cpdf_object_walker.h
blob: 8cad3c32f3ff29733b59b1174aa9430cd36a703b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
// Copyright 2017 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CORE_FPDFAPI_PARSER_CPDF_OBJECT_WALKER_H_
#define CORE_FPDFAPI_PARSER_CPDF_OBJECT_WALKER_H_

#include <memory>
#include <stack>

#include "core/fpdfapi/parser/cpdf_dictionary.h"

// Walk on all non-null sub-objects in an object in depth, include itself,
// like in flat list.
class CPDF_ObjectWalker {
 public:
  class SubobjectIterator {
   public:
    virtual ~SubobjectIterator();
    bool IsStarted() const { return is_started_; }
    bool virtual IsFinished() const = 0;
    const CPDF_Object* Increment();
    const CPDF_Object* object() const { return object_; }

   protected:
    explicit SubobjectIterator(const CPDF_Object* object);

    virtual const CPDF_Object* IncrementImpl() = 0;
    virtual void Start() = 0;

   private:
    const CPDF_Object* object_;
    bool is_started_ = false;
  };

  explicit CPDF_ObjectWalker(const CPDF_Object* root);
  ~CPDF_ObjectWalker();

  const CPDF_Object* GetNext();
  void SkipWalkIntoCurrentObject();

  size_t current_depth() const { return current_depth_; }
  const CPDF_Object* GetParent() const { return parent_object_; }
  const ByteString& dictionary_key() const { return dict_key_; }

 private:
  static std::unique_ptr<SubobjectIterator> MakeIterator(
      const CPDF_Object* object);

  const CPDF_Object* next_object_;
  const CPDF_Object* parent_object_;

  ByteString dict_key_;
  size_t current_depth_;

  std::stack<std::unique_ptr<SubobjectIterator>> stack_;
};

class CPDF_NonConstObjectWalker : public CPDF_ObjectWalker {
 public:
  explicit CPDF_NonConstObjectWalker(CPDF_Object* root)
      : CPDF_ObjectWalker(root) {}

  CPDF_Object* GetNext() {
    return const_cast<CPDF_Object*>(CPDF_ObjectWalker::GetNext());
  }
};

#endif  // CORE_FPDFAPI_PARSER_CPDF_OBJECT_WALKER_H_