--- parser3/src/main/pa_string.C 2004/10/07 09:22:01 1.201 +++ parser3/src/main/pa_string.C 2007/01/18 17:47:44 1.208 @@ -1,11 +1,11 @@ /** @file Parser: string class. @see untalength_t.C. - Copyright (c) 2001-2004 ArtLebedev Group (http://www.artlebedev.com) + Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian (http://paf.design.ru) */ -static const char * const IDENT_STRING_C="$Date: 2004/10/07 09:22:01 $"; +static const char * const IDENT_STRING_C="$Date: 2007/01/18 17:47:44 $"; #include "pcre.h" @@ -104,7 +104,7 @@ double pa_atod(const char* str, const St #ifndef DOXYGEN typedef struct { ssize_t countdown; - char target; /* Character we're looking for */ + int target; /* Character we're looking for */ } chr_data; #endif static int CORD_range_contains_chr_greater_then_proc(char c, size_t size, void* client_data) @@ -406,7 +406,7 @@ Table* String::match(Charset& source_cha 0, "regexp is empty"); - const char* pattern=regexp.cstr(); + const char* pattern=regexp.cstr(String::L_UNSPECIFIED); // fix any tainted with L_REGEX const char* errptr; int erroffset; bool need_pre_post_match=false; @@ -451,11 +451,13 @@ Table* String::match(Charset& source_cha if(exec_substrings==PCRE_ERROR_NOMATCH) { pcre_free(code); row_action(table, 0/*last time, no raw*/, 0, 0, poststart, postfinish, info); - if(global || subpatterns) - return &table; // global or with subpatterns=true+result - else { - just_matched=false; return 0; // not global=no result - } + // if(global || subpatterns) + // return &table; // global or with subpatterns=true+result + // else { + // just_matched=false; return 0; // not global=no result + // } + just_matched=false; + return &table; } if(exec_substrings<0) { @@ -609,52 +611,75 @@ static int serialize_lang_piece(char ala } String::Cm String::serialize(size_t prolog_length) const { size_t fragments_count=langs.count(); + size_t body_length=body.length(); size_t buf_length= prolog_length //1 +sizeof(size_t) //2 - +fragments_count*(sizeof(char)+sizeof(size_t)) //3 - +body.length() //4 - +1; // for zero terminator used in deserialize + +body_length //3 + +1 // 4 for zero terminator used in deserialize + +sizeof(size_t) //5 + +fragments_count*(sizeof(char)+sizeof(size_t)); //6 + String::Cm result(new(PointerFreeGC) char[buf_length], buf_length); // 1: prolog char *cur=result.str+prolog_length; - // 2: langs.count [WARNING: not cast, addresses must be %4=0 on sparc] + // 2: chars.count [WARNING: not cast, addresses must be %4=0 on sparc] + memcpy(cur, &body_length, sizeof(body_length)); cur+=sizeof(body_length); + // 3: letters + body.for_each(serialize_body_char, serialize_body_piece, &cur); + // 4: zero terminator + *cur++=0; + // 5: langs.count [WARNING: not cast, addresses must be %4=0 on sparc] memcpy(cur, &fragments_count, sizeof(fragments_count)); cur+=sizeof(fragments_count); - // 3: lang info + // 6: lang info langs.for_each(body, serialize_lang_piece, &cur); - // 4: letters - body.for_each(serialize_body_char, serialize_body_piece, &cur); - // 5: zero terminator - *cur=0; return result; } -bool String::deserialize(size_t prolog_length, void *buf, size_t buf_length) { - if(buf_length<=prolog_length) +bool String::deserialize(size_t prolog_size, void *buf, size_t buf_size) { + size_t in_buf=buf_size; + if(in_buf<=prolog_size) return false; - buf_length-=prolog_length; - buf_length-=1; // 5: zero terminator + in_buf-=prolog_size; // 1: prolog - const char* cur=(const char* )buf+prolog_length; + const char* cur=(const char* )buf+prolog_size; + + // 2: chars.count + size_t body_length; + if(in_bufbody_length) + return false; // file curruption // uchar needed to prevent propagating 0x80 bit to upper bytes langs.append(total_length, (String::Language)(uchar)lang, fragment_length); - total_length+=fragment_length; - - buf_length-=piece_length; + total_length=combined_length; + in_buf-=piece_length; } - // 4: letters - if(buf_length!=total_length) + if(total_length!=body_length) // length(all language fragments) vs length(letters) return false; - - // serialize wrote extra zero byte there, we can rely on that - body=String::Body(cur, buf_length); } + if(in_buf!=0) // some strange extra bytes + return false; ASSERT_STRING_INVARIANT(*this); return true;