Integrated the data in resources, and used it in the application.

This commit is contained in:
GoldenCrystal
2014-11-05 22:39:31 +01:00
parent 7bfb9b0bc4
commit 85ba8f9c68
16 changed files with 263 additions and 37 deletions
@@ -9,19 +9,10 @@ namespace System.Unicode.Builder
{
internal static class BinaryWriterExtensions
{
//public static void WriteUInt24(this BinaryWriter writer, int value)
//{
// if (value < 0 || value > 0xFFFFFF) throw new ArgumentOutOfRangeException("value");
// writer.Write((byte)(value));
// writer.Write((byte)(value >> 8));
// writer.Write((byte)(value >> 16));
//}
/// <summary>Writes code point in a custom, but compact encoding.</summary>
/// <remarks>
/// Unlike UTF-8, this encoding will consume at most 3 bytes.
/// It could ideally store values between 0x0 and 0x40407F, but this range is useless at the moment.
/// It could ideally store values between 0x0 and 0x40409F, but this range is useless at the moment.
/// </remarks>
/// <param name="writer">The binary writer to use.</param>
/// <param name="value">The value to write</param>
@@ -17,6 +17,10 @@ namespace System.Unicode.Builder
this.baseDirectory = Path.GetFullPath(baseDirectory);
}
public void Dispose()
{
}
public Task<Stream> OpenDataFileAsync(string fileName)
{
return Task.FromResult<Stream>(File.OpenRead(Path.Combine(baseDirectory, fileName)));
@@ -26,6 +26,11 @@ namespace System.Unicode.Builder
this.baseUri = baseUri;
}
public void Dispose()
{
httpClient.Dispose();
}
public Task<Stream> OpenDataFileAsync(string fileName)
{
return httpClient.GetStreamAsync(baseUri + fileName);
+1 -1
View File
@@ -7,7 +7,7 @@ using System.Threading.Tasks;
namespace System.Unicode.Builder
{
public interface IUcdSource
public interface IUcdSource : IDisposable
{
Task<Stream> OpenDataFileAsync(string fileName);
}
+114 -2
View File
@@ -1,15 +1,127 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
namespace System.Unicode.Builder
{
class Program
internal class Program
{
static void Main(string[] args)
public const string UcdDirectoryName = "UCD";
public const string UcdArchiveName = "UCD.zip";
public static readonly string[] ucdRequiredFiles = new[]
{
"UnicodeData.txt",
"PropList.txt",
"Jamo.txt"
};
private static byte[] DownloadUcdArchive()
{
using (var httpClient = new HttpClient())
{
return httpClient.GetByteArrayAsync(HttpUcdSource.UnicodeCharacterDataUri + UcdArchiveName).Result;
}
}
internal static IUcdSource GetUcdSource(bool? shouldDownload, bool? shouldSaveArchive, bool? shouldExtract)
{
string baseDirectory = Environment.CurrentDirectory;
string ucdDirectory = Path.Combine(baseDirectory, UcdDirectoryName);
string ucdArchiveFileName = Path.Combine(baseDirectory, UcdArchiveName);
if (shouldDownload != true)
{
bool hasValidDirectory = Directory.Exists(ucdDirectory);
if (hasValidDirectory)
{
foreach (string ucdRequiredFile in ucdRequiredFiles)
{
if (!File.Exists(Path.Combine(ucdDirectory, ucdRequiredFile)))
{
hasValidDirectory = false;
break;
}
}
}
if (hasValidDirectory)
{
return new FileUcdSource(ucdDirectory);
}
if (File.Exists(ucdArchiveFileName))
{
if (shouldExtract == true)
{
ZipFile.ExtractToDirectory(ucdArchiveFileName, ucdDirectory);
return new FileUcdSource(ucdDirectory);
}
else
{
return new ZipUcdSource(File.OpenRead(ucdArchiveFileName));
}
}
}
if (shouldDownload != false)
{
var ucdArchiveData = DownloadUcdArchive();
if (shouldSaveArchive == true)
{
var stream = File.Open(ucdArchiveFileName, FileMode.Create, FileAccess.ReadWrite, FileShare.Read);
try
{
stream.Write(ucdArchiveData, 0, ucdArchiveData.Length);
ucdArchiveData = null; // Release the reference now, since we won't need it anymore.
if (shouldExtract == true)
{
using (var archive = new ZipArchive(stream, ZipArchiveMode.Read, false))
{
archive.ExtractToDirectory(ucdDirectory);
return new FileUcdSource(ucdDirectory);
}
}
else
{
return new ZipUcdSource(stream);
}
}
catch
{
stream.Dispose();
throw;
}
}
else
{
return new ZipUcdSource(new MemoryStream(ucdArchiveData));
}
}
throw new InvalidOperationException();
}
private static void Main(string[] args)
{
UnicodeDataBuilder data;
using (var ucdSource = GetUcdSource(null, null, null))
{
data = UnicodeDataManager.BuildDataAsync(ucdSource).Result;
}
using (var stream = new DeflateStream(File.Create("ucd.dat"), CompressionLevel.Optimal, false))
data.WriteToStream(stream);
}
}
}
@@ -40,6 +40,8 @@
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.IO.Compression" />
<Reference Include="System.IO.Compression.FileSystem" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
@@ -58,6 +60,7 @@
<Compile Include="UnicodeDataBuilder.cs" />
<Compile Include="UnicodeDataFileReader.cs" />
<Compile Include="UnicodeDataManager.cs" />
<Compile Include="ZipUcdSource.cs" />
</ItemGroup>
<ItemGroup>
<None Include="..\System.Unicode.snk">
@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace System.Unicode.Builder
{
public sealed class ZipUcdSource : IUcdSource
{
private readonly ZipArchive archive;
public ZipUcdSource(Stream stream)
{
archive = new ZipArchive(stream, ZipArchiveMode.Read, false);
}
public void Dispose()
{
archive.Dispose();
}
public Task<Stream> OpenDataFileAsync(string fileName)
{
var entry = archive.Entries.Where(e => e.FullName == fileName).FirstOrDefault();
if (entry == null) throw new FileNotFoundException();
return Task.FromResult(entry.Open());
}
}
}