📄 network-mysqld-proto.c
字号:
g_assert(*(packet->str + *_off + len) == '\0'); /* this has to be a \0 */ if (len > 0) { g_assert(*_off < packet->len); g_assert(*_off + len <= packet->len); /** * copy the string w/o the NUL byte */ r = network_mysqld_proto_get_string_len(packet, _off, len); } *_off += 1; return r;}/** * get a GString from the network packet * * @param packet the MySQL network packet * @param _off offset into the packet * @param len bytes to copy * @param out a GString which carries the string * @return a pointer to the string in out */gchar *network_mysqld_proto_get_gstring_len(GString *packet, guint *_off, gsize len, GString *out) { g_string_truncate(out, 0); if (len) { g_assert(*_off < packet->len); if (*_off + len > packet->len) { g_error("packet-offset out of range: %u + "F_SIZE_T" > "F_SIZE_T, *_off, len, packet->len); } g_string_append_len(out, packet->str + *_off, len); *_off += len; } return out->str;}/** * get a NUL-terminated GString from the network packet * * @param packet the MySQL network packet * @param _off offset into the packet * @param out a GString which carries the string * @return a pointer to the string in out * * @see network_mysqld_proto_get_gstring_len() */gchar *network_mysqld_proto_get_gstring(GString *packet, guint *_off, GString *out) { guint len; gchar *r = NULL; for (len = 0; *_off + len < packet->len && *(packet->str + *_off + len); len++); g_assert(*(packet->str + *_off + len) == '\0'); /* this has to be a \0 */ if (len > 0) { g_assert(*_off < packet->len); g_assert(*_off + len <= packet->len); r = network_mysqld_proto_get_gstring_len(packet, _off, len, out); } /* skip the \0 */ *_off += 1; return r;}/** * get a variable-length GString from the network packet * * @param packet the MySQL network packet * @param _off offset into the packet * @param out a GString which carries the string * @return a pointer to the string in out * * @see network_mysqld_proto_get_gstring_len(), network_mysqld_proto_get_lenenc_int() */gchar *network_mysqld_proto_get_lenenc_gstring(GString *packet, guint *_off, GString *out) { guint64 len; len = network_mysqld_proto_get_lenenc_int(packet, _off); return network_mysqld_proto_get_gstring_len(packet, _off, len, out);}/** * create a empty field for a result-set definition * * @return a empty MYSQL_FIELD */MYSQL_FIELD *network_mysqld_proto_field_init() { MYSQL_FIELD *field; field = g_new0(MYSQL_FIELD, 1); return field;}/** * free a MYSQL_FIELD and its components * * @param field the MYSQL_FIELD to free */void network_mysqld_proto_field_free(MYSQL_FIELD *field) { if (field->catalog) g_free(field->catalog); if (field->db) g_free(field->db); if (field->name) g_free(field->name); if (field->org_name) g_free(field->org_name); if (field->table) g_free(field->table); if (field->org_table) g_free(field->org_table); g_free(field);}/** * create a array of MYSQL_FIELD * * @return a empty array of MYSQL_FIELD */GPtrArray *network_mysqld_proto_fields_init(void) { GPtrArray *fields; fields = g_ptr_array_new(); return fields;}/** * free a array of MYSQL_FIELD * * @param fields array of MYSQL_FIELD to free * @see network_mysqld_proto_field_free() */void network_mysqld_proto_fields_free(GPtrArray *fields) { guint i; for (i = 0; i < fields->len; i++) { MYSQL_FIELD *field = fields->pdata[i]; if (field) network_mysqld_proto_field_free(field); } g_ptr_array_free(fields, TRUE);}/** * set length of the packet in the packet header * * each MySQL packet is * - is prefixed by a 4 byte packet header * - length is max 16Mbyte (3 Byte) * - sequence-id (1 Byte) * * To encode a packet of more then 16M clients have to send multiple 16M frames * * the sequence-id is incremented for each related packet and wrapping from 255 to 0 * * @param header string of at least 4 byte to write the packet header to * @param length length of the packet * @param id sequence-id of the packet * @return 0 */int network_mysqld_proto_set_header(unsigned char *header, size_t length, unsigned char id) { g_assert(length <= PACKET_LEN_MAX); header[0] = (length >> 0) & 0xFF; header[1] = (length >> 8) & 0xFF; header[2] = (length >> 16) & 0xFF; header[3] = id; return 0;}/** * decode the packet length from a packet header * * @param header the first 3 bytes of the network packet * @return the packet length * @see network_mysqld_proto_set_header() */size_t network_mysqld_proto_get_header(unsigned char *header) { return header[0] | header[1] << 8 | header[2] << 16;}/** * append the variable-length integer to the packet * * @param packet the MySQL network packet * @param length integer to encode * @return 0 */int network_mysqld_proto_append_lenenc_int(GString *packet, guint64 length) { if (length < 251) { g_string_append_c(packet, length); } else if (length < 65536) { g_string_append_c(packet, (gchar)252); g_string_append_c(packet, (length >> 0) & 0xff); g_string_append_c(packet, (length >> 8) & 0xff); } else if (length < 16777216) { g_string_append_c(packet, (gchar)253); g_string_append_c(packet, (length >> 0) & 0xff); g_string_append_c(packet, (length >> 8) & 0xff); g_string_append_c(packet, (length >> 16) & 0xff); } else { g_string_append_c(packet, (gchar)254); g_string_append_c(packet, (length >> 0) & 0xff); g_string_append_c(packet, (length >> 8) & 0xff); g_string_append_c(packet, (length >> 16) & 0xff); g_string_append_c(packet, (length >> 24) & 0xff); g_string_append_c(packet, (length >> 32) & 0xff); g_string_append_c(packet, (length >> 40) & 0xff); g_string_append_c(packet, (length >> 48) & 0xff); g_string_append_c(packet, (length >> 56) & 0xff); } return 0;}/** * encode a GString in to a MySQL len-encoded string * * @param packet the MySQL network packet * @param s string to encode * @param length length of the string to encode * @return 0 */int network_mysqld_proto_append_lenenc_string_len(GString *packet, const char *s, guint64 length) { if (!s) { g_string_append_c(packet, (gchar)251); /** this is NULL */ } else { network_mysqld_proto_append_lenenc_int(packet, length); g_string_append_len(packet, s, length); } return 0;}/** * encode a GString in to a MySQL len-encoded string * * @param packet the MySQL network packet * @param s string to encode * * @see network_mysqld_proto_append_lenenc_string_len() */int network_mysqld_proto_append_lenenc_string(GString *packet, const char *s) { return network_mysqld_proto_append_lenenc_string_len(packet, s, s ? strlen(s) : 0);}/** * encode fixed length integer in to a network packet * * @param packet the MySQL network packet * @param num integer to encode * @param size byte size of the integer * @return 0 */static int network_mysqld_proto_append_int_len(GString *packet, guint64 num, gsize size) { gsize i; for (i = 0; i < size; i++) { g_string_append_c(packet, num & 0xff); num >>= 8; } return 0;}/** * encode 8-bit integer in to a network packet * * @param packet the MySQL network packet * @param num integer to encode * * @see network_mysqld_proto_append_int_len() */int network_mysqld_proto_append_int8(GString *packet, guint8 num) { return network_mysqld_proto_append_int_len(packet, num, sizeof(num));}/** * encode 16-bit integer in to a network packet * * @param packet the MySQL network packet * @param num integer to encode * * @see network_mysqld_proto_append_int_len() */int network_mysqld_proto_append_int16(GString *packet, guint16 num) { return network_mysqld_proto_append_int_len(packet, num, sizeof(num));}/** * encode 32-bit integer in to a network packet * * @param packet the MySQL network packet * @param num integer to encode * * @see network_mysqld_proto_append_int_len() */int network_mysqld_proto_append_int32(GString *packet, guint32 num) { return network_mysqld_proto_append_int_len(packet, num, sizeof(num));}/*@}*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -