Esempio n. 1
0
        public id3v2Frame ReadFrame(BinaryReader br, int version)
        {
            char[] tagSize;    // I use this to read the bytes in from the file
            int[] bytes;      // for bit shifting
            ulong newSize = 0;    // for the final number

            int nameSize = 4;
            if (version == 2)
            {
                nameSize  = 3;
            }
            else if ((version == 3) || (version == 4))
            {
                nameSize = 4;
            }

            id3v2Frame f1 = new id3v2Frame();
            f1.frameName = new string (br.ReadChars(nameSize));
            f1.MajorVersion = version;

            // in order to check for padding I have to build a string of 4 (or 3 if v2.2) null bytes
            // there must be a better way to do this
            char nullChar = System.Convert.ToChar(0);
            StringBuilder sb = new StringBuilder(0,nameSize);
            sb.Append(nullChar);
            sb.Append(nullChar);
            sb.Append(nullChar);
            if (nameSize == 4)
            {
                sb.Append(nullChar);
            }

            if (f1.frameName  == sb.ToString())
            {
                f1.padding = true;
                return f1;
            }

            if (version == 2)
            {
                // only have 3 bytes for size ;

                tagSize = br.ReadChars(3);    // I use this to read the bytes in from the file
                bytes = new int[3];      // for bit shifting
                newSize = 0;    // for the final number
                // The ID3v2 tag size is encoded with four bytes
                // where the most significant bit (bit 7)
                // is set to zero in every byte,
                // making a total of 28 bits.
                // The zeroed bits are ignored
                //
                // Some bit grinding is necessary.  Hang on.

                bytes[3] =  tagSize[2]             | ((tagSize[1] & 1) << 7) ;
                bytes[2] = ((tagSize[1] >> 1) & 63) | ((tagSize[0] & 3) << 6) ;
                bytes[1] = ((tagSize[0] >> 2) & 31) ;

                newSize  = ((UInt64)bytes[3] |
                    ((UInt64)bytes[2] << 8)  |
                    ((UInt64)bytes[1] << 16));
                //End Dan Code
            }

            else if (version == 3 || version == 4)
            {
                // version  2.4
                tagSize = br.ReadChars(4);    // I use this to read the bytes in from the file
                bytes = new int[4];      // for bit shifting
                newSize = 0;    // for the final number

                // The ID3v2 tag size is encoded with four bytes
                // where the most significant bit (bit 7)
                // is set to zero in every byte,
                // making a total of 28 bits.
                // The zeroed bits are ignored
                //
                // Some bit grinding is necessary.  Hang on.

                bytes[3] =  tagSize[3]             | ((tagSize[2] & 1) << 7) ;
                bytes[2] = ((tagSize[2] >> 1) & 63) | ((tagSize[1] & 3) << 6) ;
                bytes[1] = ((tagSize[1] >> 2) & 31) | ((tagSize[0] & 7) << 5) ;
                bytes[0] = ((tagSize[0] >> 3) & 15) ;

                newSize  = ((UInt64)bytes[3] |
                    ((UInt64)bytes[2] << 8)  |
                    ((UInt64)bytes[1] << 16) |
                    ((UInt64)bytes[0] << 24)) ;
                //End Dan Code
            }
            f1.frameSize = newSize;

            if (version > 2)
            {
                // versions 3+ have frame tags.
                if (version == 3)
                {

                    bool [] c;
                    // read teh tags
                    c = BitReader.ToBitBool(br.ReadByte());
                    f1.F_TagAlterPreservation = c[0];
                    f1.F_FileAlterPreservation= c[1];
                    f1.F_ReadOnly= c[2];

                    c = BitReader.ToBitBool(br.ReadByte());
                    f1.F_Compression= c[0];
                    f1.F_Encryption= c[1];
                    f1.F_GroupingIdentity= c[2];
                }
                else if (version == 4)
                {
                    //%0abc0000 %0h00kmnp
                    //a - Tag alter preservation
                    //     0     Frame should be preserved.
                    //     1     Frame should be discarded.
                    // b - File alter preservation
                    //  0     Frame should be preserved.
                    //1     Frame should be discarded.
                    //  c - Read only
                    //  h - Grouping identity
                    //    0     Frame does not contain group information
                    //    1     Frame contains group information
                    //   k - Compression
                    //     0     Frame is not compressed.
                    //     1     Frame is compressed using zlib [zlib] deflate method.
                    //           If set, this requires the 'Data Length Indicator' bit
                    //           to be set as well.
                    //  m - Encryption
                    //     0     Frame is not encrypted.
                    //     1     Frame is encrypted.
                    //  n - Unsynchronisation
                    //      0     Frame has not been unsynchronised.
                    //      1     Frame has been unsyrchronised.
                    //   p - Data length indicator
                    //     0      There is no Data Length Indicator.
                    //    1      A data length Indicator has been added to the frame.

                    bool [] c;
                    // read teh tags
                    c = BitReader.ToBitBool(br.ReadByte());
                    f1.F_TagAlterPreservation = c[1];
                    f1.F_FileAlterPreservation= c[2];
                    f1.F_ReadOnly= c[3];

                    c = BitReader.ToBitBool(br.ReadByte());
                    f1.F_GroupingIdentity= c[1];
                    f1.F_Compression= c[4];
                    f1.F_Encryption= c[5];
                    f1.F_Unsynchronisation = c[6];
                    f1.F_DataLengthIndicator = c[7];
                }

                if (f1.frameSize > 0)
                {
                    f1.frameContents = br.ReadBytes((int)f1.frameSize);
                }

            }
            return f1;
        }
Esempio n. 2
0
        private void ReadFrames()
        {
            id3v2Frame f = new id3v2Frame();
            do
            {
                f = f.ReadFrame(br, this.MajorVersion);

                // check if we have hit the padding.
                if (f.padding == true)
                {
                    //we hit padding.  lets advance to end and stop reading.
                    br.BaseStream.Position = System.Convert.ToInt64(headerSize);
                    break;
                }
                this.frames.Add(f);
                this.framesHash.Add(f.frameName, f);
                #region frameprocessing

                /*
                else
                {
                    // figure out which type it is
                    if (f.frameName.StartsWith("T"))
                    {
                        if (f.frameName.Equals("TXXX"))
                        {
                            ProcessTXXX(f);
                        }
                        else
                        {
                            ProcessTTYPE(f);
                        }
                    }
                    else
                    {
                        if (f.frameName.StartsWith("W"))
                        {
                            if (f.frameName.Equals("WXXX"))
                            {
                                ProcessWXXX(f);
                            }
                            else
                            {
                                ProcessWTYPE(f);
                            }
                        }
                        else
                        {
                            // if it isn't  a muliple reader case (above) then throw it into the switch to process
                            switch (f.frameName)
                            {

                                case "IPLS":
                                    ProcessIPLS(f);
                                    break;
                                case "MCDI":
                                    ProcessMCDI(f);
                                    break;
                                case "UFID":
                                    ProcessUFID(f);
                                    break;
                                case "COMM":
                                    ProcessCOMM(f);
                                    break;

                                default:
                                    frames.Add(f.frameName, f.frameContents);
                                    AddItemToList(f.frameName, "non text");
                                    break;
                            }
                }

            }

            }*/
                #endregion
            } while (br.BaseStream.Position  <= System.Convert.ToInt64(this.headerSize));
        }