* roottypes.cs: Rename from tree.cs.
[mono.git] / mcs / class / Npgsql / NpgsqlTypes / LargeObject.cs
1 /*-------------------------------------------------------------------------
2  
3   LargeObject.cs
4       This class is a port of the class LargeObject.java implemented by 
5       PostgreSQL Global Development Group
6  
7   Copyright (c) 2004, Emiliano Necciari
8   Original Code: Copyright (c) 2003, PostgreSQL Global Development Group
9   
10   Note: (Francisco Figueiredo Jr.)
11         Changed case of method names to conform to .Net names standard.
12         Also changed type names to their true names. i.e. int -> Int32
13  
14  This library is free software; you can redistribute it and/or
15  modify it under the terms of the GNU Lesser General Public
16  License as published by the Free Software Foundation; either
17  version 2.1 of the License, or (at your option) any later version.
18  
19  This library is distributed in the hope that it will be useful,
20  but WITHOUT ANY WARRANTY; without even the implied warranty of
21  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22  Lesser General Public License for more details.
23  
24  You should have received a copy of the GNU Lesser General Public
25  License along with this library; if not, write to the Free Software
26  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27 -------------------------------------------------------------------------
28 */
29
30 using System;
31 using System.IO;
32 using Npgsql;
33
34 namespace NpgsqlTypes
35 {
36
37     public class LargeObject
38     {
39         /*
40          * Indicates a seek from the begining of a file
41          */
42         public  const Int32 SEEK_SET = 0;
43
44         /*
45          * Indicates a seek from the current position
46          */
47         public  const Int32 SEEK_CUR = 1;
48
49         /*
50          * Indicates a seek from the end of a file
51          */
52         public  const Int32 SEEK_END = 2;
53
54         private Fastpath        fp; // Fastpath API to use
55         private Int32 oid;      // OID of this object
56         private Int32 fd; // the descriptor of the open large object
57
58         private Boolean closed = false; // true when we are closed
59
60         /*
61          * This opens a large object.
62          *
63          * <p>If the object does not exist, then an SQLException is thrown.
64          *
65          * @param fp FastPath API for the connection to use
66          * @param oid of the Large Object to open
67          * @param mode Mode of opening the large object
68          * (defined in LargeObjectManager)
69          * @exception SQLException if a database-access error occurs.
70          * @see org.postgresql.largeobject.LargeObjectManager
71          */
72         public LargeObject(Fastpath fp, Int32 oid, Int32 mode)
73         {
74             this.fp = fp;
75             this.oid = oid;
76
77             FastpathArg[] args = new FastpathArg[2];
78             args[0] = new FastpathArg(oid);
79             args[1] = new FastpathArg(mode);
80             this.fd = fp.GetInteger("lo_open", args);
81         }
82
83
84         /*
85          * @return the OID of this LargeObject
86          */
87         public Int32 GetOID()
88         {
89             return oid;
90         }
91
92         /*
93          * This method closes the object. You must not call methods in this
94          * object after this is called.
95          * @exception SQLException if a database-access error occurs.
96          */
97         public void Close()
98         {
99             if (!closed)
100             {
101
102                 // finally close
103                 FastpathArg[] args = new FastpathArg[1];
104                 args[0] = new FastpathArg(fd);
105                 fp.FastpathCall("lo_close", false, args); // true here as we dont care!!
106                 closed = true;
107             }
108         }
109
110         /*
111          * Reads some data from the object, and return as a byte[] array
112          *
113          * @param len number of bytes to read
114          * @return byte[] array containing data read
115          * @exception SQLException if a database-access error occurs.
116          */
117         public Byte[] Read(Int32 len)
118         {
119             // This is the original method, where the entire block (len bytes)
120             // is retrieved in one go.
121             FastpathArg[] args = new FastpathArg[2];
122             args[0] = new FastpathArg(fd);
123             args[1] = new FastpathArg(len);
124             return fp.GetData("loread", args);
125
126             // This version allows us to break this down Int32o 4k blocks
127             //if (len<=4048) {
128             //// handle as before, return the whole block in one go
129             //FastpathArg args[] = new FastpathArg[2];
130             //args[0] = new FastpathArg(fd);
131             //args[1] = new FastpathArg(len);
132             //return fp.getData("loread",args);
133             //} else {
134             //// return in 4k blocks
135             //byte[] buf=new byte[len];
136             //int off=0;
137             //while (len>0) {
138             //int bs=4048;
139             //len-=bs;
140             //if (len<0) {
141             //bs+=len;
142             //len=0;
143             //}
144             //read(buf,off,bs);
145             //off+=bs;
146             //}
147             //return buf;
148             //}
149         }
150
151         /*
152          * Reads some data from the object into an existing array
153          *
154          * @param buf destination array
155          * @param off offset within array
156          * @param len number of bytes to read
157          * @return the number of bytes actually read
158          * @exception SQLException if a database-access error occurs.
159          */
160         public Int32 Read(Byte[] buf, Int32 off, Int32 len)
161         {
162             Byte[] b = Read(len);
163             if (b.Length < len)
164                 len = b.Length;
165             Array.Copy(b,0,buf,off,len);
166             return len;
167         }
168
169         /*
170          * Writes an array to the object
171          *
172          * @param buf array to write
173          * @exception SQLException if a database-access error occurs.
174          */
175         public void Write(Byte[] buf)
176         {
177             FastpathArg[] args = new FastpathArg[2];
178             args[0] = new FastpathArg(fd);
179             args[1] = new FastpathArg(buf);
180             fp.FastpathCall("lowrite", false, args);
181         }
182
183         /*
184          * Writes some data from an array to the object
185          *
186          * @param buf destination array
187          * @param off offset within array
188          * @param len number of bytes to write
189          * @exception SQLException if a database-access error occurs.
190          */
191         public void Write(Byte[] buf, Int32 off, Int32 len)
192         {
193             Byte[] data = new Byte[len];
194
195             System.Array.Copy(buf, off, data, 0, len);
196             Write(data);
197         }
198
199         /*
200          * Sets the current position within the object.
201          *
202          * <p>This is similar to the fseek() call in the standard C library. It
203          * allows you to have random access to the large object.
204          *
205          * @param pos position within object
206          * @param ref Either SEEK_SET, SEEK_CUR or SEEK_END
207          * @exception SQLException if a database-access error occurs.
208          */
209         public void Seek(Int32 pos, Int32 refi)
210         {
211             FastpathArg[] args = new FastpathArg[3];
212             args[0] = new FastpathArg(fd);
213             args[1] = new FastpathArg(pos);
214             args[2] = new FastpathArg(refi);
215             fp.FastpathCall("lo_lseek", false, args);
216         }
217
218         /*
219          * Sets the current position within the object.
220          *
221          * <p>This is similar to the fseek() call in the standard C library. It
222          * allows you to have random access to the large object.
223          *
224          * @param pos position within object from begining
225          * @exception SQLException if a database-access error occurs.
226          */
227         public void Seek(Int32 pos)
228         {
229             Seek(pos, SEEK_SET);
230         }
231
232         /*
233          * @return the current position within the object
234          * @exception SQLException if a database-access error occurs.
235          */
236         public Int32 Tell()
237         {
238             FastpathArg[] args = new FastpathArg[1];
239             args[0] = new FastpathArg(fd);
240             return fp.GetInteger("lo_tell", args);
241         }
242
243         /*
244          * This method is inefficient, as the only way to find out the size of
245          * the object is to seek to the end, record the current position, then
246          * return to the original position.
247          *
248          * <p>A better method will be found in the future.
249          *
250          * @return the size of the large object
251          * @exception SQLException if a database-access error occurs.
252          */
253         public Int32 Size()
254         {
255             Int32 cp = Tell();
256             Seek(0, SEEK_END);
257             Int32 sz = Tell();
258             Seek(cp, SEEK_SET);
259             return sz;
260         }
261
262     }
263 }