* getCopyDataMessage - fetch next CopyData message, process async messages * * Returns length word of CopyData message (> 0), or 0 if no complete * message available, -1 if end of copy, -2 if error. */
| 1781 | * message available, -1 if end of copy, -2 if error. |
| 1782 | */ |
| 1783 | static int |
| 1784 | getCopyDataMessage(PGconn *conn) |
| 1785 | { |
| 1786 | char id; |
| 1787 | int msgLength; |
| 1788 | int avail; |
| 1789 | |
| 1790 | for (;;) |
| 1791 | { |
| 1792 | /* |
| 1793 | * Do we have the next input message? To make life simpler for async |
| 1794 | * callers, we keep returning 0 until the next message is fully |
| 1795 | * available, even if it is not Copy Data. |
| 1796 | */ |
| 1797 | conn->inCursor = conn->inStart; |
| 1798 | if (pqGetc(&id, conn)) |
| 1799 | return 0; |
| 1800 | if (pqGetInt(&msgLength, 4, conn)) |
| 1801 | return 0; |
| 1802 | if (msgLength < 4) |
| 1803 | { |
| 1804 | handleSyncLoss(conn, id, msgLength); |
| 1805 | return -2; |
| 1806 | } |
| 1807 | avail = conn->inEnd - conn->inCursor; |
| 1808 | if (avail < msgLength - 4) |
| 1809 | { |
| 1810 | /* |
| 1811 | * Before returning, enlarge the input buffer if needed to hold |
| 1812 | * the whole message. See notes in parseInput. |
| 1813 | */ |
| 1814 | if (pqCheckInBufferSpace(conn->inCursor + (size_t) msgLength - 4, |
| 1815 | conn)) |
| 1816 | { |
| 1817 | /* |
| 1818 | * XXX add some better recovery code... plan is to skip over |
| 1819 | * the message using its length, then report an error. For the |
| 1820 | * moment, just treat this like loss of sync (which indeed it |
| 1821 | * might be!) |
| 1822 | */ |
| 1823 | handleSyncLoss(conn, id, msgLength); |
| 1824 | return -2; |
| 1825 | } |
| 1826 | return 0; |
| 1827 | } |
| 1828 | |
| 1829 | /* |
| 1830 | * If it's a legitimate async message type, process it. (NOTIFY |
| 1831 | * messages are not currently possible here, but we handle them for |
| 1832 | * completeness.) Otherwise, if it's anything except Copy Data, |
| 1833 | * report end-of-copy. |
| 1834 | */ |
| 1835 | switch (id) |
| 1836 | { |
| 1837 | case 'A': /* NOTIFY */ |
| 1838 | if (getNotify(conn)) |
| 1839 | return 0; |
| 1840 | break; |
no test coverage detected