|
|
| version 1.134, 2002/04/04 13:42:50 | version 1.140, 2002/08/01 11:26:48 |
|---|---|
| Line 3 | Line 3 |
| Copyright (c) 2001, 2002 ArtLebedev Group (http://www.artlebedev.com) | Copyright (c) 2001, 2002 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) |
| $Id$ | |
| */ | */ |
| #ifndef PA_STRING_H | #ifndef PA_STRING_H |
| #define PA_STRING_H | #define PA_STRING_H |
| static const char* IDENT_STRING_H="$Id$"; | |
| #include "pa_pool.h" | #include "pa_pool.h" |
| #include "pa_types.h" | #include "pa_types.h" |
| class Table; | |
| #ifndef NO_STRING_ORIGIN | #ifndef NO_STRING_ORIGIN |
| # define STRING_APPEND_PARAMS \ | # define STRING_APPEND_PARAMS \ |
| const char *src, size_t size, \ | const char *src, size_t size, \ |
| Line 44 class Table; | Line 42 class Table; |
| /// handy: appends const char* piece to String @see String::real_append | /// handy: appends const char* piece to String @see String::real_append |
| #define APPEND_CONST(src) APPEND_AS_IS(src, 0, 0, 0) | #define APPEND_CONST(src) APPEND_AS_IS(src, 0, 0, 0) |
| class Table; | |
| class Array; | class Array; |
| class SQL_Connection; | class SQL_Connection; |
| class Dictionary; | class Dictionary; |
| Line 107 public: | Line 106 public: |
| public: | public: |
| static String& OnPool(Pool& apool, const char *local_src=0, size_t src_size=0, bool tainted=false); | |
| String(Pool& apool, const char *src=0, size_t src_size=0, bool tainted=false); | String(Pool& apool, const char *src=0, size_t src_size=0, bool tainted=false); |
| String(const String& src); | String(const String& src); |
| bool is_empty() const { return append_here==head.rows; } | bool is_empty() const { return append_here==head.chunk.rows; } |
| size_t size() const; | size_t size() const; |
| /// convert to C string. if 'lang' known, forcing 'lang' to it | /// convert to C string. if 'lang' known, forcing 'lang' to it |
| char *cstr(Untaint_lang lang=UL_AS_IS, | char *cstr(Untaint_lang lang=UL_AS_IS, |
| Line 154 public: | Line 154 public: |
| */ | */ |
| int cmp(int& partial, const char* src_ptr, size_t src_size=0, | int cmp(int& partial, const char* src_ptr, size_t src_size=0, |
| size_t this_offset=0, Untaint_lang lang=UL_UNSPECIFIED) const; | size_t this_offset=0, Untaint_lang lang=UL_UNSPECIFIED) const; |
| /// this starts with src | |
| bool starts_with(const char* src_ptr, size_t src_size=0) const { | |
| int p; cmp(p, src_ptr, src_size); | |
| return p==0 || p==2; | |
| } | |
| bool operator == (const char* src_ptr) const { | bool operator == (const char* src_ptr) const { |
| size_t src_size=src_ptr?strlen(src_ptr):0; | size_t src_size=src_ptr?strlen(src_ptr):0; |
| if(size() != src_size) | if(size() != src_size) |
| Line 195 public: | Line 200 public: |
| const String& delim, | const String& delim, |
| Untaint_lang lang=UL_UNSPECIFIED, int limit=-1) const; | Untaint_lang lang=UL_UNSPECIFIED, int limit=-1) const; |
| typedef void (*Row_action)(Table& table, Array *row, int start, int finish, | typedef void (*Row_action)(Table& table, Array *row, |
| int prestart, int prefinish, | |
| int poststart, int postfinish, | |
| void *info); | void *info); |
| /** | /** |
| @return true if fills table. | @return true if fills table. |
| Line 221 public: | Line 228 public: |
| double as_double() const; | double as_double() const; |
| int as_int() const; | int as_int() const; |
| String& join_chains(Pool& pool, char** cstr) const; | |
| #ifndef NO_STRING_ORIGIN | #ifndef NO_STRING_ORIGIN |
| /// origin of string. calculated by first row | /// origin of string. calculated by first row |
| const Origin& origin() const; | const Origin& origin() const; |
| Line 229 public: | Line 238 public: |
| private: | private: |
| /** several String fragments | /** several String fragments |
| 'mutable' because can write after it's end, after it was appended to somebody | |
| @see String::append | |
| */ | */ |
| mutable struct Chunk { | struct Chunk { |
| typedef uchar count_type; | typedef uchar count_type; |
| count_type count; ///< the number of rows in chunk | count_type count; ///< the number of rows in chunk |
| // here could be some padding bytes | |
| /// string fragment or a link to next chunk union | /// string fragment or a link to next chunk union |
| union Row { | typedef union Row { |
| typedef uchar item_size_type; | typedef uchar item_size_type; |
| /// fragment | /// fragment |
| struct { | struct { |
| Line 248 private: | Line 255 private: |
| Origin origin; ///< origin | Origin origin; ///< origin |
| #endif | #endif |
| } item; | } item; |
| // we are using the fact that there's no padding before this field! | |
| Chunk *link; ///< link to the next chunk in chain | Chunk *link; ///< link to the next chunk in chain |
| } rows[CR_PREALLOCATED_COUNT+1/*for head.rows[CR_PREALLOCATED_COUNT].link*/]; | } rows_type[CR_PREALLOCATED_COUNT]; |
| } | rows_type rows; |
| head; ///< the head chunk of the chunk chain | }; |
| /** | |
| 'mutable' because can write after it's end, after it was appended to somebody | |
| @see String::append | |
| */ | |
| mutable struct { | |
| Chunk chunk; | |
| Chunk *link_storage; | |
| } head; ///< the head chunk of the chunk chain | |
| /// next append would write to this record | /// next append would write to this record |
| Chunk::Row *append_here; | Chunk::Row *append_here; |
| Line 302 private: //disabled | Line 318 private: //disabled |
| } | } |
| #define STRING_PREFIX_FOREACH_ROW(self, body) { \ | #define STRING_PREFIX_FOREACH_ROW(self, body) { \ |
| const Chunk *chunk=&(self).head; \ | const Chunk *chunk=&(self).head.chunk; \ |
| const Chunk::Row *row=chunk->rows; \ | const Chunk::Row *row=chunk->rows; \ |
| uint countdown=chunk->count; \ | uint countdown=chunk->count; \ |
| STRING_PREPARED_FOREACH_ROW(self, body) \ | STRING_PREPARED_FOREACH_ROW(self, body) \ |