public override void Save() { ClearPageData(); // Force re-reading of the file. xiph_comment_data = comment.Render(); // Create FLAC metadata-block: // Put the size in the first 32 bit (I assume no more than 24 bit are used) ByteVector v = ByteVector.FromUInt((uint)xiph_comment_data.Count); // Set the type of the metadata-block to be a Xiph / Vorbis comment v[0] = 4; // Append the comment-data after the 32 bit header v.Add(xiph_comment_data); // Save the packet at the old spot // FIXME: Use padding if size is increasing SetPacket(comment_packet, v); base.Save(); }
public override void Save() { ClearPageData(); // Force re-reading of the file. ByteVector v = vorbis_comment_header_id; FindTag(TagTypes.Xiph, true); v.Add(comment.Render()); SetPacket(1, v); base.Save(); }
public override void Save() { if (IsReadOnly) { throw new ReadOnlyException(); } Mode = FileAccessMode.Write; long flac_data_begin; long flac_data_end; // Update ID3 tags if (id3v2_tag != null) { ByteVector id3v2_tag_data = id3v2_tag.Render(); long id3v2_location = FindId3v2(); if (id3v2_location >= 0) { int id3v2_size = 0; Seek(id3v2_location); Id3v2Header header = new Id3v2Header(ReadBlock((int)Id3v2Header.Size)); if (header.TagSize == 0) { TagLibDebugger.Debug("Flac.File.Save() -- Id3v2 header is broken. Ignoring."); } else { id3v2_size = (int)header.CompleteTagSize; } Insert(id3v2_tag_data, id3v2_location, id3v2_size); System.Console.WriteLine("ID3v2: " + id3v2_size + " " + id3v2_tag_data.Count); flac_data_begin = id3v2_location + id3v2_tag_data.Count; } else { Insert(id3v2_tag_data, 0, 0); flac_data_begin = id3v2_tag_data.Count; } } else { flac_data_begin = 0; } if (id3v1_tag != null) { long id3v1_location = FindId3v1(); if (id3v1_location >= 0) { Seek(id3v1_location); } else { Seek(0, System.IO.SeekOrigin.End); } flac_data_end = Tell; WriteBlock(id3v1_tag.Render()); } else { flac_data_end = Length; } // Create new vorbis comments is they don'type exist. FindTag(TagTypes.Xiph, true); xiph_comment_data = comment.Render(false); ByteVector v = ByteVector.FromUInt((uint)xiph_comment_data.Count); // Set the type of the comment to be a Xiph / Vorbis comment // (See scan() for comments on header-format) v[0] = 4; v.Add(xiph_comment_data); // If file already have comment => find and update it // if not => insert one scanned = false; if (Scan(flac_data_begin, flac_data_end) != null) { long next_page_offset = flac_start; Seek(next_page_offset); ByteVector header = ReadBlock(4); uint length = header.Mid(1, 3).ToUInt(); next_page_offset += length + 4; // Search through the remaining metadata byte block_type = (byte)(header[0] & 0x7f); bool last_block = (header[0] & 0x80) != 0; while (!last_block) { Seek(next_page_offset); header = ReadBlock(4); block_type = (byte)(header[0] & 0x7f); last_block = (header[0] & 0x80) != 0; length = header.Mid(1, 3).ToUInt(); // Type is vorbiscomment if (block_type == 4) { long next_keep = (last_block ? 0 : FindPaddingBreak(next_page_offset + length + 4, next_page_offset + XiphCommentData.Count + 8, ref last_block)); uint padding_length; if (next_keep != 0) { // There is space for comment and padding blocks without rewriting the whole file. // Note this can not overflow. padding_length = (uint)(next_keep - (next_page_offset + XiphCommentData.Count + 8)); } else { // Not enough space, so we will have to rewrite the whole file following this block padding_length = (uint)XiphCommentData.Count; if (padding_length < 4096) { padding_length = 4096; } next_keep = next_page_offset + length + 4; } ByteVector padding = ByteVector.FromUInt(padding_length); padding[0] = 1; if (last_block) { padding[0] = (byte)(padding[0] | 0x80); } padding.Resize((int)(padding_length + 4)); Insert(v + padding, next_page_offset, next_keep - next_page_offset); //System.Console.WriteLine ("OGG: " + (next_keep - next_page_offset) + " " + (vector.Count + padding.Count)); break; } next_page_offset += length + 4; } } else { long next_page_offset = flac_start; Seek(next_page_offset); ByteVector header = ReadBlock(4); bool last_block = (header[0] & 0x80) != 0; uint length = header.Mid(1, 3).ToUInt(); // If last block was last, make this one last if (last_block) { // Copy the bottom seven bits into the new value ByteVector h = (byte)(header[0] & 0x7F); Insert(h, next_page_offset, 1); // Set the last bit v[0] = (byte)(v[0] | 0x80); } Insert(v, next_page_offset + length + 4, 0); } Mode = FileAccessMode.Closed; }