|
|
| version 1.155, 2004/01/30 09:56:49 | version 1.168, 2007/04/20 10:19:12 |
|---|---|
| Line 1 | Line 1 |
| /** @file | /** @file |
| Parser: string class decl. | Parser: string class decl. |
| Copyright (c) 2001-2003 ArtLebedev Group (http://www.artlebedev.com) | Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) |
| Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru) | Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru) |
| */ | */ |
| Line 11 | Line 11 |
| static const char * const IDENT_STRING_H="$Date$"; | static const char * const IDENT_STRING_H="$Date$"; |
| // includes | // includes |
| #include "pa_types.h" | #include "pa_types.h" |
| #include "pa_array.h" | #include "pa_array.h" |
| Line 20 extern "C" { // cord's author forgot to | Line 19 extern "C" { // cord's author forgot to |
| #include "cord.h" | #include "cord.h" |
| }; | }; |
| // defines | |
| // cord extension | // cord extension |
| /* Returns true if x does contain */ | /* Returns true if x does contain */ |
| /* char not_c at positions i..i+n. Value i,i+n must be < CORD_len(x). */ | /* char not_c at positions i..i+n. Value i,i+n must be < CORD_len(x). */ |
| Line 90 public: | Line 91 public: |
| L_HTTP_HEADER='h', ///< text in HTTP response header | L_HTTP_HEADER='h', ///< text in HTTP response header |
| L_MAIL_HEADER='m', ///< text in mail header | L_MAIL_HEADER='m', ///< text in mail header |
| L_URI='U', ///< text in uri | L_URI='U', ///< text in uri |
| L_TABLE='L', ///< ^table:set body | |
| L_SQL='Q', ///< ^table:sql body | L_SQL='Q', ///< ^table:sql body |
| L_JS='J', ///< JavaScript code | L_JS='J', ///< JavaScript code |
| L_XML='X', ///< ^dom:set xml | L_XML='X', ///< ^dom:set xml |
| L_HTML='H', ///< HTML code (for editing) | L_HTML='H', ///< HTML code |
| L_REGEX='R', ///< RegEx expression | |
| // READ WARNING ABOVE BEFORE ADDING ANYTHING | // READ WARNING ABOVE BEFORE ADDING ANYTHING |
| L_OPTIMIZE_BIT = 0x80 ///< flag, requiring cstr whitespace optimization | L_OPTIMIZE_BIT = 0x80 ///< flag, requiring cstr whitespace optimization |
| }; | }; |
| enum Trim_kind { | |
| TRIM_BOTH, | |
| TRIM_START, | |
| TRIM_END | |
| }; | |
| union Languages { | union Languages { |
| struct { | struct { |
| #ifdef PA_LITTLE_ENDIAN | |
| Language lang:8; | Language lang:8; |
| int is_not_just_lang:sizeof(CORD)*8-8; | int is_not_just_lang:sizeof(CORD)*8-8; |
| #elif defined(PA_BIG_ENDIAN) | |
| int is_not_just_lang:sizeof(CORD)*8-8; | |
| Language lang:8; | |
| #else | |
| # error word endianness not determined for some obscure reason | |
| #endif | |
| } opt; | } opt; |
| CORD langs; | CORD langs; |
| Line 120 public: | Line 134 public: |
| :CORD_chars((char)opt.lang, alength); | :CORD_chars((char)opt.lang, alength); |
| } | } |
| /// appending when 'langs' already contain something [simple cases hanled elsewhere] | /// appending when 'langs' already contain something [simple cases handled elsewhere] |
| template<typename C> | template<typename C> |
| void append(C current, | void append(C current, |
| const CORD to_nonempty_target_langs) { | const CORD to_nonempty_target_langs) { |
| Line 140 public: | Line 154 public: |
| public: | public: |
| const char* v() const; | const char* v() const; |
| void dump() const; | |
| Languages(): langs(0) {} | Languages(): langs(0) {} |
| Languages(Language alang) { | Languages(Language alang) { |
| Line 228 public: | Line 243 public: |
| callback(opt.lang, get_length(current), info); | callback(opt.lang, get_length(current), info); |
| } | } |
| bool invariant(size_t current_length) { | bool invariant(size_t current_length) const { |
| if(!langs) | if(!langs) |
| return current_length==0; | return current_length==0; |
| if(opt.is_not_just_lang) | if(opt.is_not_just_lang) |
| Line 244 public: | Line 259 public: |
| public: | public: |
| const char* v() const; | const char* v() const; |
| void dump() const; | |
| Body(): body(CORD_EMPTY) {} | Body(): body(CORD_EMPTY) {} |
| Body(CORD abody): body(abody) { | Body(CORD abody): body(abody) { |
| Line 315 public: | Line 331 public: |
| return CORD_chr(body, offset, c); | return CORD_chr(body, offset, c); |
| } | } |
| template<typename I> void for_each( | template<typename I> int for_each( |
| int (*f)(char c, I), | |
| I info) const { | |
| return CORD_iter(body, (CORD_iter_fn)f, (void*)info); | |
| } | |
| template<typename I> int for_each( | |
| int (*f1)(char c, I), | int (*f1)(char c, I), |
| int (*f2)(const char* s, I), | int (*f2)(const char* s, I), |
| I info) const { | I info) const { |
| CORD_iter5(body, 0, (CORD_iter_fn)f1, (CORD_batched_iter_fn)f2, info); | return CORD_iter5(body, 0, (CORD_iter_fn)f1, (CORD_batched_iter_fn)f2, info); |
| } | } |
| void set_pos(CORD_pos& pos, size_t index) const { CORD_set_pos(pos, body, index); } | void set_pos(CORD_pos& pos, size_t index) const { CORD_set_pos(pos, body, index); } |
| Line 327 public: | Line 349 public: |
| /*Body normalize() const { | /*Body normalize() const { |
| return Body(CORD_balance(body)); | return Body(CORD_balance(body)); |
| }*/ | }*/ |
| /// @returns this or 0 or mid. if returns this or 0 out_* are not filled | |
| Body trim(Trim_kind kind=TRIM_BOTH, const char* chars=0, | |
| size_t* out_start=0, size_t* out_length=0) const; | |
| }; | }; |
| struct C { | struct C { |
| const char *str; | const char *str; |
| size_t length; | size_t length; |
| operator const char *() { return str; } | operator const char *() { return str; } |
| C(): str(0), length(0) {} | |
| C(const char *astr, size_t asize): str(astr), length(asize) {} | C(const char *astr, size_t asize): str(astr), length(asize) {} |
| }; | }; |
| Line 340 public: | Line 367 public: |
| char *str; | char *str; |
| size_t length; | size_t length; |
| //operator char *() { return str; } | //operator char *() { return str; } |
| Cm(): str(0), length(0) {} | |
| Cm(char *astr, size_t asize): str(astr), length(asize) {} | Cm(char *astr, size_t asize): str(astr), length(asize) {} |
| }; | }; |
| Line 349 private: | Line 377 private: |
| Languages langs; ///< string characters lang | Languages langs; ///< string characters lang |
| const char* v() const; | const char* v() const; |
| void dump() const; | |
| #define ASSERT_STRING_INVARIANT(string) \ | #define ASSERT_STRING_INVARIANT(string) \ |
| assert((string).langs.invariant((string).body.length())) | assert((string).langs.invariant((string).body.length())) |
| public: | public: |
| Line 473 public: | Line 501 public: |
| const String& regexp, | const String& regexp, |
| const String* options, | const String* options, |
| Row_action row_action, void *info, | Row_action row_action, void *info, |
| bool& just_matched) const; | int& matches_count) const; |
| enum Change_case_kind { | enum Change_case_kind { |
| CC_UPPER, | CC_UPPER, |
| CC_LOWER | CC_LOWER |
| Line 481 public: | Line 509 public: |
| String& change_case(Charset& source_charset, | String& change_case(Charset& source_charset, |
| Change_case_kind kind) const; | Change_case_kind kind) const; |
| const String& replace(const Dictionary& dict) const; | const String& replace(const Dictionary& dict) const; |
| const String& trim(Trim_kind kind=TRIM_BOTH, const char* chars=0) const; | |
| double as_double() const { return pa_atod(cstr(), this); } | double as_double() const { return pa_atod(cstr(), this); } |
| int as_int() const { return pa_atoi(cstr(), this); } | int as_int() const { return pa_atoi(cstr(), this); } |
| bool as_bool() const { return as_int()!=0; } | |
| private: //disabled | private: //disabled |