////------------------------------------------------------------------------------------------------------------------------------ /// <inheritdoc /> public byte[] ToByteArray() { using (StreamBuffer buffer = new StreamBuffer()) { if (UseHeader) { // Header buffer.Write(HeaderIdentifierBytes); buffer.WritePadding(NullByte, 2); buffer.WriteString(XingEncoderVersion); buffer.WritePadding(NullByte, 2); buffer.WriteString(Version); buffer.WritePadding(NullByte, 2); buffer.WritePadding(PaddingByte, 226); } // Image extension int imageExtensionOffset = (int)buffer.Position; if ((Image != null) && !String.IsNullOrEmpty(Image.FileExtension)) { buffer.WriteString(Image.FileExtension); buffer.WritePadding(PaddingByte, 4 - Image.FileExtension.Length); } else buffer.WritePadding(PaddingByte, 4); // Image binary int imageBinaryOffset = (int)buffer.Position; if ((Image != null) && (Image.BinaryImage != null)) { buffer.WriteInt(Image.BinaryImage.Length); buffer.Write(Image.BinaryImage); } else buffer.WriteInt(0); // Unused int unusedOffset = (int)buffer.Position; buffer.WritePadding(NullByte, 4); // Version information int versionInfoOffset = (int)buffer.Position; buffer.WriteString(HeaderIdentifier); buffer.WritePadding(NullByte, 2); buffer.WriteString(XingEncoderVersion); buffer.WritePadding(NullByte, 2); buffer.WriteString(Version); buffer.WritePadding(NullByte, 2); buffer.WritePadding(PaddingByte, 226); // Audio meta-data // The audio meta-data is the heart of the MusicMatch tag. It contains most // of the pertinent information found in other tagging formats (song title, // album title, artist, etc.) and some that are unique to this format (mood, // preference, situation). int audioMetaDataOffset = (int)buffer.Position; // Single-line text fields buffer.WriteShort((short)(SongTitle ?? String.Empty).Length); buffer.WriteString(SongTitle ?? String.Empty); buffer.WriteShort((short)(AlbumTitle ?? String.Empty).Length); buffer.WriteString(AlbumTitle ?? String.Empty); buffer.WriteShort((short)(ArtistName ?? String.Empty).Length); buffer.WriteString(ArtistName ?? String.Empty); buffer.WriteShort((short)(Genre ?? String.Empty).Length); buffer.WriteString(Genre ?? String.Empty); buffer.WriteShort((short)(Tempo ?? String.Empty).Length); buffer.WriteString(Tempo ?? String.Empty); buffer.WriteShort((short)(Mood ?? String.Empty).Length); buffer.WriteString(Mood ?? String.Empty); buffer.WriteShort((short)(Situation ?? String.Empty).Length); buffer.WriteString(Situation ?? String.Empty); buffer.WriteShort((short)(Preference ?? String.Empty).Length); buffer.WriteString(Preference ?? String.Empty); // Non-text fields buffer.WriteShort((short)(SongDuration ?? String.Empty).Length); buffer.WriteString(SongDuration ?? String.Empty); buffer.WriteDouble(CreationDate.ToOADate()); buffer.WriteInt(PlayCounter); buffer.WriteShort((short)(OriginalFilename ?? String.Empty).Length); buffer.WriteString(OriginalFilename ?? String.Empty); buffer.WriteShort((short)(SerialNumber ?? String.Empty).Length); buffer.WriteString(SerialNumber ?? String.Empty); buffer.WriteShort(TrackNumber); // Multi-line text fields buffer.WriteShort((short)(Notes ?? String.Empty).Length); buffer.WriteString(Notes ?? String.Empty); buffer.WriteShort((short)(ArtistBio ?? String.Empty).Length); buffer.WriteString(ArtistBio ?? String.Empty); buffer.WriteShort((short)(Lyrics ?? String.Empty).Length); buffer.WriteString(Lyrics ?? String.Empty); // Internet addresses buffer.WriteShort((short)(ArtistUrl ?? String.Empty).Length); buffer.WriteString(ArtistUrl ?? String.Empty); buffer.WriteShort((short)(BuyCdUrl ?? String.Empty).Length); buffer.WriteString(BuyCdUrl ?? String.Empty); buffer.WriteShort((short)(ArtistEmail ?? String.Empty).Length); buffer.WriteString(ArtistEmail ?? String.Empty); // Null bytes buffer.WritePadding(NullByte, 16); // In all versions of the MusicMatch format up to and including 3.00, the // section is always 7868 bytes in length. All subsequent versions allowed // three possible lengths for this section: 7936, 8004, and 8132 bytes. The // conditions under which a particular length from these three possibilities // was used is unknown. In all cases, this section is padded with dashes // ($2D) to achieve this constant size. double version; if (!Double.TryParse(Version, out version)) version = 3.100000; // The padding is calculated by taking the AudioMetaDataSize minus the total size of audio meta data fields, // minus the total size of the data offset fields, minus the footer size. long paddingSize = ((version <= 3.1) ? AudioMetaDataSizes.First() : AudioMetaDataSizes.Last()) - (buffer.Length - audioMetaDataOffset) - DataOffsetFieldsSize - FooterSize; buffer.WritePadding(0x2D, (int)paddingSize); // Data offsets buffer.WriteInt(imageExtensionOffset); buffer.WriteInt(imageBinaryOffset); buffer.WriteInt(unusedOffset); buffer.WriteInt(versionInfoOffset); buffer.WriteInt(audioMetaDataOffset); // Footer buffer.Write(FooterIdentifierBytes); buffer.WritePadding(PaddingByte, 13); buffer.WriteString(Version.Substring(0 ,4)); buffer.WritePadding(PaddingByte, 12); return buffer.ToByteArray(); } }
public void WriteDoubleTest() { StreamBuffer target = new StreamBuffer(); // TODO: Initialize to an appropriate value double value = 0F; // TODO: Initialize to an appropriate value target.WriteDouble(value); Assert.Inconclusive("A method that does not return a value cannot be verified."); }