Beispiel #1
0
        // NB : This only works if writeVorbisTag is called _before_ writePictures, since tagData fusion is done by vorbisTag.Write
        public bool Write(BinaryReader r, BinaryWriter w, TagData tag)
        {
            // Read all the fields in the existing tag (including unsupported fields)
            ReadTagParams readTagParams = new ReadTagParams(true, true);

            readTagParams.PrepareForWriting = true;
            bool tagExists = Read(r, readTagParams);

            // Save a snapshot of the initial embedded pictures for processing purposes
            existingPictureIndex = 0;
            targetPictureIndex   = 0;
            initialPictures      = vorbisTag.EmbeddedPictures;

            // Prepare picture data with freshly read vorbisTag
            TagData dataToWrite = new TagData();

            dataToWrite.Pictures = vorbisTag.EmbeddedPictures;
            dataToWrite.IntegrateValues(tag, true, false); // Merge existing information + new tag information except additional fields which will be merged by VorbisComment

            adjustPictureZones(dataToWrite.Pictures);

            FileSurgeon surgeon = new FileSurgeon(null, null, MetaDataIOFactory.TAG_NATIVE, TO_BUILTIN);

            surgeon.RewriteZones(w, new WriteDelegate(write), zones, dataToWrite, tagExists);

            // Set the 'isLast' bit on the actual last block
            w.BaseStream.Seek(latestBlockOffset, SeekOrigin.Begin);
            w.Write((byte)(latestBlockType | FLAG_LAST_METADATA_BLOCK));

            return(true);
        }
Beispiel #2
0
        public bool Write(BinaryReader r, BinaryWriter w, TagData tag)
        {
            bool result = true;

            // Constraint-check on non-supported values
            if (FieldCodeFixedLength > 0)
            {
                if (tag.Pictures != null)
                {
                    foreach (PictureInfo picInfo in tag.Pictures)
                    {
                        if (PictureInfo.PIC_TYPE.Unsupported.Equals(picInfo.PicType) && (picInfo.TagType.Equals(getImplementedTagType())))
                        {
                            if ((-1 == picInfo.NativePicCode) && (Utils.ProtectValue(picInfo.NativePicCodeStr).Length != FieldCodeFixedLength))
                            {
                                throw new NotSupportedException("Field code fixed length is " + FieldCodeFixedLength + "; detected field '" + Utils.ProtectValue(picInfo.NativePicCodeStr) + "' is " + Utils.ProtectValue(picInfo.NativePicCodeStr).Length + " characters long and cannot be written");
                            }
                        }
                    }
                }
                foreach (MetaFieldInfo fieldInfo in tag.AdditionalFields)
                {
                    if (fieldInfo.TagType.Equals(getImplementedTagType()) || MetaDataIOFactory.TAG_ANY == fieldInfo.TagType)
                    {
                        string fieldCode = Utils.ProtectValue(fieldInfo.NativeFieldCode);
                        if (fieldCode.Length != FieldCodeFixedLength && !fieldCode.Contains("----")) // "----" = exception for MP4 extended fields (e.g. ----:com.apple.iTunes:CONDUCTOR)
                        {
                            throw new NotSupportedException("Field code fixed length is " + FieldCodeFixedLength + "; detected field '" + fieldCode + "' is " + fieldCode.Length + " characters long and cannot be written");
                        }
                    }
                }
            }

            structureHelper.Clear();
            tagData.Pictures.Clear();

            // Read all the fields in the existing tag (including unsupported fields)
            ReadTagParams readTagParams = new ReadTagParams(true, true);

            readTagParams.PrepareForWriting = true;

            if (embedder != null && embedder.HasEmbeddedID3v2 > 0)
            {
                readTagParams.offset = embedder.HasEmbeddedID3v2;
            }

            this.read(r, readTagParams);

            if (embedder != null && getImplementedTagType() == MetaDataIOFactory.TAG_ID3V2)
            {
                structureHelper.Clear();
                structureHelper.AddZone(embedder.Id3v2Zone);
            }

            // Give engine something to work with if the tag is really empty
            if (!tagExists && 0 == Zones.Count)
            {
                structureHelper.AddZone(0, 0);
            }

            TagData dataToWrite;

            dataToWrite = tagData;
            dataToWrite.IntegrateValues(tag); // Merge existing information + new tag information
            dataToWrite.Cleanup();

            FileSurgeon surgeon = new FileSurgeon(structureHelper, embedder, getImplementedTagType(), getDefaultTagOffset());

            result = surgeon.RewriteZones(w, new FileSurgeon.WriteDelegate(writeAdapter), Zones, dataToWrite, tagExists);

            // Update tag information without calling Read

            /* TODO - this implementation is too risky :
             *   - if one of the writing operations fails, data is updated as if everything went right
             *   - any picture slot with a markForDeletion flag is recorded as-is in the tag
             */
            tagData = dataToWrite;

            return(result);
        }