mirror of
https://github.com/SabreTools/BinaryObjectScanner.git
synced 2026-09-22 14:54:56 +00:00
GsfBlob, GsfClipData, and GsfDocMetaData second pass
This commit is contained in:
3
BurnOutSharp/External/libgsf/GsfBlob.cs
vendored
3
BurnOutSharp/External/libgsf/GsfBlob.cs
vendored
@@ -23,6 +23,7 @@ using System;
|
||||
|
||||
namespace LibGSF
|
||||
{
|
||||
// TODO: Can this be made internal?
|
||||
public class GsfBlob
|
||||
{
|
||||
#region Properties
|
||||
@@ -54,6 +55,8 @@ namespace LibGSF
|
||||
{
|
||||
if (!((size > 0 && data_to_copy != null) || (size == 0 && data_to_copy == null)))
|
||||
return null;
|
||||
if (error != null)
|
||||
return null;
|
||||
|
||||
byte[] data;
|
||||
if (data_to_copy != null)
|
||||
|
||||
34
BurnOutSharp/External/libgsf/GsfClipData.cs
vendored
34
BurnOutSharp/External/libgsf/GsfClipData.cs
vendored
@@ -27,6 +27,7 @@ namespace LibGSF
|
||||
{
|
||||
#region Enums
|
||||
|
||||
// TODO: Can this be made internal?
|
||||
public enum GsfClipFormat
|
||||
{
|
||||
/// <summary>
|
||||
@@ -66,6 +67,7 @@ namespace LibGSF
|
||||
GSF_CLIP_FORMAT_UNKNOWN
|
||||
}
|
||||
|
||||
// TODO: Can this be made internal?
|
||||
public enum GsfClipFormatWindows
|
||||
{
|
||||
/// <summary>
|
||||
@@ -96,6 +98,7 @@ namespace LibGSF
|
||||
|
||||
#endregion
|
||||
|
||||
// TODO: Can this be made internal?
|
||||
public class GsfClipData
|
||||
{
|
||||
#region Properties
|
||||
@@ -156,16 +159,12 @@ namespace LibGSF
|
||||
/// <returns>A GsfClipFormatWindows value.</returns>
|
||||
public GsfClipFormatWindows GetWindowsClipboardFormat(ref Exception error)
|
||||
{
|
||||
GsfClipFormatWindows format;
|
||||
|
||||
if (error == null)
|
||||
return GsfClipFormatWindows.GSF_CLIP_FORMAT_WINDOWS_ERROR;
|
||||
|
||||
if (Format != GsfClipFormat.GSF_CLIP_FORMAT_WINDOWS_CLIPBOARD)
|
||||
return GsfClipFormatWindows.GSF_CLIP_FORMAT_WINDOWS_ERROR;
|
||||
|
||||
long size = DataBlob.Size;
|
||||
|
||||
if (size < 4)
|
||||
{
|
||||
error = new InvalidDataException("The clip_data is in Windows clipboard format, but it is smaller than the required 4 bytes.");
|
||||
@@ -173,30 +172,23 @@ namespace LibGSF
|
||||
}
|
||||
|
||||
byte[] data = DataBlob.Data;
|
||||
|
||||
uint value = GSF_LE_GET_GUINT32(data, 0);
|
||||
|
||||
switch (value)
|
||||
{
|
||||
case (uint)GsfClipFormatWindows.GSF_CLIP_FORMAT_WINDOWS_METAFILE:
|
||||
format = CheckFormatWindows(GsfClipFormatWindows.GSF_CLIP_FORMAT_WINDOWS_METAFILE, "Windows Metafile format", size, ref error);
|
||||
break;
|
||||
return CheckFormatWindows(GsfClipFormatWindows.GSF_CLIP_FORMAT_WINDOWS_METAFILE, "Windows Metafile format", size, ref error);
|
||||
|
||||
case (uint)GsfClipFormatWindows.GSF_CLIP_FORMAT_WINDOWS_DIB:
|
||||
case 2: /* CF_BITMAP */
|
||||
format = CheckFormatWindows(GsfClipFormatWindows.GSF_CLIP_FORMAT_WINDOWS_DIB, "Windows DIB or BITMAP format", size, ref error);
|
||||
break;
|
||||
return CheckFormatWindows(GsfClipFormatWindows.GSF_CLIP_FORMAT_WINDOWS_DIB, "Windows DIB or BITMAP format", size, ref error);
|
||||
|
||||
case (uint)GsfClipFormatWindows.GSF_CLIP_FORMAT_WINDOWS_ENHANCED_METAFILE:
|
||||
format = CheckFormatWindows(GsfClipFormatWindows.GSF_CLIP_FORMAT_WINDOWS_ENHANCED_METAFILE, "Windows Enhanced Metafile format", size, ref error);
|
||||
break;
|
||||
return CheckFormatWindows(GsfClipFormatWindows.GSF_CLIP_FORMAT_WINDOWS_ENHANCED_METAFILE, "Windows Enhanced Metafile format", size, ref error);
|
||||
|
||||
default:
|
||||
format = GsfClipFormatWindows.GSF_CLIP_FORMAT_WINDOWS_UNKNOWN;
|
||||
break;
|
||||
return GsfClipFormatWindows.GSF_CLIP_FORMAT_WINDOWS_UNKNOWN;
|
||||
}
|
||||
|
||||
return format;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -227,7 +219,7 @@ namespace LibGSF
|
||||
if (win_format == GsfClipFormatWindows.GSF_CLIP_FORMAT_WINDOWS_ERROR)
|
||||
return null;
|
||||
|
||||
// gsf_clip_data_get_windows_clipboard_format() already did the size checks for us,
|
||||
// GetWindowsClipboardFormat() already did the size checks for us,
|
||||
// so we can jump to the offset right away without doing extra checks.
|
||||
|
||||
offset = GetWindowsClipboardDataOffset(win_format);
|
||||
@@ -241,6 +233,10 @@ namespace LibGSF
|
||||
return new ReadOnlySpan<byte>(data, (int)offset, (int)ret_size).ToArray();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Utilities
|
||||
|
||||
private static void SetErrorMissingClipboardData(ref Exception error, string format_name, long at_least_size)
|
||||
{
|
||||
error = new InvalidDataException($"The clip_data is in {format_name}, but it is smaller than at least {at_least_size} bytes");
|
||||
@@ -257,11 +253,9 @@ namespace LibGSF
|
||||
// FIXME: does this have a PACKEDMETA in front as well, similar to GSF_CLIP_FORMAT_WINDOWS_METAFILE?
|
||||
new FormatOffsetPair { Format = GsfClipFormatWindows.GSF_CLIP_FORMAT_WINDOWS_ENHANCED_METAFILE, Offset = 4 }
|
||||
};
|
||||
|
||||
int num_pairs = pairs.Length;
|
||||
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num_pairs; i++)
|
||||
for (int i = 0; i < num_pairs; i++)
|
||||
{
|
||||
if (pairs[i].Format == format)
|
||||
return pairs[i].Offset;
|
||||
|
||||
163
BurnOutSharp/External/libgsf/GsfDocMetaData.cs
vendored
163
BurnOutSharp/External/libgsf/GsfDocMetaData.cs
vendored
@@ -31,6 +31,7 @@ using static LibGSF.GsfUtils;
|
||||
|
||||
namespace LibGSF
|
||||
{
|
||||
// TODO: Can this be made internal?
|
||||
public class GsfDocProp
|
||||
{
|
||||
#region Properties
|
||||
@@ -40,7 +41,7 @@ namespace LibGSF
|
||||
public object Value { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Optionally NULL
|
||||
/// Optionally null
|
||||
/// </summary>
|
||||
public string LinkedTo { get; set; }
|
||||
|
||||
@@ -104,9 +105,29 @@ namespace LibGSF
|
||||
return old_val;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A debugging utility to dump prop as text via Console
|
||||
/// </summary>
|
||||
/// <remarks>New in 1.14.2</remarks>
|
||||
public void Dump()
|
||||
{
|
||||
if (Value is List<GsfDocProp> va)
|
||||
{
|
||||
for (int i = 0; i < va.Count; i++)
|
||||
{
|
||||
Console.WriteLine($"\t[{i}] = Name: {va[i].Name}, Value: {va[i].Value}, Link: {va[i].LinkedTo}, Ref: {va[i].RefCount}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"\t= {Value}");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
// TODO: Can this be made internal?
|
||||
public class GsfDocMetaData
|
||||
{
|
||||
#region Properties
|
||||
@@ -122,9 +143,7 @@ namespace LibGSF
|
||||
/// </summary>
|
||||
private GsfDocMetaData() { }
|
||||
|
||||
/// <returns>
|
||||
/// A new metadata property collection
|
||||
/// </returns>
|
||||
/// <returns>A new metadata property collection</returns>
|
||||
public static GsfDocMetaData Create() => new GsfDocMetaData();
|
||||
|
||||
#endregion
|
||||
@@ -164,6 +183,84 @@ namespace LibGSF
|
||||
Table[name] = docProp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If <paramref name="name"/> does not exist in the collection, do nothing. If @name does exist,
|
||||
/// remove it and its value from the collection
|
||||
/// </summary>
|
||||
/// <param name="name">The non-null string name of the property</param>
|
||||
public void Remove(string name)
|
||||
{
|
||||
if (name == null)
|
||||
return;
|
||||
|
||||
if (!Table.ContainsKey(name))
|
||||
return;
|
||||
|
||||
Table.Remove(name);
|
||||
}
|
||||
|
||||
/// <returns>The property with <paramref name="name"/> in meta.</returns>
|
||||
public GsfDocProp Steal(string name)
|
||||
{
|
||||
if (name == null)
|
||||
return null;
|
||||
|
||||
if (!Table.ContainsKey(name))
|
||||
return null;
|
||||
|
||||
GsfDocProp prop = Table[name];
|
||||
if (prop != null)
|
||||
Table.Remove(name);
|
||||
|
||||
return prop;
|
||||
}
|
||||
|
||||
public void Store(GsfDocProp prop)
|
||||
{
|
||||
if (prop == null)
|
||||
return;
|
||||
|
||||
if (prop != Lookup(prop.Name))
|
||||
return;
|
||||
|
||||
Table[prop.Name] = prop;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Iterate through each (key, value) pair in this collection
|
||||
/// </summary>
|
||||
/// <param name="func">The function called once for each element in the collection</param>
|
||||
/// <param name="user_data">Any supplied user data</param>
|
||||
public void ForEach(Action<string, GsfDocProp, object> func, object user_data)
|
||||
{
|
||||
if (Table.Count == 0)
|
||||
return;
|
||||
|
||||
// Sort the pairs by property name in order to generate consistent files
|
||||
List<KeyValuePair<string, GsfDocProp>> pairs = Table.ToList();
|
||||
pairs.Sort((a, b) => DerefStrcmp(a.Key, b.Key));
|
||||
|
||||
for (int i = 0; i < pairs.Count; i++)
|
||||
{
|
||||
func(pairs[i].Key, pairs[i].Value, user_data);
|
||||
}
|
||||
}
|
||||
|
||||
/// <returns>The number of items in this collection</returns>
|
||||
public int Size() => Table.Count;
|
||||
|
||||
/// <summary>
|
||||
/// A debugging utility to dump the content of meta via Console
|
||||
/// </summary>
|
||||
public void Dump()
|
||||
{
|
||||
ForEach(PrintProperty, null);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region MS-OLE
|
||||
|
||||
/// <summary>
|
||||
/// Read a stream formated as a set of MS OLE properties from <paramref name="input"/> and store the
|
||||
/// results in <paramref name="accum"/>.
|
||||
@@ -361,52 +458,6 @@ namespace LibGSF
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If <paramref name="name"/> does not exist in the collection, do nothing. If @name does exist,
|
||||
/// remove it and its value from the collection
|
||||
/// </summary>
|
||||
/// <param name="name">The non-null string name of the property</param>
|
||||
public void Remove(string name)
|
||||
{
|
||||
if (name == null)
|
||||
return;
|
||||
|
||||
if (!Table.ContainsKey(name))
|
||||
return;
|
||||
|
||||
Table.Remove(name);
|
||||
}
|
||||
|
||||
/// <returns>The property with <paramref name="name"/> in meta.</returns>
|
||||
public GsfDocProp Steal(string name)
|
||||
{
|
||||
if (name == null)
|
||||
return null;
|
||||
|
||||
if (!Table.ContainsKey(name))
|
||||
return null;
|
||||
|
||||
GsfDocProp prop = Table[name];
|
||||
if (prop != null)
|
||||
Table.Remove(name);
|
||||
|
||||
return prop;
|
||||
}
|
||||
|
||||
public void Store(GsfDocProp prop)
|
||||
{
|
||||
if (prop == null)
|
||||
return;
|
||||
|
||||
if (Table.ContainsKey(prop.Name) && Table[prop.Name] == prop)
|
||||
return;
|
||||
|
||||
Table[prop.Name] = prop;
|
||||
}
|
||||
|
||||
/// <returns>The number of items in this collection</returns>
|
||||
public int Size() => Table.Count;
|
||||
|
||||
/// <summary></summary>
|
||||
/// <param name="doc_not_component">A kludge to differentiate DocumentSummary from Summary</param>
|
||||
/// <returns>True on success</returns>
|
||||
@@ -539,6 +590,18 @@ namespace LibGSF
|
||||
|
||||
#region Utilities
|
||||
|
||||
private static int DerefStrcmp(string a, string b) => a.CompareTo(b);
|
||||
|
||||
private static void PrintProperty(string name, GsfDocProp prop, object user_data)
|
||||
{
|
||||
if (prop.LinkedTo != null)
|
||||
Console.WriteLine($"prop '{name}' LINKED TO -> {prop.LinkedTo}");
|
||||
else
|
||||
Console.WriteLine($"prop '{name}'");
|
||||
|
||||
prop.Dump();
|
||||
}
|
||||
|
||||
private int CodePageCharSize(int codepage) => (codepage == 1200 || codepage == 1201 ? 2 : 1);
|
||||
|
||||
private static int PropertyCompare(GsfMSOleMetaDataProp prop_a, GsfMSOleMetaDataProp prop_b)
|
||||
|
||||
Reference in New Issue
Block a user