Annotation of parser3/src/types/pa_wwrapper.h, revision 1.37
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.37 ! misha 11: static const char * const IDENT_WWRAPPER_H="$Date: 2005/08/09 08:14:56 $";
! 12:
! 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.13 paf 38: set_constructing(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.29 paf 46: WWrapper(Value* avalue, WContext *aparent) :
47: WContext(avalue, 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:
! 72: WObjectPoolWrapper(Value* avalue, WContext *aparent) :
! 73: WWrapper(avalue, aparent), fstate(WS_NONE) {
! 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
! 102: if (dynamic_cast<VString *>(&avalue) && alang == String::L_PASS_APPENDED){
! 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: