Annotation of parser3/src/types/pa_wwrapper.h, revision 1.41
1.7 paf 1: /** @file
1.8 paf 2: Parser: @b write_wrapper write context
1.7 paf 3:
1.37 misha 4: Copyright (c) 2001-2009 ArtLebedev Group (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.41 ! misha 11: static const char * const IDENT_WWRAPPER_H="$Date: 2009-06-17 01:08:55 $";
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.29 paf 24: override Value* get_element(const String& aname, Value& aself, bool looking_up) {
25: return as_value().get_element(aname, aself, looking_up);
1.22 paf 26: }
1.7 paf 27: /// WWrapper: transparent
1.35 paf 28: override const VJunction* put_element(Value& aself, 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.39 misha 38: SET_CONSTRUCTING(this,false)
1.3 paf 39: }
40:
1.34 paf 41: return fvalue->put_element(aself, aname, avalue, areplace);
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.17 paf 54: throw Exception(0,
1.1 paf 55: 0,
56: "accessing wrapper without value");
57:
1.29 paf 58: return *fvalue;
1.1 paf 59: }
60: };
61:
1.37 misha 62: #ifdef OPTIMIZE_SINGLE_STRING_WRITE
63: class WObjectPoolWrapper: public WWrapper {
64: public:
65:
66: enum WState {
67: WS_NONE,
68: WS_KEEP_VALUE,
69: WS_TRANSPARENT
70: };
71:
1.40 misha 72: WObjectPoolWrapper(WContext *aparent) :
73: WWrapper(aparent), fstate(WS_NONE) {
1.37 misha 74: }
75:
76: override const VJunction* put_element(Value& aself, const String& aname, Value* avalue, bool areplace) {
77: if(fstate == WS_KEEP_VALUE)
78: fvalue=0; // VHash will be created, thus no need to flush fvalue
79: fstate=WS_TRANSPARENT;
80: return WWrapper::put_element(aself, aname, avalue, areplace);
81: }
82:
83: override void write(const String& astring, String::Language alang) {
84: if(fstate == WS_KEEP_VALUE)
85: flush();
86: fstate=WS_TRANSPARENT;
87: WWrapper::write(astring, alang);
88: }
89:
90: override void write(Value& avalue) {
91: if(fstate == WS_KEEP_VALUE)
92: flush();
93: fstate=WS_TRANSPARENT;
94: WWrapper::write(avalue);
95: }
96:
97: override void write(Value& avalue, String::Language alang) {
98: switch(fstate){
99: case WS_NONE:{
100: // alang is allways L_PASS_APPENDED, but just in case we check it
101: // only VString can be cached, no get_string() call as VInt/etc will be affected
1.41 ! misha 102: if(avalue.is_string() && alang == String::L_PASS_APPENDED){
1.37 misha 103: fvalue=&avalue;
104: fstate=WS_KEEP_VALUE;
105: return;
106: }
107: break;
108: }
109: case WS_KEEP_VALUE:{
110: flush();
111: break;
112: }
113: }
114: fstate=WS_TRANSPARENT;
115: // we copy WWrapper::write here to prevent virtual call to our class
116: if(const String* fstring=avalue.get_string())
117: WWrapper::write(*fstring, alang);
118: else
119: WWrapper::write(avalue);
120: }
121:
122: //override StringOrValue result() - not required as as_value() will be allways called
123: private:
124:
125: WState fstate;
126:
127: inline void flush(){
128: WWrapper::write(*fvalue->get_string(), String::L_PASS_APPENDED);
129: fvalue=0;
130: }
131: };
132: #endif
133:
1.1 paf 134: #endif
E-mail: