|
|
| version 1.100, 2001/08/10 08:10:13 | version 1.102.2.1, 2001/09/07 17:11:51 |
|---|---|
| Line 20 static const char *RCSId="$Id$"; | Line 20 static const char *RCSId="$Id$"; |
| #include "pa_array.h" | #include "pa_array.h" |
| #include "pa_globals.h" | #include "pa_globals.h" |
| #include "pa_table.h" | #include "pa_table.h" |
| #include "pa_dictionary.h" | |
| String::String(Pool& apool, const char *src, size_t src_size, bool tainted) : | String::String(Pool& apool, const char *src, size_t src_size, bool tainted) : |
| Pooled(apool), | Pooled(apool), |
| Line 653 break2: | Line 654 break2: |
| return result; | return result; |
| } | } |
| String& String::replace(Pool& pool, Dictionary& dict) const { | |
| String& result=*new(pool) String(pool); | |
| const Chunk *chunk=&head; | |
| do { | |
| const Chunk::Row *row=chunk->rows; | |
| for(size_t i=0; i<chunk->count; i++, row++) { | |
| if(row==append_here) | |
| goto break2; | |
| const char *src=row->item.ptr; | |
| size_t src_size=row->item.size; | |
| char *new_cstr=(char *)pool.malloc((size_t)ceil(src_size*dict.max_ratio())); | |
| char *dest=new_cstr; | |
| while(src_size) { | |
| // there is a row where first column starts 'src' | |
| if(Table::Item *item=dict.first_that_starts(src)) { | |
| // get a=>b values | |
| const String& a=*static_cast<Array *>(item)->get_string(0); | |
| const String& b=*static_cast<Array *>(item)->get_string(1); | |
| // skip 'a' in 'src' | |
| src+=a.size(); | |
| // write 'b' to 'dest' | |
| b.store_to(dest); | |
| // skip 'b' in 'dest' | |
| dest+=b.size(); | |
| // reduce work size | |
| src_size-=a.size(); | |
| } else { | |
| *dest++=*src++; | |
| // reduce work size | |
| src_size--; | |
| } | |
| } | |
| result.APPEND(new_cstr, dest-new_cstr, | |
| row->item.lang, | |
| row->item.origin.file, row->item.origin.line); | |
| } | |
| chunk=row->link; | |
| } while(chunk); | |
| break2: | |
| return result; | |
| } | |
| double String::as_double() const { | double String::as_double() const { |
| double result; | double result; |
| const char *cstr=this->cstr(); | const char *cstr=this->cstr(); |
| char *error_pos=0; | char *error_pos; |
| // 0xABC | // 0xABC |
| if(cstr[0]=='0') | if(cstr[0]=='0') |
| if(cstr[1]=='x' || cstr[1]=='X') | if(cstr[1]=='x' || cstr[1]=='X') |
| result=(double)(unsigned long)strtol(cstr, &error_pos, 0); | result=(double)(unsigned long)strtol(cstr, &error_pos, 0); |
| else | else |
| result=(double)strtod(/*skip leading 0*/++cstr, &error_pos); | result=(double)strtod(cstr+1/*skip leading 0*/, &error_pos); |
| else | else |
| result=(double)strtod(cstr, &error_pos); | result=(double)strtod(cstr, &error_pos); |
| if(error_pos && *error_pos) | if(error_pos==cstr/*empty*/) |
| THROW(0, 0, | result=0; |
| this, | else |
| "invalid number (double)"); | if(*error_pos/*not eos*/) |
| THROW(0, 0, | |
| this, | |
| "invalid number (double)"); | |
| return result; | return result; |
| } | } |
| int String::as_int() const { | int String::as_int() const { |
| int result; | int result; |
| const char *cstr=this->cstr(); | const char *cstr=this->cstr(); |
| char *error_pos=0; | char *error_pos; |
| // 0xABC | // 0xABC |
| if(cstr[0]=='0') | if(cstr[0]=='0') |
| if(cstr[1]=='x' || cstr[1]=='X') | if(cstr[1]=='x' || cstr[1]=='X') |
| result=(int)(unsigned long)strtol(cstr, &error_pos, 0); | result=(int)(unsigned long)strtol(cstr, &error_pos, 0); |
| else | else |
| result=(int)strtol(/*skip leading 0*/++cstr, &error_pos, 0); | result=(int)strtol(cstr+1/*skip leading 0*/, &error_pos, 0); |
| else | else |
| result=(int)strtol(cstr, &error_pos, 0); | result=(int)strtol(cstr, &error_pos, 0); |
| if(error_pos && *error_pos) | if(error_pos==cstr/*empty*/) |
| THROW(0, 0, | result=0; |
| this, | else |
| "invalid number (int)"); | if(*error_pos/*not eos*/) |
| THROW(0, 0, | |
| this, | |
| "invalid number (int)"); | |
| return result; | return result; |
| } | } |