Annotation of parser3/src/types/pa_wwrapper.h, revision 1.52
1.7 paf 1: /** @file
1.8 paf 2: Parser: @b write_wrapper write context
1.7 paf 3:
1.52 ! moko 4: Copyright (c) 2001-2017 Art. Lebedev Studio (http://www.artlebedev.com)
1.16 paf 5: Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
1.1 paf 6: */
7:
8: #ifndef PA_WWRAPPER_H
9: #define PA_WWRAPPER_H
1.19 paf 10:
1.52 ! moko 11: #define IDENT_PA_WWRAPPER_H "$Id: pa_wwrapper.h,v 1.51 2016/11/29 21:14:08 moko Exp $"
1.37 misha 12:
1.38 misha 13: #define OPTIMIZE_SINGLE_STRING_WRITE
1.1 paf 14:
15: #include "pa_wcontext.h"
16: #include "pa_exception.h"
17:
1.7 paf 18: /// specialized write context, adds to WContext VHash autocreation ability
1.29 paf 19: class WWrapper: public WContext {
1.1 paf 20: public: // Value
21:
1.29 paf 22: override const char* type() const { return "wwrapper"; }
1.49 moko 23:
1.7 paf 24: /// WWrapper: transparent
1.51 moko 25: override Value* get_element(const String& aname) {
26: return as_value().get_element(aname);
27: }
28:
29: /// WWrapper: transparent
1.45 moko 30: override const VJunction* put_element(const String& aname, Value* avalue) {
1.3 paf 31: if(!fvalue) {
1.29 paf 32: fvalue=new VHash;
1.3 paf 33: // not constructing anymore [if were constructing]
34: // so to allow method calls after real constructor-method call
35: // sample:
36: // $hash[
1.21 paf 37: // $.key1[$i]
1.3 paf 38: // ^i.inc[] ^rem{allow such calls}
1.21 paf 39: // $.key2[$1]
1.3 paf 40: }
1.45 moko 41: return fvalue->put_element(aname, avalue);
1.1 paf 42: }
43:
44: public: // usage
45:
1.40 misha 46: WWrapper(WContext *aparent) :
47: WContext(aparent) {
1.1 paf 48: }
49:
50: private:
51: // raises an exception on 0 value
1.29 paf 52: Value& as_value() const {
1.1 paf 53: if(!fvalue)
1.49 moko 54: throw Exception(0, 0, "accessing wrapper without value");
1.29 paf 55: return *fvalue;
1.1 paf 56: }
57: };
58:
1.37 misha 59: #ifdef OPTIMIZE_SINGLE_STRING_WRITE
60: class WObjectPoolWrapper: public WWrapper {
61: public:
62:
63: enum WState {
64: WS_NONE,
65: WS_KEEP_VALUE,
66: WS_TRANSPARENT
67: };
68:
1.40 misha 69: WObjectPoolWrapper(WContext *aparent) :
70: WWrapper(aparent), fstate(WS_NONE) {
1.37 misha 71: }
72:
1.45 moko 73: override const VJunction* put_element(const String& aname, Value* avalue) {
1.37 misha 74: if(fstate == WS_KEEP_VALUE)
75: fvalue=0; // VHash will be created, thus no need to flush fvalue
76: fstate=WS_TRANSPARENT;
1.45 moko 77: return WWrapper::put_element(aname, avalue);
1.37 misha 78: }
79:
1.50 moko 80: override void write(const String& astring) {
1.37 misha 81: if(fstate == WS_KEEP_VALUE)
82: flush();
83: fstate=WS_TRANSPARENT;
1.50 moko 84: WWrapper::write(astring);
1.37 misha 85: }
86:
87: override void write(Value& avalue) {
88: if(fstate == WS_KEEP_VALUE)
89: flush();
90: fstate=WS_TRANSPARENT;
91: WWrapper::write(avalue);
92: }
93:
1.50 moko 94: override void write_as_string(Value& avalue) {
1.37 misha 95: switch(fstate){
96: case WS_NONE:{
97: // alang is allways L_PASS_APPENDED, but just in case we check it
98: // only VString can be cached, no get_string() call as VInt/etc will be affected
1.50 moko 99: if(avalue.is_string()){
1.37 misha 100: fvalue=&avalue;
101: fstate=WS_KEEP_VALUE;
102: return;
103: }
104: break;
105: }
106: case WS_KEEP_VALUE:{
107: flush();
108: break;
109: }
1.46 moko 110: case WS_TRANSPARENT: break;
1.37 misha 111: }
112: fstate=WS_TRANSPARENT;
113: // we copy WWrapper::write here to prevent virtual call to our class
1.48 moko 114: if(const String* string=avalue.get_string())
1.50 moko 115: WWrapper::write(*string);
1.37 misha 116: else
117: WWrapper::write(avalue);
118: }
119:
120: //override StringOrValue result() - not required as as_value() will be allways called
121: private:
122:
123: WState fstate;
124:
125: inline void flush(){
1.50 moko 126: WWrapper::write(*fvalue->get_string());
1.37 misha 127: fvalue=0;
128: }
129: };
130: #endif
131:
1.1 paf 132: #endif
E-mail: