1 /*
2  * Copyright (C) 1996-2021 The Squid Software Foundation and contributors
3  *
4  * Squid software is distributed under GPLv2+ license and includes
5  * contributions from numerous individuals and organizations.
6  * Please see the COPYING and CONTRIBUTORS files for details.
7  */
8 
9 #ifndef SQUID_ESIELEMENT_H
10 #define SQUID_ESIELEMENT_H
11 
12 #include "base/RefCount.h"
13 #include "Debug.h"
14 #include "esi/Segment.h"
15 
16 #include <vector>
17 
18 typedef enum {
19     ESI_PROCESS_COMPLETE = 0,
20     ESI_PROCESS_PENDING_WONTFAIL = 1,
21     ESI_PROCESS_PENDING_MAYFAIL = 2,
22     ESI_PROCESS_FAILED = 3
23 } esiProcessResult_t;
24 
25 class ESIElement;
26 
27 struct esiTreeParent : public RefCountable {
provideDataesiTreeParent28     virtual void provideData (ESISegment::Pointer data, ESIElement * source) {
29         /* make abstract when all functionality complete */
30         assert (0);
31     }
32 
33     virtual void fail(ESIElement * source, char const *reason = NULL) {}
34 
~esiTreeParentesiTreeParent35     virtual ~esiTreeParent() {}
36 };
37 
38 typedef RefCount<esiTreeParent> esiTreeParentPtr;
39 
40 class ESIVarState;
41 
42 class ESIElement : public esiTreeParent
43 {
44 
45 public:
46     typedef RefCount<ESIElement> Pointer;
47 
48     /* the types we have */
49     enum ESIElementType_t {
50         ESI_ELEMENT_NONE,
51         ESI_ELEMENT_INCLUDE,
52         ESI_ELEMENT_COMMENT,
53         ESI_ELEMENT_REMOVE,
54         ESI_ELEMENT_TRY,
55         ESI_ELEMENT_ATTEMPT,
56         ESI_ELEMENT_EXCEPT,
57         ESI_ELEMENT_VARS,
58         ESI_ELEMENT_CHOOSE,
59         ESI_ELEMENT_WHEN,
60         ESI_ELEMENT_OTHERWISE,
61         ESI_ELEMENT_ASSIGN
62     };
63     static ESIElementType_t IdentifyElement (const char *);
addElement(ESIElement::Pointer)64     virtual bool addElement(ESIElement::Pointer) {
65         /* Don't accept children */
66         debugs(86,5, "ESIElement::addElement: Failed for " << this);
67         return false;
68     }
69 
70     virtual void render (ESISegment::Pointer) = 0;
71     /* process this element */
process(int dovars)72     virtual esiProcessResult_t process (int dovars) {
73         debugs(86,5, "esiProcessComplete: Processed " << this);
74         return ESI_PROCESS_COMPLETE;
75     }
76 
mayFail()77     virtual bool mayFail() const {
78         return true;
79     }
80 
81     virtual Pointer makeCacheable() const = 0;
82     virtual Pointer makeUsable(esiTreeParentPtr, ESIVarState &) const = 0;
83 
84     /* The top level no longer needs this element */
85     virtual void finish() = 0;
86 };
87 
88 /// ESI protocol types and operators
89 namespace Esi {
90 
91 /// an ordered set of ESI elements
92 typedef std::vector<ESIElement::Pointer> Elements;
93 
94 } // namespace Esi
95 
96 /// Call finish() and set to nil the given element. Element may already be nil.
97 /// When element is part of a set, use pos to indicate position/ID
98 /// for debugging.
99 extern void FinishAnElement(ESIElement::Pointer &, int pos = -1);
100 
101 // for all elements call finish() and set Pointer to nil
102 extern void FinishAllElements(Esi::Elements &);
103 
104 #endif /* SQUID_ESIELEMENT_H */
105 
106