aboutsummaryrefslogtreecommitdiff
path: root/fileformats/id3parcom/include/pv_id3_parcom.h
blob: 81e55712564538f7a7534bf69faae25ebefb2874 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
/* ------------------------------------------------------------------
 * Copyright (C) 1998-2010 PacketVideo
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 * -------------------------------------------------------------------
 */
/**
 * @file pv_id3_parcom.h
 * @brief ID3 tag parser-composer utility
 */

#ifndef PV_ID3_PARCOM_H_INCLUDED
#define PV_ID3_PARCOM_H_INCLUDED

#ifndef OSCL_BASE_H_INCLUDED
#include "oscl_base.h"
#endif
#ifndef OSCL_STRING_H_INCLUDED
#include "oscl_string.h"
#endif
#ifndef OSCL_MEM_H_INCLUDED
#include "oscl_mem.h"
#endif
#ifndef OSCL_STRING_CONTAINERS_H_INCLUDED
#include "oscl_string_containers.h"
#endif
#ifndef OSCL_VECTOR_H_INCLUDED
#include "oscl_vector.h"
#endif
#ifndef OSCL_REFCOUNTER_MEMFRAG_H_INCLUDED
#include "oscl_refcounter_memfrag.h"
#endif
#ifndef OSCL_SHARED_PTR_H_INCLUDED
#include "oscl_shared_ptr.h"
#endif
#ifndef PVMI_KVP_INCLUDED
#include "pvmi_kvp.h"
#endif
#ifndef PVMF_META_DATA_H_INCLUDED
#include "pvmf_meta_data_types.h"
#endif
#ifndef PVFILE_H_INCLUDED
#include "pvfile.h"
#endif
#ifndef PVMF_RETURN_CODES_H_INCLUDED
#include "pvmf_return_codes.h"
#endif
#ifndef PV_ID3_PARCOM_TYPES_H_INCLUDED
#include "pv_id3_parcom_types.h"
#endif
#ifndef OSCL_STRING_UTILS_H_INCLUDED
#include "oscl_string_utils.h"
#endif
#ifndef OSCL_UTF8CONV_H
#include "oscl_utf8conv.h"
#endif
#ifndef PV_ID3_PARCOM_CONSTANTS_H_INCLUDED
#include "pv_id3_parcom_constants.h"
#endif
#ifndef PVMF_GAPLESS_METADATA_H_INCLUDED
#include "pvmf_gapless_metadata.h"
#endif

/** Forward declaration */
class PVLogger;

/**
 * PVID3ParCom is an ID3 Tag parser-composer utility. This utiltiy allows user to parse an ID3 tag
 * to retrieve tag information, modify an existing ID3 tag and compose a new ID3 tag.
 */
class PVID3ParCom
{
    public:
        /** Default constructor */
        OSCL_IMPORT_REF PVID3ParCom();

        /** Destructor */
        OSCL_IMPORT_REF ~PVID3ParCom();

        /**
         * @brief Checks the file for the presence of ID3V2 Tags.
         *
         * This function checks the file for the presence of ID3V2 Tag
         * This tag is  denoted by the string "ID3" at the begining of file.
         * This method also reads the Id3 tag size from the file and returns
         * to the caller.
         *
         * @returns True if Id3V2 tag present otherwise False
         * @ aTagSize: size of the ID3 tag, if present, -1 if corrupted, else 0
         */
        OSCL_IMPORT_REF bool IsID3V2Present(PVFile* aFile, int32& aTagSize);

        /**
         * Gets size of ID3 tag in the specified file without parsing the entire tag for its data.
         *
         * @param aFile File handle of the file containing the ID3 tag
         * @return Size of ID3 tag. Returns 0 if ID3 tag is not found.
         */
        OSCL_IMPORT_REF uint32 GetID3TagSize(PVFile* aFile);

        /**
         * Gets size of ID3 tag in a memory fragment without parsing the entire tag for its data.
         *
         * @param aTag Memory fragment containing the ID3 tag
         * @return Size of ID3 tag. Returns 0 if ID3 tag is not found.
         */
        OSCL_IMPORT_REF uint32 GetID3TagSize(const OsclMemoryFragment& aTag);
        /**
         * Gets the size of a parsed ID3 tag.
         *
         * @return Size of ID3 tag.  Returns 0 if called before an ID3 tag is parsed by ParseID3Tag() call.
         */
        OSCL_IMPORT_REF uint32 GetID3TagSize();

        /**
         * Sets the maximum size of a composed ID3 tag. It is an option to pad the composed ID3 tag
         * to the specified maximum size.  If the composed ID3 tag exceeds the maximum size, one
         * or more ID3 frames data will be truncated.  This API is applicable only for ID3V2 tags.
         *
         * @param aUseMaxSize When set to true, the composed ID3 tag will have a maximum size of
         *                    aMaxSize.  When set to false, the tag will not have a maximum size.
         *                    By default, maximum tag size is disabled by this library.
         * @param aMaxSize Maximum size of the composed ID3 tag in bytes
         * @param aUsePadding When set to true, the composed ID3 tag will be padded to the
         *                    specified maximum size.
         * @return Completion status. Returns PVMFErrNotSupported if ID3V1 is used.
         */
        OSCL_IMPORT_REF PVMFStatus SetMaxID3TagSize(bool aUseMaxSize, uint32 aMaxSize, bool aUsePadding);

        /**
         * Parse an ID3 tag from the specified file.
         *
         * @param aFile File handle of the file containing the ID3 tag to be parsed
         * @return Completion status. If no ID3 tag is found in the file, PVMFFailure is returned.
         */
        OSCL_IMPORT_REF PVMFStatus ParseID3Tag(PVFile* aFile, uint32 buffsize = 100);

        /**
         * Parse an ID3 tag from the specified memory fragment.
         *
         * @param aTag Memory fragment containing the ID3 tag to be parsed
         * @return Completion status. If no ID3 tag is found in the memory fragment, PVMFFailure is returned.
         */
        OSCL_IMPORT_REF PVMFStatus ParseID3Tag(const OsclMemoryFragment& aTag);

        /**
         * Query the version of ID3 used for this tag.
         *
         * @return ID3 version of the tag.
         */
        OSCL_IMPORT_REF PVID3Version GetID3Version() const;

        /**
         * Query if id3v1 present in the clip.
         *
         * @return true if present
         */
        OSCL_IMPORT_REF bool IsID3V1Present() const;

        /**
         * Query if id3v2 present in the clip.
         *
         * @return true if present
         */
        OSCL_IMPORT_REF bool IsID3V2Present() const;

        /**
         * Retrieve a vector of key-value pairs containing data of all ID3 frames in the ID3 tag.
         *
         * @param aFrames Output parameter to store key-value pairs containing data of ID3 frames from the tag.
         * @return Status of completion.
         */
        OSCL_IMPORT_REF PVMFStatus GetID3Frames(PvmiKvpSharedPtrVector& aFrames);

        /**
         * Retrieve an ID3 frame of the specified type in the ID3 tag.
         *
         * @param aFrameType Type of ID3 frame to be retrieved
         * @param aFrame Output parameter to store key-value pair containing data of requested ID3 frame.
         * @return Status of completion. Returns PVMFFailure if a frame of the specified
         *         type is not found.
         */
        OSCL_IMPORT_REF PVMFStatus GetID3Frame(const OSCL_String& aFrameType, PvmiKvpSharedPtrVector& aFrame);

        /**
        *   Check if frame of aFrameType is available
        * @param aFrameType Type of ID3 frame
        * @return true if frame is available otherwise false
        */
        OSCL_IMPORT_REF bool IsID3FrameAvailable(const OSCL_String& aFrameType);

        /**
         * Sets ID3 version to be used.
         *
         * When composing a new ID3 tag, the default ID3 version is v2.4. When modifying
         * an existing ID3 tag, if it is ID3v2.x and is changed to ID3v1.x, ID3 frames
         * that are not supported by ID3v1.x will be removed from the tag and data strings
         * will be trimmed to the maximum lengths specified in ID3v1.x.
         *
         * @param aVersion ID3 version.
         * @return Status of completion.
         */
        OSCL_IMPORT_REF PVMFStatus SetID3Version(PVID3Version aVersion);

        /**
         * Sets an ID3 frame in the ID3 tag.
         *
         * If the frame does not already exist, a new frame will be created and added
         * to the tag.  If a frame of the same type already exists, the frame data will
         * be updated and saved to the tag.
         *
         * @param aFrame ID3 frame to be set in the tag.
         * @return Status of completion.
         */
        OSCL_IMPORT_REF PVMFStatus SetID3Frame(const PvmiKvp& aFrame);

        /**
         * Removes an ID3 frame of the specified type in the ID3 tag.
         *
         * @param aFrameType Type of ID3 frame to be removed.
         * @return Completion status. Returns PVMFFailure if ID3 frame of the specified type
         *         is not found in the tag.
         */
        OSCL_IMPORT_REF PVMFStatus RemoveID3Frame(const OSCL_String& aFrameType);

        /**
         * Compose an ID3 tag and return a shared pointer to the formatted tag to user.
         *
         * ID3 tag is composed using ID3 frames that are set for the tag.  Data strings in ID3 frames are
         * converted from Unicode to the character set specified in the frame when composing the tag.
         * The tag is formatted to the specified ID3 version and written to the memory fragment provided
         * by user.  This method will erase all data from the memory fragment before writing the ID3 tag.
         * If the memory fragment does not contain allocated memory or the capacity of fragment is less
         * than the size of ID3 tag to be written, this method would allocate memory before writing the ID3
         * tag. There must be at least one valid ID3 frame assoicated to the tag to compose successfully.
         *
         * When composing a new ID3 tag (i.e. not editing an existing tag), if no ID3 version is specified
         * through SetID3Version(), it is defaulted to ID3 v2.4.
         *
         * @param aTag Output parameter of memory fragment to which the formatted ID3 tag data will be written.
         * @return Completion status.  Returns PVMFFailure if no ID3 frame is associated with this tag.
         */
        OSCL_IMPORT_REF PVMFStatus ComposeID3Tag(OsclRefCounterMemFrag& aTag);

        /**
         * Reset the parser-composer and remove all ID3 frames.
         *
         * @return Completion status.
         */
        OSCL_IMPORT_REF PVMFStatus Reset();

        /**
         * This function returns byte offset to the end of id3 tag. Audio frame follows ID3 tag.
         *
         * @return byte offset to end of id3 tag.
         */

        OSCL_IMPORT_REF int32 GetByteOffsetToStartOfAudioFrames()
        {
            return iByteOffsetToStartOfAudioFrames;
        }

        /**
         * This function looks for ID3 V2.4 tag at the end of file.
         * It will look for ID3 footer starting from the offset till buff_sz. If footer is found, it will get the
         * id3 tag size from the footer header and parse ID3 tag.
         * @param buff_sz size of the buffer to look for footer
         * @param offset in file from the end of file. e.g An offset of 0 means end of file
         * @return Comletion status.
         */

        OSCL_IMPORT_REF PVMFStatus LookForV2_4Footer(uint32 buff_sz, uint32 offset);
        /**
         * This function will look for ID3 footer starting from the offset till buff_sz.
         * @param buff_sz size of the buffer to look for footer
         * @param offset in file from the end of file. e.g An offset of 0 means end of file
         * @return footer location in file otherwise 0 if no footer is found
         */

        uint32 SearchTagV2_4(uint32 buff_sz, uint32 offset);

        /**
         * Retrieves the gapless metadata, if present
         *
         * @param aGaplessMetadata Output parameter to store the gapless metadata
         * @return Status of operation
         */
        OSCL_IMPORT_REF PVMFStatus GetGaplessMetadata(PVMFGaplessMetadata& aGaplessMetadata);

    public:
        /** Enumerated list of supported character sets */
        typedef enum
        {
            PV_ID3_CHARSET_INVALID = -1,
            PV_ID3_CHARSET_ISO88591 = 0,
            PV_ID3_CHARSET_UTF16    = 1,
            PV_ID3_CHARSET_UTF16BE  = 2,
            PV_ID3_CHARSET_UTF8     = 3,
            PV_ID3_CHARSET_END      = 4,
        } PVID3CharacterSet;

    private:
        /** Enumerated list of ID3 Frame Types */
        typedef enum
        {
            PV_ID3_FRAME_INVALID = -3,
            PV_ID3_FRAME_CANDIDATE,     /**< Frame ID doesn't match with known frame IDs.
                                         The frame ID made out of the characters capital A-Z and 0-9.*/
            PV_ID3_FRAME_UNRECOGNIZED,  /** Valid frame ID, but ID3 parcom doesn't support. */
            PV_ID3_FRAME_TITLE,         /**< Title. Supported by all ID3 versions. Maximum 30 characters for
                                         ID3v1.x. There is no maximum length limit for ID3v2.x. */
            PV_ID3_FRAME_ARTIST,        /**< Artist. Supported by all ID3 versions. Maximum 30 characters for
                                         ID3v1.x. There is no maximum length limit for ID3v2.x*/
            PV_ID3_FRAME_ALBUM,         /**< Album. Supported by all ID3 versions. Maximum 30 characters for
                                         ID3v1.x. There is no maximum length limit for ID3v2.x */
            PV_ID3_FRAME_YEAR,          /**< 4-character numeric string with the year of the recording.
                                         Supported by all ID3 version. */
            PV_ID3_FRAME_COMMENT,       /**< Comment. Supported by all ID3 versions. Maximum 30 characters for
                                         ID3v1.x. There is no maximum length limit for ID3v2.x. */
            PV_ID3_FRAME_TRACK_NUMBER,  /**< Numeric string of track number on Album. Supported by ID3v1.1 and later. */
            PV_ID3_FRAME_GENRE,         /**< Genre of the music. For ID3v1.x, numeric string of genre type value
                                         defined at http://www.id3.org/id3v2.3.0.html#secA should be used.
                                         ID3v2.x should use the genre name, or refer to ID3v1.x genre type
                                         using the format "(genre_number)" where genre_number is a numeric
                                         string of ID3v1.x genre type value. */
            PV_ID3_FRAME_COPYRIGHT,      /**< Copyright message. It must begin with a 4-character numeric string of
                                         the year of copyright and a space character. Supported by ID3v2.x or later. */
            PV_ID3_FRAME_TRACK_LENGTH,   /**< Track length. The duration in milliseconds.*/
            PV_ID3_FRAME_DATE,
            PV_ID3_FRAME_PADDED,         /**< Padding. A frame padded with zero.*/

            PV_ID3_FRAME_PIC,            /**< PIC. */
            PV_ID3_FRAME_APIC,           /**< APIC.*/
            PV_ID3_FRAME_LYRICS,             /**< Unsynchronized Lyrics.*/
            PV_ID3_FRAME_SEEK,           /* For SEEK frame */
            PV_ID3_FRAME_RECORDING_TIME,  /* RECORDING TIME */
            PV_ID3_FRAME_AUTHOR,          /* author or writer*/
            PV_ID3_FRAME_COMPOSER,        /* music composer */
            PV_ID3_FRAME_DESCRIPTION,     /* brief description of the content */
            PV_ID3_FRAME_VERSION,         /* Software version of the authoring software */
            PV_ID3_FRAME_PART_OF_SET,     /* Which part of a set this belongs to */

            PV_ID3_FRAME_EEND            /**< End. Marks end of frames.*/
        } PVID3FrameType;

        /**
         *  @brief The TID3TagInfo class acts as temporary storage for information
         *  extracted from the different types of ID3 tags to a given ID3tag file. This
         *  class is created to keep track of certain qualities of an ID3 tag that
         *  the caller of the ID3 library would not need to know.
         */
        struct TID3TagInfo
        {
            uint32      iPositionInFile;
            PVID3CharacterSet iTextType;

            uint32    iID3V2FrameSize;
            uint32    iID3V2SeekOffset;
            uint8     iID3V2TagFlagsV2;
            uint32    iID3V2ExtendedHeaderSize;
            uint32    iID3V2TagSize;
            uint8     iID3V2FrameID[5];
            uint8     iID3V2FrameFlag[2];
            bool      iFooterPresent;
            uint8     iID3V2LanguageID[4];

        };

        /**
         * @brief The TGaplessInfo is a struct for temporary storage for gapless information
         * extracted from the COM/COMM frames.
         */
        struct TGaplessInfo
        {
            uint32 iEncoderDelay;
            uint32 iZeroPadding;
            uint64 iOriginalLength;
            bool iPartOfGaplessAlbum;
        };

        /**
         * @brief Checks the ID3 Tag v2.4 frame size whether it is syncsafe or not.
         *
         * This function validates next ID3 frame to check whether frame size is
         * syncsafe.
         *
         * @returns Validated frame size
         */
        uint32 ValidateFrameLengthV2_4(uint32 aFrameSize);

        /**
         * @brief Checks the ID3 Tag v2.4 frame is valid or not.
         *
         * This function validates ID3 frame type and then, frame size and flags
         *
         * @params
         * [IN] bUseSyncSafeFrameSize - validate syncsafe/non-syncsafe frame size
         * [OUT] frameType - frame type for frame currently validated
         *
         * @returns validation status
         */
        bool ValidateFrameV2_4(PVID3FrameType& frameType, bool bUseSyncSafeFrameSize = true);

        /**
         * @brief Checks the file for the presence of ID3V1 Tag.
         *
         * This function checks the file for the presence of ID3V1 Tag. This tag is
         * denoted by the string "TAG" starting 128 bytes in from the end-of-file.
         *
         * @returns True if Id3V1 tag present otherwise False
         */
        bool CheckForTagID3V1();

        /**
         * @brief Checks the file for the presence of ID3V2 Tag attached to
         * the beginning of the ID3tag file.
         *
         * This function checks the file for the presence of ID3V2 Tag attached to
         * the beginning of the ID3 file. This tag is  denoted by the string "ID3"
         * at the very beginning of the ID3 file.
         *
         * @returns True if Id3V2 tag present otherwise False
         */
        bool CheckForTagID3V2();

        /**
         * @brief Parses the file and populates the frame vector when an ID3V1
         * tag is found and no ID3V2 tag was found.
         *
         * This function parses the file and populates the frame vector when
         * an ID3V1 tag is found to be attached to the ID3 file and no ID3V2 tag was
         * found. The data in the ID3V1 tag can only be ASCII, so the ConvertToUnicode
         * must be called for all fields read from the ID3V1 tag.
         *
         * @param None
         * @returns None
         */
        void ReadID3V1Tag();

        /**
         * @brief reads id3 V2 tag header.
         * @param aReadTags, read the id3 frames when true, else just reads the header
         * @@returns true if tags were read successfully
         */
        bool ReadHeaderID3V2(bool aReadTags = true);

        /**
         * @brief Parses the ID3V2 tag frames from the file and populates the
         * frame vector when an ID3V2 tag is found
         * @param version ID3 V2 sub version number (v2.2, v2.3 or v2.4)
         * * @returns number of tags successfully parsed
         */
        int ReadTagID3V2(PVID3Version version);

        /**
         * @brief Parses the frame and populates the iID3TagInfo structure
         * when an ID3V2 tag is found.
         *
         * This function parses the ID3 tag frames from the file and populates the
         * frame vector when an ID3V2 tag is found attached to the start
         * of a ID3 file.
         *
         * @param version ID3 V2 sub version number (v2.2, v2.3 or v2.4)
         * @returns None
         */
        void ReadFrameHeaderID3V2(PVID3Version version);

        /**
        * @brief Parses the frame and populates the iID3TagInfo structure
        * when an ID3V2_2 tag is found.
        *
        * This function parses the ID3 tag frames from the file and populates the
        * frame vector when an ID3V2_2 tag is found attached to the start
        * of a ID3 file.
        *
        * @param None
        * @returns None
        */
        void ReadFrameHeaderID3V2_2();

        /**
         * @brief Receives a ID3V2 frame and handles it accordingly. All of the frames
         * sent to this function have ASCII strings in them.
         *
         * This function receives a ID3V2 frame and handles it accordingly. Each
         * frame header is composed of 10 bytes - 4 bytes for FrameID, 4 bytes for
         * FrameSize, and 2 bytes for FrameFlags, respectively. Once we have a
         * frame's unique FrameID, we can handle the frame accordingly. (eg. The
         * frame with FrameID = "TIT2" contains data describing the title of an ID3
         * file. Clearly, the data in that frame should be copied to it respective
         * location in frame vector. The location for the data with FrameID = "TIT2"
         * goes in the Title frame.
         *
         * @param aFrameType Enumerated TFrameTypeID3V2 type; used to determine if
         * Frame is supported
         * @param aPos Position in file where frame data begins
         * @param aSize Size of the frame data
         * @returns None
         */
        void HandleID3V2FrameDataASCII(PVID3FrameType aframeType,
                                       uint32 aPos,
                                       uint32 aSize);

        /**
         * @brief Receives a ID3V2 frame and handles it accordingly. All of the frames
         * sent to this function have unicode strings in them.
         *
         * This function receives a ID3V2 frame and handles it accordingly. Each
         * frame header is composed of 10 bytes - 4 bytes for FrameID, 4 bytes for
         * FrameSize, and 2 bytes for FrameFlags, respectively. Once we have a
         * frame's unique FrameID, we can handle the frame accordingly. (eg. The
         * frame with FrameID = "TIT2" contains data describing the title of an ID3
         * file. Clearly, the data in that frame should be copied to it respective
         * location in Frame vector. The location for the data with FrameID = "TIT2"
         * goes in the Title frame.iTitle buffer. All of the frames
         * sent to this function have unicode strings in them that will need to be
         * read different than the ASCII strings.
         *
         * @param aFrameType Enumerated TFrameTypeID3V2 type; used to determine if
         * Frame is supported
         * @param aPos Position in file where frame data begins
         * @param aSize Size of the frame data
         * @param aEndianType Flag indicator regarding the text endian type
         * @returns None
         */
        void HandleID3V2FrameDataUnicode16(PVID3FrameType aframeType,
                                           uint32 aPos,
                                           uint32 aSize,
                                           uint32 aEndienType);

        /**
         * @brief Receives a ID3V2 frame and handles it accordingly. All of the frames
         * sent to this function have UTF8 strings in them.
         *
         * This function receives a ID3V2 frame and handles it accordingly. Each
         * frame header is composed of 10 bytes - 4 bytes for FrameID, 4 bytes for
         * FrameSize, and 2 bytes for FrameFlags, respectively. Once we have a
         * frame's unique FrameID, we can handle the frame accordingly. (eg. The
         * frame with FrameID = "TIT2" contains data describing the title of an ID3
         * file. Clearly, the data in that frame should be copied to it respective
         * location in Frame vector. The location for the data with FrameID = "TIT2"
         * goes in the Title frame. All of the frames sent to this function have UTF8
         * strings in them that will need to be read different than the ASCII strings.
         *
         * @param aFrameType Enumerated TFrameTypeID3V2 type; used to determine if
         * Frame is supported
         * @param aPos Position in file where frame data begins
         * @param aSize Size of the frame data
         * @returns None
         */
        void HandleID3V2FrameDataUTF8(PVID3FrameType aframeType,
                                      uint32 aPos,
                                      uint32 aSize);


        /**
         * @brief This function handls id3 frames that are not currently supported by
         * the id3parcom library. It stores the frame alongwith the header as it is read from the file.
         * @param aFrameType Enumerated TFrameTypeID3V2 type; It will be PV_ID3_FRAME_UNSUPPORTED
         * @param aPos Position in file where frame data begins
         * @param aSize Size of the frame data
         * @returns None
         */

        void HandleID3V2FrameUnsupported(PVID3FrameType aframeType,
                                         TOsclFileOffset aPos,
                                         uint32 aSize);

        /**
         * @brief Detects the ID3V2FrameType and returns the enum value that
         * corresponds to the current frame.
         *
         * @param None
         * @returns Value that describes the current frame of type PVID3FrameType
         */
        PVID3FrameType FrameSupportedID3V2(PVID3Version version, uint8* aframeid = NULL);

        /**
         * @brief Detects the ID3V2FrameType and fine whether it us unsupported or
         * invalid frame type.
         *
         * @param None
         * @returns Value that describes the current frame of type PVID3FrameType
         */
        PVID3FrameType FrameValidatedID3V2_4(uint8* aFrameID);

        /**
         * @brief Detects the ID3V 2.2 FrameType and returns the enum value that
         * corresponds to the current frame.
         *
         * @param None
         * @returns Value that describes the current frame of type PVID3FrameType
         */
        PVID3FrameType FrameSupportedID3V2_2(void);

        /**
         * @brief Converts the data in the TBuf8 buffer and puts the data into the
         * TBuf16 buffer
         *
         * @param aPtrFrameData8 Pointer to intput string format of either big
         * or little endian.
         * @param aSize Number of character elements in aPtrFrameData8
         * @param aEndianType Indicates if the encoded Unicode text in the
         * aPtrFrameData8 buffer is in big or little endian.
         * @param aPtrFrameData16 Pointer to the output string in unicode format.
         * @returns None
         */
        uint32 EightBitToWideCharBufferTransfer(const uint8* aPtrFrameData,
                                                uint32 aSize,
                                                uint32 aEndianType,
                                                oscl_wchar* aPtrFrameData16);


        //convert an interger to Synchsafe integer
        uint32 ConvertToSyncSafeInt(uint32 src);
        uint32 SafeSynchIntToInt32(uint32 SafeSynchInteger);

        /**
         * @brief Read in byte data and take most significant byte first
         *
         * @param aInputFile File handle to input file
         * @param data Reference to output data buffer where the data read from file will be stored
         * @return true if the read is successful
         */
        bool readByteData(PVFile* aInputFile, uint32 length, uint8 *data);

        /**
         * @brief Read in the 32 bits byte by byte and take most significant byte first
         *
         * @param aInputFile File handle to input file
         * @param data Reference to output data buffer where the data read from file will be stored
         * @return true if the read is successful
         */
        bool read32(PVFile* aInputFile, uint32 &data);

        /**
         * @brief Read in the 24 bits byte by byte and take most significant byte first
         *
         * @param aInputFile File handle to input file
         * @param data Reference to output data buffer where the data read from file will be stored
         * @return true if the read is successful
         */
        bool read24(PVFile* aInputFile, uint32 &data);

        /**
         * @brief Read in 8 bytes from specified input file
         *
         * @param aInputFile File handle to input file
         * @param data Reference to output data buffer where the data read from file will be stored
         * @return true if the read is successful
         */
        bool read8(PVFile* aInputFile, uint8 &data);

        /**
         * @brief Read in 16 bytes from specified input file
         *
         * @param aInputFile File handle to input file
         * @param data Reference to output data buffer where the data read from file will be stored
         * @return true if the read is successful
         */

        bool read16(PVFile* aInputFile, uint16 &data);

        /**
         * @breif reads information stored in id3 frame
         * @param unicode tells if the data is unicode
         * @param frameType type of frame
         * @param pos position in file
         * @param currFrameLength length of the frame
         */
        bool  ReadFrameData(uint8 unicode, PVID3FrameType frameType, TOsclFileOffset pos, uint32 currFrameLength);
        /**
         * @brief reads extended header if present in id3 tag header
         * @param none
         * @return true if success.
         */
        bool ReadExtendedHeader();

        /**
         * @brief allocate memeory for key value pair structure.
         * @param aKey key string
         * @param aValueType type of key value
         * @param aValueSize size of key value
         * @param truncate bool type indicates if the frame was truncated.
         * @return shared pointer to key value pair structure
         */
        PvmiKvpSharedPtr AllocateKvp(OSCL_String& aKey, PvmiKvpValueType aValueType, uint32 aValueSize, bool &truncate);

        /**
         * @brief forms key string for id3 frames
         * @param aKey key string
         * @param aType frame type
         * @param aCharSet text encoding type (unicode, ascii)
         * @return Completion status
         */
        PVMFStatus ConstructKvpKey(OSCL_String& aKey, PVID3FrameType aType, PVID3CharacterSet aCharSet);

        /**
         * @brief reads string data in frames
         * @param aFrameType frame type
         * @param aCharSet text encoding
         * @param aValueSize size of the frame data
         * @return Completion status
         */
        PVMFStatus ReadStringValueFrame(PVID3FrameType aFrameType, PVID3CharacterSet aCharSet, uint32 aValueSize);

        /**
         * @brief reads frame of type track length
         * @param aValueSize size of the frame
         * @param aCharSet text encoding
         * @return completion status
         */
        PVMFStatus ReadTrackLengthFrame(uint32 aValueSize, PVID3CharacterSet aCharSet);

        /**
         * @brief reads ID3 frames
         * @param aFrameType frame type
         * @param aValueSize size of the frame data
         * @return Completion status
         */

        PVMFStatus ReadFrame(PVID3FrameType aFrameType, uint32 aValueSize);


        /**
         * @brief This function is costructing the key-value pair for AlbumArt(apic/pic) frame. It
         * first converts the AlbumArt frame in to the PvmfApicStruct and then set the
         * key_specific_value of the Pvmikvp struct.
         * @param frame type
         * @param unicode
         * @param frame size
         * @return Success if read successfull.
         */
        PVMFStatus ReadAlbumArtFrame(PVID3FrameType aFrameType, uint8 unicode, uint32 aFrameSize);

        /**
         * @brief This function extracts the albumart information, for ascii data, based on frametype (apic/pic).
         * @param frame type
         * @param frame size
         * @param Image format
         * @param description
         * @param picture type
         * @param data length
         * @return Success if conversion is successfull.
            */
        PVMFStatus GetAlbumArtInfo(PVID3FrameType aFrameType, uint32 aFrameSize, OSCL_HeapString<OsclMemAllocator> &ImageFormat,
                                   uint8 &PicType, OSCL_HeapString<OsclMemAllocator> &Description,  uint32 &DataLen);
        /**
         * @brief This function extracts the albumart information, for unicode data, based on frametype (apic/pic).
         * @param frame type
         * @param frame size
         * @param Image format
         * @param description
         * @param picture type
         * @param data length
         * @return Success if conversion is successfull.
         */
        PVMFStatus GetAlbumArtInfo(PVID3FrameType aFrameType, uint32 aFrameSize, OSCL_HeapString<OsclMemAllocator> &ImageFormat,
                                   uint8 &PicType, OSCL_wHeapString<OsclMemAllocator> &aDescription, uint32 &DataLen);



        /**
         * @brief This function does the actual conversion from the raw ascii data from the
         * GetAlbumArtInfo function to the PvmfApicStruct.
         * @param MimeType
         * @param Description
         * @param GraphicType
         * @param GraphicDataLen
         * @param pointer to memory allocated to store kvp information
         * @return Success if conversion is successfull.
         */
        PVMFStatus ConvertUnicodeDataToApic(char* aMimeTypeID3, oscl_wchar* aDescriptionID3,
                                            uint8 aGraphicType, uint32 aGraphicDataLen,
                                            void *key_specific_value, uint32 total_size);

        /**
         * @brief This function does the actual conversion from the raw unicode data from the
         * ConvertPictureToAPIC function to the PvmfApicStruct.
         * @param MimeType
         * @param Description
         * @param GraphicType
         * @param GraphicOffset
         * @param GraphicDataLen
         * @param pointer to memory allocated to store kvp information
         * @return Success if conversion is successfull.
         */
        PVMFStatus ConvertAsciiDataToApic(char* aMimeTypeID3, char* aDescriptionID3,
                                          uint8 aGraphicType, uint32 aGraphicDataLen,
                                          void *key_specific_value, uint32 total_size);

        /**
         * @brief Read the information from the USLT/ULT frames.
         * @param NULL
         * @return Success if successfully read.
         */
        PVMFStatus ReadLyricsCommFrame(uint8 unicodeCheck, uint32 aFramesize, PVID3FrameType aFrameType);


        /**
         * @brief Reads Null terminated ascii strings from file
         * @param aInputFile file pointer
         * @parm data heap string to store string
         * @return true on success otherwise false
         */
        bool readNullTerminatedAsciiString(PVFile* aInputFile, OSCL_HeapString<OsclMemAllocator> &data);

        /**
         * @brief Reads Null terminated unicode strings from file
         * @param aInputFile file pointer
         * @parm data heap string to store string
         * @return completion status
         */

        PVMFStatus readNullTerminatedUnicodeString(PVFile* aInputFile, OSCL_wHeapString<OsclMemAllocator> &aData, uint32 &bomSz);

        /**
         * @brief reads frame of type comment
         * @param aValueSize size of the frame
         * @return completion status
         */

        PVMFStatus ReadCommentFrame(uint32 aValueSize);

        /**
         * @brief Gets value type and char set stored in kvp
         * @param aKvp shared pointer to kvp
         * @param aValueType value type
         * @param aCharSet char set
         * @return Completion status.
         */
        PVMFStatus GetKvpValueType(PvmiKvpSharedPtr aKvp, PvmiKvpValueType& aValueType, PVID3CharacterSet& aCharSet);

        /**
         * @brief Gets frame ID and frame type from kvp
         * @param aKvp  shared pointer to key value pair structure
         * @param aFrameID frame ID
         * @param aFrameType frame type
         * @return Completion status.
         */
        PVMFStatus GetFrameTypeFromKvp(PvmiKvpSharedPtr aKvp, OSCL_String& aFrameID, PVID3FrameType& aFrameType);

        /**
         * @brief Gets frame ID and frame type from kvp
         * @param aKvp  key value pair structure
         * @param aFrameID frame ID
         * @param aFrameType frame type
         * @return Completion status.
         */
        PVMFStatus GetFrameTypeFromKvp(const PvmiKvp& aKvp, OSCL_String& aFrameID, PVID3FrameType& aFrameType);

        /**
         * @brief Get Size of ID3 frame stored in kvp.
         * @param akvp shared pointer to kvp
         * @param aValueType type of value stored in kvp
         * @param aCharSet character set of value
         * @param aSize size of the frame
         * @return Completion Status
         */
        PVMFStatus GetID3v2FrameDataSize(PvmiKvpSharedPtr aKvp, PvmiKvpValueType aValueType,
                                         PVID3CharacterSet aCharSet, uint32& aSize);

        /**
         * @brief compose ID3 V2 tag
         * @param aTag reference counter to memory fragment
         * @return Completion Status
         */
        PVMFStatus ComposeID3v2Tag(OsclRefCounterMemFrag& aTag);

        /**
         * @brief push frame to supplied frame vector
         * @param aFrame Frame to be pushed
         * @param aFrameVector vector in which frame is to be pushed
         * @return Completion Status
         */
        PVMFStatus PushFrameToFrameVector(PvmiKvpSharedPtr& aFrame, PvmiKvpSharedPtrVector& aFrameVector);
        /**
         * @brief Allocate array of specified size and type of elements
         * @param aValueType, type of array elements
         * @param aNumElements, size of required array
         * @return aLeaveCode, err code
         * @return buffer, pointer to allocated buffer
         */
        OsclAny* AllocateValueArray(int32& aLeaveCode, PvmiKvpValueType aValueType, int32 aNumElements, OsclMemAllocator* aMemAllocator = NULL);

        /**
         * @brief Allocate kvp and handle leave
         * @param aValueType, type of array elements
         * @param aValueSize, value size of required kvp
         * @return aStatus, err code
         * @return truncate, returns false if specified memory is not allocated, else true
         */
        PvmiKvpSharedPtr HandleErrorForKVPAllocation(OSCL_String& aKey, PvmiKvpValueType aValueType, uint32 aValueSize, bool &truncate, PVMFStatus &aStatus);

        /**
         * @brief Look for iTunNORM, iTunSMPN and iTunPGAP in COM/COMM frame with 8 bit char encoding
         * @param aDescPtr, pointer to content description string in the COM/COMM frame
         * @param aTextPtr, pointer to text string in the COM/COMM frame
         * @param aTextCount, character count in text string
         * @return aGaplessInfo, the gapless info stored in TGaplessInfo
         * @return true if gapless info is found
         */
        bool CheckForITunesGaplessInfo8(uint8* aDescPtr, uint8* aTextPtr, uint32 aTextCount, TGaplessInfo& aGaplessInfo);

        /**
         * @brief Look for iTunNORM, iTunSMPN and iTunPGAP in COM/COMM frame in unicode
         * @param aDescPtr, pointer to content description string in the COM/COMM frame
         * @param aTextPtr, pointer to text string in the COM/COMM frame
         * @param aTextCount, character count in text string
         * @return aGaplessInfo, the gapless info stored in TGaplessInfo
         * @return true if gapless info is found
         */
        bool CheckForITunesGaplessInfoUnicode(oscl_wchar* aDescPtr, oscl_wchar* aTextPtr, uint32 aTextCount, TGaplessInfo& aGaplessInfo);

    private:

        uint8* AllocateMem(int32& err, uint32 size);

        // Variables for parsing
        PVFile* iInputFile;
        TID3TagInfo iID3TagInfo;
        bool iTitleFoundFlag;
        bool iArtistFoundFlag;
        bool iAlbumFoundFlag;
        bool iYearFoundFlag;
        bool iCommentFoundFlag;
        bool iTrackNumberFoundFlag;
        bool iGenereFoundFlag;
        int32 iFileSizeInBytes;
        int32 iByteOffsetToStartOfAudioFrames;

        bool iID3V1Present;
        bool iID3V2Present;
        // Variables for composing
        PVID3Version iVersion;
        PvmiKvpSharedPtrVector iFrames;
        bool iUseMaxTagSize;
        uint32 iMaxTagSize;
        bool iUsePadding;
        bool iTagAtBof;
        bool iSeekFrameFound;

        TGaplessInfo iGaplessInfo;
        bool iGaplessInfoFound;

        OsclMemAllocator iAlloc;
        PVLogger* iLogger;
};

#endif // PV_ID3_PARCOM_H_INCLUDED