Beispiel #1
0
        private Boolean closed = false; // true when we are closed

        /// <summary>
        /// This opens a large object.
        /// If the object does not exist, then an NpgsqlException is thrown.
        /// </summary>
        /// <param name="fp">FastPath API for the connection to use.</param>
        /// <param name="oid">OID of the Large Object to open.</param>
        /// <param name="mode">Mode of opening the large object</param>
        public LargeObject(Fastpath fp, Int32 oid, Int32 mode)
        {
            this.fp  = fp;
            this.oid = oid;

            FastpathArg[] args = new FastpathArg[2];
            args[0] = new FastpathArg(oid);
            args[1] = new FastpathArg(mode);
            this.fd = fp.GetInteger("lo_open", args);
        }
		private Boolean closed = false; // true when we are closed

		/*
         * This opens a large object.
         *
         * <p>If the object does not exist, then an NpgsqlException is thrown.
         *
         * @param fp FastPath API for the connection to use
         * @param oid of the Large Object to open
         * @param mode Mode of opening the large object
         * (defined in LargeObjectManager)
         * @exception NpgsqlException if a database-access error occurs.
         * @see org.postgresql.largeobject.LargeObjectManager
         */

		public LargeObject(Fastpath fp, Int32 oid, Int32 mode)
		{
			this.fp = fp;
			this.oid = oid;

			FastpathArg[] args = new FastpathArg[2];
			args[0] = new FastpathArg(oid);
			args[1] = new FastpathArg(mode);
			this.fd = fp.GetInteger("lo_open", args);
		}
Beispiel #3
0
 /// <summary>
 /// This method closes the object. You must not call methods in this
 /// object after this is called.
 /// </summary>
 public void Close()
 {
     if (!closed)
     {
         // finally close
         FastpathArg[] args = new FastpathArg[1];
         args[0] = new FastpathArg(fd);
         fp.FastpathCall("lo_close", false, args); // true here as we dont care!!
         closed = true;
     }
 }
Beispiel #4
0
 /// <summary>
 /// This convenience method assumes that the return value is an Integer.
 /// </summary>
 /// <param name="name">Function name.</param>
 /// <param name="args">Function arguments.</param>
 /// <returns>Array containing result</returns>
 public Byte[] GetData(String name, FastpathArg[] args)
 {
     return (Byte[]) FastpathCall(name, false, args);
 }
        private Object FastpathV2(Int32 fnid, Boolean resulttype, FastpathArg[] args)
        {
            // added Oct 7 1998 to give us thread safety
            lock (stream)
            {
                // send the function call
                try
                {
                    // 70 is 'F' in ASCII. Note: don't use SendChar() here as it adds padding
                    // that confuses the backend. The 0 terminates the command line.
                    stream.WriteByte((Byte)70);
                    stream.WriteByte((Byte)0);

                    PGUtil.WriteInt32(stream,fnid);
                    PGUtil.WriteInt32(stream,args.Length);


                    for (Int32 i = 0;i < args.Length;i++)
                        args[i].Send(stream);

                    // This is needed, otherwise data can be lost
                    stream.Flush();

                }
                catch (IOException ioe)
                {
                    //Should be sending exception as second arg.
                    throw new Exception("postgresql.fp.send: "  + ioe.ToString());
                }

                // Now handle the result

                // Now loop, reading the results
                Object result = null; // our result
                String errorMessage = "";
                Byte[] input_buffer = new Byte[512];
                Int32 c;
                Boolean l_endQuery = false;
                while (!l_endQuery)
                {
                    c = (Char)stream.ReadByte();

                    switch (c)
                    {
                    case 'A':	// Asynchronous Notify
                        //TODO: do something with this
                        Int32 pid = PGUtil.ReadInt32(stream,input_buffer);
                        String msg = PGUtil.ReadString(stream,conn.Connector.Encoding);


                        conn.Connector.CheckErrorsAndNotifications();

                        break;

                        //------------------------------
                        // Error message returned
                    case 'E':
                        NpgsqlError e = new NpgsqlError(conn.BackendProtocolVersion);
                        e.ReadFromStream(stream,conn.Connector.Encoding);
                        errorMessage +=  e.Message;
                        break;

                        //------------------------------
                        // Notice from backend
                    case 'N':
                        NpgsqlError notice = new NpgsqlError(conn.BackendProtocolVersion);
                        notice.ReadFromStream(stream,conn.Connector.Encoding);
                        errorMessage +=  notice.Message;
                        break;

                    case 'V':
                        Char l_nextChar = (Char)stream.ReadByte();
                        if (l_nextChar == 'G')
                        {
                            Int32 sz = PGUtil.ReadInt32(stream,input_buffer);
                            // Return an Integer if
                            if (resulttype)
                                result = PGUtil.ReadInt32(stream,input_buffer);
                            else
                            {
                                Byte[] buf = new Byte[sz];

                                Int32 bytes_from_stream = 0;
                                Int32 total_bytes_read = 0;
                                Int32 size = sz;
                                do
                                {
                                    bytes_from_stream = stream.Read(buf, total_bytes_read, size);
                                    total_bytes_read += bytes_from_stream;
                                    size -= bytes_from_stream;
                                }
                                while(size > 0);

                                result = buf;
                            }
                            //There should be a trailing '0'
                            Int32 l_endChar = (Char)stream.ReadByte();
                        }
                        else
                        {
                            //it must have been a '0', thus no results
                        }
                        break;

                    case 'Z':
                        l_endQuery = true;
                        break;

                    default:
                        throw new Exception("postgresql.fp.protocol " + c.ToString());
                    }
                }

                if ( errorMessage != null )
                    throw new Exception("postgresql.fp.error" + errorMessage);

                return result;
            }
        }
		/*
         * Sets the current position within the object.
         *
         * <p>This is similar to the fseek() call in the standard C library. It
         * allows you to have random access to the large object.
         *
         * @param pos position within object
         * @param ref Either SEEK_SET, SEEK_CUR or SEEK_END
         * @exception NpgsqlException if a database-access error occurs.
         */

		public void Seek(Int32 pos, Int32 refi)
		{
			FastpathArg[] args = new FastpathArg[3];
			args[0] = new FastpathArg(fd);
			args[1] = new FastpathArg(pos);
			args[2] = new FastpathArg(refi);
			fp.FastpathCall("lo_lseek", false, args);
		}
		/*
         * Reads some data from the object, and return as a byte[] array
         *
         * @param len number of bytes to read
         * @return byte[] array containing data read
         * @exception NpgsqlException if a database-access error occurs.
         */

		public Byte[] Read(Int32 len)
		{
			// This is the original method, where the entire block (len bytes)
			// is retrieved in one go.
			FastpathArg[] args = new FastpathArg[2];
			args[0] = new FastpathArg(fd);
			args[1] = new FastpathArg(len);
			return fp.GetData("loread", args);

			// This version allows us to break this down Int32o 4k blocks
			//if (len<=4048) {
			//// handle as before, return the whole block in one go
			//FastpathArg args[] = new FastpathArg[2];
			//args[0] = new FastpathArg(fd);
			//args[1] = new FastpathArg(len);
			//return fp.getData("loread",args);
			//} else {
			//// return in 4k blocks
			//byte[] buf=new byte[len];
			//int off=0;
			//while (len>0) {
			//int bs=4048;
			//len-=bs;
			//if (len<0) {
			//bs+=len;
			//len=0;
			//}
			//read(buf,off,bs);
			//off+=bs;
			//}
			//return buf;
			//}
		}
        /*
         * This creates a large object, returning its OID
         *
         * @param mode a bitmask describing different attributes of the new object
         * @return oid of new object
         * @exception NpgsqlException on error
         */

        public Int32 Create(Int32 mode)
        {
            FastpathArg[] args = new FastpathArg[1];
            args[0] = new FastpathArg(mode);
            return(fp.GetInteger("lo_creat", args));
        }
Beispiel #9
0
 /// <summary>
 /// Report the current position within the object.
 /// </summary>
 /// <returns>The current position within the object.</returns>
 public Int32 Tell()
 {
     FastpathArg[] args = new FastpathArg[1];
     args[0] = new FastpathArg(fd);
     return(fp.GetInteger("lo_tell", args));
 }
Beispiel #10
0
 /// <summary>
 /// Send a function call to the PostgreSQL backend.
 /// </summary>
 /// <param name="fnid">Function id.</param>
 /// <param name="resulttype">True if the result is an integer, false for other results.</param>
 /// <param name="args">FastpathArguments to pass to fastpath.</param>
 /// <returns>null if no data, Integer if an integer result, or byte[] otherwise.</returns>
 public Object FastpathCall(Int32 fnid, Boolean resulttype, FastpathArg[] args)
 {
     try
     {
         if (conn.BackendProtocolVersion == ProtocolVersion.Version3)
         {
             return FastpathV3(fnid, resulttype, args);
         }
         else
         {
             return FastpathV2(fnid, resulttype, args);
         }
     }
     catch (IOException)
     {
         conn.ClearPool();
         throw new NpgsqlException("The Connection is broken.");
     }
 }
