Annotation of parser3/src/types/pa_wwrapper.h, revision 1.50

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

E-mail: