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: