Stroika Library 3.0d23x
 
Loading...
Searching...
No Matches
InterceptorChain.cpp
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2026. All rights reserved
3 */
4#include "Stroika/Frameworks/StroikaPreComp.h"
5
8
9#include "InterceptorChain.h"
10
11using namespace Stroika::Foundation;
13
14using Memory::MakeSharedPtr;
15
16using namespace Stroika::Frameworks;
17using namespace Stroika::Frameworks::WebServer;
18
19// This class MUST be re-entrant (internally synchronized)- and is STATELESS - so no syncro needed
20struct InterceptorChain::Rep_ : InterceptorChain::_IRep {
21 Rep_ (const Sequence<Interceptor>& interceptors)
22 : fInterceptors_{interceptors}
23 {
24 }
25 virtual Sequence<Interceptor> GetInterceptors () const override
26 {
27 return fInterceptors_;
28 }
29 virtual shared_ptr<_IRep> SetInterceptors (const Sequence<Interceptor>& interceptors) const override
30 {
31 return MakeSharedPtr<Rep_> (interceptors);
32 }
33 virtual void HandleMessage (Message& m) const override
34 {
35 size_t sz = fInterceptors_.size ();
36 size_t i = 0;
37 for (; i < sz; ++i) {
38 try {
39 fInterceptors_[i].HandleMessage (m);
40 }
41 catch (...) {
42 exception_ptr e = current_exception ();
43 do {
44 fInterceptors_[i].HandleFault (m, e);
45 } while (i-- != 0);
47 }
48 }
49 for (; i > 0; --i) {
50 fInterceptors_[i - 1].CompleteNormally (m);
51 }
52 }
53 const Sequence<Interceptor> fInterceptors_; // no synchro needed because always readonly
54};
55
56/*
57 ********************************************************************************
58 *********************** WebServer::InterceptorChain ****************************
59 ********************************************************************************
60 */
61InterceptorChain::InterceptorChain (const Sequence<Interceptor>& interceptors)
62 : InterceptorChain{MakeSharedPtr<Rep_> (interceptors)}
63{
64}
65
66InterceptorChain::InterceptorChain (const shared_ptr<_IRep>& rep)
67 : interceptors{[qStroika_Foundation_Common_Property_ExtraCaptureStuff] ([[maybe_unused]] const auto* property) -> Sequence<Interceptor> {
68 const InterceptorChain* thisObj = qStroika_Foundation_Common_Property_OuterObjPtr (property, &InterceptorChain::interceptors);
69 return thisObj->fRep_.cget ().load ()->GetInterceptors ();
70 },
71 [qStroika_Foundation_Common_Property_ExtraCaptureStuff] ([[maybe_unused]] auto* property, const Sequence<Interceptor>& interceptors) {
72 InterceptorChain* thisObj = qStroika_Foundation_Common_Property_OuterObjPtr (property, &InterceptorChain::interceptors);
73 auto rwLock = thisObj->fRep_.rwget ();
74 rwLock.store (rwLock->get ()->SetInterceptors (interceptors));
75 }}
76 , fRep_{rep}
77{
78}
79
80void InterceptorChain::AddBefore (const Interceptor& interceptor2Add, const Interceptor& before)
81{
82 auto rwLock = fRep_.rwget ();
83 [[maybe_unused]] bool found{false};
84 Sequence<Interceptor> newInterceptors = rwLock->get ()->GetInterceptors ();
85 for (size_t i = 0; i < newInterceptors.size (); ++i) {
86 if (newInterceptors[i] == before) {
87 newInterceptors.Insert (i, interceptor2Add);
88 found = true;
89 break;
90 }
91 }
92 Require (found);
93 rwLock.store (rwLock->get ()->SetInterceptors (newInterceptors));
94}
95
96void InterceptorChain::AddAfter (const Interceptor& interceptor2Add, const Interceptor& after)
97{
98 auto rwLock = fRep_.rwget ();
99
100 [[maybe_unused]] bool found{false};
101 Sequence<Interceptor> newInterceptors = rwLock->get ()->GetInterceptors ();
102 for (size_t i = 0; i < newInterceptors.size (); ++i) {
103 if (newInterceptors[i] == after) {
104 newInterceptors.Insert (i + 1, interceptor2Add);
105 found = true;
106 break;
107 }
108 }
109 Require (found);
110 rwLock.store (rwLock->get ()->SetInterceptors (newInterceptors));
111}
112
113Characters::String InterceptorChain::ToString () const
114{
115 StringBuilder sb;
116 sb << "["sv;
117 for (auto i : fRep_.load ()->GetInterceptors ()) {
118 sb << i << ", "sv;
119 }
120 sb << "]"sv;
121 return sb;
122}
auto MakeSharedPtr(ARGS_TYPE &&... args) -> shared_ptr< T >
same as make_shared, but if type T has block allocation, then use block allocation for the 'shared pa...
Similar to String, but intended to more efficiently construct a String. Mutable type (String is large...
String is like std::u32string, except it is much easier to use, often much more space efficient,...
Definition String.h:201
A generalization of a vector: a container whose elements are keyed by the natural numbers.
nonvirtual void Insert(size_t i, ArgByValueType< value_type > item)
Definition Sequence.inl:281
nonvirtual size_t size() const
Returns the number of items contained.
Definition Iterable.inl:303
nonvirtual void AddBefore(const Interceptor &interceptor2Add, const Interceptor &before)
nonvirtual void AddAfter(const Interceptor &interceptor2Add, const Interceptor &after)