📄 javacode.txt
字号:
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
/// <copyright>
/// Giora Tamir (giora@gtamir.com), 2005
/// </copyright>
namespace RiffParserDemo2
{
#region RiffParserException
public class RiffParserException : ApplicationException
{
public RiffParserException()
: base()
{
}
public RiffParserException(string message)
: base(message)
{
}
public RiffParserException(string message, Exception inner)
: base(message, inner)
{
}
public RiffParserException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
}
#endregion
/// <summary>
/// Summary description for RiffParser
/// </summary>
public class RiffParser
{
#region CONSTANTS
public const int DWORDSIZE = 4;
public const int TWODWORDSSIZE = 8;
public static readonly string RIFF4CC = "RIFF";
public static readonly string RIFX4CC = "RIFX";
public static readonly string LIST4CC = "LIST";
// Known file types
public static readonly int ckidAVI = ToFourCC("AVI ");
public static readonly int ckidWAV = ToFourCC("WAVE");
public static readonly int ckidRMID = ToFourCC("RMID");
#endregion
#region private members
private string m_filename;
private string m_shortname;
private long m_filesize;
private int m_datasize;
private FileStream m_stream;
private int m_fileriff;
private int m_filetype;
// For non-thread-safe memory optimization
private byte[] m_eightBytes = new byte[TWODWORDSSIZE];
private byte[] m_fourBytes = new byte[DWORDSIZE];
#endregion
#region Delegates
/// <summary>
/// Method to be called when a list element is found
/// </summary>
/// <param name="FourCCType"></param>
/// <param name="length"></param>
public delegate void ProcessListElement(RiffParser rp, int FourCCType, int length);
/// <summary>
/// Method to be called when a chunk element is found
/// </summary>
/// <param name="FourCCType"></param>
/// <param name="unpaddedLength"></param>
/// <param name="paddedLength"></param>
public delegate void ProcessChunkElement(RiffParser rp, int FourCCType, int unpaddedLength, int paddedLength);
#endregion
#region public Members
/// <summary>
/// RIFF data segment size
/// </summary>
public int DataSize
{
get
{
return m_datasize;
}
}
/// <summary>
/// Current file name
/// </summary>
public string FileName
{
get
{
return m_filename;
}
}
/// <summary>
/// Current short (name only) file name
/// </summary>
public string ShortName
{
get
{
return m_shortname;
}
}
/// <summary>
/// Return the general file type (RIFF or RIFX);
/// </summary>
public int FileRIFF
{
get
{
return m_fileriff;
}
}
/// <summary>
/// Return the specific file type (AVI/WAV...)
/// </summary>
public int FileType
{
get
{
return m_filetype;
}
}
#endregion
public RiffParser()
{
}
/// <summary>
/// Determine if the file is a valid RIFF file
/// </summary>
/// <param name="filename">File to examine</param>
/// <returns>True if file is a RIFF file</returns>
public unsafe void OpenFile(string filename)
{
// Sanity check
if (null != m_stream) {
throw new RiffParserException("RIFF file already open " + FileName);
}
bool errorOccured = false;
// Opening a new file
try
{
FileInfo fi = new FileInfo(filename);
m_filename = fi.FullName;
m_shortname = fi.Name;
m_filesize = fi.Length;
//Console.WriteLine(ShortName + " is a valid file.");
// Read the RIFF header
m_stream = new FileStream(m_filename, FileMode.Open, FileAccess.Read, FileShare.Read);
int FourCC;
int datasize;
int fileType;
ReadTwoInts(out FourCC, out datasize);
ReadOneInt(out fileType);
m_fileriff = FourCC;
m_filetype = fileType;
// Check for a valid RIFF header
string riff = FromFourCC(FourCC);
if ((0 == String.Compare(riff, RIFF4CC))
|| (0 == String.Compare(riff, RIFX4CC)))
{
// Good header. Check size
//Console.WriteLine(ShortName + " has a valid type \"" + riff + "\"");
//Console.WriteLine(ShortName + " has a specific type of \"" + FromFourCC(fileType) + "\"");
m_datasize = datasize;
if (m_filesize >= m_datasize + TWODWORDSSIZE)
{
//Console.WriteLine(ShortName + " has a valid size");
}
else
{
m_stream.Close(); m_stream = null;
throw new RiffParserException("Error. Truncated file " + FileName);
}
}
else
{
m_stream.Close(); m_stream = null;
throw new RiffParserException("Error. Not a valid RIFF file " + FileName);
}
}
catch (RiffParserException ex)
{
errorOccured = true;
throw ex;
}
catch (Exception exception)
{
errorOccured = true;
throw new RiffParserException("Error. Problem reading file " + FileName, exception);
}
finally
{
if (errorOccured && (null != m_stream))
{
m_stream.Close(); m_stream = null;
}
}
}
/// <summary>
/// Read the next RIFF element invoking the correct delegate.
/// Returns true if an element can be read
/// </summary>
/// <param name="bytesleft">Reference to number of bytes left in the current list</param>
/// <param name="chunk">Method to invoke if a chunk is found</param>
/// <param name="list">Method to invoke if a list is found</param>
/// <returns></returns>
public bool ReadElement(ref int bytesleft, ProcessChunkElement chunk, ProcessListElement list)
{
// Are we done?
if (TWODWORDSSIZE > bytesleft)
{
return false;
}
//Console.WriteLine(m_stream.Position.ToString() + ", " + bytesleft.ToString());
// We have enough bytes, read
int FourCC;
int size;
ReadTwoInts(out FourCC, out size);
// Reduce bytes left
bytesleft -= TWODWORDSSIZE;
// Do we have enough bytes?
if (bytesleft < size)
{
// Skip the bad data and throw an exception
SkipData(bytesleft);
bytesleft = 0;
throw new RiffParserException("Element size mismatch for element " + FromFourCC(FourCC)
+ " need " + size.ToString() + " but have only " + bytesleft.ToString());
}
// Examine the element, is it a list or a chunk
string type = FromFourCC(FourCC);
if (0 == String.Compare(type, LIST4CC))
{
// We have a list
ReadOneInt(out FourCC);
if (null == list)
{
SkipData(size - 4);
}
else
{
// Invoke the list method
list(this, FourCC, size - 4);
}
// Adjust size
bytesleft -= size;
}
else
{
// Calculated padded size - padded to WORD boundary
int paddedSize = size;
if (0 != (size & 1)) ++paddedSize;
if (null == chunk)
{
SkipData(paddedSize);
}
else
{
chunk(this, FourCC, size, paddedSize);
}
// Adjust size
bytesleft -= paddedSize;
}
return true;
}
#region Stream access
/// <summary>
/// Non-thread-safe method to read two ints from the stream
/// </summary>
/// <param name="FourCC">Output FourCC int</param>
/// <param name="size">Output chunk/list size</param>
public unsafe void ReadTwoInts(out int FourCC, out int size)
{
try {
int readsize = m_stream.Read(m_eightBytes, 0, TWODWORDSSIZE);
if (TWODWORDSSIZE != readsize) {
throw new RiffParserException("Unable to read. Corrupt RIFF file " + FileName);
}
fixed (byte* bp = &m_eightBytes[0]) {
FourCC = *((int*)bp);
size = *((int*)(bp + DWORDSIZE));
}
}
catch (Exception ex)
{
throw new RiffParserException("Problem accessing RIFF file " + FileName, ex);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -