Remove some deprecated libraries
[mono.git] / mcs / class / FirebirdSql.Data.Firebird / FirebirdSql.Data.Gds / GdsBlob.cs
1 /*
2  *      Firebird ADO.NET Data provider for .NET and Mono 
3  * 
4  *         The contents of this file are subject to the Initial 
5  *         Developer's Public License Version 1.0 (the "License"); 
6  *         you may not use this file except in compliance with the 
7  *         License. You may obtain a copy of the License at 
8  *         http://www.firebirdsql.org/index.php?op=doc&id=idpl
9  *
10  *         Software distributed under the License is distributed on 
11  *         an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either 
12  *         express or implied. See the License for the specific 
13  *         language governing rights and limitations under the License.
14  * 
15  *      Copyright (c) 2002, 2005 Carlos Guzman Alvarez
16  *      All Rights Reserved.
17  */
18
19 using System;
20 using System.IO;
21
22 using FirebirdSql.Data.Common;
23
24 namespace FirebirdSql.Data.Gds
25 {
26         internal sealed class GdsBlob : BlobBase
27         {
28                 #region Fields
29
30                 private GdsDatabase db;
31
32                 #endregion
33
34                 #region Properties
35
36                 public override IDatabase DB
37                 {
38                         get { return this.db; }
39                 }
40
41                 #endregion
42
43                 #region Constructors
44
45                 public GdsBlob(IDatabase db, ITransaction transaction) : this(db, transaction, 0)
46                 {
47                 }
48
49                 public GdsBlob(IDatabase db, ITransaction transaction, long blobId) : base(db)
50                 {
51                         if (!(db is GdsDatabase))
52                         {
53                                 throw new ArgumentException("Specified argument is not of GdsDatabase type.");
54                         }
55                         if (!(transaction is GdsTransaction))
56                         {
57                                 throw new ArgumentException("Specified argument is not of GdsTransaction type.");
58                         }
59
60                         this.db                         = (GdsDatabase)db;
61                         this.transaction        = transaction;
62                         this.position           = 0;
63                         this.blobHandle         = 0;
64                         this.blobId                     = blobId;
65                 }
66
67                 #endregion
68
69                 #region Protected Methods
70
71                 protected override void Create()
72                 {
73                         try
74                         {
75                                 this.CreateOrOpen(IscCodes.op_create_blob, null);
76                                 this.RblAddValue(IscCodes.RBL_create);
77                         }
78                         catch (IscException)
79                         {
80                                 throw;
81                         }
82                 }
83
84                 protected override void Open()
85                 {
86                         try
87                         {
88                                 this.CreateOrOpen(IscCodes.op_open_blob, null);
89                         }
90                         catch (IscException)
91                         {
92                                 throw;
93                         }
94                 }
95
96                 protected override byte[] GetSegment()
97                 {
98                         int requested = this.SegmentSize;
99
100                         lock (this.db)
101                         {
102                                 try
103                                 {
104                                         this.db.Send.Write(IscCodes.op_get_segment);
105                                         this.db.Send.Write(this.blobHandle);
106                                         this.db.Send.Write((requested + 2 < short.MaxValue) ? requested + 2 : short.MaxValue);
107                                         this.db.Send.Write((int)0);     // Data segment
108                                         this.db.Send.Flush();
109
110                                         GdsResponse r = this.db.ReadGenericResponse();
111
112                                         this.RblRemoveValue(IscCodes.RBL_segment);
113                                         if (r.ObjectHandle == 1)
114                                         {
115                                                 this.RblAddValue(IscCodes.RBL_segment);
116                                         }
117                                         else if (r.ObjectHandle == 2)
118                                         {
119                                                 this.RblAddValue(IscCodes.RBL_eof_pending);
120                                         }
121
122                                         byte[] buffer = r.Data;
123
124                                         if (buffer.Length == 0)
125                                         {
126                                                 // previous     segment was     last, this has no data
127                                                 return buffer;
128                                         }
129
130                                         int len = 0;
131                                         int srcpos = 0;
132                                         int destpos = 0;
133                                         while (srcpos < buffer.Length)
134                                         {
135                                                 len = IscHelper.VaxInteger(buffer, srcpos, 2);
136                                                 srcpos += 2;
137
138                                                 Buffer.BlockCopy(buffer, srcpos, buffer, destpos, len);
139                                                 srcpos  += len;
140                                                 destpos += len;
141                                         }
142
143                                         byte[] result = new byte[destpos];
144                                         Buffer.BlockCopy(buffer, 0, result, 0, destpos);
145
146                                         return result;
147                                 }
148                                 catch (IOException)
149                                 {
150                                         throw new IscException(IscCodes.isc_net_read_err);
151                                 }
152                         }
153                 }
154
155                 protected override void PutSegment(byte[] buffer)
156                 {
157                         lock (this.db)
158                         {
159                                 try
160                                 {
161                                         this.db.Send.Write(IscCodes.op_batch_segments);
162                                         this.db.Send.Write(this.blobHandle);
163                                         this.db.Send.WriteBlobBuffer(buffer);
164                                         this.db.Send.Flush();
165
166                                         this.db.ReadGenericResponse();
167                                 }
168                                 catch (IOException)
169                                 {
170                                         throw new IscException(IscCodes.isc_net_read_err);
171                                 }
172                         }
173                 }
174
175                 protected override void Seek(int position)
176                 {
177                         lock (this.db)
178                         {
179                                 try
180                                 {
181                                         this.db.Send.Write(IscCodes.op_seek_blob);
182                                         this.db.Send.Write(this.blobHandle);
183                                         this.db.Send.Write(0);                                  // Seek mode
184                                         this.db.Send.Write(position);                   // Seek offset
185                                         this.db.Send.Flush();
186
187                                         GdsResponse r = db.ReadGenericResponse();
188
189                                         this.position = r.ObjectHandle;
190                                 }
191                                 catch (IOException)
192                                 {
193                                         throw new IscException(IscCodes.isc_network_error);
194                                 }
195                         }
196                 }
197
198                 protected override void GetBlobInfo()
199                 {
200                         throw new NotSupportedException();
201                 }
202
203                 protected override void Close()
204                 {
205                         this.db.ReleaseObject(IscCodes.op_close_blob, this.blobHandle);
206                 }
207
208                 protected override void Cancel()
209                 {
210                         this.db.ReleaseObject(IscCodes.op_cancel_blob, this.blobHandle);
211                 }
212
213                 #endregion
214
215                 #region Private API     Methods
216
217                 private void CreateOrOpen(int op, BlobParameterBuffer bpb)
218                 {
219                         lock (this.db)
220                         {
221                                 try
222                                 {
223                                         this.db.Send.Write(op);
224                                         if (bpb != null)
225                                         {
226                                                 this.db.Send.WriteTyped(IscCodes.isc_bpb_version1, bpb.ToArray());
227                                         }
228                                         this.db.Send.Write(this.transaction.Handle);
229                                         this.db.Send.Write(this.blobId);
230                                         this.db.Send.Flush();
231
232                                         GdsResponse r = this.db.ReadGenericResponse();
233
234                                         this.blobId = r.BlobId;
235                                         this.blobHandle = r.ObjectHandle;
236                                 }
237                                 catch (IOException)
238                                 {
239                                         throw new IscException(IscCodes.isc_net_read_err);
240                                 }
241                         }
242                 }
243
244                 #endregion
245         }
246 }