Beispiel #11
0
        private Object FastpathV2(Int32 fnid, Boolean resulttype, FastpathArg[] args)
        {
            // added Oct 7 1998 to give us thread safety
            lock (stream)
            {
                // send the function call

                stream
                    .WriteBytesNullTerminated((byte)ASCIIBytes.F)
                    .WriteInt32(fnid)
                    .WriteInt32(args.Length);

                for (Int32 i = 0; i < args.Length; i++)
                {
                    args[i].Send(stream);
                }

                // This is needed, otherwise data can be lost
                stream.Flush();

                // Now handle the result

                // Now loop, reading the results
                Object result = null; // our result
                String errorMessage = "";
                Int32 c;
                Boolean l_endQuery = false;
                while (!l_endQuery)
                {
                    c = (Char) stream.ReadByte();

                    switch (c)
                    {
                        case 'A': // Asynchronous Notify
                            //TODO: do something with this
                            Int32 pid = PGUtil.ReadInt32(stream);
                            String msg = PGUtil.ReadString(stream);

                            break;

                            //------------------------------
                            // Error message returned
                        case 'E':
                            NpgsqlError e = new NpgsqlError(conn.BackendProtocolVersion, stream);
                            errorMessage += e.Message;
                            break;

                            //------------------------------
                            // Notice from backend
                        case 'N':
                            NpgsqlError notice = new NpgsqlError(conn.BackendProtocolVersion, stream);
                            errorMessage += notice.Message;
                            break;

                        case 'V':
                            Char l_nextChar = (Char) stream.ReadByte();
                            if (l_nextChar == 'G')
                            {
                                Int32 sz = PGUtil.ReadInt32(stream);
                                // Return an Integer if
                                if (resulttype)
                                {
                                    result = PGUtil.ReadInt32(stream);
                                }
                                else
                                {
                                    Byte[] buf = new Byte[sz];

                                    Int32 bytes_from_stream = 0;
                                    Int32 total_bytes_read = 0;
                                    Int32 size = sz;
                                    do
                                    {
                                        bytes_from_stream = stream.Read(buf, total_bytes_read, size);
                                        total_bytes_read += bytes_from_stream;
                                        size -= bytes_from_stream;
                                    }
                                    while (size > 0);

                                    result = buf;
                                }
                                //There should be a trailing '0'
                                Int32 l_endChar = (Char) stream.ReadByte();
                            }
                            else
                            {
                                //it must have been a '0', thus no results
                            }
                            break;

                        case 'Z':
                            l_endQuery = true;
                            break;

                        default:
                            throw new NpgsqlException(string.Format("postgresql.fp.protocol {0}", c));
                    }
                }

                if (errorMessage != null)
                {
                    throw new NpgsqlException("postgresql.fp.error" + errorMessage);
                }

                return result;
            }
        }
Beispiel #12
0
 /*
  * Reads some data from the object, and return as a byte[] array
  *
  * @param len number of bytes to read
  * @return byte[] array containing data read
  * @exception NpgsqlException if a database-access error occurs.
  */
 public Byte[] Read(Int32 len)
 {
     // This is the original method, where the entire block (len bytes)
     // is retrieved in one go.
     FastpathArg[] args = new FastpathArg[2];
     args[0] = new FastpathArg(fd);
     args[1] = new FastpathArg(len);
     return fp.GetData("loread", args);
 }
Beispiel #13
0
 /// <summary>
 /// Send a function call to the PostgreSQL backend.
 /// </summary>
 /// <param name="fnid">Function id.</param>
 /// <param name="resulttype">True if the result is an integer, false for other results.</param>
 /// <param name="args">FastpathArguments to pass to fastpath.</param>
 /// <returns>null if no data, Integer if an integer result, or byte[] otherwise.</returns>
 public Object FastpathCall(Int32 fnid, Boolean resulttype, FastpathArg[] args)
 {
     try
     {
         return FastpathV3(fnid, resulttype, args);
     }
     catch (IOException)
     {
         conn.ClearPool();
         throw new NpgsqlException("The Connection is broken.");
     }
 }
 /*
  * Send a function call to the PostgreSQL backend
  *
  * @param fnid Function id
  * @param resulttype True if the result is an integer, false for other results
  * @param args FastpathArguments to pass to fastpath
  * @return null if no data, Integer if an integer result, or byte[] otherwise
  * @exception SQLException if a database-access error occurs.
  */
 public Object FastpathCall(Int32 fnid, Boolean resulttype, FastpathArg[] args)
 {
     if (conn.BackendProtocolVersion == ProtocolVersion.Version3)
     {
         return FastpathV3(fnid, resulttype, args);
     }
     else
     {
         return FastpathV2(fnid, resulttype, args);
     }
 }
Beispiel #15
0
 /// <summary>
 /// Send a function call to the PostgreSQL backend.
 /// </summary>
 /// <param name="fnid">Function id.</param>
 /// <param name="resulttype">True if the result is an integer, false for other results.</param>
 /// <param name="args">FastpathArguments to pass to fastpath.</param>
 /// <returns>null if no data, Integer if an integer result, or byte[] otherwise.</returns>
 public Object FastpathCall(Int32 fnid, Boolean resulttype, FastpathArg[] args)
 {
     try
     {
         return FastpathV3(fnid, resulttype, args);
     }
     catch (IOException)
     {
         conn.ClearPool();
         throw;
     }
 }
Beispiel #16
0
 /// <summary>
 /// This creates a large object, returning its OID.
 /// </summary>
 /// <returns>OID of new object.</returns>
 public Int32 Create()
 {
     FastpathArg[] args = new FastpathArg[1];
     args[0] = new FastpathArg(READWRITE);
     return fp.GetInteger("lo_creat", args);
 }
Beispiel #17
0
 /*
  * This creates a large object, returning its OID
  *
  * @param mode a bitmask describing different attributes of the new object
  * @return oid of new object
  */
 /// <summary>
 /// This creates a large object, returning its OID.
 /// </summary>
 /// <param name="mode">Bitmask describing different attributes of the new object.</param>
 /// <returns>OID of new object.</returns>
 public Int32 Create(Int32 mode)
 {
     FastpathArg[] args = new FastpathArg[1];
     args[0] = new FastpathArg(mode);
     return fp.GetInteger("lo_creat", args);
 }
Beispiel #18
0
        /*
         * This creates a large object, returning its OID.
         *
         * <p>It defaults to READWRITE for the new object's attributes.
         *
         * @return oid of new object
         * @exception NpgsqlException on error
         */

        public Int32 Create()
        {
            FastpathArg[] args = new FastpathArg[1];
            args[0] = new FastpathArg(READWRITE);
            return(fp.GetInteger("lo_creat", args));
        }
Beispiel #19
0
 /// <summary>
 /// This deletes a large object.
 /// </summary>
 /// <param name="oid">OID describing object to delete.</param>
 public void Delete(Int32 oid)
 {
     FastpathArg[] args = new FastpathArg[1];
     args[0] = new FastpathArg(oid);
     fp.FastpathCall("lo_unlink", false, args);
 }
Beispiel #20
0
        /*
         * This deletes a large object.
         *
         * @param oid describing object to delete
         * @exception NpgsqlException on error
         */

        public void Delete(Int32 oid)
        {
            FastpathArg[] args = new FastpathArg[1];
            args[0] = new FastpathArg(oid);
            fp.FastpathCall("lo_unlink", false, args);
        }
Beispiel #21
0
        private Object FastpathV3(Int32 fnid, Boolean resulttype, FastpathArg[] args)
        {
            // give  thread safety
            lock (stream)
            {
                // send the function call

                {
                    Int32 l_msgLen = 0;
                    l_msgLen += 16;
                    for (Int32 i = 0; i < args.Length; i++)
                    {
                        l_msgLen += args[i].SendSize();
                    }

                    stream
                        .WriteByte(ASCIIByteArrays.FunctionCallMessageCode)
                        .WriteInt32(l_msgLen)
                        .WriteInt32(fnid)
                        .WriteInt16(1)
                        .WriteInt16(1)
                        .WriteInt16((short)args.Length);

                    for (Int32 i = 0; i < args.Length; i++)
                    {
                        args[i].Send(stream);
                    }

                    stream.WriteInt16(1);

                    // This is needed, otherwise data can be lost
                    stream.Flush();
                }

                // Now handle the result

                // Now loop, reading the results
                Object result = null; // our result
                Exception error = null;
                Int32 c;
                Boolean l_endQuery = false;

                while (!l_endQuery)
                {
                    c = (Char) stream.ReadByte();

                    switch (c)
                    {
                        case 'A': // Asynchronous Notify
                            Int32 msglen = stream.ReadInt32();
                            Int32 pid = stream.ReadInt32();
                            String msg = stream.ReadString();
                            stream.ReadString();
                            String param = stream.ReadString();

                            break;
                            //------------------------------
                            // Error message returned
                        case 'E':
                            NpgsqlError e = new NpgsqlError(stream);
                            throw new NpgsqlException(e.ToString());

                            //------------------------------
                            // Notice from backend
                        case 'N':
                            Int32 l_nlen = stream.ReadInt32();

                            conn.Connector.FireNotice(new NpgsqlError(stream));

                            break;

                        case 'V':
                            Int32 l_msgLen = stream.ReadInt32();
                            Int32 l_valueLen = stream.ReadInt32();

                            if (l_valueLen == -1)
                            {
                                //null value
                            }
                            else if (l_valueLen == 0)
                            {
                                result = new Byte[0];
                            }
                            else
                            {
                                // Return an Integer if
                                if (resulttype)
                                {
                                    result = stream.ReadInt32();
                                }
                                else
                                {
                                    Byte[] buf = new Byte[l_valueLen];

                                    Int32 bytes_from_stream = 0;
                                    Int32 total_bytes_read = 0;
                                    Int32 size = l_valueLen;
                                    do
                                    {
                                        bytes_from_stream = stream.Read(buf, total_bytes_read, size);
                                        total_bytes_read += bytes_from_stream;
                                        size -= bytes_from_stream;
                                    }
                                    while (size > 0);

                                    result = buf;
                                }
                            }
                            break;

                        case 'Z':
                            //TODO: use size better
                            if (stream.ReadInt32() != 5)
                            {
                                throw new Exception("Received Z");
                            }
                            //TODO: handle transaction status
                            Char l_tStatus = (Char) stream.ReadByte();
                            l_endQuery = true;
                            break;

                        default:
                            throw new Exception(string.Format("postgresql.fp.protocol received {0}", c));
                    }
                }

                if (error != null)
                {
                    throw error;
                }

                return result;
            }
        }
		/*
         * Writes an array to the object
         *
         * @param buf array to write
         * @exception NpgsqlException if a database-access error occurs.
         */

		public void Write(Byte[] buf)
		{
			FastpathArg[] args = new FastpathArg[2];
			args[0] = new FastpathArg(fd);
			args[1] = new FastpathArg(buf);
			fp.FastpathCall("lowrite", false, args);
		}
Beispiel #23
0
 /// <summary>
 /// Send a function call to the PostgreSQL backend by name.
 /// Note: the mapping for the procedure name to function id needs to exist,
 /// usually to an earlier call to addfunction().
 /// This is the prefered method to call, as function id's can/may change
 /// between versions of the backend.
 /// For an example of how this works, refer to NpgsqlTypes.LargeObject
 /// </summary>
 /// <param name="name">Function name.</param>
 /// <param name="resulttype">True if the result is an integer, false for other results.</param>
 /// <param name="args">FastpathArguments to pass to fastpath.</param>
 /// <returns>null if no data, Integer if an integer result, or byte[] otherwise.</returns>
 public Object FastpathCall(String name, Boolean resulttype, FastpathArg[] args)
 {
     return FastpathCall(GetID(name), resulttype, args);
 }
		/*
         * @return the current position within the object
         * @exception NpgsqlException if a database-access error occurs.
         */

		public Int32 Tell()
		{
			FastpathArg[] args = new FastpathArg[1];
			args[0] = new FastpathArg(fd);
			return fp.GetInteger("lo_tell", args);
		}
Beispiel #25
0
        /// <summary>
        /// This convenience method assumes that the return value is an Integer.
        /// </summary>
        /// <param name="name">Function name.</param>
        /// <param name="args">Function arguments.</param>
        /// <returns>Integer result.</returns>
        public Int32 GetInteger(String name, FastpathArg[] args)
        {
            Int32 i = (Int32) FastpathCall(name, true, args);

            return i;
        }
		/*
         * This method closes the object. You must not call methods in this
         * object after this is called.
         * @exception NpgsqlException if a database-access error occurs.
         */

		public void Close()
		{
			if (!closed)
			{
				// finally close
				FastpathArg[] args = new FastpathArg[1];
				args[0] = new FastpathArg(fd);
				fp.FastpathCall("lo_close", false, args); // true here as we dont care!!
				closed = true;
			}
		}
        private Object FastpathV3(Int32 fnid, Boolean resulttype, FastpathArg[] args)
        {
            // give  thread safety
            lock (stream)
            {
                // send the function call
                try
                {
                    Int32 l_msgLen = 0;
                    l_msgLen += 16;
                    for (Int32 i=0;i < args.Length;i++)
                        l_msgLen += args[i].SendSize();

                    stream.WriteByte((Byte)'F');
                    PGUtil.WriteInt32(stream,l_msgLen);
                    PGUtil.WriteInt32(stream,fnid);
                    PGUtil.WriteInt16(stream,1);
                    PGUtil.WriteInt16(stream,1);
                    PGUtil.WriteInt16(stream,(short)args.Length);

                    for (Int32 i = 0;i < args.Length;i++)
                        args[i].Send(stream);

                    PGUtil.WriteInt16(stream,1);

                    // This is needed, otherwise data can be lost
                    stream.Flush();

                }
                catch (Exception ex)
                {
                    throw new Exception(ex.ToString());
                }

                // Now handle the result

                // Now loop, reading the results
                Object result = null; // our result
                Exception error = null;
                Int32 c;
                Boolean l_endQuery = false;
                Byte[] input_buffer = new Byte[512];

                while (!l_endQuery)
                {
                    c = (Char)stream.ReadByte();

                    switch (c)
                    {
                    case 'A':	// Asynchronous Notify
                        Int32 msglen = PGUtil.ReadInt32(stream,input_buffer);
                        Int32 pid = PGUtil.ReadInt32(stream,input_buffer);
                        String msg = PGUtil.ReadString(stream,conn.Connector.Encoding);
                        PGUtil.ReadString(stream,conn.Connector.Encoding);
                        String param = PGUtil.ReadString(stream,conn.Connector.Encoding);

                        conn.Connector.CheckErrorsAndNotifications();
                        break;
                        //------------------------------
                        // Error message returned
                    case 'E':
                        NpgsqlError e = new NpgsqlError(conn.BackendProtocolVersion);
                        e.ReadFromStream(stream,conn.Connector.Encoding);
                        throw new Exception(e.ToString());

                        //------------------------------
                        // Notice from backend
                    case 'N':
                        Int32 l_nlen = PGUtil.ReadInt32(stream,input_buffer);

                        NpgsqlError e1 = new NpgsqlError(conn.BackendProtocolVersion);
                        e1.ReadFromStream(stream,conn.Connector.Encoding);
                        conn.Connector.Mediator.Errors.Add(e1);

                        break;

                    case 'V':
                        Int32 l_msgLen = PGUtil.ReadInt32(stream,input_buffer);
                        Int32 l_valueLen = PGUtil.ReadInt32(stream,input_buffer);

                        if (l_valueLen == -1)
                        {
                            //null value
                        }
                        else if (l_valueLen == 0)
                        {
                            result = new Byte[0];
                        }
                        else
                        {
                            // Return an Integer if
                            if (resulttype)

                                result = PGUtil.ReadInt32(stream,input_buffer);
                            else
                            {
                                Byte[] buf = new Byte[l_valueLen];

                                Int32 bytes_from_stream = 0;
                                Int32 total_bytes_read = 0;
                                Int32 size = l_valueLen;
                                do
                                {
                                    bytes_from_stream = stream.Read(buf, total_bytes_read, size);
                                    total_bytes_read += bytes_from_stream;
                                    size -= bytes_from_stream;
                                }
                                while(size > 0);

                                result = buf;
                            }
                        }
                        break;

                    case 'Z':
                        //TODO: use size better
                        if (PGUtil.ReadInt32(stream,input_buffer) != 5)
                            throw new Exception("Received Z" );
                        //TODO: handle transaction status
                        Char l_tStatus = (Char)stream.ReadByte();
                        l_endQuery = true;
                        break;

                    default:
                        throw new Exception("postgresql.fp.protocol received " + c.ToString());
                    }
                }

                if ( error != null )
                    throw error;

                return result;
            }
        }