From ddd05b2c7e4b5c9f95f913b5ca24be9edc5bd7bb Mon Sep 17 00:00:00 2001 From: MDC Service Date: Wed, 25 May 2022 13:07:19 +0200 Subject: replace files with copyright header and Doxygen comments --- software/main/SimplePgSQL.cpp | 900 ------------------------------------------ 1 file changed, 900 deletions(-) delete mode 100644 software/main/SimplePgSQL.cpp (limited to 'software/main/SimplePgSQL.cpp') diff --git a/software/main/SimplePgSQL.cpp b/software/main/SimplePgSQL.cpp deleted file mode 100644 index 0e76e0a..0000000 --- a/software/main/SimplePgSQL.cpp +++ /dev/null @@ -1,900 +0,0 @@ -/* - SimplePgSQL.c - Lightweight PostgreSQL connector for Arduino - Copyright (C) Bohdan R. Rau 2016 - - SimplePgSQL is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - SimplePgSQL is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with SimplePgSQL. If not, write to: - The Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor - Boston, MA 02110-1301, USA. - */ -#include -//#include "esp_eth.h" -#include -#include -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/event_groups.h" -#include "esp_system.h" -#include "esp_wifi.h" -#include "esp_event.h" -#include "esp_log.h" -#include "nvs_flash.h" -#include "esp_netif.h" -#include "lwip/err.h" -#include "lwip/sockets.h" - - -#include "SimplePgSQL.h" - -#define AUTH_REQ_OK 0 /* User is authenticated */ -#define AUTH_REQ_PASSWORD 3 /* Password */ -#define PGTAG "PGSQL" -static const char EM_OOM[] = "Out of mem"; -static const char EM_READ[] = "Backend read err"; -static const char EM_WRITE[] = "Backend write err"; -static const char EM_CONN[] = "Cannot conn 2 srv"; -static const char EM_SYNC[] = "Backend out of sync"; -static const char EM_INTR[] = "Internal err"; -static const char EM_UAUTH[] = "auth method !sptd"; -static const char EM_BIN[] = "Bin fmt !sptd"; -static const char EM_EXEC[] = "Previ exe !finished"; -static const char EM_PASSWD[] = "Pwd req"; -static const char EM_EMPTY[] = "empty qry"; -static const char EM_FORMAT[] = "Illegal chr fmt"; - -PGconnection::PGconnection(const int flags, const unsigned char *Buffer, const int bufSize) { - conn_status = CONNECTION_NEEDED; - _passwd = NULL; - _user = NULL; - _buffer = (char *) Buffer; - _bufSize = bufSize; - bufPos = 0; - result_status=0; - _available=0; - _nfields=0; - _ntuples=0; - _flags=0; -} - -int PGconnection::PGsetDbLogin(const char *ServerIP, int ServerPort, const char *dbName, const char *dbUser, const char *dbPasswd, const char *dbCharset) { - - char *startpacket; - int packetlen; - int len; - -// close(); - memset(&DestAddr, 0, sizeof(DestAddr)); - AddrFamily = AF_INET; - ipProtocol = IPPROTO_IP; - DestAddr.sin_addr.s_addr = inet_addr(ServerIP); - DestAddr.sin_family = AF_INET; - DestAddr.sin_port = htons(ServerPort); - - if (!dbName) - dbName = dbUser; - len = strlen(dbUser) + 1; - if (dbPasswd) { - len += strlen(dbPasswd) + 1; - } - _user = (char *) malloc(len); - strcpy(_user, dbUser); - if (dbPasswd) { - _passwd = _user + strlen(dbUser) + 1; - strcpy(_passwd, dbPasswd); - } else { - _passwd = NULL; - } - - //int8_t connected = connect(client->connect(server, port); - SockH = socket(AddrFamily, SOCK_STREAM, ipProtocol); - if (SockH < 0) { - ESP_LOGE(PGTAG, "Unable to create socket: errno %d", errno); - setMsg_P(EM_CONN, PG_RSTAT_HAVE_ERROR); - return conn_status = CONNECTION_BAD; - } else { - int err = connect(SockH, (struct sockaddr *) &DestAddr, sizeof(DestAddr)); - if (err != 0) { - ESP_LOGE(PGTAG, "Socket unable to connect: errno %d", errno); - return conn_status = CONNECTION_BAD; - } - NetConnected = 1; - ESP_LOGI(PGTAG, "Successfully connected"); - } - - packetlen = build_startup_packet(NULL, dbName, dbCharset); - if (packetlen > _bufSize - 10) { - setMsg_P(EM_OOM, PG_RSTAT_HAVE_ERROR); - conn_status = CONNECTION_BAD; - return conn_status; - } - - startpacket = _buffer + (_bufSize - (packetlen + 1)); - build_startup_packet(startpacket, dbName, dbCharset); - if (pqPacketSend(0, startpacket, packetlen) < 0) { - setMsg_P(EM_WRITE, PG_RSTAT_HAVE_ERROR); - return conn_status = CONNECTION_BAD; - } - attempts = 0; - return conn_status = CONNECTION_AWAITING_RESPONSE; -} - -void PGconnection::PGclose(void) { - if (NetConnected) { - pqPacketSend('X', NULL, 0); -// client->stop(); - shutdown(SockH, 0); - close(SockH); - } - if (_user) { - free(_user); - _user = _passwd = NULL; - } - NetConnected = 0; - conn_status = CONNECTION_NEEDED; -} - -int PGconnection::PGstatus(void) { - char bereq; - char rc; - int32_t msgLen; - int32_t areq; - char * pwd = _passwd; - - switch (conn_status) { - case CONNECTION_NEEDED: - case CONNECTION_OK: - case CONNECTION_BAD: - - return conn_status; - - case CONNECTION_AWAITING_RESPONSE: - if (dataAvailable() == 0) return conn_status; - if (attempts++ >= 2) { - setMsg_P(EM_SYNC, PG_RSTAT_HAVE_ERROR); - return conn_status = CONNECTION_BAD; - } - if (pqGetc(&bereq)) { - goto read_error; - } - if (bereq == 'E') { - pqGetInt4(&msgLen); - pqGetNotice(PG_RSTAT_HAVE_ERROR); - return conn_status = CONNECTION_BAD; - } - if (bereq != 'R') { - setMsg_P(EM_SYNC, PG_RSTAT_HAVE_ERROR); - return conn_status = CONNECTION_BAD; - } - if (pqGetInt4(&msgLen)) { - goto read_error; - } - if (pqGetInt4(&areq)) { - goto read_error; - } - if (areq == AUTH_REQ_OK) { - if (_user) { - free(_user); - _user = _passwd = NULL; - } - result_status = PG_RSTAT_READY; - return conn_status = CONNECTION_AUTH_OK; - } - if (areq != AUTH_REQ_PASSWORD) { - setMsg_P(EM_UAUTH, PG_RSTAT_HAVE_ERROR); - return conn_status = CONNECTION_BAD; - } - if (!_passwd || !*_passwd) { - setMsg_P(EM_PASSWD, PG_RSTAT_HAVE_ERROR); - return conn_status = CONNECTION_BAD; - } - pwd = _passwd; - rc = pqPacketSend('p', pwd, strlen(pwd) + 1); - if (rc) { - goto write_error; - } - return conn_status; - - case CONNECTION_AUTH_OK: - for (;;) { - if (dataAvailable() == 0) return conn_status; - if (pqGetc(&bereq)) - goto read_error; - if (pqGetInt4(&msgLen)) - goto read_error; - msgLen -= 4; - if (bereq == 'A' || bereq == 'N' || bereq == 'S' || bereq == 'K') { - if (pqSkipnchar(msgLen)) - goto read_error; - continue; - } - if (bereq == 'E') { - pqGetNotice(PG_RSTAT_HAVE_ERROR); - return conn_status = CONNECTION_BAD; - } - - /* if (bereq == 'K') { - if (pqGetInt4(&be_pid)) goto read_error; - if (pqGetInt4(&be_key)) goto read_error; - continue; - } - */ - if (bereq == 'Z') { - pqSkipnchar(msgLen); - return conn_status = CONNECTION_OK; - } - return conn_status = CONNECTION_BAD; - } - break; - default: - setMsg_P(EM_INTR, PG_RSTAT_HAVE_ERROR); - return conn_status = CONNECTION_BAD; - } - read_error: setMsg_P(EM_READ, PG_RSTAT_HAVE_ERROR); - return conn_status = CONNECTION_BAD; - write_error: setMsg_P(EM_WRITE, PG_RSTAT_HAVE_ERROR); - return conn_status = CONNECTION_BAD; -} - -int PGconnection::PGexecute(const char *query) { - /* - if (!(result_status & PG_RSTAT_READY)) { - setMsg_P(EM_EXEC, PG_RSTAT_HAVE_ERROR); - return -1; - } - */ - int len = strlen(query); - if (pqPacketSend('Q', query, len + 1)) { - setMsg_P(EM_WRITE, PG_RSTAT_HAVE_ERROR); - conn_status = CONNECTION_BAD; - return -1; - } - result_status = PG_RSTAT_COMMAND_SENT; - return 0; -} - -int PGconnection::PGescapeName(const char *inbuf, char *outbuf) { - const char *c; - int l = 2; - for (c = inbuf; *c; c++) { - l++; - if (*c == '\\' || *c == '"') - l++; - } - if (outbuf) { - *outbuf++ = '"'; - for (c = inbuf; *c; c++) { - *outbuf++ = *c; - if (*c == '\\' || *c == '"') - *outbuf++ = *c; - } - *outbuf++ = '"'; - } - return l; -} - -int PGconnection::PGescapeString(const char *inbuf, char *outbuf) { - const char *c; - int e = 0, l; - for (c = inbuf; *c; c++) { - if (*c == '\\' || *c == '\'') - e++; - } - l = e + (c - inbuf) + (e ? 4 : 2); - if (outbuf) { - if (e) { - *outbuf++ = ' '; - *outbuf++ = 'E'; - } - *outbuf++ = '\''; - for (c = inbuf; *c; c++) { - *outbuf++ = *c; - if (*c == '\\' || *c == '\'') - *outbuf++ = *c; - } - *outbuf++ = '\''; - } - return l; -} - -char * PGconnection::PGgetValue(int nr) { - int i; - if (_null & (1 << nr)) return NULL; - char *c = _buffer; - if (nr < 0 || nr >= _nfields) return NULL; - for (i = 0; i < nr; i++) { - if (_null & (1 << i)) continue; - c += strlen(c) + 1; - } - return c; -} - -char *PGconnection::PGgetColumn(int n) { - char *c; - int i; - if (!(result_status & PG_RSTAT_HAVE_COLUMNS)) return NULL; - if (n < 0 || n >= _nfields) return NULL; - for (c = _buffer, i = 0; i < n; i++) { - c += strlen(c) + 1; - } - return c; -} - -char *PGconnection::PGgetMessage(void) { - if (!(result_status & PG_RSTAT_HAVE_MESSAGE)) - return NULL; - return _buffer; -} - -void dumpbuffer(char *b,int l) { - int i; - unsigned int v; - for (i=0;i31) printf(" %c ",v); - else printf(" "); - b++; - } - printf("\n"); -} - -int PGconnection::PGgetData(void) { - char id; - int32_t msgLen; - int rc; - char *c; - int r=0; - r=dataAvailable(); -// printf("getData:avail:%d\n",r);fflush(stdout); - if (r==0) return 0; - - if (pqGetc(&id)) goto read_error; - if (pqGetInt4(&msgLen)) goto read_error; -// printf("MSG ID: %c Len:%d (avail:%d)\n",id,msgLen,r);fflush(stdout); - msgLen -= 4; - switch (id) { - case 'T': - if ((rc = pqGetRowDescriptions())) { - if (rc == -2) - setMsg_P(EM_OOM, PG_RSTAT_HAVE_ERROR); - else if (rc == -3) - setMsg_P(EM_BIN, PG_RSTAT_HAVE_ERROR); - goto read_error; - } - if (_flags & PG_FLAG_IGNORE_COLUMNS) { - result_status &= ~PG_RSTAT_HAVE_MASK; - return 0; - } - return result_status = (result_status & ~PG_RSTAT_HAVE_MASK) | PG_RSTAT_HAVE_COLUMNS; - - case 'E': - if (pqGetNotice(PG_RSTAT_HAVE_ERROR)) - goto read_error; - return result_status; - - case 'N': - if (_flags & PG_FLAG_IGNORE_NOTICES) { - if (pqSkipnchar(msgLen)) - goto read_error; - return 0; - } - if (pqGetNotice(PG_RSTAT_HAVE_NOTICE)) - goto read_error; - return result_status = (result_status & ~PG_RSTAT_HAVE_MASK) | PG_RSTAT_HAVE_NOTICE; - - case 'A': - if (_flags & PG_FLAG_IGNORE_NOTICES) { - if (pqSkipnchar(msgLen)) - goto read_error; - return 0; - } - if (pqGetNotify(msgLen)) - goto read_error; - return result_status = (result_status & ~PG_RSTAT_HAVE_MASK) | PG_RSTAT_HAVE_NOTICE; - - case 'Z': - if (pqSkipnchar(msgLen)) - goto read_error; - result_status = (result_status & PG_RSTAT_HAVE_SUMMARY) | PG_RSTAT_READY; - return PG_RSTAT_READY; - - case 'S': - case 'K': - if (pqSkipnchar(msgLen)) - goto read_error; - return 0; - - case 'C': - if (msgLen > _bufSize - 1) - goto oom; - if (pqGetnchar(_buffer, msgLen)) - goto read_error; - _buffer[msgLen] = 0; - _ntuples = 0; - result_status = (result_status & ~PG_RSTAT_HAVE_MASK) | PG_RSTAT_HAVE_SUMMARY; - for (c = _buffer; *c && !isdigit(*c); c++) - ; - if (!*c) - return result_status; - if (strncmp(_buffer, "SELECT ", 7)) { - for (; *c && isdigit(*c); c++) - ; - for (; *c && !isdigit(*c); c++) - ; - } - if (*c) - _ntuples = strtol(c, NULL, 10); - return result_status; - - case 'D': - if ((rc = pqGetRow())) { - if (rc == -2) - setMsg_P(EM_OOM, PG_RSTAT_HAVE_ERROR); - else if (rc == -3) - setMsg_P(EM_SYNC, PG_RSTAT_HAVE_ERROR); - goto read_error; - } - if (_flags & PG_FLAG_IGNORE_COLUMNS) { - result_status &= ~PG_RSTAT_HAVE_MASK; - return 0; - } - - return result_status = (result_status & ~PG_RSTAT_HAVE_MASK) | PG_RSTAT_HAVE_ROW; - - case 'I': - if (pqSkipnchar(msgLen)) - goto read_error; - setMsg_P(EM_EMPTY, PG_RSTAT_HAVE_ERROR); - return result_status; - - default: - setMsg_P(EM_SYNC, PG_RSTAT_HAVE_ERROR); - conn_status = CONNECTION_BAD; - return -1; - } - - oom: setMsg_P(EM_OOM, PG_RSTAT_HAVE_ERROR); - - read_error: if (!(result_status & PG_RSTAT_HAVE_ERROR)) { - printf("READERROR!\n");fflush(stdout); - setMsg_P(EM_READ, PG_RSTAT_HAVE_ERROR); - } - conn_status = CONNECTION_BAD; - return -1; -} - -int PGconnection::PGexecuteFormat(const char *format, ...) { - int32_t msgLen; - va_list va; - va_start(va, format); - msgLen = writeFormattedQuery(0, format, va); - va_end(va); - if (msgLen < 0) - return -1; - va_start(va, format); - msgLen = writeFormattedQuery(msgLen, format, va); - va_end(va); - if (msgLen) { - return -1; - } - result_status = PG_RSTAT_COMMAND_SENT; - return 0; -} - -int PGconnection::build_startup_packet(char *packet, const char *dbName, const char *dbCharset) { - int packet_len = 4; - if (packet) { - memcpy(packet, "\0\003\0\0", 4); - } -#define ADD_STARTUP_OPTION(optname, optval) \ - do { \ - if (packet) \ - strcpy(packet + packet_len, (char *)optname); \ - packet_len += strlen((char *)optname) + 1; \ - if (packet) \ - strcpy(packet + packet_len, (char *)optval); \ - packet_len += strlen((char *)optval) + 1; \ - } while(0) - -#define ADD_STARTUP_OPTION_P(optname, optval) \ - do { \ - if (packet) \ - strcpy(packet + packet_len, (char *)optname); \ - packet_len += strlen((char *)optname) + 1; \ - if (packet) \ - strcpy(packet + packet_len, (char *)optval); \ - packet_len += strlen((char *)optval) + 1; \ - } while(0) - - if (_user && _user[0]) - ADD_STARTUP_OPTION("user", _user); - if (dbName && dbName[0]) - ADD_STARTUP_OPTION("database", dbName); - if (dbCharset && dbCharset[0]) - ADD_STARTUP_OPTION("client_encoding", dbCharset); - ADD_STARTUP_OPTION_P("application_name", "Scaladis"); -#undef ADD_STARTUP_OPTION - if (packet) - packet[packet_len] = '\0'; - packet_len++; - - return packet_len; -} - -int PGconnection::pqPacketSend(char pack_type, const char *buf, int buf_len) { - char *start = _buffer; - int l = _bufSize - 4; -// int n; - if (pack_type) { - *start++ = pack_type; - l--; - } - *start++ = ((buf_len + 4) >> 24) & 0xff; - *start++ = ((buf_len + 4) >> 16) & 0xff; - *start++ = ((buf_len + 4) >> 8) & 0xff; - *start++ = (buf_len + 4) & 0xff; - - if (buf) { - if (buf_len <= l) { - memcpy(start, buf, buf_len); - start += buf_len; - buf_len = 0; - } else { - memcpy(start, buf, l); - start += l; - buf_len -= l; - buf += l; - } - } - int err = send(SockH, _buffer, start - _buffer, 0); - if (err < 0) { - ESP_LOGE(PGTAG, "Send Error occurred during sending: errno %d", errno); - return err; - } - if (buf && buf_len) { - err = send(SockH, (const char *) buf, (size_t) buf_len, 0); - if (err < 0) { - ESP_LOGE(PGTAG, "Send2 Error occurred during sending: errno %d", errno); - return err; - - } - } - - return 0; -} - -int PGconnection::pqGetc(char *buf) { - int i=0; -// for (i = 0; !client->available() && i < 10; i++) { - while (i<10) { - if (dataAvailable()>0) break; - else { - vTaskDelay(i++); - } - } - if (i==10) return -1; - - int len = read(SockH, (void *) buf, 1); - _available-=len; - return -1+len; -} - -int PGconnection::pqGetInt4(int32_t *result) { - uint32_t tmp4 = 0; - uint8_t tmp, i; - int rt=0; - for (i = 0; i < 4; i++) { - rt=pqGetc((char *) &tmp); - if (rt) return -1; - tmp4 = (tmp4 << 8) | tmp; - } - *result = tmp4; - return 0; -} - -int PGconnection::pqGetInt2(int16_t *result) { - uint16_t tmp2 = 0; - uint8_t tmp, i; - for (i = 0; i < 2; i++) { - if (pqGetc((char *) &tmp)) return -1; - tmp2 = (tmp2 << 8) | tmp; - } - *result = tmp2; - return 0; -} - -int PGconnection::pqGetnchar(char *s, int len) { - while (len-- > 0) { - if (pqGetc(s++)) return -1; - } - return 0; -} - -int PGconnection::pqGets(char *s, int maxlen) { - int len; - char z; - for (len = 0; len < maxlen; len++) { - if (pqGetc(&z)) return -1; - if (s) *s++ = z; - if (!z) return len + 1; - } - return -(len + 1); -} - -int PGconnection::pqSkipnchar(int len) { - char dummy; - int i; - for (i=0;i 0) { - if (pqGetc(&dummy)) - return -1; - } - */ - return 0; -} - -int PGconnection::pqGetRow(void) { - int i; - int bufpos = 0; - int32_t len; - int16_t cols; - - _null = 0; - if (pqGetInt2(&cols)) return -1; - if (cols != _nfields) return -3; - - for (i = 0; i < _nfields; i++) { - if (pqGetInt4(&len)) return -1; - if (len < 0) { - _null |= 1 << i; - continue; - } - if (bufpos + len + 1 > _bufSize) { - return -2; - } - if (pqGetnchar(_buffer + bufpos, len)) - return -1; - bufpos += len; - _buffer[bufpos++] = 0; - } - return 0; -} - -int PGconnection::pqGetRowDescriptions(void) { - int i; - int16_t format; - int rc; - int bufpos; - if (pqGetInt2(&_nfields)) - return -1; - if (_nfields > PG_MAX_FIELDS) - return -2; // implementation limit - _formats = 0; - bufpos = 0; - - for (i = 0; i < _nfields; i++) { - if (!(_flags & PG_FLAG_IGNORE_COLUMNS)) { - if (bufpos >= _bufSize - 1) - return -2; - rc = pqGets(_buffer + bufpos, _bufSize - bufpos); - if (rc < 0) - return -1; - bufpos += rc; - } else { - if (pqGets(NULL, 8192) < 0) { - return -1; - } - } - if (pqSkipnchar(16)) - return -1; - if (pqGetInt2(&format)) - return -1; - format = format ? 1 : 0; - _formats |= format << i; - } - if (_formats) - return -3; - return 0; -} - -void PGconnection::setMsg(const char *s, int type) { - strcpy(_buffer, s); - result_status = (result_status & ~PG_RSTAT_HAVE_MASK) | type; -} - -void PGconnection::setMsg_P(const char *s, int type) { - strcpy(_buffer, s); - result_status = (result_status & ~PG_RSTAT_HAVE_MASK) | type; -} - -int PGconnection::pqGetNotice(int type) { - int bufpos = 0; - char id; - int rc; - for (;;) { - if (pqGetc(&id)) goto read_error; - if (!id) - break; - if (id == 'S' || id == 'M') { - if (bufpos && bufpos < _bufSize - 1) - _buffer[bufpos++] = ':'; - rc = pqGets(_buffer + bufpos, _bufSize - bufpos); - if (rc < 0) - goto read_error; - bufpos += rc - 1; - } else { - rc = pqGets(NULL, 8192); - if (rc < 0) goto read_error; - } - } - _buffer[bufpos] = 0; - result_status = (result_status & ~PG_RSTAT_HAVE_MASK) | type; - return 0; - - read_error: if (!bufpos) - setMsg_P(EM_READ, PG_RSTAT_HAVE_ERROR); - return -1; -} - -int PGconnection::pqGetNotify(int32_t msgLen) { - int32_t pid; - int bufpos, i; - if (pqGetInt4(&pid)) - return -1; - msgLen -= 4; - bufpos = sprintf(_buffer, "%d:", pid); - if (msgLen > _bufSize - (bufpos + 1)) { - if (pqGetnchar(_buffer + bufpos, _bufSize - (bufpos + 1))) - return -1; - msgLen -= _bufSize - (bufpos + 1); - if (pqSkipnchar(msgLen)) - return -1; - _buffer[msgLen = _bufSize - 1] = 0; - - } else { - if (pqGetnchar(_buffer + bufpos, msgLen)) - return -1; - _buffer[bufpos + msgLen] = 0; - msgLen += bufpos; - } - for (i = 0; i < msgLen; i++) - if (!_buffer[i]) - _buffer[i] = ':'; - return 0; -} - -int PGconnection::dataAvailable() { - int res=0; -// if (_available) return _available; - ioctl(SockH,FIONREAD,&res); - return res; -} - -int PGconnection::writeMsgPart(const char *s, int len, int fine) { - while (len > 0) { - int n = len; - if (n > _bufSize - bufPos) - n = _bufSize - bufPos; - memcpy(_buffer + bufPos, s, n); - bufPos += n; - s += n; - len -= n; - if (bufPos >= _bufSize) { -// if (client->write((uint8_t *) Buffer, bufPos) != (size_t) bufPos) return -1; - int err = send(SockH, _buffer, bufPos, 0); - if (err < 0) - return -1; - bufPos = 0; - } - } - if (bufPos && fine) { -// if (client->write((uint8_t *) Buffer, bufPos) != (size_t) bufPos) return -1; - int err = send(SockH, _buffer, bufPos, 0); - if (err < 0) - return -1; - - bufPos = 0; - } - - return 0; -} - -int32_t PGconnection::writeFormattedQuery(int32_t length, const char *format, va_list va) { - int32_t msgLen = 0; - const char *percent; - int blen, rc; -#define LBUFLEN 32 - char buf[LBUFLEN], znak; - if (length) { - length += 4; - bufPos = 0; - _buffer[bufPos++] = 'Q'; - _buffer[bufPos++] = (length >> 24) & 0xff; - _buffer[bufPos++] = (length >> 16) & 0xff; - _buffer[bufPos++] = (length >> 8) & 0xff; - _buffer[bufPos++] = (length) & 0xff; - } - for (;;) { - percent = strchr(format, '%'); - if (!percent) - break; - znak = percent[1]; - if (!length) { - msgLen += (percent - format); - } else { - rc = writeMsgPart(format, percent - format, false); - if (rc) - goto write_error; - } - format = percent + 2; - if (znak == 's' || znak == 'n') { - char *str = va_arg(va, char *); - blen = (znak == 's') ? PGescapeString(str, NULL) : PGescapeName(str, NULL); - if (!length) { - msgLen += blen; - } else { - if (bufPos + blen > _bufSize) { - rc = writeMsgPart(NULL, 0, true); - if (rc) - goto write_error; - } - } - if (znak == 's') { - PGescapeString(str, _buffer + bufPos); - } else { - PGescapeName(str, _buffer + bufPos); - } - bufPos += blen; - continue; - } - if (znak == 'l' || znak == 'd') { - if (znak == 'l') { - long n = va_arg(va, long); - blen = snprintf(buf, LBUFLEN, "'%ld'", n); - } else { - int n = va_arg(va, int); - blen = snprintf(buf, LBUFLEN, "'%d'", n); - } - if (length) { - rc = writeMsgPart(buf, blen, false); - if (rc) - goto write_error; - } else { - msgLen += blen; - } - } - setMsg_P(EM_FORMAT, PG_RSTAT_HAVE_ERROR); - return -1; - } - blen = strlen(format); - if (length) { - rc = writeMsgPart(format, blen, false); - if (!rc) { - rc = writeMsgPart("\0", 1, true); - } - if (rc) - goto write_error; - } else { - msgLen += blen + 1; - } - return msgLen; - - write_error: setMsg_P(EM_WRITE, PG_RSTAT_HAVE_ERROR); - conn_status = CONNECTION_BAD; - return -1; -} -- cgit v1.2.3