00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef __CLIPROTO_H__
00012 #define __CLIPROTO_H__
00013
00014 BEGIN_GIGABASE_NAMESPACE
00015
00016 enum cli_commands {
00017 cli_cmd_close_session,
00018 cli_cmd_prepare_and_execute,
00019 cli_cmd_execute,
00020 cli_cmd_get_first,
00021 cli_cmd_get_last,
00022 cli_cmd_get_next,
00023 cli_cmd_get_prev,
00024 cli_cmd_free_statement,
00025 cli_cmd_abort,
00026 cli_cmd_commit,
00027 cli_cmd_update,
00028 cli_cmd_remove,
00029 cli_cmd_remove_current,
00030 cli_cmd_insert,
00031 cli_cmd_prepare_and_insert,
00032 cli_cmd_describe_table,
00033 cli_cmd_show_tables,
00034 cli_cmd_login,
00035 cli_cmd_precommit,
00036 cli_cmd_skip,
00037 cli_cmd_create_table,
00038 cli_cmd_drop_table,
00039 cli_cmd_alter_index,
00040 cli_cmd_freeze,
00041 cli_cmd_unfreeze,
00042 cli_cmd_seek,
00043 cli_cmd_alter_table,
00044 cli_cmd_insert_cpp,
00045 cli_cmd_update_cpp,
00046 cli_cmd_remove_cpp,
00047 cli_cmd_remove_cond,
00048 cli_cmd_select_cpp,
00049 cli_cmd_reload_schema,
00050 cli_cmd_lock,
00051 cli_cmd_unlock,
00052 cli_cmd_commit_async,
00053 cli_cmd_rollback_async,
00054 cli_cmd_last
00055 };
00056
00057 static const int sizeof_type[] = {
00058 sizeof(cli_oid_t),
00059 sizeof(cli_bool_t),
00060 sizeof(cli_int1_t),
00061 sizeof(cli_int2_t),
00062 sizeof(cli_int4_t),
00063 sizeof(cli_int8_t),
00064 sizeof(cli_real4_t),
00065 sizeof(cli_real8_t),
00066 sizeof(cli_real8_t),
00067 sizeof(char*),
00068 sizeof(char*),
00069 sizeof(char*),
00070 sizeof(cli_array_t),
00071 sizeof(cli_array_t),
00072 sizeof(cli_array_t),
00073 sizeof(cli_array_t),
00074 sizeof(cli_array_t),
00075 sizeof(cli_array_t),
00076 sizeof(cli_array_t),
00077 sizeof(cli_array_t),
00078 sizeof(cli_array_t),
00079 sizeof(cli_array_t),
00080 0,
00081 sizeof(cli_int8_t),
00082 sizeof(cli_int4_t),
00083 sizeof(cli_rectangle_t),
00084 0
00085 };
00086
00087 union cli_field_alignment {
00088 struct { char n; cli_oid_t v; } _cli_oid_t;
00089 struct { char n; cli_bool_t v; } _cli_bool_t;
00090 struct { char n; cli_int1_t v; } _cli_int1_t;
00091 struct { char n; cli_int2_t v; } _cli_int2_t;
00092 struct { char n; cli_int4_t v; } _cli_int4_t;
00093 struct { char n; cli_int8_t v; } _cli_int8_t;
00094 struct { char n; cli_real4_t v; } _cli_real4_t;
00095 struct { char n; cli_real8_t v; } _cli_real8_t;
00096 struct { char n; cli_array_t v; } _cli_array_t;
00097 struct { char n; char* v; } _cli_asciiz_t;
00098 struct { char n; cli_cstring_t v; } _cli_cstring_t;
00099 struct { char n; cli_rectangle_t v; } _cli_rectangle_t;
00100 };
00101
00102 #define CLI_ALIGNMENT(type) \
00103 (((char *)&(((union cli_field_alignment*)0)->_##type.v)) - ((char *)&(((union cli_field_alignment*)0)->_##type.n)))
00104
00105 static const int alignof_type[] = {
00106 CLI_ALIGNMENT(cli_oid_t),
00107 CLI_ALIGNMENT(cli_bool_t),
00108 CLI_ALIGNMENT(cli_int1_t),
00109 CLI_ALIGNMENT(cli_int2_t),
00110 CLI_ALIGNMENT(cli_int4_t),
00111 CLI_ALIGNMENT(cli_int8_t),
00112 CLI_ALIGNMENT(cli_real4_t),
00113 CLI_ALIGNMENT(cli_real8_t),
00114 CLI_ALIGNMENT(cli_real8_t),
00115 CLI_ALIGNMENT(cli_asciiz_t),
00116 CLI_ALIGNMENT(cli_asciiz_t),
00117 CLI_ALIGNMENT(cli_cstring_t),
00118 CLI_ALIGNMENT(cli_array_t),
00119 CLI_ALIGNMENT(cli_array_t),
00120 CLI_ALIGNMENT(cli_array_t),
00121 CLI_ALIGNMENT(cli_array_t),
00122 CLI_ALIGNMENT(cli_array_t),
00123 CLI_ALIGNMENT(cli_array_t),
00124 CLI_ALIGNMENT(cli_array_t),
00125 CLI_ALIGNMENT(cli_array_t),
00126 CLI_ALIGNMENT(cli_array_t),
00127 CLI_ALIGNMENT(cli_array_t),
00128 0,
00129 CLI_ALIGNMENT(cli_int8_t),
00130 CLI_ALIGNMENT(cli_int4_t),
00131 CLI_ALIGNMENT(cli_rectangle_t),
00132 0
00133 };
00134
00135 static const int gb2cli_type_mapping[] = {
00136 cli_bool,
00137 cli_int1,
00138 cli_int2,
00139 cli_int4,
00140 cli_int8,
00141 cli_real4,
00142 cli_real8,
00143 cli_asciiz,
00144 cli_oid
00145 };
00146
00147
00148 #if defined(__FreeBSD__)
00149 END_GIGABASE_NAMESPACE
00150 #include <sys/param.h>
00151 #include <netinet/in.h>
00152 BEGIN_GIGABASE_NAMESPACE
00153 #define USE_HTON_NTOH
00154 #elif defined(__linux__)
00155
00156
00157
00158 END_GIGABASE_NAMESPACE
00159 #include <netinet/in.h>
00160 BEGIN_GIGABASE_NAMESPACE
00161 #define USE_HTON_NTOH
00162 #else
00163 #if defined(_WIN32) && _M_IX86 >= 400 && !defined(__BCPLUSPLUS__) && !defined(__MINGW32__)
00164 #pragma warning(disable:4035) // disable "no return" warning
00165 #ifdef __BORLANDC__
00166 static
00167 #else
00168 inline
00169 #endif
00170 int swap_bytes_in_dword(int val) {
00171 __asm {
00172 mov eax, val
00173 bswap eax
00174 }
00175 }
00176 #ifdef __BORLANDC__
00177 static
00178 #else
00179 inline
00180 #endif
00181 short swap_bytes_in_word(short val) {
00182 __asm {
00183 mov ax, val
00184 xchg al,ah
00185 }
00186 }
00187 #pragma warning(default:4035)
00188 #define ntohl(w) swap_bytes_in_dword(w)
00189 #define htonl(w) swap_bytes_in_dword(w)
00190 #define ntohs(w) swap_bytes_in_word(w)
00191 #define htons(w) swap_bytes_in_word(w)
00192
00193 #define USE_HTON_NTOH
00194 #endif
00195 #endif
00196
00197
00198
00199
00200 inline char* pack2(char* dst, int2 val) {
00201 *dst++ = char(val >> 8);
00202 *dst++ = char(val);
00203 return dst;
00204 }
00205
00206 inline char* pack2(char* dst, char const* src) {
00207 return pack2(dst, *(int2*)src);
00208 }
00209
00210 inline void pack2(int2& val) {
00211 #if BYTE_ORDER != BIG_ENDIAN
00212 #ifdef USE_HTON_NTOH
00213 val = htons(val);
00214 #else
00215 pack2((char*)&val, val);
00216 #endif
00217 #endif
00218 }
00219
00220
00221 inline char* pack4(char* dst, int4 val) {
00222 *dst++ = char(val >> 24);
00223 *dst++ = char(val >> 16);
00224 *dst++ = char(val >> 8);
00225 *dst++ = char(val);
00226 return dst;
00227 }
00228
00229 inline char* pack4(char* dst, char const* src) {
00230 return pack4(dst, *(int4*)src);
00231 }
00232
00233 inline void pack4(int4& val) {
00234 #if BYTE_ORDER != BIG_ENDIAN
00235 #ifdef USE_HTON_NTOH
00236 val = htonl(val);
00237 #else
00238 pack4((char*)&val, val);
00239 #endif
00240 #endif
00241 }
00242
00243
00244 inline char* pack8(char* dst, char const* src) {
00245 #if BYTE_ORDER == BIG_ENDIAN
00246 return pack4( pack4(dst, src), src + 4);
00247 #else
00248 return pack4( pack4(dst, src + 4), src);
00249 #endif
00250 }
00251
00252 inline char* pack8(char* dst, db_int8 val) {
00253 return pack8(dst, (char*)&val);
00254 }
00255
00256 inline char* pack_oid(char* dst, cli_oid_t oid)
00257 {
00258 #if dbDatabaseOidBits > 32
00259 return pack8(dst, (char*)&oid);
00260 #else
00261 return (sizeof(oid) == 4) ? pack4(dst, oid) : pack8(dst, (char*)&oid);
00262 #endif
00263 }
00264
00265 inline char* pack_rectangle(char* dst, cli_rectangle_t* rect)
00266 {
00267 if (sizeof(cli_coord_t) == 4) {
00268 for (int i = 0; i < RECTANGLE_DIMENSION*2; i++) {
00269 dst = pack4(dst, (char*)&rect->boundary[i]);
00270 }
00271 } else {
00272 for (int i = 0; i < RECTANGLE_DIMENSION*2; i++) {
00273 dst = pack8(dst, (char*)&rect->boundary[i]);
00274 }
00275 }
00276 return dst;
00277 }
00278
00279 #ifdef UNICODE
00280 inline char* pack_str(char* dst, char_t const* src) {
00281 char_t ch;
00282 do {
00283 ch = *src++;
00284 *dst++ = (char)(ch >> 8);
00285 *dst++ = (char)ch;
00286 } while (ch != '\0');
00287 return dst;
00288 }
00289 inline char* pack_str(char* dst, char_t const* src, int n) {
00290 char_t ch;
00291 while (--n >= 0) {
00292 ch = *src++;
00293 *dst++ = (char)(ch >> 8);
00294 *dst++ = (char)ch;
00295 }
00296 return dst;
00297 }
00298 #else
00299 inline char* pack_str(char* dst, char const* src) {
00300 while ((*dst++ = *src++) != '\0');
00301 return dst;
00302 }
00303 inline char* pack_str(char* dst, char const* src, int n) {
00304 while (--n >= 0) {
00305 *dst++ = *src++;
00306 }
00307 return dst;
00308 }
00309 #endif
00310
00311 inline int2 unpack2(char const* src) {
00312 nat1* s = (nat1*)src;
00313 return (s[0] << 8) + s[1];
00314 }
00315
00316 inline char* unpack2(char* dst, char* src) {
00317 *(int2*)dst = unpack2(src);
00318 return src + 2;
00319 }
00320
00321 inline void unpack2(int2& val) {
00322 #if BYTE_ORDER != BIG_ENDIAN
00323 #ifdef USE_HTON_NTOH
00324 val = ntohs(val);
00325 #else
00326 val = unpack2((char*)&val);
00327 #endif
00328 #endif
00329 }
00330
00331
00332 inline int4 unpack4(char const* src) {
00333 nat1* s = (nat1*)src;
00334 return (((((s[0] << 8) + s[1]) << 8) + s[2]) << 8) + s[3];
00335 }
00336
00337 inline char* unpack4(char* dst, char* src) {
00338 *(int4*)dst = unpack4(src);
00339 return src + 4;
00340 }
00341
00342 inline void unpack4(int4& val) {
00343 #if BYTE_ORDER != BIG_ENDIAN
00344 #ifdef USE_HTON_NTOH
00345 val = ntohl(val);
00346 #else
00347 val = unpack4((char*)&val);
00348 #endif
00349 #endif
00350 }
00351
00352 inline char* unpack8(char* dst, char* src) {
00353 #if BYTE_ORDER == BIG_ENDIAN
00354 *(int4*)dst = unpack4(src);
00355 *((int4*)dst+1) = unpack4(src+4);
00356 #else
00357 *(int4*)dst = unpack4(src+4);
00358 *((int4*)dst+1) = unpack4(src);
00359 #endif
00360 return src + 8;
00361 }
00362
00363 inline db_int8 unpack8(char* src) {
00364 db_int8 val;
00365 unpack8((char*)&val, src);
00366 return val;
00367 }
00368
00369 inline cli_oid_t unpack_oid(char* src)
00370 {
00371 cli_oid_t oid;
00372 if (sizeof(oid) == 4) {
00373 oid = unpack4(src);
00374 } else {
00375 unpack8((char*)&oid, src);
00376 }
00377 return oid;
00378 }
00379
00380 inline char* unpack_rectangle(cli_rectangle_t* rect, char* src)
00381 {
00382 if (sizeof(cli_coord_t) == 4) {
00383 for (int i = 0; i < RECTANGLE_DIMENSION*2; i++) {
00384 src = unpack4((char*)&rect->boundary[i], src);
00385 }
00386 } else {
00387 for (int i = 0; i < RECTANGLE_DIMENSION*2; i++) {
00388 src = unpack8((char*)&rect->boundary[i], src);
00389 }
00390 }
00391 return src;
00392 }
00393
00394 #ifdef UNICODE
00395 inline char* skip_str(char* p) {
00396 while (p[0] != 0 || p[1] != 0) {
00397 p += 2;
00398 }
00399 return p + 2;
00400 }
00401 inline char* unpack_str(char_t* dst, char* src) {
00402 char_t ch;
00403 do {
00404 ch = (src[0] << 8) | (src[1] & 0xFF);
00405 src += sizeof(char_t);
00406 *dst++ = ch;
00407 } while (ch != '\0');
00408 return src;
00409 }
00410 inline char* unpack_str(char_t* dst, char* src, int n) {
00411 char_t ch;
00412 while (--n >= 0) {
00413 ch = (src[0] << 8) | (src[1] & 0xFF);
00414 src += sizeof(char_t);
00415 *dst++ = ch;
00416 }
00417 return src;
00418 }
00419 inline char_t unpack_char(char const* p) {
00420 return (p[0] << 8) | (p[1] & 0xFF);
00421 }
00422 #else
00423 inline char* skip_str(char* p) {
00424 while (*p++ != 0);
00425 return p;
00426 }
00427 inline char* unpack_str(char* dst, char* src) {
00428 while ((*dst++ = *src++) != '\0');
00429 return src;
00430 }
00431 inline char* unpack_str(char* dst, char* src, int n) {
00432 while (--n >= 0) {
00433 *dst++ = *src++;
00434 }
00435 return src;
00436 }
00437 inline char_t unpack_char(char const* p) {
00438 return *p;
00439 }
00440 #endif
00441
00442 struct cli_request {
00443 int4 length;
00444 int4 cmd;
00445 int4 stmt_id;
00446 #ifdef SECURE_SERVER
00447 int4 sig;
00448 #endif
00449
00450 void pack() {
00451 #ifdef SECURE_SERVER
00452 int i, s = length + cmd + stmt_id;
00453 char *p = (char *)&length + sizeof(cli_request);
00454 for (i = 0; i < length - sizeof(cli_request); i++, p++) {
00455 s += (*p << 7) + (*p << 3) + i;
00456 }
00457 sig = s;
00458 #endif
00459 pack4(length);
00460 pack4(cmd);
00461 pack4(stmt_id);
00462 #ifdef SECURE_SERVER
00463 pack4(sig);
00464 #endif
00465 }
00466
00467 void unpack() {
00468 unpack4(length);
00469 unpack4(cmd);
00470 unpack4(stmt_id);
00471 #ifdef SECURE_SERVER
00472 unpack4(sig);
00473 #endif
00474 }
00475 };
00476
00477 END_GIGABASE_NAMESPACE
00478
00479 #endif