From 7f54c0f49224a25aa232eadf5b18656a8c53fc26 Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Thu, 15 Sep 2016 01:54:13 +0100 Subject: [PATCH] * DiscImageChef.Helpers/StringHandlers.cs: Adds support for OSTA Compressed Unicode. * DiscImageChef.Helpers/DateHandlers.cs: Adds support for timestamps in ECMA-167 format. --- DiscImageChef.Filesystems/UDF.cs | 42 +++++++++++++++++++++++++ DiscImageChef.Helpers/DateHandlers.cs | 26 +++++++++++++++ DiscImageChef.Helpers/StringHandlers.cs | 34 ++++++++++++++++++++ 3 files changed, 102 insertions(+) create mode 100644 DiscImageChef.Filesystems/UDF.cs diff --git a/DiscImageChef.Filesystems/UDF.cs b/DiscImageChef.Filesystems/UDF.cs new file mode 100644 index 000000000..a2860df82 --- /dev/null +++ b/DiscImageChef.Filesystems/UDF.cs @@ -0,0 +1,42 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : UDF.cs +// Author(s) : Natalia Portillo +// +// Component : Component +// +// --[ Description ] ---------------------------------------------------------- +// +// Description +// +// --[ License ] -------------------------------------------------------------- +// +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 2.1 of the +// License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, see . +// +// ---------------------------------------------------------------------------- +// Copyright © 2011-2016 Natalia Portillo +// ****************************************************************************/ +using System; +namespace DiscImageChef.Filesystems +{ + public class UDF + { + public UDF() + { + } + } +} + diff --git a/DiscImageChef.Helpers/DateHandlers.cs b/DiscImageChef.Helpers/DateHandlers.cs index e634e713d..2a0e5fd5b 100644 --- a/DiscImageChef.Helpers/DateHandlers.cs +++ b/DiscImageChef.Helpers/DateHandlers.cs @@ -198,6 +198,32 @@ namespace DiscImageChef { return AppleDoubleEpoch.AddSeconds(AppleDoubleTimeStamp); } + + public static DateTime ECMAToDateTime(ushort typeAndTimeZone, short year, byte month, byte day, byte hour, byte minute, byte second, byte centiseconds, byte hundredsOfMicroseconds, byte microseconds) + { + byte specification = (byte)((typeAndTimeZone & 0xF000) >> 12); + long ticks = (long)centiseconds * 100000 + (long)hundredsOfMicroseconds * 1000 + (long)microseconds * 10; + if(specification == 0) + return new DateTime(year, month, day, hour, minute, second, DateTimeKind.Utc).AddTicks(ticks); + + ushort preOffset = (ushort)(typeAndTimeZone & 0xFFF); + short offset; + + if((preOffset & 0x800) == 0x800) + { + offset = (short)(preOffset | 0xF000); + } + else + offset = (short)(preOffset & 0x7FF); + + if(offset == -2047) + return new DateTime(year, month, day, hour, minute, second, DateTimeKind.Unspecified).AddTicks(ticks); + + if(offset < -1440 || offset > 1440) + offset = 0; + + return new DateTimeOffset(year, month, day, hour, minute, second, new TimeSpan(0, offset, 0)).AddTicks(ticks).DateTime; + } } } diff --git a/DiscImageChef.Helpers/StringHandlers.cs b/DiscImageChef.Helpers/StringHandlers.cs index 2e43fb5bb..a17a2acbe 100644 --- a/DiscImageChef.Helpers/StringHandlers.cs +++ b/DiscImageChef.Helpers/StringHandlers.cs @@ -118,6 +118,40 @@ namespace DiscImageChef return length == 0 ? "" : Encoding.ASCII.GetString(SpacePaddedString, 0, length); } + + /// + /// Converts an OSTA compressed unicode byte array to a C# string + /// + /// The C# string. + /// OSTA compressed unicode byte array. + public static string DecompressUnicode(byte[] dstring) + { + ushort unicode; + byte compId = dstring[0]; + string temp = ""; + + if(compId != 8 && compId != 16) + return null; + + for(int byteIndex = 1; byteIndex < dstring.Length;) + { + if(compId == 16) + unicode = (ushort)(dstring[byteIndex++] << 8); + else + unicode = 0; + + if(byteIndex < dstring.Length) + unicode |= dstring[byteIndex++]; + + if(unicode == 0) + break; + + temp += Encoding.Unicode.GetString(System.BitConverter.GetBytes(unicode)); + } + + return temp; + } + } }