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