summaryrefslogtreecommitdiff
path: root/rds-csv-nginx-module-0.09/src/ngx_http_rds_utils.h
diff options
context:
space:
mode:
Diffstat (limited to 'rds-csv-nginx-module-0.09/src/ngx_http_rds_utils.h')
-rw-r--r--rds-csv-nginx-module-0.09/src/ngx_http_rds_utils.h205
1 files changed, 205 insertions, 0 deletions
diff --git a/rds-csv-nginx-module-0.09/src/ngx_http_rds_utils.h b/rds-csv-nginx-module-0.09/src/ngx_http_rds_utils.h
new file mode 100644
index 0000000..4a71d4a
--- /dev/null
+++ b/rds-csv-nginx-module-0.09/src/ngx_http_rds_utils.h
@@ -0,0 +1,205 @@
+
+/*
+ * Copyright (C) Yichun Zhang (agentzh)
+ */
+
+
+#ifndef NGX_HTTP_RDS_UTILS_H
+#define NGX_HTTP_RDS_UTILS_H
+
+
+#include <stdint.h>
+
+
+static ngx_inline ngx_int_t
+ngx_http_rds_parse_header(ngx_http_request_t *r, ngx_buf_t *b,
+ ngx_http_rds_header_t *header)
+{
+ ssize_t rest;
+
+ rest = sizeof(uint8_t) /* endian type */
+ + sizeof(uint32_t) /* format version */
+ + sizeof(uint8_t) /* result type */
+
+ + sizeof(uint16_t) /* standard error code */
+ + sizeof(uint16_t) /* driver-specific error code */
+
+ + sizeof(uint16_t) /* driver-specific errstr len */
+ + 0 /* driver-specific errstr data */
+ + sizeof(uint64_t) /* affected rows */
+ + sizeof(uint64_t) /* insert id */
+ + sizeof(uint16_t) /* column count */
+ ;
+
+ if (b->last - b->pos < rest) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "rds: header is incomplete in the buf");
+ return NGX_ERROR;
+ }
+
+ /* check endian type */
+
+ if (*(uint8_t *) b->pos !=
+#if (NGX_HAVE_LITTLE_ENDIAN)
+ 0
+#else /* big endian */
+ 1
+#endif
+ )
+ {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "rds: endian type in the header differ");
+ return NGX_ERROR;
+ }
+
+ b->pos += sizeof(uint8_t);
+
+ /* check RDS format version number */
+
+ if (*(uint32_t *) b->pos != (uint32_t) resty_dbd_stream_version) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "rds: RDS format version differ");
+ return NGX_ERROR;
+ }
+
+ dd("RDS format version: %d", (int) *(uint32_t *) b->pos);
+
+ b->pos += sizeof(uint32_t);
+
+ /* check RDS result type */
+
+ if (*b->pos != 0) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "rds: RDS result type must be 0 for now");
+ return NGX_ERROR;
+ }
+
+ b->pos++;
+
+ /* save the standard error code */
+
+ header->std_errcode = *(uint16_t *) b->pos;
+
+ b->pos += sizeof(uint16_t);
+
+ /* save the driver-specific error code */
+
+ header->drv_errcode = *(uint16_t *) b->pos;
+
+ b->pos += sizeof(uint16_t);
+
+ /* save the error string length */
+
+ header->errstr.len = *(uint16_t *) b->pos;
+
+ b->pos += sizeof(uint16_t);
+
+ dd("errstr len: %d", (int) header->errstr.len);
+
+ /* check the rest data's size */
+
+ rest = header->errstr.len
+ + sizeof(uint64_t) /* affected rows */
+ + sizeof(uint64_t) /* insert id */
+ + sizeof(uint16_t) /* column count */
+ ;
+
+ if (b->last - b->pos < rest) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "rds: header is incomplete in the buf");
+ return NGX_ERROR;
+ }
+
+ /* save the error string data */
+
+ header->errstr.data = b->pos;
+
+ b->pos += header->errstr.len;
+
+ /* save affected rows */
+
+ header->affected_rows = *(uint64_t *) b->pos;
+
+ b->pos += sizeof(uint64_t);
+
+ /* save insert id */
+
+ header->insert_id = *(uint64_t *)b->pos;
+
+ b->pos += sizeof(uint64_t);
+
+ /* save column count */
+
+ header->col_count = *(uint16_t *) b->pos;
+
+ b->pos += sizeof(uint16_t);
+
+ dd("saved column count: %d", (int) header->col_count);
+
+ return NGX_OK;
+}
+
+
+static ngx_inline ngx_int_t
+ngx_http_rds_parse_col(ngx_http_request_t *r, ngx_buf_t *b,
+ ngx_http_rds_column_t *col)
+{
+ ssize_t rest;
+
+ rest = sizeof(uint16_t) /* std col type */
+ + sizeof(uint16_t) /* driver col type */
+ + sizeof(uint16_t) /* col name str len */
+ ;
+
+ if (b->last - b->pos < rest) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "rds: column spec is incomplete in the buf");
+ return NGX_ERROR;
+ }
+
+ /* save standard column type */
+ col->std_type = *(uint16_t *) b->pos;
+ b->pos += sizeof(uint16_t);
+
+ /* save driver-specific column type */
+ col->drv_type = *(uint16_t *) b->pos;
+ b->pos += sizeof(uint16_t);
+
+ /* read column name string length */
+
+ col->name.len = *(uint16_t *) b->pos;
+ b->pos += sizeof(uint16_t);
+
+ if (col->name.len == 0) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "rds_csv: column name empty");
+ return NGX_ERROR;
+ }
+
+ rest = col->name.len;
+
+ if (b->last - b->pos < rest) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "rds: column name string is incomplete in the buf");
+ return NGX_ERROR;
+ }
+
+ /* save the column name string data */
+
+ col->name.data = ngx_palloc(r->pool, col->name.len);
+ if (col->name.data == NULL) {
+ return NGX_ERROR;
+ }
+
+ ngx_memcpy(col->name.data, b->pos, col->name.len);
+ b->pos += col->name.len;
+
+ dd("saved column name \"%.*s\" (len %d, offset %d)",
+ (int) col->name.len, col->name.data,
+ (int) col->name.len, (int) (b->pos - b->start));
+
+ return NGX_OK;
+}
+
+
+#endif /* NGX_HTTP_RDS_UTILS_H */