a5f88f536b1f651e8403206d8f49ef01afc70fab
[platform/core/csapi/tizenfx.git] / src / Tizen.Applications.Common / Tizen.Applications.RPCPort / Parcel.cs
1 /*
2  * Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 using System;
18 using System.Runtime.InteropServices;
19
20 namespace Tizen.Applications.RPCPort
21 {
22     /// <summary>
23     /// This structure represents the time stamp.
24     /// </summary>
25     /// <since_tizen> 9 </since_tizen>
26     public class TimeStamp
27     {
28         /// <summary>
29         /// Constructor with TimeStamp.
30         /// </summary>
31         /// <since_tizen> 9 </since_tizen>
32         internal TimeStamp(long second, long nanoSecond)
33         {
34             this.Second = second;
35             this.NanoSecond = nanoSecond;
36         }
37
38         /// <summary>
39         /// The second of TimeStamp.
40         /// </summary>
41         /// <since_tizen> 9 </since_tizen>
42         public long Second
43         {
44             get;
45             private set;
46         }
47
48         /// <summary>
49         /// The nano second of TimeStamp.
50         /// </summary>
51         /// <since_tizen> 9 </since_tizen>
52         public long NanoSecond
53         {
54             get;
55             private set;
56         }
57     }
58
59     /// <summary>
60     /// The class is the header that has the Parcel's information.
61     /// </summary>
62     /// <since_tizen> 9 </since_tizen>
63     public class ParcelHeader
64     {
65         internal IntPtr _handle;
66
67         /// <summary>
68         /// Constructor with Header
69         /// </summary>
70         /// <since_tizen> 9 </since_tizen>
71         internal ParcelHeader()
72         {
73         }
74
75         /// <summary>
76         /// Sets tag of Header.
77         /// </summary>
78         /// <param name="tag">The tag of Header</param>
79         /// <exception cref="InvalidIOException">Thrown when an internal IO error occurs.</exception>
80         /// <since_tizen> 9 </since_tizen>
81         public void SetTag(string tag)
82         {
83             var r = Interop.LibRPCPort.Parcel.SetTag(_handle, tag);
84             if (r != Interop.LibRPCPort.ErrorCode.None)
85                 throw new InvalidIOException();
86         }
87
88         /// <summary>
89         /// Gets tag of Header.
90         /// </summary>
91         /// <returns>Tag</returns>
92         /// <exception cref="InvalidIOException">Thrown when an internal IO error occurs.</exception>
93         /// <since_tizen> 9 </since_tizen>
94         public string GetTag()
95         {
96             var r = Interop.LibRPCPort.Parcel.GetTag(_handle, out string tag);
97             if (r != Interop.LibRPCPort.ErrorCode.None)
98                 throw new InvalidIOException();
99
100             return tag;
101         }
102
103         /// <summary>
104         /// Sets sequence number of Header.
105         /// </summary>
106         /// <param name="sequenceNumber">The seqence number of Header</param>
107         /// <exception cref="InvalidIOException">Thrown when an internal IO error occurs.</exception>
108         /// <since_tizen> 9 </since_tizen>
109         public void SetSequenceNumber(int sequenceNumber)
110         {
111             var r = Interop.LibRPCPort.Parcel.SetSeqNum(_handle, sequenceNumber);
112             if (r != Interop.LibRPCPort.ErrorCode.None)
113                 throw new InvalidIOException();
114         }
115
116         /// <summary>
117         /// Gets sequence number of Header.
118         /// </summary>
119         /// <returns>Sequence number</returns>
120         /// <exception cref="InvalidIOException">Thrown when an internal IO error occurs.</exception>
121         /// <since_tizen> 9 </since_tizen>
122         public int GetSequenceNumber()
123         {
124             var r = Interop.LibRPCPort.Parcel.GetSeqNum(_handle, out int sequenceNumber);
125             if (r != Interop.LibRPCPort.ErrorCode.None)
126                 throw new InvalidIOException();
127
128             return sequenceNumber;
129         }
130
131         /// <summary>
132         /// Gets time stamp of Header.
133         /// </summary>
134         /// <returns>Time stamp</returns>
135         /// <exception cref="InvalidIOException">Thrown when an internal IO error occurs.</exception>
136         /// <since_tizen> 9 </since_tizen>
137         public TimeStamp GetTimeStamp()
138         {
139             Interop.Libc.TimeStamp time = new Interop.Libc.TimeStamp();
140
141             var r = Interop.LibRPCPort.Parcel.GetTimeStamp(_handle, ref time);
142             if (r != Interop.LibRPCPort.ErrorCode.None)
143                 throw new InvalidIOException();
144
145             return new TimeStamp(time.sec.ToInt64(), time.nsec.ToInt64());
146         }
147     };
148
149     /// <summary>
150     /// The class that helps to perform marshalling and unmarshalling for RPC.
151     /// </summary>
152     /// <since_tizen> 5 </since_tizen>
153     public class Parcel : IDisposable
154     {
155         private IntPtr _handle;
156         private ParcelHeader _header;
157
158         /// <summary>
159         /// Constructor for this class.
160         /// </summary>
161         /// <exception cref="InvalidIOException">Thrown when an internal IO error occurs.</exception>
162         /// <since_tizen> 5 </since_tizen>
163         public Parcel()
164         {
165             var r = Interop.LibRPCPort.Parcel.Create(out _handle);
166             if (r != Interop.LibRPCPort.ErrorCode.None)
167                 throw new InvalidIOException();
168         }
169
170         /// <summary>
171         /// Constructor with port object.
172         /// </summary>
173         /// <param name="port">Port object.</param>
174         /// <exception cref="InvalidIOException">Thrown when an internal IO error occurs.</exception>
175         /// <since_tizen> 5 </since_tizen>
176         public Parcel(Port port)
177         {
178             if (port == null)
179                 throw new InvalidIOException();
180             var r = Interop.LibRPCPort.Parcel.CreateFromPort(out _handle, port.Handle);
181             if (r != Interop.LibRPCPort.ErrorCode.None)
182                 throw new InvalidIOException();
183         }
184
185         /// <summary>
186         /// Constructor with the raw bytes.
187         /// </summary>
188         /// <param name="bytes">The raw bytes.</param>
189         /// <exception cref="InvalidIOException">Thrown when an internal IO error occurs.</exception>
190         /// <since_tizen> 9 </since_tizen>
191         public Parcel(byte[] bytes)
192         {
193             if (bytes == null)
194                 throw new InvalidIOException();
195             var r = Interop.LibRPCPort.Parcel.CreateFromRaw(out _handle, bytes, (uint)bytes.Length);
196             if (r != Interop.LibRPCPort.ErrorCode.None)
197                 throw new InvalidIOException();
198         }
199
200         /// <summary>
201         /// Gets the raw bytes of the parcel.
202         /// </summary>
203         /// <returns>The raw bytes of the parcel.</returns>
204         /// <exception cref="InvalidIOException">Thrown when an internal IO error occurs.</exception>
205         /// <since_tizen> 9 </since_tizen>
206         public byte[] ToBytes()
207         {
208             var r = Interop.LibRPCPort.Parcel.GetRaw(_handle, out IntPtr raw, out uint size);
209             if (r != Interop.LibRPCPort.ErrorCode.None)
210                 throw new InvalidIOException();
211             byte[] bytes = new byte[size];
212             Marshal.Copy(raw, bytes, 0, (int)size);
213             return bytes;
214         }
215
216         /// <summary>
217         /// Sends parcel data through the port.
218         /// </summary>
219         /// <param name="p">The RPC port object for writing data.</param>
220         /// <exception cref="InvalidIOException">Thrown when an internal IO error occurs.</exception>
221         /// <since_tizen> 5 </since_tizen>
222         public void Send(Port p)
223         {
224             if (p == null)
225                 throw new InvalidIOException();
226             var r = Interop.LibRPCPort.Parcel.Send(_handle, p.Handle);
227             if (r != Interop.LibRPCPort.ErrorCode.None)
228                 throw new InvalidIOException();
229         }
230
231         /// <summary>
232         /// Writes a byte value into parcel object.
233         /// </summary>
234         /// <param name="b">byte data.</param>
235         /// <since_tizen> 5 </since_tizen>
236         public void WriteByte(byte b)
237         {
238             Interop.LibRPCPort.Parcel.WriteByte(_handle, b);
239         }
240
241         /// <summary>
242         /// Writes a short value into parcel object.
243         /// </summary>
244         /// <param name="b">short data.</param>
245         /// <since_tizen> 5 </since_tizen>
246         public void WriteShort(short b)
247         {
248             Interop.LibRPCPort.Parcel.WriteInt16(_handle, b);
249         }
250
251         /// <summary>
252         /// Writes an int value into parcel object.
253         /// </summary>
254         /// <param name="b">int data.</param>
255         /// <since_tizen> 5 </since_tizen>
256         public void WriteInt(int b)
257         {
258             Interop.LibRPCPort.Parcel.WriteInt32(_handle, b);
259         }
260
261         /// <summary>
262         /// Writes a long value into parcel object.
263         /// </summary>
264         /// <param name="b">long data.</param>
265         /// <since_tizen> 5 </since_tizen>
266         public void WriteLong(long b)
267         {
268             Interop.LibRPCPort.Parcel.WriteInt64(_handle, b);
269         }
270
271         /// <summary>
272         /// Writes a float value into parcel object.
273         /// </summary>
274         /// <param name="b">float data.</param>
275         /// <since_tizen> 5 </since_tizen>
276         public void WriteFloat(float b)
277         {
278             Interop.LibRPCPort.Parcel.WriteFloat(_handle, b);
279         }
280
281         /// <summary>
282         /// Writes a double value into parcel object.
283         /// </summary>
284         /// <param name="b">double data.</param>
285         /// <since_tizen> 5 </since_tizen>
286         public void WriteDouble(double b)
287         {
288             Interop.LibRPCPort.Parcel.WriteDouble(_handle, b);
289         }
290
291         /// <summary>
292         /// Writes a string value into parcel object.
293         /// </summary>
294         /// <param name="b">string data.</param>
295         /// <since_tizen> 5 </since_tizen>
296         public void WriteString(string b)
297         {
298             Interop.LibRPCPort.Parcel.WriteString(_handle, b);
299         }
300
301         /// <summary>
302         /// Writes a bool value into parcel object.
303         /// </summary>
304         /// <param name="b">bool data.</param>
305         /// <since_tizen> 5 </since_tizen>
306         public void WriteBool(bool b)
307         {
308             Interop.LibRPCPort.Parcel.WriteBool(_handle, b);
309         }
310
311         /// <summary>
312         /// Writes a Bundle data into parcel object.
313         /// </summary>
314         /// <param name="b">Bundle data.</param>
315         /// <since_tizen> 5 </since_tizen>
316         public void WriteBundle(Bundle b)
317         {
318             Interop.LibRPCPort.Parcel.WriteBundle(_handle, b.SafeBundleHandle.DangerousGetHandle());
319         }
320
321         /// <summary>
322         /// Writes a count of an array into parcel object.
323         /// </summary>
324         /// <param name="cnt">Array count.</param>
325         /// <since_tizen> 5 </since_tizen>
326         public void WriteArrayCount(int cnt)
327         {
328             Interop.LibRPCPort.Parcel.WriteArrayCount(_handle, cnt);
329         }
330
331         /// <summary>
332         /// Reads a byte value from parcel object.
333         /// </summary>
334         /// <returns>byte data.</returns>
335         /// <since_tizen> 5 </since_tizen>
336         public byte ReadByte()
337         {
338             Interop.LibRPCPort.Parcel.ReadByte(_handle, out byte b);
339             return b;
340         }
341
342         /// <summary>
343         /// Reads a short value from parcel object.
344         /// </summary>
345         /// <returns>short data.</returns>
346         /// <since_tizen> 5 </since_tizen>
347         public short ReadShort()
348         {
349             Interop.LibRPCPort.Parcel.ReadInt16(_handle, out short b);
350             return b;
351         }
352
353         /// <summary>
354         /// Reads an int value from parcel object.
355         /// </summary>
356         /// <returns>int data.</returns>
357         /// <since_tizen> 5 </since_tizen>
358         public int ReadInt()
359         {
360             Interop.LibRPCPort.Parcel.ReadInt32(_handle, out int b);
361             return b;
362         }
363
364         /// <summary>
365         /// Reads a long value from parcel object.
366         /// </summary>
367         /// <returns>long data.</returns>
368         /// <since_tizen> 5 </since_tizen>
369         public long ReadLong()
370         {
371             Interop.LibRPCPort.Parcel.ReadInt64(_handle, out long b);
372             return b;
373         }
374
375         /// <summary>
376         /// Reads a float value from parcel object.
377         /// </summary>
378         /// <returns>float data.</returns>
379         /// <since_tizen> 5 </since_tizen>
380         public float ReadFloat()
381         {
382             Interop.LibRPCPort.Parcel.ReadFloat(_handle, out float b);
383             return b;
384         }
385
386         /// <summary>
387         /// Reads a double value from parcel object.
388         /// </summary>
389         /// <returns>double data.</returns>
390         /// <since_tizen> 5 </since_tizen>
391         public double ReadDouble()
392         {
393             Interop.LibRPCPort.Parcel.ReadDouble(_handle, out double b);
394             return b;
395         }
396
397         /// <summary>
398         /// Reads a string value from parcel object.
399         /// </summary>
400         /// <returns>string data.</returns>
401         /// <since_tizen> 5 </since_tizen>
402         public string ReadString()
403         {
404             Interop.LibRPCPort.Parcel.ReadString(_handle, out string b);
405             return b;
406         }
407
408         /// <summary>
409         /// Reads a bool value from parcel object.
410         /// </summary>
411         /// <returns>bool data.</returns>
412         /// <since_tizen> 5 </since_tizen>
413         public bool ReadBool()
414         {
415             Interop.LibRPCPort.Parcel.ReadBool(_handle, out bool b);
416             return b;
417         }
418
419         /// <summary>
420         /// Reads a Bundle value from parcel object.
421         /// </summary>
422         /// <returns>Bundle data.</returns>
423         /// <since_tizen> 5 </since_tizen>
424         public Bundle ReadBundle()
425         {
426             Interop.LibRPCPort.Parcel.ReadBundle(_handle, out IntPtr b);
427
428             return new Bundle(new SafeBundleHandle(b, true));
429         }
430
431         /// <summary>
432         /// Reads a count of an array from parcel object.
433         /// </summary>
434         /// <returns>Array count.</returns>
435         /// <since_tizen> 5 </since_tizen>
436         public int ReadArrayCount()
437         {
438             Interop.LibRPCPort.Parcel.ReadArrayCount(_handle, out int b);
439             return b;
440         }
441
442         /// <summary>
443         /// Writes bytes into parcel object.
444         /// </summary>
445         /// <param name="bytes">Array of bytes.</param>
446         /// <since_tizen> 5 </since_tizen>
447         public void Write(byte[] bytes)
448         {
449             Interop.LibRPCPort.Parcel.Write(_handle, bytes, bytes.Length);
450         }
451
452         /// <summary>
453         /// Reads bytes from parcel object.
454         /// </summary>
455         /// <param name="size">Bytes to read.</param>
456         /// <returns>Array of bytes.</returns>
457         /// <since_tizen> 5 </since_tizen>
458         public byte[] Read(int size)
459         {
460             var ret = new byte[size];
461             Interop.LibRPCPort.Parcel.Read(_handle, ret, size);
462             return ret;
463         }
464
465         /// <summary>
466         /// Gets header of rpc port parcel.
467         /// </summary>
468         /// <returns>Parcel header</returns>
469         /// <since_tizen> 9 </since_tizen>
470         public ParcelHeader GetHeader()
471         {
472             if (_header == null) {
473                 Interop.LibRPCPort.Parcel.GetHeader(_handle, out IntPtr handle);
474                 _header = new ParcelHeader() {
475                     _handle = handle
476                 };
477             }
478
479             return _header;
480         }
481
482         #region IDisposable Support
483         private bool disposedValue = false;
484
485         private void Dispose(bool disposing)
486         {
487             if (!disposedValue)
488             {
489                 if (disposing)
490                 {
491                 }
492
493                 if (_handle != IntPtr.Zero)
494                 {
495                     Interop.LibRPCPort.Parcel.Destroy(_handle);
496                     _handle = IntPtr.Zero;
497                 }
498
499                 disposedValue = true;
500             }
501         }
502
503         /// <summary>
504         /// Finalizer of the class Parcel.
505         /// </summary>
506         ~Parcel()
507         {
508             Dispose(false);
509         }
510
511         /// <summary>
512         /// Release all the resources used by the class Parcel.
513         /// </summary>
514         /// <since_tizen> 5 </since_tizen>
515         public void Dispose()
516         {
517             Dispose(true);
518             GC.SuppressFinalize(this);
519         }
520         #endregion
521     }
522 }