Annotation of parser3/src/types/pa_vfile.C, revision 1.51

1.34      paf         1: 
1.5       paf         2: /** @file
1.14      paf         3:        Parser: @b file parser type.
1.3       paf         4: 
1.51    ! moko        5:        Copyright (c) 2001-2012 Art. Lebedev Studio (http://www.artlebedev.com)
1.26      paf         6:        Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
1.30      paf         7: */
1.3       paf         8: 
1.37      paf         9: #include "classes.h"
1.1       paf        10: #include "pa_vfile.h"
                     11: #include "pa_vstring.h"
1.3       paf        12: #include "pa_vint.h"
1.50      misha      13: #include "pa_request.h"
1.1       paf        14: 
1.51    ! moko       15: volatile const char * IDENT_PA_VFILE_C="$Id: 2011-11-23 12:17:23 $" IDENT_PA_VFILE_H;
        !            16: 
1.37      paf        17: // externs
                     18: 
                     19: extern Methoded* file_class;
                     20: 
                     21: // defines for statics
                     22: 
                     23: #define SIZE_NAME "size"
                     24: #define TEXT_NAME "text"
                     25: 
1.50      misha      26: #define MODE_VALUE_TEXT "text"
                     27: #define MODE_VALUE_BINARY "binary"
                     28: 
1.37      paf        29: // statics
                     30: 
                     31: static const String size_name(SIZE_NAME);
                     32: static const String text_name(TEXT_NAME);
1.50      misha      33: 
                     34: static const String mode_value_text(MODE_VALUE_TEXT);
                     35: static const String mode_value_binary(MODE_VALUE_BINARY);
1.37      paf        36: 
                     37: // methods
                     38: 
                     39: VStateless_class *VFile::get_class() { return file_class; }
                     40: 
                     41: void VFile::set(
1.43      misha      42:                bool atainted, 
1.50      misha      43:                const char* avalue_ptr,
                     44:                size_t avalue_size,
                     45:                const String* afile_name,
                     46:                Value* acontent_type,
                     47:                Request* r) {
1.8       paf        48:        fvalue_ptr=avalue_ptr;
                     49:        fvalue_size=avalue_size;
1.43      misha      50:        ftext_tainted=atainted;
1.8       paf        51: 
1.10      paf        52:        ffields.clear();
1.43      misha      53: 
1.50      misha      54:        // $size
                     55:        ffields.put(size_name, new VInt(fvalue_size));
                     56: 
1.3       paf        57:        // $name
1.50      misha      58:        set_name(afile_name);
                     59: 
                     60:        // $mime-type
                     61:        set_content_type(acontent_type, afile_name, r);
                     62: }
                     63: 
                     64: void VFile::set(VFile& avfile){
                     65:        set(
                     66:                avfile.ftext_tainted,
                     67:                avfile.fvalue_ptr,
                     68:                avfile.fvalue_size
                     69:        );
                     70: 
                     71:        for(HashStringValue::Iterator i(avfile.ffields); i; i.next())
                     72:                ffields.put_dont_replace(*new String(i.key(), String::L_TAINTED), i.value());
                     73: }
                     74: 
                     75: void VFile::set_mode(bool ais_text){
                     76:        ffields.put(mode_name, new VString(ais_text? mode_value_text : mode_value_binary ));
                     77: }
                     78: 
                     79: void VFile::set_name(const String* afile_name){
1.14      paf        80:        char *lfile_name;
1.50      misha      81:        if(afile_name) {
                     82:                lfile_name=strdup(afile_name->taint_cstr(String::L_FILE_SPEC));
1.10      paf        83:                if(char *after_slash=rsplit(lfile_name, '\\'))
                     84:                        lfile_name=after_slash;
                     85:                if(char *after_slash=rsplit(lfile_name, '/'))
                     86:                        lfile_name=after_slash;
1.14      paf        87:        } else
1.16      paf        88:                lfile_name=NONAME_DAT;
1.50      misha      89: 
1.37      paf        90:        String& sfile_name=*new String;
                     91:        sfile_name.append_help_length(lfile_name, 0, String::L_FILE_SPEC);
1.50      misha      92: 
1.37      paf        93:        ffields.put(name_name, new VString(sfile_name));
1.50      misha      94: }
1.43      misha      95: 
1.50      misha      96: void VFile::set_content_type(Value* acontent_type, const String* afile_name, Request* r){
                     97:        if(!acontent_type && afile_name && r)
                     98:                acontent_type=new VString(r->mime_type_of(afile_name));
1.43      misha      99: 
                    100:        if(acontent_type)
                    101:                ffields.put(content_type_name, acontent_type);
                    102: }
                    103: 
