odyssey/sources/be_write.h

309 lines
8.6 KiB
C

#ifndef SHAPITO_BE_WRITE_H
#define SHAPITO_BE_WRITE_H
/*
* SHAPITO.
*
* Protocol-level PostgreSQL client library.
*/
static inline int
so_bewrite_error_as(so_stream_t *stream, char *severity, char *code,
char *message, int len)
{
int size = 1 /* S */ + 6 +
1 /* C */ + 6 +
1 /* M */ + len + 1 +
1 /* zero */;
int rc = so_stream_ensure(stream, sizeof(so_header_t) + size);
if (so_unlikely(rc == -1))
return -1;
so_stream_write8(stream, 'E');
so_stream_write32(stream, sizeof(uint32_t) + size);
so_stream_write8(stream, 'S');
so_stream_write(stream, severity, 6);
so_stream_write8(stream, 'C');
so_stream_write(stream, code, 6);
so_stream_write8(stream, 'M');
so_stream_write(stream, message, len);
so_stream_write8(stream, 0);
so_stream_write8(stream, 0);
return 0;
}
static inline int
so_bewrite_error(so_stream_t *stream, char *code, char *message, int len)
{
return so_bewrite_error_as(stream, "ERROR", code, message, len);
}
static inline int
so_bewrite_error_fatal(so_stream_t *stream, char *code, char *message, int len)
{
return so_bewrite_error_as(stream, "FATAL", code, message, len);
}
static inline int
so_bewrite_error_panic(so_stream_t *stream, char *code, char *message, int len)
{
return so_bewrite_error_as(stream, "PANIC", code, message, len);
}
static inline int
so_bewrite_notice(so_stream_t *stream, char *message, int len)
{
int rc = so_stream_ensure(stream, sizeof(so_header_t) + len + 1);
if (so_unlikely(rc == -1))
return -1;
so_stream_write8(stream, 'N');
so_stream_write32(stream, sizeof(uint32_t) + len);
so_stream_write(stream, message, len);
so_stream_write8(stream, 0);
return 0;
}
static inline int
so_bewrite_authentication_ok(so_stream_t *stream)
{
int rc = so_stream_ensure(stream, sizeof(so_header_t) + sizeof(uint32_t));
if (so_unlikely(rc == -1))
return -1;
so_stream_write8(stream, 'R');
so_stream_write32(stream, sizeof(uint32_t) + sizeof(uint32_t));
so_stream_write32(stream, 0);
return 0;
}
static inline int
so_bewrite_authentication_clear_text(so_stream_t *stream)
{
int rc = so_stream_ensure(stream, sizeof(so_header_t) + sizeof(uint32_t));
if (so_unlikely(rc == -1))
return -1;
so_stream_write8(stream, 'R');
so_stream_write32(stream, sizeof(uint32_t) + sizeof(uint32_t));
so_stream_write32(stream, 3);
return 0;
}
static inline int
so_bewrite_authentication_md5(so_stream_t *stream, char salt[4])
{
int rc = so_stream_ensure(stream, sizeof(so_header_t) + sizeof(uint32_t) + 4);
if (so_unlikely(rc == -1))
return -1;
so_stream_write8(stream, 'R');
so_stream_write32(stream, sizeof(uint32_t) + sizeof(uint32_t) + 4);
so_stream_write32(stream, 5);
so_stream_write(stream, salt, 4);
return 0;
}
static inline int
so_bewrite_backend_key_data(so_stream_t *stream, uint32_t pid, uint32_t key)
{
int rc = so_stream_ensure(stream, sizeof(so_header_t) +
sizeof(uint32_t) +
sizeof(uint32_t));
if (so_unlikely(rc == -1))
return -1;
so_stream_write8(stream, 'K');
so_stream_write32(stream, sizeof(uint32_t) + sizeof(uint32_t) +
sizeof(uint32_t));
so_stream_write32(stream, pid);
so_stream_write32(stream, key);
return 0;
}
static inline int
so_bewrite_parameter_status(so_stream_t *stream, char *key, int key_len,
char *value, int value_len)
{
int rc = so_stream_ensure(stream, sizeof(so_header_t) + key_len + value_len);
if (so_unlikely(rc == -1))
return -1;
so_stream_write8(stream, 'S');
so_stream_write32(stream, sizeof(uint32_t) + key_len + value_len);
so_stream_write(stream, key, key_len);
so_stream_write(stream, value, value_len);
return 0;
}
static inline int
so_bewrite_ready(so_stream_t *stream, uint8_t status)
{
int rc = so_stream_ensure(stream, sizeof(so_header_t) + sizeof(uint8_t));
if (so_unlikely(rc == -1))
return -1;
so_stream_write8(stream, 'Z');
so_stream_write32(stream, sizeof(uint32_t) + sizeof(uint8_t));
so_stream_write8(stream, status);
return 0;
}
static inline int
so_bewrite_row_description(so_stream_t *stream)
{
int rc = so_stream_ensure(stream, sizeof(so_header_t) + sizeof(uint16_t));
if (so_unlikely(rc == -1))
return -1;
int position = so_stream_used(stream);
so_stream_write8(stream, 'T');
so_stream_write32(stream, sizeof(uint32_t) + sizeof(uint16_t));
so_stream_write16(stream, 0);
return position;
}
static inline int
so_bewrite_row_description_add(so_stream_t *stream, int start,
char *name, int name_len,
int32_t table_id,
int16_t attrnum,
int32_t type_id,
int16_t type_size,
int32_t type_modifier,
int32_t format_code)
{
int size = name_len + 1 +
sizeof(uint32_t) /* table_id */+
sizeof(uint16_t) /* attrnum */ +
sizeof(uint32_t) /* type_id */ +
sizeof(uint16_t) /* type_size */ +
sizeof(uint32_t) /* type_modifier */ +
sizeof(uint16_t) /* format_code */;
int rc = so_stream_ensure(stream, size);
if (so_unlikely(rc == -1))
return -1;
so_stream_write(stream, name, name_len);
so_stream_write8(stream, 0);
so_stream_write32(stream, table_id);
so_stream_write16(stream, attrnum);
so_stream_write32(stream, type_id);
so_stream_write16(stream, type_size);
so_stream_write32(stream, type_modifier);
so_stream_write16(stream, format_code);
so_header_t *header;
header = (so_header_t*)(stream->start + start);
uint32_t pos_size = sizeof(uint32_t) + sizeof(uint16_t);
char *pos = (char*)&header->len;
uint32_t total_size;
uint16_t count;
so_stream_read32(&total_size, &pos, &pos_size);
so_stream_read16(&count, &pos, &pos_size);
total_size += size;
count++;
so_stream_write32to((char*)&header->len, total_size);
so_stream_write16to((char*)&header->len + sizeof(uint32_t), count);
return 0;
}
static inline int
so_bewrite_data_row(so_stream_t *stream)
{
int rc = so_stream_ensure(stream, sizeof(so_header_t) + sizeof(uint16_t));
if (so_unlikely(rc == -1))
return -1;
int position = so_stream_used(stream);
so_stream_write8(stream, 'D');
so_stream_write32(stream, sizeof(uint32_t) + sizeof(uint16_t));
so_stream_write16(stream, 0);
return position;
}
static inline int
so_bewrite_data_row_add(so_stream_t *stream, int start, char *data, int32_t len)
{
int is_null = len == -1;
int size = sizeof(uint32_t) + (is_null) ? 0 : len;
int rc = so_stream_ensure(stream, size);
if (so_unlikely(rc == -1))
return -1;
so_stream_write32(stream, len);
if (! is_null)
so_stream_write(stream, data, len);
so_header_t *header;
header = (so_header_t*)(stream->start + start);
uint32_t pos_size = sizeof(uint32_t) + sizeof(uint16_t);
char *pos = (char*)&header->len;
uint32_t total_size;
uint16_t count;
so_stream_read32(&total_size, &pos, &pos_size);
so_stream_read16(&count, &pos, &pos_size);
total_size += size;
count++;
so_stream_write32to((char*)&header->len, total_size);
so_stream_write16to((char*)&header->len + sizeof(uint32_t), count);
return 0;
}
static inline int
so_bewrite_complete(so_stream_t *stream, char *message, int len)
{
int rc = so_stream_ensure(stream, sizeof(so_header_t) + len);
if (so_unlikely(rc == -1))
return -1;
so_stream_write8(stream, 'C');
so_stream_write32(stream, sizeof(uint32_t) + len);
so_stream_write(stream, message, len);
return 0;
}
static inline int
so_bewrite_empty_query(so_stream_t *stream)
{
int rc = so_stream_ensure(stream, sizeof(so_header_t));
if (so_unlikely(rc == -1))
return -1;
so_stream_write8(stream, 'I');
so_stream_write32(stream, sizeof(uint32_t));
return 0;
}
static inline int
so_bewrite_parse_complete(so_stream_t *stream)
{
int rc = so_stream_ensure(stream, sizeof(so_header_t));
if (so_unlikely(rc == -1))
return -1;
so_stream_write8(stream, '1');
so_stream_write32(stream, sizeof(uint32_t));
return 0;
}
static inline int
so_bewrite_bind_complete(so_stream_t *stream)
{
int rc = so_stream_ensure(stream, sizeof(so_header_t));
if (so_unlikely(rc == -1))
return -1;
so_stream_write8(stream, '2');
so_stream_write32(stream, sizeof(uint32_t));
return 0;
}
static inline int
so_bewrite_portal_suspended(so_stream_t *stream)
{
int rc = so_stream_ensure(stream, sizeof(so_header_t));
if (so_unlikely(rc == -1))
return -1;
so_stream_write8(stream, 's');
so_stream_write32(stream, sizeof(uint32_t));
return 0;
}
static inline int
so_bewrite_no_data(so_stream_t *stream)
{
int rc = so_stream_ensure(stream, sizeof(so_header_t));
if (so_unlikely(rc == -1))
return -1;
so_stream_write8(stream, 'n');
so_stream_write32(stream, sizeof(uint32_t));
return 0;
}
#endif /* SHAPITO_BE_WRITE_H */