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