1.46      misha     104: void VFile::save(Request_charsets& charsets, const String& file_spec, bool is_text, Charset* asked_charset) {
                    105:        if(fvalue_ptr)
                    106:                file_write(charsets, file_spec, fvalue_ptr, fvalue_size, is_text, false/*do_append*/, asked_charset);
                    107:        else
                    108:                throw Exception(PARSER_RUNTIME,
                    109:                        &file_spec,
                    110:                        "saving stat-ed file");
                    111: }
                    112: 
1.50      misha     113: bool VFile::is_text_mode(const String& mode) {
                    114:        if(mode==mode_value_text)
                    115:                return true;
                    116:        if(mode==mode_value_binary)
                    117:                return false;
                    118:        throw Exception(PARSER_RUNTIME,
                    119:                &mode,
                    120:                "is invalid mode, must be either '"MODE_VALUE_TEXT"' or '"MODE_VALUE_BINARY"'");
                    121: }
                    122:        
                    123: bool VFile::is_valid_mode (const String& mode) {
                    124:        return (mode==mode_value_text || mode==mode_value_binary);
                    125: }
                    126: 
1.45      misha     127: Value* VFile::get_element(const String& aname) {
1.43      misha     128:        Value* result;
                    129: 
                    130:        // $method
1.45      misha     131:        if(result=VStateless_object::get_element(aname))
1.43      misha     132:                return result;
                    133: 
                    134:        // $field
                    135:        if(result=ffields.get(aname))
                    136:                return result;
                    137: 
                    138:        // $text - if not cached
1.48      misha     139:        if(aname == text_name && fvalue_ptr && fvalue_size){
1.43      misha     140:                // assigned file have ptr and we really have some bytes
1.42      misha     141: 
                    142:                const char *premature_zero_pos=(const char *)memchr(fvalue_ptr, 0, fvalue_size);
                    143:                size_t copy_size=premature_zero_pos?premature_zero_pos-fvalue_ptr:fvalue_size;
                    144: 
1.43      misha     145:                char *copy_ptr=0;
1.42      misha     146:                if(copy_size){
1.43      misha     147:                        copy_ptr=strdup(fvalue_ptr, copy_size);
1.29      paf       148:                        fix_line_breaks(copy_ptr, copy_size);
                    149:                }
1.42      misha     150: 
1.43      misha     151:                result=new VString(*new String(copy_ptr, ftext_tainted ? String::L_TAINTED : String::L_AS_IS));
                    152:                ffields.put(text_name, result);
1.35      paf       153: 
                    154:                return result;
1.43      misha     155:        }
1.35      paf       156: 
1.43      misha     157:        return 0;
1.3       paf       158: }
1.48      misha     159: 
                    160: const String* VFile::get_json_string(Json_options* options){
1.49      moko      161:        String& result=*new String("{\n", String::L_AS_IS);
                    162:        
                    163:        String * indent=NULL;
                    164: 
                    165:        if (options->indent){
                    166:                indent = new String(",\n\t", String::L_AS_IS); *indent << options->indent << "\"";
                    167:                result << "\t" << options->indent;
                    168:        }
                    169: 
                    170:        result << "\"class\":\"file\"";
1.48      misha     171: 
                    172:        for(HashStringValue::Iterator i(ffields); i; i.next() ){
                    173:                String::Body key=i.key();
                    174:                if(key != text_name){
1.49      moko      175:                        indent ? result << *indent : result << ",\n\"";
                    176:                        result << String(key, String::L_JSON) << "\":" << *i.value()->get_json_string(options);
1.48      misha     177:                }
                    178:        }
                    179: 
                    180:        if(fvalue_ptr){
                    181:                switch(options->file){
                    182:                        case Json_options::F_BASE64:
                    183:                                {
1.49      moko      184:                                        indent ? result << *indent : result << ",\n\"";
                    185:                                        result << "base64\":\"";
1.48      misha     186:                                        const char* encoded=pa_base64_encode(fvalue_ptr, fvalue_size);
1.49      moko      187:                                        result.append_help_length(encoded, strlen(encoded), String::L_JSON);
                    188:                                        result << "\"";
1.48      misha     189:                                        break;
                    190:                                }
                    191:                        case Json_options::F_TEXT:
                    192:                                {
1.49      moko      193:                                        indent ? result << *indent : result << ",\n\"";
                    194:                                        result << "text\":\"";
                    195:                                        result.append(get_element(text_name)->as_string(), String::L_JSON, true/*forced lang*/);
                    196:                                        result << "\"";
1.48      misha     197:                                        break;
                    198:                                }
                    199:                }
                    200:        }
                    201: 
1.49      moko      202:        result << "\n" << options->indent << "}";
                    203:        return &result;
1.48      misha     204: }

E-mail: