Splitted the project into multiple module level projects.
[platform/core/csapi/tizenfx.git] / src / Tizen.Multimedia.Metadata / MetadataEditor / MetadataEditor.cs
1 /*
2 * Copyright (c) 2016 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
18 using System;
19 using System.Runtime.InteropServices;
20
21 namespace Tizen.Multimedia
22 {
23     static internal class MetadataEditorLog
24     {
25         internal const string LogTag = "Tizen.Multimedia.MetadataEditor";
26     }
27
28     /// <summary>
29     /// The Metadata editor class provides a set of functions to edit the metadata of the media file
30     /// </summary>
31     /// <privilege>
32     /// If you want to access only internal storage,
33     /// you should add privilege http://tizen.org/privilege/mediastorage. \n
34     /// Or if you want to access only external storage,
35     /// you should add privilege http://tizen.org/privilege/externalstorage. \n
36     /// </privilege>
37     public class MetadataEditor : IDisposable
38     {
39         private bool _disposed = false;
40         private IntPtr _handle = IntPtr.Zero;
41
42         private IntPtr MetadataHandle
43         {
44             get
45             {
46                 if (_handle == IntPtr.Zero)
47                 {
48                     throw new ObjectDisposedException(nameof(MetadataEditor));
49                 }
50
51                 return _handle;
52             }
53         }
54
55         /// <summary>
56         /// Metadata extractor constructor
57         /// </summary>
58         /// <param name="path"> The path of the media file to edit metadata </param>
59         /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
60         /// <exception cref="OutOfMemoryException">Memory allocation failed.</exception>
61         /// <exception cref="NotSupportedException">Unsupported file type</exception>
62         /// <exception cref="FileNotFoundException">File not exist</exception>
63         public MetadataEditor(string path)
64         {
65             if (path == null)
66             {
67                 throw new ArgumentNullException(nameof(path));
68             }
69
70             MetadataEditorError ret = Interop.MetadataEditor.Create(out _handle);
71             MetadataEditorErrorFactory.ThrowIfError(ret, "Failed to create metadata");
72
73             try
74             {
75                 MetadataEditorErrorFactory.ThrowIfError(
76                     Interop.MetadataEditor.SetPath(MetadataHandle, path), "Failed to set path");
77             }
78             catch (Exception)
79             {
80                 Interop.MetadataEditor.Destroy(_handle);
81                 _handle = IntPtr.Zero;
82                 throw;
83             }
84         }
85
86         private string GetParam(MetadataEditorAttr attr)
87         {
88             IntPtr val = IntPtr.Zero;
89
90             try
91             {
92                 MetadataEditorError e = Interop.MetadataEditor.GetMetadata(MetadataHandle, attr, out val);
93                 MetadataEditorErrorFactory.ThrowIfError(e, "Failed to get metadata");
94
95                 return Marshal.PtrToStringAnsi(val);
96             }
97             finally
98             {
99                 Interop.Libc.Free(val);
100             }
101         }
102
103         private void SetParam(MetadataEditorAttr attr, string value)
104         {
105             MetadataEditorErrorFactory.ThrowIfError(
106                     Interop.MetadataEditor.SetMetadata(MetadataHandle, attr, value), "Fail to set value");
107         }
108
109         /// <summary>
110         /// Artist of media
111         /// </summary>
112         public string Artist
113         {
114             get
115             {
116                 return GetParam(MetadataEditorAttr.Artist);
117             }
118
119             set
120             {
121                 SetParam(MetadataEditorAttr.Artist, value);
122             }
123         }
124
125         /// <summary>
126         /// Title of media
127         /// </summary>
128         public string Title
129         {
130             get
131             {
132                 return GetParam(MetadataEditorAttr.Title);
133             }
134
135             set
136             {
137                 SetParam(MetadataEditorAttr.Title, value);
138             }
139         }
140
141         /// <summary>
142         /// Album name of media
143         /// </summary>
144         public string Album
145         {
146             get
147             {
148                 return GetParam(MetadataEditorAttr.Album);
149             }
150
151             set
152             {
153                 SetParam(MetadataEditorAttr.Album, value);
154             }
155         }
156
157         /// <summary>
158         /// Genre of media
159         /// </summary>
160         public string Genre
161         {
162             get
163             {
164                 return GetParam(MetadataEditorAttr.Genre);
165             }
166
167             set
168             {
169                 SetParam(MetadataEditorAttr.Genre, value);
170             }
171         }
172
173         /// <summary>
174         /// Author of media
175         /// </summary>
176         public string Author
177         {
178             get
179             {
180                 return GetParam(MetadataEditorAttr.Author);
181             }
182
183             set
184             {
185                 SetParam(MetadataEditorAttr.Author, value);
186             }
187         }
188
189         /// <summary>
190         /// Copyright of media
191         /// </summary>
192         public string Copyright
193         {
194             get
195             {
196                 return GetParam(MetadataEditorAttr.Copyright);
197             }
198
199             set
200             {
201                 SetParam(MetadataEditorAttr.Copyright, value);
202             }
203         }
204
205         /// <summary>
206         /// Date of media
207         /// </summary>
208         /// <remarks>
209         /// If the added media contains ID3 tag, This parameter refers to the recording time.
210         /// If the added media is a mp4 format, This parameter refers to the year.
211         /// </remarks>
212         public string Date
213         {
214             get
215             {
216                 return GetParam(MetadataEditorAttr.Date);
217             }
218
219             set
220             {
221                 SetParam(MetadataEditorAttr.Date, value);
222             }
223         }
224
225         /// <summary>
226         /// Description of media
227         /// </summary>
228         public string Description
229         {
230             get
231             {
232                 return GetParam(MetadataEditorAttr.Description);
233             }
234
235             set
236             {
237                 SetParam(MetadataEditorAttr.Description, value);
238             }
239         }
240
241         /// <summary>
242         /// Comment of media
243         /// </summary>
244         public string Comment
245         {
246             get
247             {
248                 return GetParam(MetadataEditorAttr.Comment);
249             }
250
251             set
252             {
253                 SetParam(MetadataEditorAttr.Comment, value);
254             }
255         }
256
257         /// <summary>
258         /// Track number of media
259         /// </summary>
260         public string TrackNumber
261         {
262             get
263             {
264                 return GetParam(MetadataEditorAttr.TrackNumber);
265             }
266
267             set
268             {
269                 SetParam(MetadataEditorAttr.TrackNumber, value);
270             }
271         }
272
273         /// <summary>
274         /// Album art count of media
275         /// </summary>
276         public string PictureCount
277         {
278             get
279             {
280                 return GetParam(MetadataEditorAttr.PictureCount);
281             }
282         }
283
284         /// <summary>
285         /// Conductor of media
286         /// </summary>
287         public string Conductor
288         {
289             get
290             {
291                 return GetParam(MetadataEditorAttr.Conductor);
292             }
293
294             set
295             {
296                 SetParam(MetadataEditorAttr.Conductor, value);
297             }
298         }
299
300         /// <summary>
301         /// Unsynchronized lyric of media
302         /// </summary>
303         public string UnsyncLyrics
304         {
305             get
306             {
307                 return GetParam(MetadataEditorAttr.UnsyncLyrics);
308             }
309
310             set
311             {
312                 SetParam(MetadataEditorAttr.UnsyncLyrics, value);
313             }
314         }
315
316         /// <summary>
317         /// Writes the modified metadata to a media file
318         /// </summary>
319         /// <exception cref="InvalidOperationException"> When internal process error is occured</exception>
320         public void Commit()
321         {
322             MetadataEditorErrorFactory.ThrowIfError(
323                 Interop.MetadataEditor.UpdateMetadata(MetadataHandle), "Failed to update file");
324         }
325
326         /// <summary>
327         /// Gets the artwork image in a media file
328         /// </summary>
329         /// <param name="index"> Index of picture to import </param>
330         /// <returns> Artwork included in the media file</returns>
331         /// <exception cref="InvalidOperationException"> When internal process error is occured</exception>
332         /// <exception cref="ArgumentOutOfRangeException"> Wrong index number </exception>
333         public Artwork GetPicture(int index)
334         {
335             if (index < 0)
336             {
337                 throw new ArgumentOutOfRangeException("Index should be larger than 0 [" + index + "]");
338             }
339
340             IntPtr data = IntPtr.Zero;
341             int size;
342             IntPtr mimeType = IntPtr.Zero;
343
344             try
345             {
346                 MetadataEditorErrorFactory.ThrowIfError(
347                     Interop.MetadataEditor.GetPicture(MetadataHandle, index, out data, out size, out mimeType), "Failed to get the value");
348
349                 if (size > 0)
350                 {
351                     byte[] tmpBuf = new byte[size];
352                     Marshal.Copy(data, tmpBuf, 0, size);
353
354                     return new Artwork(tmpBuf, Marshal.PtrToStringAnsi(mimeType));
355                 }
356
357                 return null;
358             }
359             finally
360             {
361                 if (data != IntPtr.Zero)
362                 {
363                     Interop.Libc.Free(data);
364                 }
365
366                 if (mimeType != IntPtr.Zero)
367                 {
368                     Interop.Libc.Free(mimeType);
369                 }
370             }
371         }
372
373         /// <summary>
374         /// Append the picture to the media file
375         /// </summary>
376         /// <param name="path"> The path of picture for adding to the metadata </param>
377         /// <exception cref="InvalidOperationException"> When internal process error is occured</exception>
378         /// <exception cref="ArgumentNullException"> Picture path is null</exception>
379         public void AddPicture(string path)
380         {
381             if (path == null)
382             {
383                 throw new ArgumentNullException(nameof(path));
384             }
385
386             MetadataEditorErrorFactory.ThrowIfError(
387                 Interop.MetadataEditor.AddPicture(MetadataHandle, path), "Failed to append picture");
388         }
389
390         /// <summary>
391         /// Remove the picture from the media file
392         /// </summary>
393         /// <param name="index"> Index of picture to remove </param>
394         /// <exception cref="InvalidOperationException"> When internal process error is occured</exception>
395         /// <exception cref="ArgumentOutOfRangeException"> Wrong index number </exception>
396         public void RemovePicture(int index)
397         {
398             if (index < 0)
399             {
400                 throw new ArgumentOutOfRangeException("Index should be larger than 0 [" + index + "]");
401             }
402
403             MetadataEditorErrorFactory.ThrowIfError(
404                 Interop.MetadataEditor.RemovePicture(MetadataHandle, index), "Failed to remove picture");
405         }
406
407         /// <summary>
408         /// Metadata Editor destructor
409         /// </summary>
410         ~MetadataEditor()
411         {
412             Dispose(false);
413         }
414
415         protected virtual void Dispose(bool disposing)
416         {
417             if (!_disposed)
418             {
419                 if (disposing)
420                 {
421                     // To be used if there are any other disposable objects
422                 }
423
424                 if (_handle != IntPtr.Zero)
425                 {
426                     Interop.MetadataEditor.Destroy(_handle);
427                     _handle = IntPtr.Zero;
428                 }
429
430                 _disposed = true;
431             }
432         }
433
434         public void Dispose()
435         {
436             Dispose(true);
437             GC.SuppressFinalize(this);
438         }
439     }
440 }